What the Claude Code client already exposes

August 10, 2026 · View on GitHub

Extracted from the shipped binary on 2026-08-10, version 2.1.226, at ~/.local/share/claude/versions/2.1.226 (an ELF executable, not a JS bundle — use strings, not grep).

CLI=~/.local/share/claude/versions/2.1.226
strings -n 6 "$CLI" | grep -oE '\bCLAUDE_CODE_[A-Z0-9_]{3,}|\bANTHROPIC_[A-Z0-9_]{3,}' | sort -u
strings -n 6 "$CLI" | grep -oE 'anthropic-ratelimit-[a-z-]+' | sort -u

Evidence tier: the strings below are confirmed present in the binary. What each one does, and whether it is honoured in every code path, is inferred from its name unless noted. None of them are in the published documentation as far as this search found. Test before depending on any of them.

Concurrency controls that already exist

These are per-session, not fleet-wide — but they are the cheapest available mitigation and should be tried before any proxy is built.

VariableInferred meaning
CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTSCap on subagents running at once. Directly targets the fan-out that issue #68502 identifies as the trigger.
CLAUDE_CODE_MAX_TOOL_USE_CONCURRENCYCap on parallel tool invocations within a turn.
CLAUDE_CODE_MAX_SUBAGENTS_PER_SESSIONLifetime budget of subagents for one session.
CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTHNesting depth for subagents spawning subagents.
CLAUDE_CODE_MAX_RETRIESClient retry attempts.
CLAUDE_CODE_RETRY_WATCHDOGPresent; behaviour unknown.
CLAUDE_CODE_MAX_TURNSTurn cap, presumably for non-interactive runs.
CLAUDE_CODE_RATE_LIMIT_TIERPresent; likely reflects or overrides the account's tier for client-side pacing.
CLAUDE_CODE_BLOCKING_LIMIT_OVERRIDEPresent; name suggests it bypasses a client-side limit gate.

A per-session cap does not solve the fleet problem — eight sessions each capped at three subagents still offers 24 concurrent requests — but it converts the worst spikes into something a shaper can smooth, and it is one line in a shell profile.

The hook that makes flow identity possible

ANTHROPIC_CUSTOM_HEADERS is present in the binary (34 occurrences). If it does what the name implies and injects operator-supplied headers into upstream API requests, it is the mechanism for tagging a session's traffic:

ANTHROPIC_BASE_URL=http://127.0.0.1:8787 \
ANTHROPIC_CUSTOM_HEADERS='X-Flow-Id: payments-refactor
X-Flow-Priority: 1' \
claude

Unverified: whether the header survives to the outbound request, what the separator between multiple headers is (newline is the convention in comparable clients), and whether the client strips unknown X- headers. This is the first thing to test, because the whole design hangs off it. The fallback if it fails is one listener port per priority class, which needs no client cooperation at all.

Also present: ANTHROPIC_SESSION_ID, CLAUDE_CODE_SESSION_ID, CLAUDE_CODE_SESSION_NAME, CLAUDE_CODE_CHILD_SESSION, CLAUDE_CODE_TMUX_SESSION. These name a session internally; no evidence was found that any of them is sent as a request header — a scan for x-* strings turned up x-api-key, x-organization-uuid, x-anthropic-billing-header, x-should-retry, x-stainless-* and various unrelated AWS/Azure/Google names, but no session identifier. So identity has to be injected; it cannot be read off the wire.

Rate-limit headers the client consumes

The client parses a anthropic-ratelimit-unified-* family — meaning these arrive on subscription (OAuth) traffic, not only on API-key traffic. That is load-bearing: it means a proxy can pace proactively from response headers instead of waiting for a 429.

Confirmed present in the binary:

anthropic-ratelimit-unified-status
anthropic-ratelimit-unified-reset
anthropic-ratelimit-unified-representative-claim
anthropic-ratelimit-unified-grace-status
anthropic-ratelimit-unified-overage-status
anthropic-ratelimit-unified-overage-reset
anthropic-ratelimit-unified-overage-period
anthropic-ratelimit-unified-overage-in-use
anthropic-ratelimit-unified-overage-disabled-reason
anthropic-ratelimit-unified-overage-utilization
anthropic-ratelimit-unified-overage-period-monthly-utilization
anthropic-ratelimit-unified-overage-period-channel-utilization
anthropic-ratelimit-unified-overage-surpassed-threshold
anthropic-ratelimit-unified-upgrade-paths

Note the shape: this is a quota view (status, reset, overage, utilisation), not a classic limit/remaining/reset triple. The exact values and their semantics have not been captured from a live response — do that early, since the pacing logic depends on whether "status" is categorical (allowed / allowed_warning / rejected) or numeric. teamclaude's source is the best existing reference for how these decode.

retry-after and overloaded_error are also present, confirming the client handles both error classes internally — which is why sessions "unstick themselves" without intervention.

Two error classes, one symptom

CodeTypeCauseDoes shaping help?
429rate_limit_errorYour account exceeded its own limitsYes, directly.
529overloaded_errorAnthropic-side capacity, in principle account-independentIndirectly. But #68502 argues observed 529s behave account-wide — they block unrelated sessions including on other machines, clear after a cooldown, and recur under sustained parallel load — which would make a local cap genuinely effective.

The client's UI renders both as "Rate limited", so the distinction is invisible from a session. A proxy sees the real status code, which is on its own a reason to interpose: it can tell the operator which one is actually happening.