Skip to content

How It Works

Claude Code ──► Proxy (localhost:8082) ──► Upstream OpenAI-compatible API
◄────────────── ◄──────────────────────
  1. Claude Code sends a request to the proxy using the Anthropic API format.
  2. The proxy converts the request to the OpenAI Chat Completions format.
  3. The proxy forwards the converted request to your upstream provider.
  4. The upstream response is converted back to Anthropic format.
  5. Claude Code receives the response as if it came from the Anthropic API.

When Claude Code requests a Claude model, the proxy maps it to the configured upstream model based on the tier keyword in the model name:

Claude Model PatternTierMaps ToDefault
Any name containing haikuSmallSMALL_MODELgpt-4o-mini
Any name containing sonnetMiddleMIDDLE_MODELgpt-4o
Any name containing opusBigBIG_MODELgpt-4o
Unknown model names—BIG_MODELgpt-4o

Models with the following prefixes are forwarded to the upstream provider without remapping:

  • gpt-* — OpenAI GPT models
  • o1-*, o3-*, o4-* — OpenAI reasoning models
  • ep-* — ARK/Volcano Engine models
  • doubao-* — Doubao models
  • deepseek-* — DeepSeek models
MethodPathDescription
POST/v1/messagesClaude Messages API (main endpoint for Claude Code)
POST/v1/messages/count_tokensToken count estimation
POST/v1/responses, /responsesOpenAI Responses API (Codex CLI)
POST/v1/chat/completions, /chat/completionsChat Completions pass-through
GET/v1/models, /modelsModels list pass-through
GET/healthHealth check with configuration status
GET/test-connectionLive connectivity test to upstream API
POST/admin/reloadTrigger graceful server reload
  • Streaming — Server-sent events (SSE) for real-time responses
  • Function calling / tool use — Bidirectional tool-call conversion
  • Image inputs — Base64 and URL image content blocks
  • Multi-turn conversations — Full message history support
  • Token counting — Approximate input token estimation

The proxy can intercept Claude’s web_search tool calls and execute them using a configurable search provider plugin instead of relying on Anthropic’s server-side search.

ProviderEnv VarDescription
TavilyTAVILY_API_KEYAI-optimised search API
  1. Claude Code sends a request containing a web_search tool.
  2. The proxy checks whether the configured search provider is available (result is cached for 60 seconds).
  3. If the provider is available, the proxy intercepts the tool call, queries the provider, and returns results in Anthropic’s web_search_tool_result format.
  4. If no provider is configured or the provider is not available, the web_search tool is silently stripped from the request so the upstream provider does not receive an unsupported tool definition.

Set the SEARCH_PROVIDER environment variable to select a provider and provide any required API keys:

Terminal window
SEARCH_PROVIDER="tavily"
TAVILY_API_KEY="tvly-your-api-key"

See the Configuration Reference for details.

The search system uses a plugin architecture. To add a new provider:

  1. Create src/services/search/yourprovider.py — subclass SearchProvider and call register_provider("yourprovider", factory)
  2. Add yourprovider_api_key: Optional[str] = None to Config
  3. Import the module in src/services/search/__init__.py
  4. Write tests in tests/test_search_yourprovider.py

No other files need changes — the registry, wiring, and degradation logic are provider-agnostic.