| name | claude-code-local-mlx |
| description | Run Claude Code 100% on-device with local AI on Apple Silicon using MLX-native models (Qwen 3.5 122B, Llama 3.3 70B, Gemma 4 31B, DeepSeek V4 Flash) |
| triggers | ["set up local claude code","run claude code offline","install mlx local ai","configure qwen llama gemma locally","run deepseek v4 flash locally","setup airgap ai on apple silicon","run anthropic api server locally","configure mlx-lm with claude code"] |
Claude Code Local — MLX On-Device AI
Skill by ara.so — Claude Code Skills collection.
Run Claude Code 100% on-device with local AI on Apple Silicon. This project provides an MLX-native Anthropic-API-compatible server that lets you use powerful local models (Qwen 3.5 122B at 65 tok/s, Llama 3.3 70B, Gemma 4 31B, DeepSeek V4 Flash with 1M context) as drop-in replacements for Claude. Built for privacy-critical workflows (NDA, legal, healthcare) where data cannot leave the device.
What It Does
- MLX-native inference optimized for Apple Silicon (M1/M2/M3/M4)
- Anthropic API compatibility — point Claude Code clients at
localhost:8000
- Four model options: Gemma 4 31B (fast), Qwen 3.5 122B (balanced), Llama 3.3 70B (dense), DeepSeek V4 Flash (1M context)
- 100% offline — works in airplane mode, airgap-ready
- Voice mode — hands-free coding with on-device STT/TTS
- Browser agent — remote access from any device on your LAN
Installation
Prerequisites
python3 --version
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
Quick Start (3 Commands)
git clone https://github.com/nicedreamzapp/claude-code-local.git
cd claude-code-local
pip install -r requirements.txt
bash scripts/start-mlx-server.sh
The server will:
- Download the model from HuggingFace (~65 GB for Qwen)
- Start an Anthropic-API-compatible server on
http://localhost:8000
- Print usage instructions
Model Selection
Set MLX_MODEL environment variable before starting:
export MLX_MODEL="bartowski/gemma-4-code-it-31b-MLX-4bit"
bash scripts/start-mlx-server.sh
export MLX_MODEL="mlx-community/Qwen3.5-MoE-A10B-4bit"
bash scripts/start-mlx-server.sh
export MLX_MODEL="divinetribe/Llama-3.3-70B-Instruct-abliterated-8bit-mlx"
bash scripts/start-mlx-server.sh
DeepSeek V4 Flash Setup
DeepSeek uses the separate ds4 engine:
git clone https://github.com/antirez/ds4.git ~/.ds4
cd ~/.ds4
make
huggingface-cli download antirez/deepseek-v4-gguf \
deepseek-v4-q2.gguf --local-dir ~/.ds4/models
~/.local/bin/ds4-server-up
~/.local/bin/claude-ds4 "your prompt here"
Configuration
Claude Code Client Setup
Point your Claude Code client to the local server:
export ANTHROPIC_API_KEY="sk-ant-local-placeholder"
export ANTHROPIC_BASE_URL="http://localhost:8000"
./claude-local "create a react component for a todo list"
Server Configuration
Create config/server.yaml:
server:
host: "0.0.0.0"
port: 8000
model:
name: "mlx-community/Qwen3.5-MoE-A10B-4bit"
max_tokens: 256000
temperature: 0.7
performance:
cache_prompt: true
max_kv_size: 256000
Launcher Scripts
The project includes .command launchers for double-click execution:
"Claude Local.command"
"Gemma 4 Code.command"
"DeepSeek V4 Flash.app"
Key Commands
Starting the Server
bash scripts/start-mlx-server.sh
MLX_MODEL="mlx-community/Qwen3.5-MoE-A10B-4bit" \
bash scripts/start-mlx-server.sh
PORT=8080 bash scripts/start-mlx-server.sh
python3 scripts/monitor.py
Using the API
import anthropic
client = anthropic.Anthropic(
api_key="sk-ant-local-placeholder",
base_url="http://localhost:8000"
)
with client.messages.stream(
model="qwen-3.5-122b",
max_tokens=4096,
messages=[
{"role": "user", "content": "Write a Python function to parse JSON"}
]
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)
Voice Mode Setup
pip install -r requirements-voice.txt
python3 scripts/download-voice-models.py
bash scripts/start-voice-server.sh
python3 scripts/voice-client.py
Browser Agent
Access Claude Code from any device on your LAN:
python3 scripts/browser-agent-server.py
Real Code Examples
Example 1: Basic Coding Task
"""Send a coding task to local Claude Code"""
import anthropic
client = anthropic.Anthropic(
api_key="sk-ant-local",
base_url="http://localhost:8000"
)
response = client.messages.create(
model="local",
max_tokens=8192,
messages=[{
"role": "user",
"content": """Create a FastAPI endpoint that:
1. Accepts POST with JSON {query: str}
2. Validates query is 1-500 chars
3. Returns {result: str, timestamp: int}
Include error handling and type hints."""
}]
)
print(response.content[0].text)
Example 2: Document Analysis (Airgap Mode)
"""Analyze confidential document with offline AI"""
import anthropic
import sys
def analyze_nda(filepath):
with open(filepath, 'r') as f:
doc_text = f.read()
client = anthropic.Anthropic(
api_key="sk-ant-local",
base_url="http://localhost:8000"
)
response = client.messages.create(
model="llama-3.3-70b",
max_tokens=16384,
messages=[{
"role": "user",
"content": f"""Analyze this NDA for:
1. Term length
2. Geographic scope
3. Definition of confidential info
4. Carve-outs and exceptions
5. Red flags
Document:
{doc_text}"""
}]
)
return response.content[0].text
if __name__ == "__main__":
result = analyze_nda(sys.argv[1])
print(result)
Example 3: Long-Context Processing (DeepSeek)
"""Use DeepSeek V4 Flash for 1M token context"""
import anthropic
import glob
def analyze_codebase(directory):
files = glob.glob(f"{directory}/**/*.py", recursive=True)
codebase = ""
for filepath in files[:100]:
with open(filepath, 'r') as f:
codebase += f"\n\n# {filepath}\n{f.read()}"
client = anthropic.Anthropic(
api_key="sk-ant-local",
base_url="http://localhost:8001"
)
response = client.messages.create(
model="deepseek-v4-flash",
max_tokens=32000,
messages=[{
"role": "user",
"content": f"""Analyze this entire codebase:
1. Architecture patterns used
2. Security vulnerabilities
3. Performance bottlenecks
4. Suggested refactorings
Codebase:
{codebase}"""
}]
)
return response.content[0].text
result = analyze_codebase("./my-project")
print(result)
Example 4: Streaming with Tool Use
"""Stream responses with tool calling"""
import anthropic
tools = [{
"name": "run_bash",
"description": "Execute a bash command and return output",
"input_schema": {
"type": "object",
"properties": {
"command": {"type": "string", "description": "Bash command"}
},
"required": ["command"]
}
}]
client = anthropic.Anthropic(
api_key="sk-ant-local",
base_url="http://localhost:8000"
)
with client.messages.stream(
model="qwen-3.5",
max_tokens=4096,
tools=tools,
messages=[{
"role": "user",
"content": "List all Python files in current directory and count lines"
}]
) as stream:
for event in stream:
if event.type == "content_block_delta":
if hasattr(event.delta, "text"):
print(event.delta.text, end="", flush=True)
elif event.type == "tool_use":
print(f"\n[Tool call: {event.name}]")
Common Patterns
Pattern 1: Multi-Model Workflow
"""Use different models for different tasks"""
import anthropic
def get_client(model_port):
return anthropic.Anthropic(
api_key="sk-ant-local",
base_url=f"http://localhost:{model_port}"
)
gemma = get_client(8000)
quick_response = gemma.messages.create(
model="gemma-4",
max_tokens=1024,
messages=[{"role": "user", "content": "Summarize: <long text>"}]
)
qwen = get_client(8001)
deep_analysis = qwen.messages.create(
model="qwen-3.5",
max_tokens=8192,
messages=[{
"role": "user",
"content": f"Analyze this summary: {quick_response.content[0].text}"
}]
)
Pattern 2: Prompt Caching for Speed
"""Leverage KV cache for repeated contexts"""
import anthropic
client = anthropic.Anthropic(
api_key="sk-ant-local",
base_url="http://localhost:8000"
)
system_prompt = """You are an expert Python developer.
Follow PEP 8, use type hints, write docstrings.
Prefer dataclasses over dicts, use pathlib over os.path.
[... 5000 more tokens of coding guidelines ...]"""
response1 = client.messages.create(
model="qwen",
max_tokens=2048,
system=system_prompt,
messages=[{"role": "user", "content": "Write a parser"}]
)
response2 = client.messages.create(
model="qwen",
max_tokens=2048,
system=system_prompt,
messages=[{"role": "user", "content": "Write a validator"}]
)
Pattern 3: Airgap Verification
"""Verify no network calls during inference"""
import subprocess
import anthropic
import time
monitor = subprocess.Popen(
["lsof", "-i", "-n", "-P"],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
client = anthropic.Anthropic(
api_key="sk-ant-local",
base_url="http://localhost:8000"
)
response = client.messages.create(
model="llama-3.3",
max_tokens=4096,
messages=[{"role": "user", "content": "Analyze sensitive data"}]
)
time.sleep(2)
monitor.terminate()
stdout, _ = monitor.communicate()
external = [
line for line in stdout.decode().split('\n')
if 'ESTABLISHED' in line and '127.0.0.1' not in line
]
if external:
print(f"⚠️ External connections detected:\n{chr(10).join(external)}")
else:
print("✅ Airgap verified: no external connections")
Troubleshooting
Issue: Model download fails
huggingface-cli whoami
huggingface-cli login
huggingface-cli download mlx-community/Qwen3.5-MoE-A10B-4bit \
--local-dir ~/.cache/huggingface/hub/models--mlx-community--Qwen3.5-MoE-A10B-4bit
Issue: Out of memory
vm_stat | perl -ne '/page size of (\d+)/ and $size=$1; /Pages\s+([^:]+)[^\d]+(\d+)/ and printf("%-16s % 16.2f Mi\n", "$1:", $2 * $size / 1048576);'
export MLX_MODEL="bartowski/gemma-4-code-it-31b-MLX-4bit"
export MAX_KV_SIZE=32768
Issue: Slow inference
python3 scripts/profile-inference.py
sudo powermetrics --samplers gpu_power -i 1000
export METAL_DEVICE_WRAPPER_TYPE=1
export METAL_DEBUG_ERROR_MODE=0
Issue: API compatibility errors
tail -f logs/mlx-server.log
curl http://localhost:8000/v1/messages \
-H "Content-Type: application/json" \
-H "x-api-key: sk-ant-local" \
-d '{
"model": "local",
"max_tokens": 100,
"messages": [{"role": "user", "content": "test"}]
}'
pip show anthropic
Issue: DeepSeek V4 Flash won't start
cd ~/.ds4
make clean && make
ls -lh ~/.ds4/models/deepseek-v4-q2.gguf
tail -f ~/.ds4/server.log
~/.ds4/ds4 -m ~/.ds4/models/deepseek-v4-q2.gguf \
-p "Test prompt" -c 200000
Issue: Voice mode not working
python3 -c "
from faster_whisper import WhisperModel
model = WhisperModel('base')
segments, _ = model.transcribe('test.wav')
print(list(segments))
"
python3 scripts/test-tts.py "Hello world"
Performance Benchmarks
| Model | Tokens/sec | Claude Code Task | RAM | Context |
|---|
| Gemma 4 31B | ~15 | 56s | 18 GB | 128K |
| Qwen 3.5 122B | 65 | 17.6s | 75 GB | 256K |
| Llama 3.3 70B | ~12 | 137s | 75 GB | 128K |
| DeepSeek V4 Flash | ~32 | 45s | 81 GB | 1M |
Tested on M4 Max 128GB. "Claude Code Task" = generate HTML physics animation with live counters.
Environment Variables Reference
export MLX_MODEL="mlx-community/Qwen3.5-MoE-A10B-4bit"
export PORT=8000
export HOST="0.0.0.0"
export MAX_KV_SIZE=256000
export CACHE_PROMPT=true
export ANTHROPIC_API_KEY="sk-ant-local-placeholder"
export ANTHROPIC_BASE_URL="http://localhost:8000"
export DS4_MODEL_PATH="$HOME/.ds4/models/deepseek-v4-q2.gguf"
export DS4_PORT=8001
export DS4_CONTEXT=200000
export WHISPER_MODEL="base"
export TTS_VOICE="af_bella"
export VOICE_SERVER_PORT=5001
export BROWSER_AGENT_PORT=5000
export BROWSER_AGENT_HOST="0.0.0.0"
Integration with Claude Code
VS Code Extension
- Install Claude Code extension
- Configure settings.json:
{
"claude.apiKey": "sk-ant-local-placeholder",
"claude.apiUrl": "http://localhost:8000",
"claude.model": "qwen-3.5-122b"
}
CLI Wrapper
ln -s "$(pwd)/claude-local" /usr/local/bin/claude-local
claude-local "refactor this function to use async/await"
Cursor IDE
Add to Cursor settings:
{
"claude.overrideApiUrl": "http://localhost:8000",
"claude.overrideApiKey": "sk-ant-local"
}
This skill covers the essential knowledge for using claude-code-local with MLX on Apple Silicon, from installation through advanced patterns and troubleshooting.