ToolsExplainer
Claude Code Router explained: running Claude Code on GPT, Gemini and local models
How Claude Code Router uses ANTHROPIC_BASE_URL to run Claude Code on other models: setup, routing rules, tool-call and caching caveats, and when a gateway fits.

Claude Code Router is an open-source proxy that lets Claude Code, Anthropic’s terminal coding agent, send its requests to models other than Claude: GPT, Gemini, DeepSeek, Qwen, Kimi or a model running on your own machine. It works by standing in for the Anthropic API on 127.0.0.1:3456, picking a model for each request by rule, and translating the request into whatever format that model’s provider speaks.
That matters because Claude Code’s agent loop, permission model and tooling are what many developers want, while the model behind it is the expensive part. The router lets an individual developer keep the harness and change the engine, or mix engines: a cheap model for background chatter, a reasoning model for planning, a long-context model when the conversation grows. This explainer is for developers deciding whether to try it and for platform teams who are about to find it on their colleagues’ laptops.
It covers what the project is, the Claude Code settings it relies on, a step-by-step setup, how the routing rules decide, the caveats Anthropic and the providers document, and the point at which a personal router should give way to a shared gateway.
What Claude Code Router is, and what it is not
Claude Code Router (CCR) is an MIT-licensed project by the developer musistudio, first published on GitHub in February 2025. Its README now describes it as “a local model gateway and control plane for coding agents” that gives each agent “one stable local endpoint” while you manage providers, models, accounts and routing rules behind it.
The project has grown well beyond its name. Version 3, the current line (v3.1.3 was released on 9 October 2026), ships as a desktop app for macOS, Windows and Linux and as an npm package, @musistudio/claude-code-router, that needs Node.js 22 or newer. It now fronts several agents besides Claude Code, including Codex, Grok CLI, Kimi CLI, Kilo Code and OpenCode, and speaks five upstream protocols: OpenAI Chat, OpenAI Responses, Anthropic Messages, Gemini Generate Content and Gemini Interactions.
The core capabilities listed in the README fall into five groups:
- Providers: presets and custom endpoints, protocol probing, model discovery and credential pools that rotate several keys for one provider.
- Routing: conditions on request headers and bodies, rewrites, retries and ordered fallback models.
- Tools: “Fusion” models that bolt vision or web search onto a model that lacks them, an MCP tool hub and browser automation.
- Access: separate CCR client keys with expiry and local request, token and image limits.
- Observability: request and response details, the resolved provider and model, latency, tokens and estimated cost.
What it is not is a team service. Its defaults bind to localhost, its configuration lives in a SQLite file in your home directory (~/.claude-code-router/config.sqlite on macOS and Linux, per the install guide), and its limits and logs describe one machine. A Docker distribution exists for running it as a persistent endpoint, and the docs say plainly to read the deployment guide before exposing it remotely. The project is best understood as a developer’s personal switchboard, which is the frame this article uses.
It is also not the only way to point Claude Code somewhere else. Several providers now expose their own Anthropic-compatible endpoints, and organisations run AI gateways that do the same job centrally. The router’s distinctive feature is per-request model choice inside one Claude Code session, without anyone else’s infrastructure.
How Claude Code reaches a model: ANTHROPIC_BASE_URL and the model variables
Claude Code decides where to send model requests from two environment variables: ANTHROPIC_BASE_URL, the address, and a credential variable. Anything that answers at that address in the Anthropic Messages format is treated as the Claude API. Claude Code Router, a gateway and a provider’s compatible endpoint all plug in at the same point.
Anthropic documents this under the heading “LLM gateway”. The gateway compatibility guide says that when a developer sets ANTHROPIC_BASE_URL, “Claude Code treats the gateway as the Claude API and can’t tell which upstream you forward to.” Inference requests post to /v1/messages?beta=true; /v1/messages/count_tokens is optional, and without it Claude Code falls back to a character-based estimate of context usage.
The credential variable
The connection guide lists three ways to authenticate, and each lands in a different HTTP header:
| Variable | Header sent | Use when |
|---|---|---|
ANTHROPIC_AUTH_TOKEN | Authorization: Bearer | The endpoint expects a bearer token |
ANTHROPIC_API_KEY | x-api-key | The endpoint expects an API key header |
apiKeyHelper | Both | The credential rotates or comes from a vault |
The choice has billing consequences. Anthropic’s gateway overview notes that setting ANTHROPIC_AUTH_TOKEN turns off subscription login for the session, so requests are no longer charged against a claude.ai plan. Setting only ANTHROPIC_BASE_URL, with no credential variable, leaves a saved claude.ai login active, and that login is what gets sent. For a router that forwards to other providers, you want the credential variable set.
The variables can be exported in a shell, or placed in the env block of ~/.claude/settings.json so they apply everywhere Claude Code runs, including background agents. When both exist, the settings-file value wins. Anthropic warns against putting a credential in a project’s committed .claude/settings.json. Running /status inside Claude Code shows the active base URL and credential source, which is the fastest way to confirm a router is in the path.
The model variables
The address decides where requests go; a separate set of variables decides which model name Claude Code puts in them. The model configuration page documents:
ANTHROPIC_MODELor--model: the model for the session you launch.ANTHROPIC_DEFAULT_OPUS_MODEL,ANTHROPIC_DEFAULT_SONNET_MODEL,ANTHROPIC_DEFAULT_HAIKU_MODELandANTHROPIC_DEFAULT_FABLE_MODEL: what theopus,sonnet,haikuandfablealiases resolve to. The Haiku variable also sets the model for “background functionality”.CLAUDE_CODE_SUBAGENT_MODEL: the default for subagents, agent-team teammates and workflow agents that are not assigned a model another way.ANTHROPIC_CUSTOM_MODEL_OPTION: adds one custom entry to the/modelpicker, with no validation of the string.CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY=1: asks the endpoint’s/v1/modelsat startup and adds what it returns to the picker. It is off by default.
One detail explains much of the router’s design. For an ANTHROPIC_BASE_URL connection authenticated with ANTHROPIC_AUTH_TOKEN, the compatibility guide says background tasks run on the main model unless ANTHROPIC_DEFAULT_HAIKU_MODEL pins one. Claude Code also assumes a 200K context window for model IDs it does not recognise. A router that wants to treat background work differently, or a model with a smaller window, has to know both facts.

