Local MLX-backed, Claude-Code-style coding agent (Apple Silicon, Ornith 35B/9B)
Project description
chad — a local, MLX-backed coding agent
Claude can do anything, for anyone, anywhere. chad does one thing. 🗿 Coding under supervision.
A single-user coding agent that runs entirely locally on Apple Silicon via MLX. Claude-Code-style tool use (bash, read, write, edit, glob, grep), plan mode, and a full-screen TUI — driven by a local model on your laptop instead of a frontier model in a datacenter. No Docker, no API key, no model picker.
Quickstart
Apple Silicon Mac + uv. One command — no clone, no config:
uvx chad-code # runs chad anywhere — the command is still `chad`
uvx chad-code prove # 2-min offline smoke test: 4 tiny fix-it tasks, verified, timed 🗿
First run picks the right Ornith model for your RAM (9B under 24 GB, 35B at 24 GB+), asks,
and downloads it once (~5 GB / ~13 GB, resumable) into the shared Hugging Face cache. While
it downloads, cd into a project and think of a scoped first ask — "fix the failing test
in tests/test_x.py" lands; "improve my codebase" flails.
The PyPI package is
chad-code; barechadis an unrelated squatted package. Other ways in (PATH install, bleeding-edgemain, dev clone) are in Installing & upgrading.
chad is not a baby Claude
He has some of the same moves — tool use, plan mode, a real TUI — but he's a blunter instrument:
| Claude | chad 🗿 | |
|---|---|---|
| Range | every workflow, every person, incredible nuance | one job: code, on your machine |
| Runs | anywhere — cloud, IDE, terminal, phone | your mac. that's it. |
| Brain | a frontier model in a datacenter | Ornith model |
| Disposition | understands what you meant | does what you said |
| Harness | open-ended, anything you can imagine | plan. execute. nothing else. |
| When wrong | reasons a way out | already shipped |
Real session, unedited (cold model load cut): a local 35B reasons through the failure, edits the file, reruns the tests, confirms green.
Frontier scores, laptop cost
The exam is Terminal-Bench, the standard benchmark for CLI coding agents. chad won't top it — every verified entry on Terminal-Bench 2.1 is a frontier model in a datacenter, scoring 59–84%. The number worth looking at is what that capability costs: the paid field spends $130–$2,000 in API fees per run. chad + Ornith clears 57% on an Apple Silicon laptop, for the electricity — no API, no tokens, no datacenter. On a laptop, capability per dollar is the axis you actually compete on, and chad is the only point on the board that runs there.
Provisional number —
57%(51/89, k=1, self-run, not yet leaderboard-verified). The whole benchmark is publicly reproducible from a Mac: the exact Harbor adapter, the runner, and the recipe live inbenchmarks/tb2/. Check it, don't trust it.
The bet: at this end of the report card, the harness beats the model
Every serious coding harness was built for a frontier model behind a datacenter API — which bakes in two assumptions that are both false on a laptop: the model is an A student, and prefill is somebody else's electricity. A C+ student emits tool calls with typos, quotes edits it never applies, and rambles — and every token of transcript it drags around must be re-read by your GPU at a few hundred tokens a second.
So chad's thesis isn't "run a model locally" — plenty of tools do that. It's that for a small model, harness quality is worth more than a model upgrade, and the harness and inference engine have to be designed together. The failure modes are all nameable: the model pours its edit into the reasoning channel and the harness drops it; asks for a tool the harness doesn't ship; balloons the context until cache reuse hits 0% and decode falls to 2 tok/s. chad handles each inside the harness — tool calls parsed in four dialects and repaired, arguments schema-coerced with a self-repair loop, edits run through a forgiveness cascade, and above all the transcript kept a strict token-prefix of the live KV cache so prefill never re-reads what it already read. That co-design is the whole moat. The full story is in Design & internals.
Installing & upgrading
The one-line quickstart (uvx chad-code) is up top. The other ways in:
uv tool install chad-code # install for good — then it's just `chad`
uvx --from git+https://github.com/nathansutton/chad chad # bleeding-edge main, no clone
Or from a clone (the dev path):
uv sync # install deps + the `chad` entrypoint (one time)
uv run chad # full-screen TUI
uv run chad "add a --json flag to main.py and update the tests" # one-shot, headless
uv run chad -c # resume this directory's last conversation
The model. chad picks one for you by RAM and downloads it once into the shared Hugging
Face cache (~/.cache/huggingface, reused across every project). Override with
--model 9b / --model 35b, or --model <repo or local dir> for anything else.
| Your Mac | Model | Footprint |
|---|---|---|
| ≥ 24 GB | Ornith-1.0-35B UD-Q2_K_XL — 35B MoE, 2-bit experts |
~13 GB resident (~16 GB with KV) |
| 16 / 18 GB | Ornith-1.0-9B UD-Q4_K_XL — 4-bit AWQ |
~5 GB |
The 35B's floor used to be 32 GB — its working set SIGKILLed a 24 GB Mac mid-turn. The
fused attention kernel and the 8-bit-from-the-start KV cache it enables cut the per-token
cache cost enough to give that headroom back, and the compaction trigger now sizes itself
from the live Metal budget, so a tight box narrows its context window instead of dying.
24 GB runs the 35B; 16/18 GB still get the 9B. If a 24 GB machine feels tight next to your
other apps, --model 9b puts it back. Quant names follow
Unsloth's dynamic-quant convention (UD-…).
Upgrading — depends on how you installed: uv tool upgrade chad-code; uvx --refresh chad-code; or git pull && uv sync for a clone. What changed lands in
CHANGELOG.md. Model weights are versioned separately — a code upgrade never
re-downloads the model.
Development. uv sync once, then uv run pytest -q — the fast unit gate loads no
model weights, runs in seconds, and is what CI runs. Throughput on your own machine:
uv run chad-bench (see Throughput & performance). LSP-precise
find-references / rename need the lsp extra (uv tool install 'chad-code[lsp]'); without
it chad uses the tree-sitter fallback automatically.
Interactive UX
uv run chad launches a full-screen terminal UI (built on prompt_toolkit):
- shift-tab cycles permission modes —
normal(confirm each bash/write/edit) →auto-accept edits→plan mode(read-only: investigate + propose a numbered plan) → back. - type-ahead message queue — keep typing while the agent works; messages run in order.
- ctrl-c interrupts the running turn without killing the session.
- live status line — model, mode, context %, a state glyph + verb, elapsed seconds, and ↑prefilled / ↓generated token counts (with an advancing % on an unavoidable full re-prefill, so it's never silent).
- slash commands —
/init,/skills,/mcp,/accept,/resume,/compact,/model,/mode,/help,/exit. Same set in the--replline interface. @file/@dirmentions and!commandshell passthrough — pull a file into context inline, or run a shell command without invoking the model.
Usage. uv run chad --help is the source of truth:
| Flag | What it does |
|---|---|
-c, --continue |
resume this directory's most recent session (non-destructive) |
--resume |
list recent sessions, pick one by number (interactive TTY only) |
--plan |
start in read-only plan mode (investigate + propose, edits blocked) |
--yolo |
auto-approve bash/write/edit (skip confirm prompts) |
--no-think |
skip Ornith's <think> blocks — faster on well-scoped work |
--model |
35b, 9b, auto, or any HF repo id / local model dir |
--repl |
plain line REPL instead of the TUI |
Plus three subcommands, each with its own --help:
| Command | What it does |
|---|---|
chad serve |
serve this Mac's model to a container or the LAN (Configuration) |
chad prove |
2-minute offline smoke test: 4 tiny fix-it tasks, verified, timed |
chad levers |
print the harness lever registry as JSON (ablation driver) |
A headless task (positional, or piped with no TTY) auto-approves mutating tools; the model
runs greedy (temp 0). Every conversation is persisted under ~/.chad/sessions/, and every
resume forks a new branch rather than overwriting — details in
Configuration. The rarely-touched tuning knobs
(CHAD_MAX_CONTEXT, CHAD_KV_BITS, turn-budget/think-cap, safety opt-outs) all live in
environment variables, fully documented there.
Extending chad
chad speaks the same two extension formats as Claude Code:
- Agent Skills — drop a
SKILL.mdfolder in./.claude/skills/and chad discovers it, loading the full instructions only when a task matches. - MCP servers — configure stdio or HTTP servers in
./.mcp.jsonto expose external tools (GitHub, Postgres, Linear, Slack, …) alongside chad's builtins, with static-token and OAuth auth.
Both are covered in full in the Configuration reference.
Documentation
- Design & internals — why prefill is the bill, the persistent prefix cache, the trimmable/append-only trade, and the ideas borrowed from other agents.
- Throughput & performance — prefill / decode / warm-step numbers
you can reproduce with
chad-bench. - Terminal-Bench 2.1 reproduction — the exact Harbor adapter and runner behind the chart; serve Ornith yourself and check the number.
- Configuration reference — Agent Skills, MCP servers, the context window, every environment variable, and the safety opt-outs.
- Troubleshooting — when a session rambles, loops, or slows: the symptom→knob map for a small local model.
- Contributing — what lands easily, and what needs a conversation first.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file chad_code-1.0.5.tar.gz.
File metadata
- Download URL: chad_code-1.0.5.tar.gz
- Upload date:
- Size: 539.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ba36be44dc8b79491ad250e24d32b4cd97d85fd68f18224b01288333de8b6deb
|
|
| MD5 |
49e2226aa19eff8c897ff531701b3352
|
|
| BLAKE2b-256 |
2bc66d4ebb5a0e2cfb66b8f75944c2d059ad35e78e7a63495b74c86bc946e005
|
Provenance
The following attestation bundles were made for chad_code-1.0.5.tar.gz:
Publisher:
publish.yml on nathansutton/chad
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
chad_code-1.0.5.tar.gz -
Subject digest:
ba36be44dc8b79491ad250e24d32b4cd97d85fd68f18224b01288333de8b6deb - Sigstore transparency entry: 2256522985
- Sigstore integration time:
-
Permalink:
nathansutton/chad@487a3c25da88eb77477166a7a297a626c58605a2 -
Branch / Tag:
refs/tags/v1.0.5 - Owner: https://github.com/nathansutton
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@487a3c25da88eb77477166a7a297a626c58605a2 -
Trigger Event:
push
-
Statement type:
File details
Details for the file chad_code-1.0.5-py3-none-any.whl.
File metadata
- Download URL: chad_code-1.0.5-py3-none-any.whl
- Upload date:
- Size: 345.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fd4f9ef6a6200012d2de9ca11a518d098e408dd1b43db4e525bdfb0b46e00509
|
|
| MD5 |
06cf836bee7d82e882876ceb7d3f3a30
|
|
| BLAKE2b-256 |
8393d72760ddafa138b77a06c0ac514f44125cceea6f78875c179ceccab28a90
|
Provenance
The following attestation bundles were made for chad_code-1.0.5-py3-none-any.whl:
Publisher:
publish.yml on nathansutton/chad
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
chad_code-1.0.5-py3-none-any.whl -
Subject digest:
fd4f9ef6a6200012d2de9ca11a518d098e408dd1b43db4e525bdfb0b46e00509 - Sigstore transparency entry: 2256522991
- Sigstore integration time:
-
Permalink:
nathansutton/chad@487a3c25da88eb77477166a7a297a626c58605a2 -
Branch / Tag:
refs/tags/v1.0.5 - Owner: https://github.com/nathansutton
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@487a3c25da88eb77477166a7a297a626c58605a2 -
Trigger Event:
push
-
Statement type: