Skip to main content
Claude Code connects to Bifrost through Bifrost’s Anthropic-compatible endpoint. Claude Code treats Bifrost as an LLM gateway: it sends every model request to ANTHROPIC_BASE_URL with a Bifrost credential instead of an Anthropic login. Tested on Claude Code versions:

Before you begin

You need:
  • Claude Code installed. See Set up Claude Code.
  • The Bifrost gateway URL. Claude Code uses the /anthropic path, for example https://bifrost.example.com/anthropic.
  • A Bifrost credential that allows the models you plan to use:
    • Virtual key (OSS and Enterprise): a sk-bf-* key. A new virtual key with no provider configuration denies all providers, so confirm the key allows your model.
    • Enterprise SSO (Enterprise): a user provisioned through User Provisioning with an assigned access profile or virtual key.

Choose a setup

For enterprise developers, use dynamic credentials with Bifrost CLI SSO. Each request is attributed to the signed-in user, no long-lived secret is stored in Claude Code settings, and expired sessions refresh automatically.
Signing in with your identity provider (Enterprise): to have users authenticate with their work account instead of a virtual key, run Code sessions in Claude Desktop on 3P. Its configuration covers Code sessions as well as Chat and Cowork. See Claude Desktop: Authenticate with SSO.

Launch through Bifrost CLI

Bifrost CLI starts Claude Code with the gateway URL, credential, and model already set for that session. It does not modify ~/.claude/settings.json.
With Enterprise SSO, Bifrost CLI passes Claude Code a temporary --settings file whose apiKeyHelper runs bifrost auth print-token. The token is never written to Claude settings, and the temporary file is removed when Claude Code exits. With a virtual key, the key is set in the child process environment only. See Coding harness integrations for model selection, persistent configuration, and removal.

Static virtual key

Use this when a fixed virtual key is acceptable. Claude Code sends ANTHROPIC_AUTH_TOKEN as Authorization: Bearer <token>, which Bifrost accepts as a virtual key. No Anthropic account login is required.
1

Verify the key against Bifrost

A 200 with a JSON message confirms the URL, key, and model. A 401 means the key was rejected; a 403 usually means the key does not allow that provider or model.
2

Persist the configuration

Add an env block to your user settings, ~/.claude/settings.json (%USERPROFILE%\.claude\settings.json on Windows). Merge it into the existing file instead of replacing it.
To scope the configuration to one repository, use .claude/settings.local.json and make sure it is gitignored.
3

Verify in Claude Code

Never put a credential in a project’s .claude/settings.json. That file is committed and shared with everyone who clones the repository.

Use a Claude subscription through Bifrost

To keep billing on a Claude Pro, Max, Team, or Enterprise subscription while Bifrost applies governance and logging, sign in to Claude Code with /login and send the virtual key in a custom header instead of ANTHROPIC_AUTH_TOKEN:
Claude Code sends its subscription token as Authorization: Bearer sk-ant-oat…. On the /anthropic route, Bifrost forwards that token to Anthropic instead of selecting a provider key, and uses x-bf-vk for governance. Do not set ANTHROPIC_AUTH_TOKEN, ANTHROPIC_API_KEY, or apiKeyHelper in this mode; any of them replaces the subscription login. Subscription usage limits still apply.

Dynamic credentials with apiKeyHelper

Claude Code’s apiKeyHelper setting runs a command that prints the current credential. Use it whenever the credential expires, rotates, or comes from a vault or SSO tool.
The setting is named apiKeyHelper. Claude Code has no apiKeyScript setting.

How Claude Code uses the helper

bifrost auth print-token prints a current Bifrost session token for the signed-in user. If the access token has expired, the CLI refreshes it with the stored refresh token before printing. Requests are governed by the user’s access profile or selected assigned virtual key.
1

Install Bifrost CLI and sign in

Follow Install the CLI, then:
2

Configure Claude Code

In ~/.claude/settings.json, merge:
  • Use the full path to bifrost; the helper shell may not load your interactive PATH.
  • Pin --context so the helper does not follow a later bifrost context use.
  • Remove ANTHROPIC_AUTH_TOKEN and ANTHROPIC_API_KEY from the same env block and from your shell. Both take precedence over apiKeyHelper.
3

Verify

Start claude and follow Verify requests reach Bifrost. Bifrost logs show the signed-in user for each request.
Bifrost session access tokens are valid for one hour. The refresh token is valid for 30 days and rotates on each refresh. A 15-minute helper cache keeps Claude Code well inside the access-token lifetime, and Claude Code also re-runs the helper after any 401. When the refresh token expires or is revoked, the helper fails until you run bifrost auth login again. To use a specific assigned virtual key instead of the gateway’s default for your user, run bifrost virtual-keys assigned and then bifrost auth select-virtual-key <id>. The selection applies to the context.