Figure 1: The router sits where Claude Code expects the Claude API. Everything after that point, including translation, is outside Anthropic’s support.
Setting up Claude Code Router, step by step
Setup takes four moves: install the router, add a provider and its key, start the local gateway, and point Claude Code at it. Version 3 does most of this through a management UI; the older config.json workflow from version 2 is still widely documented and is shown afterwards for readers on that line.
Version 3: desktop app or npm CLI
The CLI reference gives the terminal route:
npm install -g @musistudio/claude-code-router
ccr ui
ccr ui starts a background service and opens the management UI at http://127.0.0.1:3458. The model gateway itself listens on http://127.0.0.1:3456. On a headless machine, ccr ui --no-open does the same without a browser, and ccr serve runs in the foreground for process supervisors or when you need to see startup errors.
From there the documented order is:
- Add a provider. Under Providers, choose a preset or “Other / custom API endpoint”, enter the key, and let CCR auto-detect the protocol and models. The provider guide says Check Connection sends a real request, which “may still consume a few tokens”.
- Create a client key. Under API Keys, create a CCR client key. The docs separate the management token, which protects the UI, from client keys, which authenticate model requests.
- Set a default model and rules. Choose the default model and any routing rules and fallbacks.
- Start the gateway. Under Server, click Start and confirm it shows Running;
GET /healthshould return 200. - Point the agent at it. Use Agent Config to generate a Claude Code profile, then launch Claude Code from CCR (
ccr <profile-name>), or set the variables yourself.
Setting the variables by hand looks like any other gateway connection:
export ANTHROPIC_BASE_URL=http://127.0.0.1:3456
export ANTHROPIC_AUTH_TOKEN=<your CCR client key>
claude
The project’s troubleshooting page lists the usual reason the router is not in the path: Claude Code was opened directly rather than from CCR, or the Agent Config profile is not applied to the current project. /status in Claude Code and the router’s Logs page, which shows the requested model, resolved provider and resolved model, settle the question.
Version 2: the config.json workflow
Most tutorials still describe version 2, where everything lived in ~/.claude-code-router/config.json. Version 3 reads that file only as a migration source when no SQLite configuration exists. A trimmed version 2 configuration shows the shape:
{
"APIKEY": "a-local-secret",
"Providers": [
{ "name": "deepseek", "api_base_url": "https://api.deepseek.com/chat/completions",
"api_key": "$DEEPSEEK_API_KEY", "models": ["deepseek-chat", "deepseek-reasoner"],
"transformer": { "use": ["deepseek"] } },
{ "name": "ollama", "api_base_url": "http://localhost:11434/v1/chat/completions",
"api_key": "ollama", "models": ["qwen2.5-coder:latest"] }
],
"Router": {
"default": "deepseek,deepseek-chat",
"background": "ollama,qwen2.5-coder:latest",
"think": "deepseek,deepseek-reasoner",
"longContextThreshold": 60000
}
}
Each provider declares a base URL, a key (environment interpolation with $VAR is supported), its models and a list of transformers: adapters that rewrite requests and responses for a given API. The built-in set included deepseek, gemini, openrouter, groq, maxtoken, tooluse (nudges tool use through tool_choice), enhancetool (adds error tolerance to tool-call arguments, at the cost of no longer streaming them) and cleancache (strips cache_control fields).
Version 2 started Claude Code with ccr code, or exported the variables into the shell with eval "$(ccr activate)", which set ANTHROPIC_AUTH_TOKEN, ANTHROPIC_BASE_URL, NO_PROXY, DISABLE_TELEMETRY, DISABLE_COST_WARNINGS and API_TIMEOUT_MS. Inside a session, /model provider,model switched models on the fly. The README also notes that when no APIKEY is set, the host is forced to 127.0.0.1, a sensible default worth keeping.
Routing rules: background, think, long context and subagents
The router’s reason to exist is choosing a different model per request. Version 2 did this with fixed scenario slots, detected from the shape of each request; version 3 replaces them with an ordered rule list plus built-in handling for Claude Code and its subagents.
The version 2 scenario slots
The Router block took six slots besides default. The table pairs each with the trigger in the project’s router source, which is more precise than the README:
| Slot | What the README says | What the code checks |
|---|---|---|
longContext | Long contexts, default threshold 60,000 tokens | Estimated tokens above longContextThreshold, or last turn’s input above it and current request above 20,000 |
| Subagent tag | Route a subagent to a named model | System prompt block starting with <CCR-SUBAGENT-MODEL>provider,model</CCR-SUBAGENT-MODEL> |
background | Background tasks, can be a small local model | Requested model name contains both claude and haiku |
webSearch | Web search tasks | A tool whose type starts with web_search |
think | Reasoning-heavy tasks such as Plan Mode | The request carries a thinking field |
default | General tasks | Anything else |
Two lessons come from reading the code. First, order matters: a long conversation goes to the long-context model even when thinking is on, because that check runs first. Second, the background slot depends entirely on Claude Code asking for a Haiku-named model. Given Anthropic’s note that ANTHROPIC_AUTH_TOKEN connections run background tasks on the main model unless ANTHROPIC_DEFAULT_HAIKU_MODEL is set, a user who wants the background slot to fire should set that variable to a Haiku model ID so the router can recognise and redirect it.
Version 2 also allowed per-project and per-session Router overrides, and a CUSTOM_ROUTER_PATH pointing at a JavaScript module that returns "provider,model" or null to fall through to the defaults.

