Summary
The built-in agentrouter provider talks the correct protocol (Anthropic Messages API), but it sends a static, hardcoded Claude Code CLI fingerprint via getClaudeCliHeaders(). AgentRouter runs a WAF that only accepts traffic matching the current Claude Code "wire image", so as that fingerprint drifts, users increasingly hit unauthorized client detected. We should route the built-in agentrouter provider through the same dynamic Claude-Code-compatible wire-image pipeline used by anthropic-compatible-cc-* providers, instead of the static default-executor headers.
Current implementation (correct protocol, fragile fingerprint)
open-sse/config/providers/registry/agentrouter/index.ts:
format: "claude", // ✅ Anthropic Messages API (not OpenAI)
baseUrl: "https://agentrouter.org/v1/messages", // ✅ /v1/messages, not /chat/completions
authType: "apikey", authHeader: "x-api-key", // ✅ Anthropic-style auth
headers: getClaudeCliHeaders(), // ⚠️ STATIC fingerprint
The static fingerprint lives in open-sse/config/anthropicHeaders.ts:124-127:
export const CLAUDE_CLI_VERSION = "2.1.195";
export const CLAUDE_CLI_USER_AGENT = `claude-cli/${CLAUDE_CLI_VERSION} (external, cli)`;
export const CLAUDE_CLI_STAINLESS_PACKAGE_VERSION = "0.94.0";
export const CLAUDE_CLI_STAINLESS_RUNTIME_VERSION = "v24.3.0";
The agentrouter registry entry has not been touched since v3.8.27; the fingerprint constants were last bumped at v3.8.40. Only claude (official OAuth — safe, it hits the real Anthropic endpoint) and agentrouter use getClaudeCliHeaders(). For a third-party relay with a strict WAF, a static fingerprint is a slow-moving footgun.
Why users see unauthorized client detected
AgentRouter markets itself as a drop-in ANTHROPIC_BASE_URL replacement for Claude Code and its WAF rejects anything that does not look like current Claude Code. The two failure modes (documented in our own Agentrouter wiki):
- Provider added as a generic
openai-compatible-chat custom provider → wrong wire image → rejected.
- Static/aged Claude Code fingerprint no longer matches what the WAF expects → rejected.
The robust path today is the Claude Code Compatible provider (anthropic-compatible-cc-*) with ENABLE_CC_COMPATIBLE_PROVIDER=true (Base URL https://agentrouter.org, chat path /v1/messages?beta=true), which runs the full dynamic wire-image pipeline (open-sse/services/ccBridgeTransforms.ts, open-sse/services/systemTransforms.ts T4-200, isClaudeCodeCompatible in open-sse/services/provider.ts:31). But that requires manual advanced setup + a feature flag, while the "Quick Start" built-in provider silently uses the fragile static path.
Proposed improvement
Make the built-in agentrouter provider consume the same dynamic Claude-Code wire-image pipeline as anthropic-compatible-cc-* (dynamic identity/anchors + /v1/messages?beta=true), so the "Quick Start" path stays WAF-valid without users needing the advanced flow or the ENABLE_CC_COMPATIBLE_PROVIDER flag. Options to evaluate:
- Have the
agentrouter registry entry opt into the CC-bridge pipeline (a registry flag that makes the default executor route through ccBridgeTransforms/systemTransforms instead of static getClaudeCliHeaders()), or
- Internally alias the built-in
agentrouter to an anthropic-compatible-cc-agentrouter configuration so the dashboard "Quick Start" wires the CC pipeline transparently.
Acceptance criteria
- Built-in
agentrouter provider passes AgentRouter's WAF without manual anthropic-compatible-cc setup.
- The fix does not require operators to set
ENABLE_CC_COMPATIBLE_PROVIDER=true for the built-in provider.
- Regression test asserting the outbound request for
agentrouter carries the dynamic CC wire image (not the static claude-cli/2.1.195 headers).
- Wiki updated to reflect the simplified path.
Not in scope
Bumping the static CLAUDE_CLI_VERSION/stainless constants is only a temporary patch — the point is to stop depending on a static fingerprint for a WAF-gated relay.
Summary
The built-in
agentrouterprovider talks the correct protocol (Anthropic Messages API), but it sends a static, hardcoded Claude Code CLI fingerprint viagetClaudeCliHeaders(). AgentRouter runs a WAF that only accepts traffic matching the current Claude Code "wire image", so as that fingerprint drifts, users increasingly hitunauthorized client detected. We should route the built-inagentrouterprovider through the same dynamic Claude-Code-compatible wire-image pipeline used byanthropic-compatible-cc-*providers, instead of the static default-executor headers.Current implementation (correct protocol, fragile fingerprint)
open-sse/config/providers/registry/agentrouter/index.ts:The static fingerprint lives in
open-sse/config/anthropicHeaders.ts:124-127:The
agentrouterregistry entry has not been touched since v3.8.27; the fingerprint constants were last bumped at v3.8.40. Onlyclaude(official OAuth — safe, it hits the real Anthropic endpoint) andagentrouterusegetClaudeCliHeaders(). For a third-party relay with a strict WAF, a static fingerprint is a slow-moving footgun.Why users see
unauthorized client detectedAgentRouter markets itself as a drop-in
ANTHROPIC_BASE_URLreplacement for Claude Code and its WAF rejects anything that does not look like current Claude Code. The two failure modes (documented in our own Agentrouter wiki):openai-compatible-chatcustom provider → wrong wire image → rejected.The robust path today is the Claude Code Compatible provider (
anthropic-compatible-cc-*) withENABLE_CC_COMPATIBLE_PROVIDER=true(Base URLhttps://agentrouter.org, chat path/v1/messages?beta=true), which runs the full dynamic wire-image pipeline (open-sse/services/ccBridgeTransforms.ts,open-sse/services/systemTransforms.tsT4-200,isClaudeCodeCompatibleinopen-sse/services/provider.ts:31). But that requires manual advanced setup + a feature flag, while the "Quick Start" built-in provider silently uses the fragile static path.Proposed improvement
Make the built-in
agentrouterprovider consume the same dynamic Claude-Code wire-image pipeline asanthropic-compatible-cc-*(dynamic identity/anchors +/v1/messages?beta=true), so the "Quick Start" path stays WAF-valid without users needing the advanced flow or theENABLE_CC_COMPATIBLE_PROVIDERflag. Options to evaluate:agentrouterregistry entry opt into the CC-bridge pipeline (a registry flag that makes the default executor route throughccBridgeTransforms/systemTransformsinstead of staticgetClaudeCliHeaders()), oragentrouterto ananthropic-compatible-cc-agentrouterconfiguration so the dashboard "Quick Start" wires the CC pipeline transparently.Acceptance criteria
agentrouterprovider passes AgentRouter's WAF without manualanthropic-compatible-ccsetup.ENABLE_CC_COMPATIBLE_PROVIDER=truefor the built-in provider.agentroutercarries the dynamic CC wire image (not the staticclaude-cli/2.1.195headers).Not in scope
Bumping the static
CLAUDE_CLI_VERSION/stainless constants is only a temporary patch — the point is to stop depending on a static fingerprint for a WAF-gated relay.