MCP server that routes mechanical dev tasks to a local LLM
Project description
pedalpoint
Route mechanical development tasks to a local LLM (Ollama, LM Studio, Jan) via Claude Code. Automatically falls back to local-only mode when Claude quota is exhausted.
What it does
- Hybrid routing: Claude classifies each task. Mechanical work (scaffolding, CRUD, test stubs) goes to your local LLM. Judgment work (architecture, debugging, integration) stays with Claude.
- Three-tier quota fallback: When Claude Pro returns a quota error, pedalpoint first routes judgment and structural tasks to Claude API (pay-per-token) while mechanical tasks continue on local LLM. If the API key is absent or Claude API quota is also exhausted, all tasks fall back to local LLM. Restores to normal when quota recovers.
- Context Courier: Before sending any task to the local LLM, pedalpoint greps your codebase for existing patterns and injects them into the prompt. Local LLMs only get tasks they have templates for.
- Single install: One script installs the MCP server, pulls the default model, and registers the companion skill.
Requirements
- Claude Code
- Python 3.11+
- Ollama (or any OpenAI-compatible inference server)
Install
curl -fsSL https://raw.githubusercontent.com/EMSwank/pedalpoint/main/install.sh | sh
With a custom model or endpoint:
curl -fsSL https://raw.githubusercontent.com/EMSwank/pedalpoint/main/install.sh | \
sh -s -- --model llama3 --base-url http://localhost:11434/v1
Restart Claude Code after install.
Note: If installing without the script, use
uv tool install pedalpoint— notpip install -e .. The tool install putspedalpoint-serverin PATH where Claude Code can find it.
Usage
Ollama must be running before you open Claude Code:
ollama serve # or open Ollama.app on macOS
Then in any Claude Code session:
/route-tasks
pedalpoint handles routing automatically. No manual flagging needed.
To verify the MCP server connected:
claude mcp get pedalpoint
Should show Status: ✓ Connected. If disconnected, run pedalpoint-server directly to see the error.
Modes
| Mode | Set via | Behavior |
|---|---|---|
hybrid |
default | Claude classifies each task into mechanical (local LLM direct), structural (local LLM draft + Agent review), or judgment (Agent only) |
local-only |
PEDALPOINT_MODE=local-only |
All tasks → local LLM (use when quota exhausted preemptively) |
passthrough |
PEDALPOINT_MODE=passthrough |
All tasks → Claude Agent (disables pedalpoint) |
Configuration
| Variable | Default | Description |
|---|---|---|
PEDALPOINT_BASE_URL |
http://localhost:11434/v1 |
OpenAI-compatible endpoint |
PEDALPOINT_MODEL |
gemma4:e4b |
Default local model |
PEDALPOINT_MODE |
hybrid |
Routing mode |
PEDALPOINT_TIMEOUT |
120 |
Read timeout in seconds |
PEDALPOINT_INITIAL_FALLBACK_MINUTES |
60 |
Initial circuit-open duration (doubles on each probe failure) |
PEDALPOINT_API_MODEL |
claude-sonnet-4-6 |
Claude model used for API fallback |
ANTHROPIC_API_KEY |
(unset) | Anthropic API key for Claude API fallback tier. Optional — if unset, circuit skips api_fallback and goes directly to open. |
Uninstall
curl -fsSL https://raw.githubusercontent.com/EMSwank/pedalpoint/main/install.sh | sh -s -- --uninstall
Troubleshooting
| Symptom | Fix |
|---|---|
local_llm calls fail with "Ollama not reachable" |
ollama serve (or open Ollama.app on macOS) |
local_llm fails with "Model gemma4:e4b not found" |
ollama pull gemma4:e4b |
/route-tasks says local_llm tool not available |
claude mcp get pedalpoint (check status; if missing, re-run install) |
claude_api returns "ANTHROPIC_API_KEY not set" — api_fallback tier disabled |
export ANTHROPIC_API_KEY=sk-ant-... then restart Claude Code |
| All tasks route to local LLM even after Claude quota resets | echo '{"circuit":"closed"}' > ~/.pedalpoint/state.json |
Development
git clone https://github.com/EMSwank/pedalpoint
cd pedalpoint
uv sync --extra dev # or: pip install -e ".[dev]"
pytest tests/unit/ -v
Integration tests (requires Ollama running):
PEDALPOINT_INTEGRATION=true pytest tests/integration/ -v
Install script tests (requires bats-core):
brew install bats-core # macOS; use apt-get install bats on Linux
bats tests/install/
License
MIT
Project details
Release history Release notifications | RSS feed
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 pedalpoint-0.3.0.tar.gz.
File metadata
- Download URL: pedalpoint-0.3.0.tar.gz
- Upload date:
- Size: 62.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
929dc7ee4c0cc1fab69c9fec21ec28cded687d99f65c89f9a047ecfb3fdfa2b7
|
|
| MD5 |
0a631e0feece01cd1fda27df483b4886
|
|
| BLAKE2b-256 |
72239c3d95031ffe92eaa7ec236341a99e019e9dd256469ee1ecde163e42d31b
|
Provenance
The following attestation bundles were made for pedalpoint-0.3.0.tar.gz:
Publisher:
release.yml on EMSwank/pedalpoint
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pedalpoint-0.3.0.tar.gz -
Subject digest:
929dc7ee4c0cc1fab69c9fec21ec28cded687d99f65c89f9a047ecfb3fdfa2b7 - Sigstore transparency entry: 1521077342
- Sigstore integration time:
-
Permalink:
EMSwank/pedalpoint@c450268c3e8226565a584db8435102ed7db4377f -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/EMSwank
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@c450268c3e8226565a584db8435102ed7db4377f -
Trigger Event:
push
-
Statement type:
File details
Details for the file pedalpoint-0.3.0-py3-none-any.whl.
File metadata
- Download URL: pedalpoint-0.3.0-py3-none-any.whl
- Upload date:
- Size: 9.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1f418083b1a83de3ba7dbb7e5751877df0813e5a24f541e2a0139fa60f6a3058
|
|
| MD5 |
f6cc7d65ddd0eb6b879e97912b8767a9
|
|
| BLAKE2b-256 |
0ac151917cff60d313e26504ccc0fc598faaab5069f265d294bce3301c74fad7
|
Provenance
The following attestation bundles were made for pedalpoint-0.3.0-py3-none-any.whl:
Publisher:
release.yml on EMSwank/pedalpoint
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pedalpoint-0.3.0-py3-none-any.whl -
Subject digest:
1f418083b1a83de3ba7dbb7e5751877df0813e5a24f541e2a0139fa60f6a3058 - Sigstore transparency entry: 1521077354
- Sigstore integration time:
-
Permalink:
EMSwank/pedalpoint@c450268c3e8226565a584db8435102ed7db4377f -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/EMSwank
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@c450268c3e8226565a584db8435102ed7db4377f -
Trigger Event:
push
-
Statement type: