Original research

How Claude Code actually works

Everything here was reverse-engineered from the native Bun-compiled binary. We extract and deobfuscate ~3,000 JavaScript modules per release using bun-demincer, then grep for patterns: beta flags, feature gates, endpoints, headers, env vars, model logic. Where static analysis wasn't enough, we captured live traffic through a reverse proxy (ANTHROPIC_BASE_URL override).

User-agent fingerprinting

Every request includes a user-agent that tells Anthropic exactly where the request came from:

claude-cli/<VERSION> (external, <ENTRYPOINT><SDK_SUFFIX><CLIENT_SUFFIX><WORKLOAD_SUFFIX>)

The entrypoint changes depending on how the CLI was invoked. Running claude -p sends sdk-cli, not cli. VSCode and JetBrains extensions set their own values. The Agent SDK appends its version. Background tasks get a workload/cron suffix.

cliInteractive terminal (default)
sdk-cliPrint mode (-p flag)
vscodeVSCode extension
jetbrainsJetBrains extension
agent-sdkAgent SDK

This is set via CLAUDE_CODE_ENTRYPOINT. The SDK version and client app name come from CLAUDE_AGENT_SDK_VERSION and CLAUDE_AGENT_SDK_CLIENT_APP.

Default headers

Every request carries these, regardless of auth method:

x-app: cli
anthropic-version: 2023-06-01
anthropic-dangerous-direct-browser-access: true

The Stainless SDK (which the CLI uses internally) adds its own set — platform, arch, runtime version, retry count, timeout. Streaming requests also get X-Stainless-Helper-Method: stream.

Auth splits into two paths. OAuth sends Authorization: Bearer <token>. API key auth sends x-api-key. Both get redacted in logs.

Beta flag assembly

The anthropic-beta header isn't static. It's assembled per-request based on model, platform, and feature gates. The builder function checks about ten conditions:

if (!isHaiku)                    push("claude-code-20250219")
if (isOAuth)                     push("oauth-2025-04-20")
if (has1mSuffix)                 push("context-1m-2025-08-07")
if (supportsThinking && !disabled) push("interleaved-thinking-2025-05-14")
if (firstParty && tengu_quiet_hollow && !showSummaries)
                                 push("redact-thinking-2026-02-12")
if (firstParty && (envFlag || tengu_marble_anvil))
                                 push("context-management-2025-06-27")
if (supportsStructured && tengu_tool_pear)
                                 push("structured-outputs-2025-12-15")
if (firstParty && tengu_scarf_coffee)
                                 push("tool-examples-2025-10-29")
if (vertex && supportsWebSearch) push("web-search-2025-03-05")
if (firstParty)                  push("prompt-caching-scope-2026-01-05")

Users can inject custom betas via the ANTHROPIC_BETAS env var (comma-separated).

Bedrock strips a few of these before sending — interleaved thinking, 1M context, tool search, and tool examples all get filtered out on that platform.

One thing worth calling out: the context-1m beta is opt-in only. It requires a [1m] suffix in the model ID (e.g. claude-opus-4-6[1m]). It is not sent automatically for any model. Some third-party implementations get this wrong. There is a separate gate for automatic 1M — see client data below.

Context window logic

The context window size isn't just "whatever the model supports." There's a decision tree:

  1. If the model ID has a [1m] suffix → 1,000,000
  2. If the model's API info reports max_input_tokens >= 100,000 → use that value
  3. If the context-1m beta is active and the model supports it → 1,000,000
  4. If coral_reef_sonnet is "true" in client data and the model is Sonnet 4.6 → 1,000,000
  5. Otherwise → 200,000

1M context is limited to claude-sonnet-4* (4.0, 4.5, 4.6) and claude-opus-4-6. It can be disabled entirely with CLAUDE_CODE_DISABLE_1M_CONTEXT.

Output token limits

opus-4-664k default, 128k upper
sonnet-4-632k default, 128k upper
opus-4-5, sonnet-4*, haiku-4*32k default, 64k upper
opus-4-1, opus-432k default, 32k upper
3-7-sonnet32k default, 64k upper
claude-3-opus4,096 both

Client data endpoint

OAuth users get their feature gates from a separate endpoint:

GET <BASE_API_URL>/api/oauth/claude_cli/client_data
Authorization: Bearer <accessToken>

Requires the user:profile OAuth scope. Returns {"client_data": {}} for most accounts.

The only field we've found referenced in code is coral_reef_sonnet. When it's "true", Sonnet 4.6 gets 1M context automatically without the [1m] suffix. This is how Anthropic can roll out 1M context to specific users without them having to change anything.

The response is cached locally. The CLI only refetches when stale, and skips the call entirely if CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC is set.

Billing attribution

Here's a weird one. The billing header isn't actually sent as an HTTP header. It's injected as plain text into the first system prompt block:

system[0].text = "x-anthropic-billing-header: cc_version=2.1.80.a46; cc_entrypoint=sdk-cli; cch=00000;"

The format: cc_version=<ver>.<modelId>; cc_entrypoint=<entrypoint>; cch=00000; cc_workload=<workload>;

Gated by tengu_attribution_header (default: true). Disable with CLAUDE_CODE_ATTRIBUTION_HEADER=false.

Feature flags (tengu)

The CLI uses a remote feature flag system with the tengu_ prefix. Flags come from GrowthBook's CDN and are checked with a helper function. As of v2.1.81: 784 distinct flags.

Most are telemetry event names. The interesting ones are the behavioral gates:

tengu_marble_anvilEnables context management beta
tengu_tool_pearEnables structured outputs beta
tengu_scarf_coffeeEnables tool examples beta
tengu_quiet_hollowEnables thinking redaction
tengu_amber_flintAgent teams (default: true)
tengu_attribution_headerBilling header (default: true)
tengu_penguins_offFast mode control
tengu_coral_fernTeam memory directories
tengu_herring_clockTeam memory sync
tengu_mcp_elicitationMCP elicitation support
tengu_passport_quailMemory extraction mode
tengu_harbor_permissionsNew permission system (v2.1.81+)

The flag names are deliberately obscure — marble_anvil, scarf_coffee, quiet_hollow. Probably auto-generated to avoid leaking intent through the name alone.

Internal codenames

Anthropic uses animal and object-themed codenames. Some we've mapped, others are still opaque.

TenguTelemetry + feature flag namespace. 786 events as of v2.1.81.
CoworkDesktop VM agent execution. Runs coworkd inside a Linux microVM.
TeleportSession transfer between local CLI and remote environments.
HarborNew permission system (v2.1.81+). Likely replacing the current trust dialog.
CoralFeature gate. coral_reef_sonnet controls automatic 1M context.
GrovePrivacy/consent management.
IonPreview environment at ion-preview.claude.ai.
PivotOffice file integration. Manifest at pivot.claude.ai/manifest.xml.

The Desktop app has its own set: PlushRaccoon, QuietPenguin, LouderPenguin, SparkleHedgehog, ChillingSloth, MidnightOwl, FloatingAtoll, YukonSilver, MemoryBalloon. GrowthBook flags for A/B testing different UI treatments.

Desktop VM architecture

The Claude Desktop app doesn't just shell out to the CLI. It runs agent tasks inside lightweight Linux VMs using a custom Go binary called coworkd, packaged in an 11MB boot image (smol-bin.img).

The macOS Electron app embeds a 35MB swift_addon.node native binary — a SwiftUI Markdown rendering engine. That's how the app gets native-looking text rendering inside an Electron window.

VM images download from https://downloads.claude.ai/vms/linux/{arch}/{sha} with hash verification from a separate endpoint.

Environment variables

The CLI reads ~200 environment variables. These are the ones that affect API behavior:

ANTHROPIC_BASE_URLOverride the API endpoint. Useful for proxying.
ANTHROPIC_API_KEYAPI key authentication.
ANTHROPIC_BETASInject custom beta headers (comma-separated).
ANTHROPIC_CUSTOM_HEADERSAdd arbitrary headers to requests.
API_TIMEOUT_MSRequest timeout. Default: 600,000ms (10 min).
CLAUDE_CODE_ENTRYPOINTSets entrypoint in user-agent. Default: cli.
CLAUDE_CODE_DISABLE_1M_CONTEXTForces 200k context for all models.
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFICSkips client_data, telemetry, non-critical calls.
CLAUDE_CODE_ATTRIBUTION_HEADERSet to false to disable billing header.
CLAUDE_CODE_ADDITIONAL_PROTECTIONAdds x-anthropic-additional-protection: true.
CLAUDE_CODE_USE_BEDROCKRoute through AWS Bedrock.
CLAUDE_CODE_USE_VERTEXRoute through GCP Vertex AI.
CLAUDE_CODE_USE_FOUNDRYRoute through Foundry.
CLAUDE_CODE_USE_POWERSHELL_TOOLPowerShell tool (v2.1.81+).
DISABLE_INTERLEAVED_THINKINGSuppress interleaved thinking beta.
USE_API_CONTEXT_MANAGEMENTForce context management beta.
CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETASSuppress non-essential betas.

API endpoints

/v1/messagesChat completions
/api/oauth/claude_cli/client_dataUser feature gates
/v1/oauth/tokenOAuth token exchange (console.anthropic.com)
/api/oauth/claude_cli/create_api_keyProgrammatic key creation
/api/claude_code/metricsTelemetry
/api/claude_cli_feedbackFeedback
/api/claude_code_shared_session_transcriptsSession sharing

Infrastructure

cdn.growthbook.ioFeature flag distribution
mcp-proxy.anthropic.comMCP proxy service
platform.claude.comPlatform portal
downloads.claude.aiDesktop + VM images
pivot.claude.aiOffice integration
ion-preview.claude.aiPreview environment

Model IDs in binary

These model identifiers are hardcoded for capability checks. Some don't correspond to publicly available models yet.

claude-haiku-3-5 claude-haiku-4 claude-haiku-4-5 claude-haiku-4-5-20251001 claude-sonnet-3-7 claude-sonnet-4 claude-sonnet-4-20250514 claude-sonnet-4-5 claude-sonnet-4-5-20250929 claude-sonnet-4-6 claude-opus-4 claude-opus-4-0 claude-opus-4-1 claude-opus-4-1-20250805 claude-opus-4-20250514 claude-opus-4-5 claude-opus-4-5-20251101 claude-opus-4-6

Claude 3.x models don't get thinking, context management, or structured outputs. Claude 4.x Haiku gets most features on Bedrock/Vertex but not structured outputs on first-party. Opus 4.6 and Sonnet 4.6 get everything including 128k output tokens.

System prompt validation

For OAuth sessions, the server validates that the system prompt starts with one of three identity prefixes:

"You are Claude Code, Anthropic's official CLI for Claude."
"You are Claude Code, ..., running within the Claude Agent SDK."
"You are a Claude agent, built on Anthropic's Claude Agent SDK."

Requests that don't match get rejected. The billing header gets prepended to this, before the identity prefix, as part of system[0].text.