Claude plans. Your GPU writes the code.
localexec is a local MCP server for Claude Code. It passes small, precisely specified coding tasks to a model running in Ollama on your machine, checks the result with your own tests and linters, and returns a short verdict instead of a diff.
Sent to the local model
GOAL: add() returns the sum of its arguments.
FILES: calc.py
STEPS: In add(), return a + b instead of a - b.
ACCEPTANCE: the syntax check passes.Applied to calc.py
def add(a, b):- return a - b+ return a + bReturned to Claude
{"status":"passed","attempts":1,"files":["calc.py"],"stat":"+1 -1 in 1 file","patch":".localexec/T1-fix-add.patch","log":".localexec/T1-fix-add.log","escalate":false,"why":"all checks passed"}See a task run in 21 seconds
One real task from spec to verdict: Claude writes the brief, a local model makes the edit, your checks decide, and Claude gets a few lines back instead of a diff.
calc.py; the local model changes a - b to a + b; tests, linters and size limits pass; the result returned to Claude is a short JSON verdict. It ends with the install command.How a task runs
- Claude writes a specA short brief: the goal, the files, exact signatures, edge cases and the checks that must pass.
- localexec builds the promptIt adds the files to edit, any context you named and your project conventions, within the model's context budget.
- The local model replies with editsOllama returns search-and-replace blocks. If they do not parse or match, they are sent back for repair. Nothing is written until every block applies.
- Your checks runTests, linters and the size limits run on the result. A failure goes back to the model, up to the attempt limit.
- Claude gets a verdictOne short result: status, files changed and a reason. The full diff and logs wait in .localexec/ until someone asks.
What you get
The model runs on your machine
Code is written by a model in Ollama. localexec needs no API key and makes no network calls except to your Ollama server.
Your checks decide
A task passes when your tests, linters and type checks pass, not when the model sounds sure. You configure them per project in one file.
Results stay short
Claude receives a verdict of a few lines. Reading a diff costs tokens only when a task fails or you want to review it.
Edits are atomic and reversible
Every block must apply or nothing is written. Each task keeps backups, so revert_task restores files exactly.
Files stay small
Optional standards fail a change that leaves a function over 50 code lines or a file over 500, so generated code stays reviewable.
It never commits
Changes stay in your working tree for you to review. localexec reads git status and never touches your history.
Eight tools
Claude calls these over MCP. The first three change your project. The rest only read.
| Tool | What it does |
|---|---|
implement_task | Gives one small task to the local model, applies its edits, runs your checks and retries on failure. |
run_checks | Runs the configured checks and returns pass or fail per check. |
revert_task | Undoes a task: restores changed files and removes files it created. |
list_tasks | Lists recent tasks, one short line each. Use it after losing context. |
show_patch | Skims a task's diff cheaply, with a line cap. |
status | Checks that Ollama is reachable, the model is installed and the config is valid. |
outline | Lists a file's functions, classes and methods with line ranges. |
find | Searches the project with a regular expression. |
Hold generated code to a size limit
Turn on the standards check and every task is measured. A function over 50 code lines fails, and the model is asked to extract helpers. A file over 500 lines fails and goes back to Claude, because splitting a file is a planning decision, not a retry.
Function length
File length
Start in three steps
Install the server and create the model. You need uv, git and Ollama. The guide has the two-line Modelfile.
uv sync ollama create qwen-coder-16k -f ModelfileDescribe your checks. Copy
.localexec.example.jsoninto your project as.localexec.jsonand list the commands that must pass.Register it with Claude Code.
claude mcp add --scope user localexec -- uv run --project <install-dir> localexec-mcp