Use your own credential script

Any command that prints a credential Bifrost accepts works as a helper: Example for a virtual key stored in HashiCorp Vault:
~/bin/bifrost-credential.sh
~/.claude/settings.json
For an identity-provider token, replace the vault command with your provider’s token command. Set CLAUDE_CODE_API_KEY_HELPER_TTL_MS below the token lifetime, and make the script exit non-zero when it cannot produce a token.
Send only one credential type per request. If you also send a virtual key, for example through ANTHROPIC_CUSTOM_HEADERS: x-bf-vk: ..., alongside an identity-provider JWT, Bifrost applies the gateway’s dual-credential policy: it uses the JWT identity by default, and can instead prefer the virtual key or reject the request.

Verify requests reach Bifrost

  1. Start claude from a new terminal.
  2. Run /status. On the Status tab, confirm:
    • Anthropic base URL shows your Bifrost URL ending in /anthropic.
    • The credential line names ANTHROPIC_AUTH_TOKEN or apiKeyHelper, not a claude.ai Login method.
  3. Send a short prompt and confirm a normal response.
  4. In the Bifrost dashboard, open Logs and confirm the request appears with the expected virtual key or user, provider, and model.
If /status shows no Anthropic base URL, the variable did not reach the session. If it shows a claude.ai login, the Bifrost credential is missing or outranked; see Credential precedence.

Credential precedence

Claude Code chooses one credential, in this order (abbreviated from Anthropic’s authentication precedence):
  1. Cloud-provider credentials, when CLAUDE_CODE_USE_BEDROCK, CLAUDE_CODE_USE_VERTEX, or CLAUDE_CODE_USE_FOUNDRY is set
  2. ANTHROPIC_AUTH_TOKEN
  3. ANTHROPIC_API_KEY
  4. apiKeyHelper
  5. CLAUDE_CODE_OAUTH_TOKEN, Anthropic profiles, and the claude.ai login from /login
Settings files apply in this order, highest first: managed settings, --settings on the command line, .claude/settings.local.json, .claude/settings.json, then ~/.claude/settings.json. A value in a settings-file env block overrides the same variable exported in your shell.
bifrost configure claude writes a virtual key to ANTHROPIC_AUTH_TOKEN in ~/.claude/settings.json. While that value is present, it outranks the SSO apiKeyHelper that bifrost claude injects, so requests use the virtual key instead of your SSO identity. Run bifrost unconfigure claude before switching to SSO.

Caveats

  • Unset CLAUDE_CODE_USE_* variables. Any of them routes Claude Code to that cloud provider instead of ANTHROPIC_BASE_URL.
  • Managed login policy. If managed settings set forceLoginMethod or forceLoginOrgUUID, Claude Code refuses ANTHROPIC_AUTH_TOKEN, ANTHROPIC_API_KEY, and apiKeyHelper at startup. An administrator must remove those keys to use Bifrost credentials.
  • Restrict destinations centrally. Administrators can set allowedProviders to ["customEndpoint"] and pin ANTHROPIC_BASE_URL in managed settings so Claude Code only reaches Bifrost. See Restrict which API providers a machine may use.
  • Features that need a claude.ai login. Remote Control and voice dictation are unavailable while a gateway credential is active.
  • Credential storage. Keep credentials in user or local settings, or behind apiKeyHelper. Bifrost CLI stores SSO tokens and virtual keys in the operating-system keyring.
  • Background traffic. Claude Code still sends nonessential traffic, such as update checks and telemetry, outside the gateway. Set CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1 on networks that only allow egress to Bifrost; this also disables auto-updates.
Bifrost’s Settings → Client Settings → Allowed Headers list controls CORS responses for browser-based clients. The Claude Code CLI does not send CORS preflight requests and does not require changes to this list.

Troubleshooting

Model configuration

Claude Code sends x-claude-code-session-id on every request, so a session sticks to the provider and key that served it and keeps hitting the same prompt cache, with nothing to configure. See Session Affinity.
Claude Code maps its sonnet, opus, and haiku aliases through ANTHROPIC_DEFAULT_SONNET_MODEL, ANTHROPIC_DEFAULT_OPUS_MODEL, and ANTHROPIC_DEFAULT_HAIKU_MODEL. ANTHROPIC_MODEL or --model selects the session model. A model value in settings that names a specific model ID overrides the alias mapping for new sessions, so remove it or set it to an alias when you manage models through these variables. The env snippets below show only the model variables. Add them to the same env block as your base URL and credential.

Using alias

This approach uses Bifrost’s dynamic aliasing via routing rules. The names sonnet-model and haiku-model are arbitrary labels that Claude Code sends, and a routing rule rewrites them to whatever provider and model you want at request time. Because the rewrite is rule-based, you can route the same alias to different targets per scope, per header, or per other request attributes.
  1. Add these routing rules in Bifrost.