Figure 2: Version 2 checks scenarios in a fixed order, so a long conversation reaches the long-context model even when thinking is switched on.
Version 3: ordered rules, scripts and fallbacks
The version 3 routing documentation describes three layers.
Built-in routes. A Claude Code route sends main requests to the model in the Claude Code Agent Config when the client has not selected a model CCR recognises. Subagent routing survives as a tag mechanism: if any model on the Models page has a Description, CCR injects the list of models and descriptions into the Agent and Task tool descriptions, Claude Code writes <CCR-SUBAGENT-MODEL>provider/model</CCR-SUBAGENT-MODEL> at the top of a spawned agent’s prompt, and CCR strips the tag and routes that request accordingly. The docs suggest descriptions such as “Good for code search, file triage, summaries” for a cheap model and “Good for reading large logs, long documents” for a long-context one. In effect, the model chooses its own subagent models from your menu.
Custom rules. Each rule has a condition on a request header or a body path (for example request.body.model starts with claude-, or messages contains deep image), one or more rewrites (usually setting request.body.model), and an on-failure policy. Rules match in list order and the first enabled match wins. When a single condition is not enough, a rule can run a local Node.js script that sees the full request, an estimated token count and a summary of tool names, and returns a model, rewrites and fallback behaviour. Scripts that throw or time out “fail open” to the next rule, and three failures in 60 seconds open a 30-second circuit breaker for that rule.
Fallback. Three modes apply globally or per rule: Off, Retry (same model, on 408, 409, 429 and 5xx) and Fallback targets (an ordered list of alternative models, triggered by any 4xx or 5xx). CCR honours Retry-After when the upstream sends it, otherwise backs off exponentially from one second to a 30-second cap, and reports what happened in x-ccr-fallback-* response headers.
The docs also include an optional example script that classifies requests whose model is auto with an external decision model and picks between a fast and a reasoning model, a pattern covered in our piece on what decision models like Jev are for. The docs are candid that its tests “cover the contract and fallback behavior, without measuring live classification accuracy or latency”.
A long-context rule in version 3 is therefore something you write, typically a script rule on input.tokenCount, rather than a slot you fill. The upside is that the same machinery covers routing by repository, by header or by tool list.
Using Claude Code with GPT, Gemini, DeepSeek and local models
There are three ways to run Claude Code on another model, and the router is only one of them. The right one depends on whether the target provider already speaks Anthropic’s format, and whether you need per-request switching between models.
Provider endpoints that already speak Anthropic’s format
Some providers now accept Anthropic Messages requests directly, which removes the translation step.
DeepSeek documents an Anthropic-format base URL at https://api.deepseek.com/anthropic in its API guide. It maps Claude model names on arrival: names starting with claude-opus go to deepseek-v4-pro, and claude-haiku or claude-sonnet names go to deepseek-flash; unsupported names also fall back to deepseek-flash. Its compatibility table is worth reading line by line: the anthropic-beta header is ignored on /messages, thinking is supported but budget_tokens is ignored, and cache_control on tool definitions is ignored.
Ollama runs the same idea locally. Its Claude Code integration page offers a one-line launcher, ollama launch claude, or a manual setup:
export ANTHROPIC_AUTH_TOKEN=ollama
export ANTHROPIC_API_KEY=""
export ANTHROPIC_BASE_URL=http://localhost:11434
claude --model qwen3.5
Ollama tells users to pick a model that supports tools, and says that “hosted WebSearch and advanced tool controls are not fully supported”. For teams weighing local inference more broadly, our ranking of gateways for routing between vLLM, Ollama and cloud LLMs covers the serving side.
Providers that do not: the translation job
OpenAI’s and Google’s native APIs do not accept Anthropic’s request format, so something must convert messages, tool definitions, tool results, streaming events and thinking blocks in both directions. That is exactly what CCR’s protocol adapters (and version 2’s transformers) do, and what gateways with an Anthropic-compatible front do. The conversion is not lossless: Anthropic-specific fields such as cache_control, server tools like web_search, and thinking signatures have no exact counterpart, so each adapter has to decide what to drop, emulate or reject.
Choosing the route
| Approach | Example | Per-request model switching | Translation | Best fit |
|---|---|---|---|---|
| Provider’s Anthropic endpoint | DeepSeek, Ollama | No, one provider | None needed | Trying one alternative model quickly |
| Personal router | Claude Code Router | Yes, by rule or tag | In the router | One developer mixing several providers |
| Shared gateway | LiteLLM, Bifrost, Kong, Cloudflare | Yes, by model name or gateway rule | In the gateway | Teams that need keys, budgets and logs |
For the third row, the comparison in our ranking of gateways for Claude Code, Codex CLI and Cursor is the place to start; this article stays with the router.
Caveats: tool calling, prompt caching and features that quietly break
Running Claude Code on another model works often enough to be useful and fails in ways that are easy to misread. Anthropic does not support it; the substitute model may mishandle tools; caching can switch off without an error; and some Claude Code features depend on endpoints a router does not serve.
Anthropic’s position
Anthropic’s LLM gateway page is direct: Anthropic “doesn’t endorse, maintain, or audit third-party gateway products, and doesn’t support routing Claude Code to non-Claude models through any gateway.” It also warns that Claude Code “adds capabilities with each release, and a gateway that doesn’t forward them breaks the corresponding features.” A router is a gateway in this sense, maintained by one open-source project, and it has to keep pace with Claude Code’s release cadence.
Tool-calling fidelity
Claude Code is an agent: nearly everything it does, from reading files to running tests, is a tool call. A substitute model has to emit well-formed tool calls with valid JSON arguments, in Anthropic’s shape after translation, many times per task. The failure modes are documented by the tools themselves:
- Bifrost’s Claude Code page states the hard requirement plainly: the chosen model must support tool calling “for the operations you intend to perform”, and it reports that some upstreams, OpenRouter at the time of writing, do not stream function-call arguments properly, so calls arrive with empty arguments and file operations fail.
- Claude-specific server tools (
web_search, computer use, citations) exist only on Claude models from providers that expose them. - CCR’s version 2 shipped
tooluseandenhancetooltransformers precisely because some models’ tool calls needed coaxing or repair, and version 3 rewrites Codex’s freeformapply_patchtool into an ordinary function tool for non-GPT models because many third-party models “handle ordinary function tools more reliably”.
The practical test is short. Before trusting a model, run a task that edits several files, runs a command and reads its output, and compare the result with a Claude model on the same task. If a tool call misbehaves, Bifrost’s guidance applies to any router: swap back to a known-good Claude model to establish whether the problem is the model or the configuration.
Prompt caching
Caching is the caveat with the largest cost effect, because it fails silently. Claude Code attaches cache_control markers to its system prompt and message history so that the stable prefix of each request is billed as a cache read. Anthropic’s prompt caching documentation prices cache reads at 0.1 times the base input price on most models, and lower on some newer ones, against 1.25 times for a five-minute cache write. On a long agent session, that is the difference between paying for the conversation once and paying for it on every turn.
The compatibility guide spells out what happens when a proxy interferes: there is no error, “the conversation bills as uncached input on every turn, visible as high input_tokens with little or no cache activity”. Its remedy is to forward cache_control unchanged and not to flatten block-form system or message content into strings.
Once a request leaves Anthropic’s format, the rules change again. OpenAI’s prompt caching guide caches automatically on supported models but requires “the entire rendered prefix to match”, with a 1,024-token minimum on recent models; DeepSeek’s Anthropic endpoint ignores cache_control on tools and runs its own context caching. A router that injects text into the system prompt per request, or that alternates providers mid-conversation, can defeat whichever cache the provider runs. Gateways address the second problem with session affinity: Bifrost’s session affinity adopts the x-claude-code-session-id header Claude Code already sends, so each conversation keeps landing on the provider and key that holds its cache.
Smaller things that break
- Context window assumptions. Claude Code assumes 200K tokens for a model ID it does not recognise. A model with a smaller window will overflow before Claude Code thinks it should compact, which is one reason the long-context route exists.
- Beta fields. Claude Code sends the same beta headers and body fields it sends to Anthropic. Upstreams that reject them return
400errors naming fields such ascontext_management;CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS=1removes most of them. - Fine-grained tool streaming is off by default whenever a custom base URL is set.
- Traffic outside the router. Version checks and telemetry still go to Anthropic.
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1turns them off, and also turns off auto-updates. - Subscription features. With a gateway credential active, requests do not use a claude.ai plan, and Bifrost’s documentation notes that Remote Control and voice dictation are unavailable in that mode.

