MCP connector for multi-backend LLM routing (DeepSeek, GLM, Codex) with native Claude Code orchestration
Project description
mcp-brain-router
An MCP server for Claude Code and Codex that delegates agentic sub-tasks to external CLI workers, returning structured answers with metadata.
What It Is
mcp-brain-router is a local Model Context Protocol server shared by Claude Code, Codex, and Grok. Standard calls select a role (worker, simple, thinker, or adversary) and run an agentic CLI worker in the caller's absolute working directory. Each role owns an ordered provider shard and advances only on confirmed quota exhaustion. Legacy complexity calls (cheap, code, adversarial) remain single-provider.
Why It Exists
Keep orchestration separate from worker selection. The human chooses Claude, Codex, or Grok as orchestrator; the router owns the worker shard and its quota-only fallback policy:
- Worker: GLM 5.2 → Grok → Codex Terra → Claude Sonnet 5.
- Simple: GLM 4.7 → Codex Luna → Claude Haiku.
- Thinker: Claude Fable → Codex Sol.
- Adversary: Claude Opus 4.8 → Codex Sol, excluding the orchestrator's provider.
Every role call is agentic-only and requires cwd. Timeouts, authentication errors, process errors, and empty output stop loud; they never trigger provider fallback.
Install
Zero-friction setup:
git clone https://github.com/mohan-n-swamy/mcp-brain-router.git
cd mcp-brain-router
pip install -e .
mcp-brain-router-install
The install script will:
- Interactively prompt for API keys and detect installed Codex/Grok CLIs.
- Store secrets in
~/.config/mcp-brain-router/config.toml(mode 0600, gitignored). - Register the same MCP in installed Claude Code, Codex, and Grok clients with distinct caller identity.
claude mcp add brain-router -e BRAIN_ROUTER_CALLER=claude -- python -m mcp_brain_router.server - Run smoke tests (one cheap call, one code call, codex if enabled).
Re-running the script updates keys idempotently without duplicating the registration.
Usage from Claude Code
from mcp import delegate
# Trivial task: brainstorm 10 ideas
answer = delegate(
complexity="cheap",
prompt="Brainstorm 10 naming ideas for a CLI tool that routes tasks to cheaper LLMs."
)
print(answer)
# Returns:
# {
# "answer": "1. TaskRouter\n2. TierDispatch\n...",
# "backend": "deepseek",
# "model": "deepseek-v4-flash",
# "complexity": "cheap",
# "tokens_in": 120,
# "tokens_out": 340,
# "est_cost": 0.0024,
# "source": "external-untrusted"
# }
# Code review: ask GLM to review Python logic
code_snippet = "def merge(a, b): return sorted(a + b)"
answer = delegate(
complexity="code",
prompt=f"Review this merge function for correctness and efficiency:\n{code_snippet}"
)
# Adversarial: ask Codex to find the worst flaw in your design
answer = delegate(
complexity="adversarial",
prompt="I'm caching user sessions in memory for 24 hours. What's the single worst thing that can happen?"
)
Role-based routing
Configure ordered candidates in ~/.config/mcp-brain-router/config.toml, then call. This role-based path owns the standard agentic cascade; callers must not recreate it with repeated complexity= calls:
delegate(role="worker", orchestrator="claude", mode="agentic", cwd="/abs/repo", prompt="Implement this isolated task")
delegate(role="adversary", orchestrator="codex", mode="agentic", cwd="/abs/repo", prompt="Refute this design")
Roles: thinker, adversary, worker, simple. orchestrator is never
router-selected. Candidate order comes only from [roles]. Standard worker
order is GLM → Grok → Codex → Claude. Only genuine quota exhaustion advances;
timeouts, process errors, authentication failures, and empty answers stop loud.
All public role calls are agentic-only and require absolute cwd. Anthropic
candidates run through cc-brain claude. Only the adversary role excludes the
orchestrator's provider; every other role may use it.
Legacy delegate(complexity=..., prompt=...) remains supported and single-tier.
Use it only for an explicit one-provider request, not the standard cascade.
Tier Map
| Tier | Backend | Model | Use Case | Cost | Speed |
|---|---|---|---|---|---|
cheap |
GLM | glm-4.7 | Explicit fast single-provider request | — | Fastest |
code |
GLM | glm-5.2 | Code review, algorithm design, debugging | ~$0.50/1M tokens | Fast |
adversarial |
Codex | gpt-5.5, low effort (via Codex CLI) | Security reviews, refutation, second opinion | Higher | Slowest |
Enforced role policy
worker: GLM 5.2 → Grok → Codex Terra → Claude Sonnet 5.simple: GLM 4.7 → Codex Luna → Claude Haiku.thinker: Claude Fable → Codex Sol.adversary: Claude Opus 4.8 → Codex Sol; candidate matching the orchestrator provider is skipped.- Provider advancement happens only on confirmed quota exhaustion. Timeout, process, authentication, permission, and empty-output failures stop loud.
Claude, Codex, and Grok each register the same MCP with distinct
BRAIN_ROUTER_CALLER identity. Orchestrator remains human-selected.
Codex registration example:
[mcp_servers.brain-router]
command = "python"
args = ["-m", "mcp_brain_router.server"]
env = { BRAIN_ROUTER_CALLER = "codex" }
Architecture
┌──────────────────────────┐
│ Claude / Codex / Grok │ Human-selected orchestrator
│ native CLI + same MCP │
└────────────┬─────────────┘
│
│ MCP call: delegate(role, prompt, cwd)
│
┌────────────▼──────────────────────────────────┐
│ mcp-brain-router (this tool) │ Local MCP server
│ Routes by configured role candidates │
│ Returns answer + metadata │
└──┬─────────────────┬───────────────┬───────────┘
│ │ │
│ (own API key) │ (OAuth CLI) │ (subscription CLI)
│ │ │
┌──▼──────────┐ ┌───▼────────┐ ┌──▼────────────┐
│ GLM │ │ Grok/Codex │ │ Claude CLI │ Agentic workers
│ API + CLI │ │ local CLI │ │ fallback │
│ │ │ │ │ │
└─────────────┘ └────────────┘ └───────────────┘
Key point:
- The router may launch native Claude CLI as a configured role fallback.
- Provider credentials stay inside their native API/CLI auth paths.
- Worker output is labeled external-untrusted regardless of provider.
Configuration
After installation, your config lives at ~/.config/mcp-brain-router/config.toml:
deepseek_key = "sk-..."
glm_key = "..."
codex_enabled = true
grok_enabled = true
# headroom_base_url = "http://localhost:8282"
[model_overrides]
adversarial = "gpt-5.5"
[roles]
thinker = ["claude-fable-5", "gpt-5.6-sol"]
adversary = ["claude-opus-4-8", "gpt-5.6-sol"]
worker = ["glm-5.2", "grok-4.5", "gpt-5.6-terra", "claude-sonnet-5"]
simple = ["glm-4.7", "gpt-5.6-luna", "claude-haiku-4-5-20251001"]
GPT-5.6 routing policy
gpt-5.6-solis the capability-first adversarial candidate. Production default remainsgpt-5.5until representative eval promotion.gpt-5.6-terrais an explicit cost-balanced candidate; adopt only after the same representative adversarial eval holds.gpt-5.6-lunais for efficient high-volume work, not the default refutation/security lane.- Keep
model_reasoning_effort="low"as the migration baseline; comparenoneon the same eval before lowering it. - Reserve pro mode or
maxeffort for quality-first tasks with measured gain; the CLI worker does not enable either by default. - Codex runs as an ephemeral, direct CLI worker. Responses-API explicit caching and Programmatic Tool Calling do not apply to this backend unless it is deliberately migrated to that API surface.
- Model efficiency never replaces caller fallback, timeout, nested-Codex prevention, untrusted-output handling, or downstream verification.
Changing keys later:
mcp-brain-router-install # Re-runs setup, updates config, skips Claude Code re-registration
Validating the repo:
pytest -q
Validating the installed MCP path:
delegate(complexity="code", prompt="Health check. Reply exactly PONG.")
Compliance
Short version: role shards can launch GLM, Grok, Codex, or native Claude CLI workers. The prior non-Anthropic-only compliance analysis is invalid after this migration. Treat subscription-backed automated workers as personal/testing-only pending explicit policy confirmation.
See COMPLIANCE.md for the full, sourced analysis of how this design respects Anthropic's Consumer Terms and the third-party tool landscape.
Troubleshooting
"Config not found / unconfigured backend"
mcp-brain-router-install # Re-run setup
"DeepSeek call failed: 429 rate limit"
You've hit the provider limit. The tool returns exhausted=true; the orchestrator decides whether to call another tier or handle the task natively. The router never crosses tiers itself.
"Codex not installed"
The tool is optional. If codex binary is not on your PATH, adversarial-tier calls fail with a clear message. Install Codex CLI separately if you want this tier:
# Installation depends on your Codex provider; example:
pip install codex-cli
"Headroom proxy not responding"
The tool routes DeepSeek/GLM through your local headroom proxy when configured. If that proxy is down, the call returns an error; clear headroom_base_url or restart the proxy to use the backend again.
"TypeError: delegate() got unexpected keyword"
Check your function call signature against the Usage section above. The tool accepts complexity (required), prompt (required), and model (optional override).
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 mcp_brain_router-0.1.1.tar.gz.
File metadata
- Download URL: mcp_brain_router-0.1.1.tar.gz
- Upload date:
- Size: 59.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
16e4a89401455bbea4978bd7e3a241c7add4e2c9b44b72ed26a37afa005ac370
|
|
| MD5 |
5578cc5cc065e2edca7326f4b911d61a
|
|
| BLAKE2b-256 |
cba4eff355e3bd026b1348327a1b51e0862b78ae3d37178d9e7b5f385c0c5146
|
File details
Details for the file mcp_brain_router-0.1.1-py3-none-any.whl.
File metadata
- Download URL: mcp_brain_router-0.1.1-py3-none-any.whl
- Upload date:
- Size: 41.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b4d418d481878baf8fd6e0f8d87eaf5f208d38964ffd10c5337b6d19d2e6ef7c
|
|
| MD5 |
0c947c36f1b44cc4336ef57f82fbe576
|
|
| BLAKE2b-256 |
4643b07d4ff1898d656f44b3401c3ce27ab1931eac42a13fcffbe5aa8558a7bd
|