ANTHROPIC_BASE_URL: point Claude Code at any model you want
Claude Code sends every request to ANTHROPIC_BASE_URL if the endpoint speaks Anthropic's Messages API. How to use it with any model, and the gotchas.
Claude Code is an Anthropic product, so most people assume it only talks to Anthropic. It does not. It reads a base URL from the environment, and it will happily send its requests anywhere that speaks the same API:
export ANTHROPIC_BASE_URL=http://localhost:20128/v1
export ANTHROPIC_AUTH_TOKEN=<your-key>That is the whole mechanism. Everything below is what it makes possible.
What the variables do
| Variable | Purpose |
|---|---|
ANTHROPIC_BASE_URL | Where requests go instead of api.anthropic.com |
ANTHROPIC_AUTH_TOKEN | The bearer token sent to that endpoint |
ANTHROPIC_DEFAULT_OPUS_MODEL | Which model the "opus" alias maps to |
ANTHROPIC_DEFAULT_SONNET_MODEL | Which model the "sonnet" alias maps to |
ANTHROPIC_DEFAULT_HAIKU_MODEL | Which model the "haiku" alias maps to, also used for background work |
CLAUDE_CODE_MAX_CONTEXT_TOKENS | The context window Claude Code should assume for the active model |
The alias variables matter more than they look. Claude Code refers to models by tier -- opus, sonnet, haiku -- and those aliases are remappable. Point them at whatever you like and the interface stays identical.
Why this is the interesting part
Claude Code's value is the agent loop: the tool use, the file editing, the planning. That is client-side. The model behind it is swappable.
So the question stops being "can I afford Claude Max" and becomes "what do I want answering these requests" -- which is a different and much cheaper question.
One honest caveat: Anthropic documents ANTHROPIC_BASE_URL for proxies and LLM gateways, and says plainly that it does not support routing Claude Code to non-Claude models. It works, but if something breaks with a non-Claude model, Anthropic support will not help you.
Setting it up
The endpoint has to speak Anthropic's Messages API: Claude Code posts to /v1/messages and, when it can, /v1/messages/count_tokens. An endpoint that only speaks OpenAI's Chat Completions will not work. A local router that translates is the straightforward option:
npm install -g @sifxprime/krouter
krouter -tkRouter serves both Messages endpoints and translates each request to whichever provider sits behind the model you picked (the full list is in the API reference). Connect a provider in the dashboard at http://localhost:20128/dashboard, then:
export ANTHROPIC_BASE_URL=http://localhost:20128/v1
export ANTHROPIC_AUTH_TOKEN=sk_krouter
export ANTHROPIC_DEFAULT_SONNET_MODEL=ag/claude-sonnet-4-6
export ANTHROPIC_DEFAULT_HAIKU_MODEL=kr/claude-haiku-4.5Requests from the same machine do not need a real key, so sk_krouter is just a placeholder. From another machine, use a key from the dashboard's Endpoint page.
Start Claude Code as usual. Nothing about the interface changes; the requests now go through your machine and out to whichever provider each alias points at.
The mapping worth copying
The aliases let you split work by cost without thinking about it during a session:
- haiku handles background work: session titles, summaries, the small classification requests Claude Code makes on its own. Set this one explicitly. Through a gateway with
ANTHROPIC_AUTH_TOKEN, Claude Code sends that background work to your main model when the haiku variable is unset, so you pay main-model prices for it. - sonnet handles normal coding. The same Claude model is often available from more than one provider -- kRouter's catalog lists Sonnet 4.6 under Claude Code, Antigravity and GitHub Copilot -- so this does not have to mean paying Anthropic directly. It does not have to be Claude either; an open model such as
ocg/glm-5.3orocg/kimi-k2.6can sit behind the alias the same way. Which open models hold up as the agent covers the trade-offs. - opus handles the hard problems. Keep this on whatever you trust most, because it will be used least.
Background requests are frequent and small. There is no reason to send them to the model you pay the most for, and moving them is a saving you never notice during the session.
Gotchas
Restart after exporting. The variable is read at process start. Setting it in a shell where Claude Code is already running does nothing. This is the single most common reason people think it did not work.
The token is not your Anthropic key. It authenticates you to whatever endpoint you pointed at. Sending your Anthropic key to a local router does nothing useful.
Mind the /v1. Claude Code appends /v1/messages to whatever you set, so a strict endpoint wants the API root without /v1. kRouter rewrites the doubled /v1/v1/ prefix to the same handler, which is why the examples here work either way -- but if you point at something other than kRouter, drop the /v1.
Check it took effect. If requests still land on Anthropic, the variable is not in the environment the tool actually launched from -- verify with env | grep ANTHROPIC in that same shell. Also look at ~/.claude/settings.json: when the same variable is set in your shell and in that file's env block, the file usually wins.
Non-Claude models get the wrong context window. Claude Code assumes 200K tokens for a model ID it does not recognize. If the real window is smaller, you get "prompt is too long" errors; if it is larger, Claude Code compacts too early. Set CLAUDE_CODE_MAX_CONTEXT_TOKENS to the real size -- the context window post goes through it.
Some backends carry account risk. The Antigravity (ag/) and Kiro (kr/) examples above use subscription logins, and so do kRouter's Claude Code, Codex, GitHub Copilot, Gemini CLI and Qoder providers. kRouter shows a Risk Notice before you connect any of them: those sessions are not licensed for proxy use, and the account may be restricted or banned. An API-key provider has no such risk.
Making it permanent
Add the exports to your shell profile, or let a settings file hold them so they apply to every session rather than the one terminal you set them in. Claude Code reads the env block in ~/.claude/settings.json.
kRouter can write that block for you. In the dashboard, open CLI Tools, then the Claude Code card: pick the models for each alias, optionally a Max context value, and click Apply. It writes the base URL, the token and the model mappings. Reset removes them again.
Common questions
Does ANTHROPIC_BASE_URL work with the Claude Code CLI?
Yes. It is a documented variable for sending Claude Code's requests through a proxy or LLM gateway; Amazon Bedrock and Google Cloud have their own variables. Anything speaking Anthropic's Messages API works, though Anthropic does not support using it to reach non-Claude models.
I set the variable and nothing changed. What went wrong?
Almost always that the variable was not in the environment the tool actually launched from. It is read at process start, so exporting it in a shell where Claude Code is already running does nothing. Restart the session and confirm with env | grep ANTHROPIC. If a value in ~/.claude/settings.json disagrees with your shell, the settings file usually wins.
Is ANTHROPIC_AUTH_TOKEN my Anthropic API key?
No. It authenticates you to whichever endpoint you pointed at. Sending your Anthropic key to a local router accomplishes nothing.
Do tool use and MCP still work?
Yes. The agent loop, tool execution, and MCP connections are all client-side. Two things change when the base URL is not Anthropic's: MCP tool search is off by default (Claude Code then loads every MCP tool up front), and Remote Control is disabled from Claude Code 2.1.196 on.
Will kRouter's models show up in /model?
Not reliably. Claude Code's gateway model discovery is opt-in (CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY=1) and keeps only model IDs that contain "claude" or "anthropic", so a GLM or Kimi model never appears there. Map models through the three alias variables instead.
Can I keep my subscription and switch back?
Yes. Unset the variables and the CLI goes back to Anthropic. If kRouter wrote them into ~/.claude/settings.json, click Reset on the Claude Code card (or delete the keys) as well, because unsetting your shell variables does not touch that file.
Related
Published by Kodelyth, the team that builds kRouter. Posts are drafted with AI assistance and reviewed by a person before they go out. kRouter is free and MIT licensed.
Install kRouterRelated posts
- Save moneyQwen Code's free tier is gone: keep the CLI, swap the modelQwen OAuth's free tier closed on April 15, 2026. What still works in Qwen Code, where Qwen models come from now, and how to keep the CLI answering.
- Save moneyUse your GitHub Copilot plan in Claude Code and any toolCopilot plans now include monthly AI Credits spent at API rates. How to spend them from Claude Code, scripts and other tools, and when that is worth it.
- Save moneyClaude Code without a subscription: 6 backends that workSix backends that can run Claude Code instead of a Claude plan: what each costs in 2026, which models it carries, and where each one breaks.
Relevant docs
- Token savers: RTK, Caveman, Ponytail, Headroom, PXPIPEFive ways kRouter can shrink a request before it reaches the provider. Only RTK is on by default. What each saver does, what it needs, and its limits.
- Combos & fallbackPut several models behind one name. kRouter falls back from one to the next, rotates them, or asks a panel of models and merges the answers.
- ProvidersConnect 95+ AI providers to kRouter: OAuth subscriptions, free services, free-tier and pay-per-token API keys, and browser-cookie logins.