Figure 3: The three ways to put another model behind Claude Code differ less in routing than in who holds the keys and who can see the spend.
When a team should move from a personal router to a shared gateway
A personal router is the right tool while one developer is experimenting. It becomes the wrong one as soon as several people copy the setup, because each laptop then holds its own provider keys, its own rules and its own logs. Anthropic’s gateway documentation describes what the shared version provides: credentials that stay server-side, usage attributed per developer, budgets and rate limits in one place, audit logging, and provider switching “without touching developer machines”.
The signals that a team has crossed that line are concrete:
- Keys are being shared. Developers paste the same provider key into their routers, so revoking one person means rotating everyone.
- Nobody can answer “who spent what”. Anthropic’s own cost guidance puts average enterprise Claude Code spend at about $13 per developer per active day and $150 to $250 per developer per month, with 90 per cent of users below $30 per active day. A team multiplying that by a dozen developers needs per-person numbers.
- Outages hit everyone differently. Each router has its own fallback list, or none.
- Policy matters. Someone needs to decide which providers may see the codebase, and enforce it.
The rollout Anthropic describes is the same for any gateway: deploy it with the provider credentials, issue each developer a gateway credential, distribute ANTHROPIC_BASE_URL and the credential through managed settings, and have developers confirm with /status. Managed settings can also set allowedProviders to ["customEndpoint"] with a pinned ANTHROPIC_BASE_URL, so Claude Code refuses any other destination, including a developer’s own router (this needs Claude Code v2.1.285 or later).
| Need | Personal router | Shared gateway |
|---|---|---|
| Provider keys | On each laptop | Held server-side |
| Developer identity | None, or a local client key | One revocable credential per developer |
| Budgets and rate limits | Local limits per machine | Per developer, team and organisation |
| Failover | Per-machine fallback list | One policy for everyone |
| Logs and cost | Local, per machine | Central, attributable |
| Enforcing the destination | Not possible | allowedProviders in managed settings |
What the gateway options look like
Anthropic now ships its own option, the Claude apps gateway, inside the claude binary. It routes to the Anthropic API, Amazon Bedrock, Claude Platform on AWS, Google Cloud or Microsoft Foundry, signs developers in through the corporate identity provider and enforces model access by group. It is the lowest-friction choice for a team that only wants Claude models; every upstream it lists is a Claude endpoint.
For teams that want Claude Code to reach other providers as well, the gateway needs an Anthropic-compatible endpoint and a model catalogue that spans vendors. Bifrost, an open-source AI gateway written in Go, is a strong fit for that job and the most direct team-scale equivalent of what a router does on one laptop. Its Claude Code integration exposes an Anthropic-compatible path at /anthropic; developers set ANTHROPIC_BASE_URL to it and put a Bifrost virtual key (sk-bf-…) in ANTHROPIC_AUTH_TOKEN. The same alias variables then point at any configured provider with a prefix, for example:
{
"env": {
"ANTHROPIC_BASE_URL": "https://bifrost.example.com/anthropic",
"ANTHROPIC_AUTH_TOKEN": "sk-bf-your-virtual-key",
"ANTHROPIC_DEFAULT_SONNET_MODEL": "vertex/gemini-3.1-pro",
"ANTHROPIC_DEFAULT_HAIKU_MODEL": "openai/gpt-5.5"
}
}
Inside a session, /model openai/gpt-5.5 switches provider, and model discovery fills the picker from the gateway. The governance a router lacks comes from the rest of the gateway: virtual keys carry per-key model and provider allow-lists, budgets with reset periods from a minute to a year, and token and request rate limits; retries and fallbacks rotate keys on per-key failures and move to the next provider when one fails; built-in logs record tokens, cost and latency per request; and session affinity keeps each Claude Code conversation on one provider so its prompt cache stays warm. Its published benchmark reports 11 µs of added overhead per request at 5,000 requests per second. Advanced controls (SSO, RBAC, audit logs, guardrails, clustering) come with the enterprise tier. The product overview is on the Bifrost page, and the broader case for putting this layer in front of every model call is set out on Maxim’s LLM gateway page.
LiteLLM is the other widely used open-source option, with a Claude Code quickstart and a long series of Claude Code tutorials covering cost tracking and non-Anthropic models. Kong, Cloudflare and Vercel also document Claude Code setups for hosted or existing-platform deployments; the trade-offs between them are covered in our comparison of five LLM gateways.
None of this makes the router obsolete. A developer can keep CCR for personal experiments and point it at the team gateway as its upstream, keeping per-request model tricks local while keys, budgets and logs stay central. What should not happen is a team’s production coding spend flowing through a dozen unmanaged laptop proxies.
What to do with Claude Code Router
Claude Code Router is a good answer to a specific question: what happens to Claude Code’s usefulness and cost when the model underneath changes? It is a poor answer to the question of how a team should run coding agents. The practical sequence:
- Try the cheapest path first. If the model you want comes from a provider with an Anthropic-compatible endpoint, such as DeepSeek or Ollama, set
ANTHROPIC_BASE_URLandANTHROPIC_AUTH_TOKENdirectly and skip the router. - Use the router when you want to mix models. Install version 3, add providers, create a client key, and start with one rule: a cheap or local model for Haiku-named background requests, with
ANTHROPIC_DEFAULT_HAIKU_MODELset so those requests are recognisable. - Test tool calling before trusting a model. Run a multi-file edit with a test run on the substitute model and on Claude, and compare.
- Watch cache reads, not just token prices. Compare cache read tokens in the provider’s usage data before and after switching. A cheaper model that loses caching can cost more per session.
- Move routing to a gateway when the second or third developer copies your setup. Issue per-developer credentials, set budgets, configure failover, distribute the base URL through managed settings and pin it with
allowedProviders.
The router proves that Claude Code’s harness and Claude’s models can be separated. Whether they should be, for a given team, is a question about tool-calling quality and cache economics that each team has to measure for itself, and the measuring is far easier from one central log than from twelve laptops.
Sources
- Claude Code Router README musistudio (GitHub)
- Claude Code Router v2.0.0 README (config.json and Router scenarios) musistudio (GitHub)
- Claude Code Router v2.0.0 router source (scenario selection) musistudio (GitHub)
- Claude Code Router docs: Routing Claude Code Router
- Claude Code Router docs: Install and start CCR Claude Code Router
- Claude Code Router docs: CLI installation and command reference Claude Code Router
- Other LLM gateways (Claude Code) Anthropic
- Run Claude Code through a gateway Anthropic
- Connect Claude Code to an LLM gateway Anthropic
- Claude Code gateway compatibility guide Anthropic
- Model configuration (Claude Code) Anthropic
- Manage costs effectively (Claude Code) Anthropic
- Prompt caching Anthropic
- Prompt caching OpenAI
- Using the Anthropic API (DeepSeek) DeepSeek
- Claude Code integration (Ollama) Ollama
- Bifrost with Claude Code Maxim AI
- Bifrost virtual keys Maxim AI
- Bifrost retries and fallbacks Maxim AI
- Bifrost session affinity Maxim AI
- LiteLLM Claude Code quickstart BerriAI
Frequently asked questions
What is Claude Code Router?
Claude Code Router (CCR) is an open-source, MIT-licensed local proxy by the developer musistudio. It listens on 127.0.0.1:3456, receives the Anthropic-format requests Claude Code sends, chooses a provider and model by rule, translates the request into that provider's API format and streams the answer back, so Claude Code can run on GPT, Gemini, DeepSeek, Qwen or local models.
How do I use Claude Code with other models?
Point ANTHROPIC_BASE_URL at something that speaks the Anthropic Messages API and routes to the model you want, and put the matching credential in ANTHROPIC_AUTH_TOKEN. That can be Claude Code Router on your laptop, a provider's own Anthropic-compatible endpoint such as DeepSeek's or Ollama's, or a shared gateway. Then pick the model with --model, /model or the ANTHROPIC_DEFAULT_*_MODEL variables.
What does ANTHROPIC_BASE_URL do in Claude Code?
ANTHROPIC_BASE_URL tells Claude Code where to send its model requests instead of api.anthropic.com. Claude Code then treats that address as the Claude API, posting to /v1/messages and sending the same headers and body fields. Setting it without a gateway credential keeps a saved claude.ai login active, so the credential variable matters as much as the URL.
Does Anthropic support Claude Code on non-Claude models?
No. Anthropic's gateway documentation says it does not support routing Claude Code to non-Claude models through any gateway, and does not endorse or audit third-party gateway products. The setup works because the protocol is open, but tool calling, thinking and caching behaviour with other models is the user's responsibility to test.
Is Claude Code Router safe to use?
It runs locally and binds to 127.0.0.1 by default, which limits exposure to your own machine. The risks are holding several provider keys in one local config, sending your code to whichever provider a rule selects, and exposing the gateway beyond localhost without its client keys. The project's Docker guide tells users to read it before exposing CCR remotely.
Why is Claude Code more expensive through a router?
Usually because prompt caching stopped working. Claude Code marks the stable part of each request with cache_control so most input bills as cheap cache reads. If the router or the upstream model drops those markers or rewrites the prefix, every turn bills as fresh input. Check cache read tokens in the provider's usage data before and after switching.
When should a team move from Claude Code Router to an AI gateway?
When more than one or two developers share the setup, or when someone asks who spent what. A gateway issues one revocable credential per developer, enforces budgets and rate limits centrally, fails over between providers, and keeps a log of every request, none of which a set of laptop-local routers can provide.