sonnet-model route
  • Keep it at the global level and assign the priority you want.
  • Add a model condition model = sonnet-model. This option is not available out of the box, so type the string and select Create sonnet-model.
  • Add a second header condition that checks whether user-agent starts with claude-cli.
  • Map the model to any model configured in Bifrost, from Anthropic, OpenAI, Gemini, or another provider. The example uses vertex/claude-sonnet-4-6.
sonnet-model routing example
haiku-model route
  • Repeat the steps above, replacing sonnet-model with haiku-model.
  1. Set the aliases in Claude Code:
An arbitrary alias such as sonnet-model may not be recognized by Claude Code for features that depend on the model name. See Auto mode classifier compatibility.

Using provider-specific model pinning

This approach pins Claude Code’s model aliases to specific provider and model identifiers. It behaves like Bifrost’s static aliasing: the value you set is the exact target Bifrost forwards to. You can pin any model on any provider configured in Bifrost, as long as the model supports the tool calling Claude Code needs.
Anthropic models do not need a provider prefix.

Choose a model at launch or mid-session

Inside a session, /model <name> switches to any provider and model configured in Bifrost, for example /model vertex/claude-haiku-4-5 or /model openai/gpt-5.5. Run /model without arguments to see the current model. Claude Code can also add Bifrost’s models to the /model picker. Set CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY=1; Claude Code then reads /anthropic/v1/models at startup and lists IDs that contain claude or anthropic. Bifrost CLI enables this automatically for sessions it launches.

Auto mode classifier compatibility

Claude Code can perform eligible auto mode classifier checks on the server without separate classifier requests. This requires both a supported Claude Code model name and an upstream platform that has server-side checks enabled. When you use a Bifrost model alias, keep a recognizable Claude model name in the value sent by Claude Code. Provider prefixes are supported, so values such as bedrock/claude-sonnet-5-5 can work. An arbitrary alias such as sonnet-model can route to the same model in Bifrost but may not be recognized by Claude Code as an auto mode-compatible model. For Bedrock models that require an inference profile, you can expose a recognizable alias from the Bedrock key and map it to the profile ID:
The exact profile name depends on the AWS account and region. Use a profile that the configured credentials can invoke.
Model naming is only one eligibility check. Anthropic enables server-side checks by platform, region, and credential. A correctly named model can still use local classifier requests if the upstream platform has not enabled the feature for that environment.
To verify the active session, run /status in Claude Code. Auto mode server should read Enabled. If Claude Code reports that the session is not eligible:
  1. Confirm /model shows the intended provider and recognizable Claude model name.
  2. Confirm the provider key maps that alias to a callable deployment or inference profile.
  3. Check whether the upstream response contains delta.safeguard_results.
  4. Make sure CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS is not set to 1.
If the upstream platform does not support server-side checks, set CLAUDE_CODE_AUTO_MODE_SERVER=0 to suppress the notice and use Claude Code’s local classifier. Those classifier requests remain billable. Anthropic documents the current behavior and version requirements in Auto mode classifier request charges.

Provider compatibility

Bifrost lets Claude Code talk to any model on any provider it’s configured for. The only hard requirement is that the model you pick properly supports tool calling for the operations you intend to perform. Claude Code relies heavily on tool use for file edits, bash, code editing, web search, computer use, and citations.
  • Claude-specific server-side tools (web_search, computer_use, citations) are only available on Claude-family models on providers that expose them. Non-Claude models might silently lack these capabilities.
  • Streaming tool-call arguments must be implemented correctly by the upstream. Some providers (notably OpenRouter at the time of writing) do not stream function-call arguments properly. Tool calls arrive with empty arguments fields and Claude Code fails on file operations. If this happens, switch to a different provider in your Bifrost configuration.
  • Azure-hosted models must explicitly support tool use; verify before pinning.
If a tool call isn’t executing as expected, swap to a known-good model (for example claude-sonnet-4-6 direct from Anthropic) to confirm the issue is provider- or model-specific rather than Bifrost configuration.

Using Bifrost as an MCP Gateway

Bifrost can also act as an MCP server, aggregating every MCP tool you’ve connected (filesystem, GitHub, web search, databases, etc.) behind a single /mcp endpoint. Pointing Claude Code at it means one config entry instead of N, plus per-VK tool filtering, centralized governance, and observability for every tool call.

Adding Bifrost as an MCP server

Use the claude mcp add CLI with the HTTP transport:
--scope controls where the entry is stored: local (default, current project only), project (writes a checked-in .mcp.json), or user (available across all your projects). Or write it directly into .mcp.json / ~/.claude.json:
Bifrost also accepts X-Api-Key: <vk> or x-bf-vk: <vk> if the Authorization header conflicts with another tool in the chain. To remove the server later:

