Cached at:
05/31/26, 03:26 AM
# mlx-code — local LLM coding agent for Apple Silicon
Source: [https://josefalbers.github.io/mlx-code/](https://josefalbers.github.io/mlx-code/)
Apple Silicon · MLX · Local\-first
## A coding agent that*ships its own LLM* **and talks to everything else\.**
mlx\-code bundles an MLX inference server, a minimal terminal harness, multi\-protocol API support, git worktree isolation, and composable multi\-agent primitives — all in one Python package\. Run it offline, pipe it into shell scripts, or swap in any external API\.
$pip install mlx\-code
$mlc
requires Python 3\.11\+ · Apple Silicon · mlx\-lm installed automatically
// How it works
One package, three layers\. The MLX server runs the local model and speaks every major API dialect\. The harness layer decides who drives — the built\-in REPL or an external tool like Claude Code\. Tools are dispatched in a loop until the task is done\.
harness — built\-in
Minimal terminal REPL
Streams to stdout\. Composable with shell pipes\.`/branch`,`/abort`,`/history`slash commands\. No dependencies beyond the package\.
harness — external \(\-\-leash\)
Claude Code · Codex · Gemini CLI
Routes any external harness through the local server by setting`ANTHROPIC\_BASE\_URL`/`OPENAI\_BASE\_URL`/`GEMINI\_BASE\_URL`before launch\.
harness — library
Agent API
Import`Agent`directly\. Compose pipelines, fork parallel workers, resume from git commits\. No server required for library use\.
↓ HTTP or in\-process ↓
inference server · main\.py · batteries included
MLX\-LM local model \+ multi\-protocol server
Ships its own inference engine\. No separate server process to manage\. Speaks four API dialects on the same port\.
OpenAI /v1/chat/completionsOpenAI /v1/responsesAnthropic /v1/messagesGemini generateContentDeepSeek
↓ token stream ↓↓ tool calls dispatched ↓
built\-in tools \(9\)
`Read``Write``Edit``Bash``Grep``Find``Ls``Skill``Agent`
isolation
Fresh git worktree per session\. Commits after every tool round\-trip\. Full conversation in commit message — resume any checkpoint\.
extensibility
Subclass`Tool`with a Pydantic schema\. Pass at instantiation\. LSP, knowledge base, and custom DB tools ship as examples\.
// What's inside
01
Batteries\-included local model
Ships with`mlx\-lm`as the inference backend\. Download any`mlx\-community`model and`mlc`serves it immediately — no separate Ollama, llama\.cpp, or API key needed\.
02
Multi\-protocol API server
One server, four dialects: OpenAI`/v1/chat/completions`, OpenAI`/v1/responses`, Anthropic`/v1/messages`, and Gemini`generateContent`\. SSE streaming on all routes\.
03
Shell\-native REPL
Streams to stdout\. Reads from stdin when not a TTY, so it composes naturally in pipelines\. Chain tasks, redirect outputs, or build multi\-step workflows entirely in the shell\.
04
Git worktree isolation
Every session starts from a clean worktree on a new branch\. Every tool call commits — file state*and*conversation history\. Go off the rails? You have a full timeline to debug or resume from\.
05
Multi\-agent pipelines
Spawn sub\-agents via the`Agent`tool or`asyncio\.gather`for parallel workers\. Context decay is real — delegating subtasks keeps both contexts focused\.
06
Swappable harnesses
Use the built\-in REPL or`\-\-leash claude/codex/gemini`to point any external harness at your local model\. Same weights, different front\-end — or`mlc\-run`to target a remote API instead\.
// Shell composability
Because`mlc`reads stdin when it isn't a TTY, it behaves like any Unix tool\. Pipe outputs between tasks, redirect results, or chain multiple agents in a single command\.
```
# ask for a solution, then immediately critique it
echo "Here's the solution: <excerpt>$(mlc -p "write a chrome extension to play YouTube at 5x speed")</excerpt>
Now argue against it. What edge cases doesn't it handle?" | mlc
# research agent → extraction agent via pipe
mlc -p "summarise BFT consensus into kb/draft.md" && \
mlc -p "read kb/draft.md, extract papers to kb/papers.json"
# target a remote deepseek model instead of local
echo "explain lsp.py" | mlc-run --api deepseek --model deepseek-v3
# chain two remote endpoints: first explains, second plans
echo "explain lsp.py" | mlc-run -a deepseek | cat - PLAN.md | mlc-run --url http://localhost:9000
```
// Usage
```
# Install and run — local MLX model, built-in REPL
pip install mlx-code
mlc
# Specific model
mlc --model mlx-community/Qwen3.5-4B-OptiQ-4bit
# Use Claude Code as the harness, local model as the brain
mlc --leash claude --work ~/my-project
# Restrict available tools, add a system prompt
mlc --tools Read Write Bash --system "You are a careful refactoring assistant."
# Server only — hit it from curl or your own script
mlc --leash none --port 8000
# mlc-run: harness only, no local model — point at any endpoint
mlc-run --api claude
mlc-run --api deepseek --model deepseek-v3
mlc-run --url http://192.168.1.5:8000
```
```
import asyncio
from mlx_code.repl import Agent
async def main():
# Simple single agent
agent = Agent(system="You are a concise technical writer.")
await agent.run(
"Summarise all *.py files changed in the last 7 days. Save to digest.md."
)
# Pipe: researcher writes, reviewer critiques
researcher = Agent(system="You are a research assistant.")
await researcher.run("Research PBFT. Save structured summary to kb/draft.md.")
reviewer = Agent(system="You are a critical reviewer.")
await reviewer.run(
"Read kb/draft.md. Write a one-paragraph critique to kb/critique.md. "
"Use ONLY information already in that file."
)
asyncio.run(main())
```
```
import asyncio
from mlx_code.repl import Agent
async def main():
# Fork three agents in parallel, each owns one subtopic
# Delegating keeps contexts focused — avoids context decay
topics = ["history", "algorithms", "industry_usage"]
agents = [Agent() for _ in topics]
await asyncio.gather(*[
a.run(f"Research the {t} of Byzantine Fault Tolerance. Save to kb/{t}.md.")
for a, t in zip(agents, topics)
])
# Single reducer synthesises all outputs
reducer = Agent()
await reducer.run("Read all files in kb/. Synthesise into final_report.md.")
asyncio.run(main())
```
```
from mlx_code.tools import Tool
from mlx_code.repl import Agent
from pydantic import BaseModel, Field
class QueryParams(BaseModel):
query: str = Field(description="SQL query to run")
class LiveDBTool(Tool):
name = "QueryDB"
description = "Execute a query against the dev database"
parameters = QueryParams
async def execute(self, params: QueryParams, signal=None) -> dict:
result = run_query(params.query)
return {"content": [{"type": "text", "text": result}], "is_error": False}
# Pass extra_tool_classes at instantiation — no global registry
agent = Agent(extra_tool_classes=[LiveDBTool], tool_names=["QueryDB"])
```
```
import asyncio
from mlx_code.gits import resume_worktree
from mlx_code.repl import Agent, repl
# Every commit stores the full conversation as JSON in the message.
# resume_worktree restores both file state and agent memory.
async def main():
gwt, messages = resume_worktree(".", "abc1234")
agent = Agent(ctx={"gwt": gwt})
agent.messages = messages
await repl(agent) # pick up exactly where you left off
asyncio.run(main())
```
// \-\-leash modes
The`\-\-leash`flag decides what harness runs against the local MLX server\. Use`mlc\-run`to skip the local model entirely and connect to a remote provider\.
local model \(mlc\) — harness optionsnoapidefaultmlcBuilt\-in terminal REPL\. Streams to stdout, reads from stdin when not a TTY\.claudemlc \-\-leash claudeLaunches Claude Code with`ANTHROPIC\_BASE\_URL`pointed at the local server\.codexmlc \-\-leash codexLaunches Codex CLI via a generated profile routing to the local`/v1`endpoint\.geminimlc \-\-leash geminiSpawns Gemini CLI with`GOOGLE\_GEMINI\_BASE\_URL`set to the local server\.nonemlc \-\-leash noneServer only — no harness\. Bring your own client or hit it from curl\.no local model \(mlc\-run\) — remote providersclaudemlc\-run \-\-api claudeHarness only, routed to Anthropic's API\.geminimlc\-run \-\-api geminiHarness only, routed to Google Gemini\.deepseekmlc\-run \-\-api deepseekHarness only, routed to DeepSeek\.custommlc\-run \-\-url http://…Any OpenAI\-compatible endpoint — another machine, a VM, a cloud instance\.