Connect Claude Code
Claude Code reaches models through a Tetrate Agent Router gateway once ANTHROPIC_BASE_URL points at it, and tare integrate writes that config from the logged-in session. Managed mode bills Anthropic traffic through Agent Router; passthrough mode keeps an existing Claude Max (or Pro) subscription as the billing path while the gateway routes and observes.
Persona: Developer running Claude Code against an Agent Router gateway.
Estimated time: 10 minutes.
Outcomes
By the end of this guide:
- Claude Code's
ANTHROPIC_BASE_URLpoints at the Agent Router gateway. - Traffic is authenticated in either managed mode or passthrough mode, matching how it should be billed.
- The gateway destination is confirmed with
/status, and the requests appear in Request Logs.
Prerequisites
-
The
tareCLI installed and authenticated:curl -fsSL https://tare.tetrate.ai/tools/install.sh | bashtare --versiontare api login --base-url https://api.example.tetrate.ai--base-urlis the management plane API host (https://api.<tenant>.tetrate.ai), not the Console gateway Base URL. How to derive<tenant>is covered under Configure coding tools with the tare CLI.Login can be skipped on integrate by passing
--gateway-url,--api-key, and--modelexplicitly, but then nothing is reused from the account. -
A dataplane id for the gateway to route through. After
tare api login, list dataplanes:tare integrate dataplanesExample output:
DATAPLANE NAME GATEWAY URLacme-prod Acme Production https://acme-prod.gateway.example.comacme-dev Acme Dev https://acme-dev.gateway.example.com--dataplanetakes the workspace id from the DATAPLANE column (for exampleacme-prod), not the display name in NAME. -
Claude Code installed. Anthropic's native installer is the recommended method: it auto-updates in the background and does not require Node.js.
macOS, Linux, WSL:
curl -fsSL https://claude.ai/install.sh | bashWindows PowerShell:
irm https://claude.ai/install.ps1 | iexOther supported methods (Homebrew, WinGet, apt/dnf/apk, npm) are documented in the Claude Code setup guide.
Configure Claude Code with tare CLI
After tare api login, preview then apply:
tare integrate dataplanes
tare integrate claude-code --dry-run --dataplane <dataplane-id>
tare integrate claude-code --dataplane <dataplane-id> --yes
Add --passthrough for Claude Max (or Pro) billing with Agent Router attribution only:
tare integrate claude-code --dataplane <dataplane-id> --passthrough --yes
The CLI writes ~/.claude/settings.json (backing up any existing file), sets 0600 permissions, and validates the key against the gateway. The shared workflow behind these commands, including key rotation and cleanup, is documented in Configure coding tools with the tare CLI.
Connectors trade-off: managed mode sets ANTHROPIC_API_KEY, which disables claude.ai connectors, because an explicit API key takes precedence over the claude.ai login. Where connectors are needed, --passthrough leaves ANTHROPIC_API_KEY unset.
Alternative: manual configuration
In both modes, ANTHROPIC_BASE_URL is the gateway proxy host from the Console Dashboard. The examples below use https://proxy.acme.example.com as a placeholder.
Option A: managed mode (Agent Router-managed Anthropic key)
This mode applies without a Claude Max subscription, or where all traffic should be billed through Agent Router using its managed Anthropic credentials.
How it works
- Agent Router authenticates the request with its managed Anthropic key.
- Cost = base + Agent Router margin.
- The Agent Router API key goes in
ANTHROPIC_API_KEY.
Add the following to the shell profile (for example ~/.zshrc or ~/.bashrc):
# Use the proxy host (not a full /v1/messages URL): Anthropic clients append /v1/messages automatically
export ANTHROPIC_BASE_URL="https://proxy.acme.example.com"
export ANTHROPIC_API_KEY="your-tars-api-key"
Where claude.ai connectors are required, use passthrough mode (Option B) instead: connectors stay disabled while ANTHROPIC_API_KEY is set.
Option B: passthrough mode (an existing Claude Max subscription)
This mode applies where a Claude Max (or Pro) subscription already exists and Claude Code should bill against it. Agent Router routes the request and observes it, but the Anthropic OAuth token passes through untouched, so Anthropic authenticates the user the same as on a direct connection.
Passthrough carries Anthropic traffic only, so it cannot run Claude Code against Vertex, Bedrock, OpenAI, or a self-hosted model. It also needs an administrator to set the Anthropic provider's authentication type to API key. See Enable passthrough for Claude Code.
How it works
ANTHROPIC_API_KEYis left unset, because Claude Code's stored OAuth token is what authenticates with Anthropic.x-tars-api-keyauthenticates the request with Agent Router for routing and observability.- Cost = the Claude Max plan, with no Agent Router margin on tokens. Passthrough requests are labeled
passthroughin Request Logs.
Max, Pro, and Team subscriptions work. Organization-managed Claude Enterprise plans have not been tested.
Gateway model discovery does not run in passthrough mode, so models are named explicitly with --model or ANTHROPIC_MODEL. Claude Code requests a model list only where one of its own credential sources is present (ANTHROPIC_AUTH_TOKEN, apiKeyHelper, or a resolved API key), and passthrough deliberately supplies none of them: the Agent Router key travels in a custom header instead. See Show gateway models.
First, log in to the Anthropic account once through Claude Code's normal flow, so it stores the OAuth token locally:
claude /login
Then add the following to the shell profile:
export ANTHROPIC_BASE_URL="https://proxy.acme.example.com"
export ANTHROPIC_CUSTOM_HEADERS="x-tars-api-key: your-tars-api-key"
Start a session
Change to the project directory and launch Claude Code:
cd your-project
claude
Verify
Run the /status command inside the Claude Code session and confirm the base URL points to the gateway:
> /status
Anthropic base URL: https://proxy.acme.example.com
The Request Logs show the requests as they arrive.
Show gateway models in the model picker (optional)
Claude Code can populate its /model picker from the gateway, by calling GET /v1/models at startup and listing the results as gateway models. Three limits apply.
It is off by default. Discovery runs only where CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY is set to 1, in the shell profile or in the env block of ~/.claude/settings.json. Releases before 2.1.129 ran it automatically.
export CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY=1
The result is cached in ~/.claude/cache/gateway-models.json, and refreshed at each launch wherever Claude Code holds a credential of its own.
Only Claude models are listed. Claude Code keeps an entry only where the model id contains claude or anthropic, matched anywhere in the id and without regard to case, and discards the rest before the picker renders. A gateway serving Claude, OpenAI, and Gemini models therefore offers only the Claude ones.
Where a non-Anthropic model should appear in the picker, an administrator can publish the catalog entry under a name that contains claude or anthropic. Either word satisfies the match, in any position: claude-gemini-flash and anthropic/gemini-2.5 are both listed, while gemini-2.5 is not. The name then misrepresents which provider serves the request, and cost, rate limits, and behaviour continue to follow the real backend, so this is a convention to document deliberately rather than a default to adopt.
Models that are not listed still work. The filter governs what the picker offers, not what the gateway serves. Any model the key can call runs when it is named:
claude --model gpt-5.4 # or: export ANTHROPIC_MODEL="gemini-2.5-flash"
Filling the picker in passthrough
In passthrough mode Claude Code does not request the list, so the picker stays empty. It does read the list from a cache file, ~/.claude/cache/gateway-models.json, whether or not it wrote that file. Writing that file therefore fills the picker:
In passthrough mode Claude Code does not request the list, so the picker stays empty. The picker is filled by writing the list into the cache file that Claude Code reads at launch, ~/.claude/cache/gateway-models.json: fetch the models from the gateway's /v1/models endpoint with the Agent Router API key, save them into that file, then start Claude Code with the usual passthrough settings and CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY=1.
- Call
GET <gateway>/v1/modelswith the Agent Router API key inx-tars-api-key. - Convert the response into Claude Code's cache format.
- Save it as
~/.claude/cache/gateway-models.json. - Start Claude Code with the usual passthrough settings and
CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY=1, then open/model.
The raw /v1/models response is not written directly, because the two formats differ. The cache format is internal to Claude Code and is not published by Anthropic, so it can change in any release. As observed in Claude Code 2.1.251:
{"baseUrl": "<gateway>", "fetchedAt": 1788079381160, "models": [{"id": "gpt-5.4"}]}
Models are listed exactly as the file names them, including names that contain neither claude nor anthropic, because the name filter is applied only when Claude Code builds the list itself.
The file is not refreshed on its own, so it is written again whenever the catalog changes. It is also replaced by Claude Code at the next launch if the developer later configures an API key, since discovery then runs normally.
| Setup | Who builds the list | Filtered |
|---|---|---|
| API key, discovery enabled | Claude Code | Yes, only ids containing claude or anthropic |
Passthrough, discovery enabled, file written from /v1/models | The operator | No, every entry in the file is shown |
CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY=1 is required in both cases. Without it the picker shows no gateway models, whether or not the file exists.
Where a non-Anthropic model should appear in the picker, an administrator can publish the catalog entry under a name that contains claude or anthropic. Either word satisfies the match, in any position: claude-gemini-flash and anthropic/gemini-2.5 are both listed, while gemini-2.5 is not. The name then misrepresents which provider serves the request, while cost, rate limits, and behavior continue to follow the real backend, so this is a convention to adopt deliberately rather than by default.
Troubleshooting
| Issue | What to check |
|---|---|
| Claude still asks for credentials or login | A known issue on macOS where ~/.claude.json exists. Rename that file temporarily and restart Claude. |
| API key issues | In managed mode, ANTHROPIC_API_KEY must be set to the Agent Router API key. In passthrough mode, ANTHROPIC_API_KEY must be unset, and ANTHROPIC_CUSTOM_HEADERS (or the CLI-written settings) must carry x-tars-api-key. |
| Connection errors | Verify that ANTHROPIC_BASE_URL points to the correct gateway URL, with no trailing /v1/messages, which Claude Code appends automatically. |
| Passthrough returns 401 from Anthropic | The Claude Max OAuth token is missing or expired. Re-run claude /login and try again. |
400 rejecting anthropic-beta headers | Claude Code sends experimental beta headers the upstream provider does not accept. Set CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS=1 in the shell profile, then start a new session. |
400 model_not_found | The model Claude Code sent is not enabled in Agent Router. Claude Code offers its own built-in list, which does not reflect what is enabled for the account. On Agent Router Enterprise, ask an administrator to enable that model and assign it to the project, see Enable passthrough for Claude Code. |
No gateway models in the /model picker | CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY=1 must be set. It is also skipped, silently, where CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC is set to any value. In passthrough Claude Code does not build the list at all, and the file is written separately, see Filling the picker in passthrough. |
| OpenAI or Gemini models missing from the picker | Expected wherever Claude Code builds the list, since it keeps only ids containing claude or anthropic. Those models are still reachable with --model or ANTHROPIC_MODEL, and they are listed where the file is written in passthrough. |
| The picker listed every model and now lists only Claude ones | An API key was configured for that developer, so Claude Code fetched the list itself at the next launch and replaced the file, applying its own name filter. |
| The file was written and the picker is still empty | CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY=1 must be set, and the file has to be in Claude Code's cache format rather than the raw /v1/models response. See Filling the picker in passthrough. |
No gateway models in the /model picker | Discovery is off unless CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY=1 is set. It is also skipped, silently, where CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC is set to any value, and it does not run at all in passthrough mode. See Show gateway models. |
| OpenAI or Gemini models missing from the picker | Expected. Claude Code lists only ids containing claude or anthropic. Those models are still reachable with --model or ANTHROPIC_MODEL. |
| Fewer models available than the administrator enabled | Enabling a model organization-wide is not enough; it also has to be granted to the project the key belongs to. GET /v1/models lists what the key can actually call, so check there rather than against the catalog count. See Create a project and grant models. |
| claude.ai connectors unavailable | Managed mode's ANTHROPIC_API_KEY disables connectors. Use --passthrough with tare integrate, unset the API key, or remove the env block from ~/.claude/settings.json. |
| Permission denied | Claude Code needs read/write access to the project files. |
| Context limits | For very large repositories, use .claudeignore to exclude irrelevant directories. |
Where to go next