When you need an identity header

For setups that only use global MCPs (auth type none, headers, or oauth), Claude Code can connect to /mcp without any header and get the full global tool set. Identity headers only become load-bearing when per-user MCPs (per_user_oauth or per_user_headers) are in the mix — and even then the connection itself still succeeds; only tool calls into the per-user server return an error until an identity is present. For a per-user-headers MCP without identity, the tool call returns:
Bifrost recognizes three identity modes:
Session-mode (x-bf-mcp-session-id only) requires enforce_auth_on_inference=false on the Bifrost client config. With enforcement on, every request must carry a valid VK — session-only requests are rejected before identity resolution even runs.
You can attach a VK even when you don’t strictly need per-user auth — it’s how Bifrost scopes tool filtering and governance per caller. When the same Claude Code instance routes inference through Bifrost’s LLM gateway and connects to /mcp, the same tool can reach the model twice — once because the LLM gateway auto-injects every configured MCP tool, and once because Claude Code’s own MCP client discovers it via /mcp. Bifrost auto-dedupes tools for Claude Code specifically, but turning the inject toggle off is still recommended — it cleanly separates the two paths and matches what other MCP-host clients expect. See Recommended: disable auto tool injection for the toggle.

Verifying

Run /mcp inside Claude Code. bifrost should appear as connected with a tool count next to it. The same panel surfaces reconnect, re-authenticate, and disconnect actions.

FAQs

The full error reads:
This appears whenever the gateway auth mode is headers: clicking Re-authenticate makes Claude Code probe /register (RFC 7591 Dynamic Client Registration), but registration and discovery aren’t served in that mode, so the SDK logs the parse error. The /mcp connection itself keeps working.To make Re-authenticate work, switch mcp_server_auth_mode to both or oauth — Bifrost then serves real Dynamic Client Registration and the error disappears. If you’re staying on headers, use Reconnect in the /mcp panel to refresh tools instead. See the upstream Claude Code bug report for context.
Claude Code completed an OAuth flow, but the token it presented to /mcp was rejected. Two common causes:
  1. You recently switched mcp_server_auth_mode. Claude Code caches OAuth state per server, and tokens issued under the old mode are no longer accepted. Remove and re-add the server (claude mcp remove bifrost, then add it again).
  2. A VK header is being sent alongside the OAuth token. Bifrost rejects requests carrying two credential types at once (conflicting credentials). This typically happens in both mode when the VK is configured under a non-standard header: Claude Code only treats a configured Authorization header as “use header auth” — with x-bf-vk or X-Api-Key it may still run the OAuth flow and then send the OAuth token and your VK header together, which Bifrost rejects.
In both mode, configure the VK as Authorization: Bearer <vk> (not x-bf-vk / X-Api-Key), or drop the header entirely and authenticate via OAuth.
You’ll see this when clicking Reconnect in /mcp if the request reaches Bifrost without a valid identity:
  • No Authorization / x-bf-vk / X-Api-Key header and enforce_auth_on_inference=true
  • Sending only x-bf-mcp-session-id while enforce_auth_on_inference=true
  • A VK that doesn’t exist or has been disabled
Fix: either send a valid active VK in your header config, or set enforce_auth_on_inference=false if you intend to use session-id (or unauthenticated) callers. After updating the header, re-add the server or click Reconnect again.
Three things to check, in order:
  1. The upstream MCP is still connected in Bifrost. Bifrost’s health monitor marks a server disconnected after 5 consecutive failed pings, and disconnected servers serve zero tools. Reconnect from the Bifrost MCP page or via POST /api/mcp/client/{id}/reconnect.
  2. The attached VK allows the tools. If you’re sending a VK, its mcp_configs allowlist must include the MCP client name and the tools you expect to see. A VK with no entry for that MCP exposes none of its tools.
  3. The MCP isn’t running in Code Mode. Code-mode MCPs don’t expose their raw tools through tools/list — they’re exposed as meta tools (list_tools, call_tool, etc.) that the LLM uses to discover and call the underlying tools indirectly. From a stock MCP client’s perspective the server looks like it only has a handful of meta tools.
Expected behavior for per_user_oauth and per_user_headers MCPs. Open the URL surfaced in the tool result — for OAuth flows it points at the upstream provider’s consent page; for headers flows it points at a Bifrost form to enter your values. Bifrost stores the credential against your identity and the next tool call executes normally. See Per-User OAuth and Per-User Headers.
If Claude Code behaves unexpectedly after any change to Bifrost’s MCP auth settings, remove and re-add the server — Claude Code caches auth tokens per MCP server, and stale cached credentials can survive Reconnect.