Claude Code Router is an adaptive LLM gateway for Claude Code. It routes each request to the most suitable model and provider while preserving tool calls, streaming, extended thinking, and multi-turn context across different APIs.
- Adaptive Model Routing: Route requests by scenario, including background tasks, thinking, long context, web search, and image workflows.
- Tool Use & Thinking: Preserve tool calls, tool results, and reasoning content across providers with different API formats.
- Multi-Provider Support: Supports various model providers like OpenRouter, DeepSeek, Ollama, Gemini, Antigravity, Volcengine, SiliconFlow, Codex, Claude subscription, Qwen, Chrome On-Device, and Cursor (SDK).
- Request/Response Transformation: Customize requests and responses for different providers using transformers.
- Native Client Protocols: Accept Anthropic Messages, OpenAI Chat Completions, and OpenAI Responses requests through the same router and fallback pipeline.
- Dynamic Model Switching: Switch models on-the-fly within Claude Code using the
/modelcommand. - CLI Model Management: Manage models and providers directly from the terminal with
ccr model. - GitHub Actions Integration: Trigger Claude Code tasks in your GitHub workflows.
- Plugin System: Extend functionality with custom transformers.
This fork is based on claude-code-router and includes several enhancements:
- Improved LLM Support: Fixed streaming for Gemini/Gemma and enhanced OpenAI API handling.
- Reasoning & Streaming Refactor: Modularized streaming and reasoning logic into reusable utilities for better maintainability.
- Mistral Integration: Added specific handling for Mistral's reasoning parameters and decoupled transformation logic.
- Build & Deployment: Integrated the UI package into the Docker build process and added a Docker Compose configuration.
- Code Quality: Localized codebase (English comments), improved error handling, and addressed Copilot review feedback.
- Gemini Stability & Tool Use Fixes: Corrected
thoughtSignatureplacement in Gemini request bodies (Gemini 3 expects it as a sibling field on thefunctionCallpart itself, and validates only the first such part per step); filtered syntheticccr_placeholder signatures from outgoing Gemini requests to prevent Gemini 500 errors; fixedtool_resultcontent-array serialization in the Anthropic transformer so models receive plain text instead of JSON-wrapped arrays (resolves "Error editing file" in Claude Code); fixed FastifyonSendhook to preventinvalid type 'object'unhandled rejections on error responses. - Codex (ChatGPT) Integration: Added Codex transformer for the ChatGPT backend API (Responses API), supporting both OAuth-based authentication (
ccr codex-auth) and PAT auth viaapi_key: "at-...", plus SSE streaming, reasoning/thinking content, tool calls with web search, and image handling. - Cursor SDK Integration: Added
cursor-sdktransformer that runs Cursor models in-process via@cursor/sdk. Default bridge mode keeps Claude Code as the tool host (Cursor built-ins denied); supportsplan/agentmodes,crsr_/CURSOR_API_KEYauth,ccr model get cursormodel discovery, and Docker runtime install of the SDK native packages. - Claude Subscription Integration: Added
claude-authsupport for routing through a Claude Pro or Max subscription via OAuth (ccr claude-auth), using theclaude-auth+Anthropictransformer chain. - Antigravity Integration: Added Google Antigravity OAuth via
ccr antigravity-auth, with theantigravity-auth+geminitransformer chain targeting the Antigravity /cloudcode-paAPI. Supports Gemini and Claude models under that quota, thought-signature round-tripping / fallback, and Claude tool-schema sanitization for Gemini-backed Claude models. Requiresgeminioptions{"cachedContent": false}because Antigravity has no GooglecachedContentsresource (leaving the defaulttruecauses 404s). - Qwen Chat Integration: Added
qwen-authtransformer for the Qwen Chat backend (qwen.aikit.club/v1/chat/completions), supporting JWT-based authentication (ccr qwen-auth) where the user pastes a token copied fromchat.qwen.ailocalStorage, automatic token rotation, and stripping of the trailing<details>...</details>metadata block Qwen injects into responses. - DeepSeek Reasoning Replay: Implemented mandatory reasoning replay for DeepSeek models (e.g., via OpenCode/ZenGo). DeepSeek requires previous assistant reasoning content to be included in subsequent requests — the
reasoningtransformer automatically replays reasoning output from prior turns. - Model Discovery: Enabled non-interactive model discovery for arbitrary API providers. Using
ccr model get <provider>, the tool automatically fetches remote models, parses custom JSON structures using configurable paths, and appends missing models to the local configuration while preserving existing settings. - Chrome On-Device Model: Added
chrome-on-devicetransformer for Chrome's built-in Gemini Nano (~4GB local model). Communicates via a bridge process (ccr chrome-bridge) that connects to Chrome's Prompt API over CDP. UsesresponseConstraintfor structured JSON output (tool calls + text), supports streaming and non-streaming, exposes an OpenAI-compatible/v1/chat/completionsendpoint, and replaces Claude Code's system prompt with a minimal tool-focused one. Zero API cost, zero latency to external providers.- Stability & Prompting: Implemented an "OPERATIONAL OVERRIDE" in the system prompt to prevent hallucinations and force adherence to user-provided paths.
- Stall Recovery: Added a tiered retry mechanism for whitespace-heavy content: if the model stalls (emits 1000+ whitespace chars), the bridge aborts and retries without constraints and with increased temperature (Dynamic Temperature Scaling).
- Contextual awareness: Added labels ("Tool Result:") to tool outputs and instructed the model to check for existing results before calling tools again.
Before you begin, ensure you have the following installed on your system:
- Docker (Recommended): The primary way to run the router via the published image. See Docker Install Guide.
- Node.js (Optional): Required to run from source, publish packages, or use the Chrome On-Device bridge. This fork requires Node.js ≥ 22.19.0 (needed by
undici). See Node.js Download. - Claude Code: See the official quickstart guide for installation instructions.
The fastest way to launch Claude Code Router is the published Docker image:
mkdir -p ~/.claude-code-router
docker run -d --name ccr \
-p 3456:3456 \
-v ~/.claude-code-router:/root/.claude-code-router \
ghcr.io/oakimov/claude-code-router:latestThe image ships the server and UI, exposes the proxy on http://localhost:3456, and mounts ~/.claude-code-router as the config directory (/root/.claude-code-router inside the container). Set "HOST": "0.0.0.0" in your config.json so the port mapping can reach the server. After changing the config, restart with docker restart ccr; view logs with docker logs -f ccr.
Create and configure your ~/.claude-code-router/config.json file. For more details, you can refer to config.example.json.
The config.json file has several key sections:
-
PROXY_URL(optional): You can set a proxy for API requests, for example:"PROXY_URL": "http://127.0.0.1:7890". Loopback targets (localhost,127.0.0.1,::1) always bypass the proxy. Hosts listed in theNO_PROXY/no_proxyenvironment variables also bypass it (comma-separated hosts,.domain/*.domain, CIDR, optional:port). -
LOG(optional): You can enable logging by setting it totrue. When set tofalse, no log files will be created. Default istrue. -
LOG_LEVEL(optional): Set the logging level. Available options are:"fatal","error","warn","info","debug","trace". Default is"debug". -
Logging Systems: The Claude Code Router uses two separate logging systems:
- Server-level logs: HTTP requests, API calls, and server events are logged using pino in the
~/.claude-code-router/logs/directory with filenames likeccr-*.log - Application-level logs: Routing decisions and business logic events are logged in
~/.claude-code-router/claude-code-router.log
- Server-level logs: HTTP requests, API calls, and server events are logged using pino in the
-
APIKEY(optional): You can set a secret key to authenticate requests. API clients can provide it in theAuthorizationheader (e.g.,Bearer your-secret-key) or thex-api-keyheader. The web UI exchanges it for an opaqueHttpOnly, same-site session cookie and never stores the key in browser storage. UI sessions are kept in memory and require login again after CCR restarts. Example:"APIKEY": "your-secret-key". -
HOST(optional): You can set the host address for the server. IfAPIKEYis not set, the host will be forced to127.0.0.1for security reasons to prevent unauthorized access. Example:"HOST": "0.0.0.0". -
Rate limiting: Every route has a default limit of 1000 requests per minute. The shared default is defined by
RATE_LIMIT_CONFIGinpackages/shared/src/constants.ts; change it there to update all route limits. -
NON_INTERACTIVE_MODE(optional): When set totrue, enables compatibility with non-interactive environments like GitHub Actions, Docker containers, or other CI/CD systems. This sets appropriate environment variables (CI=true,FORCE_COLOR=0, etc.) and configures stdin handling to prevent the process from hanging in automated environments. Example:"NON_INTERACTIVE_MODE": true. -
Providers: Used to configure different model providers. -
Router: Used to set up routing rules.defaultspecifies the default model, which will be used for all requests if no other route is configured. -
API_TIMEOUT_MS: Specifies the timeout for API calls in milliseconds.
Claude Code Router supports environment variable interpolation for secure API key management. You can reference environment variables in your config.json using either $VAR_NAME or ${VAR_NAME} syntax:
{
"OPENAI_API_KEY": "$OPENAI_API_KEY",
"GEMINI_API_KEY": "${GEMINI_API_KEY}",
"Providers": [
{
"name": "openai",
"api_base_url": "https://api.openai.com/v1/chat/completions",
"api_key": "$OPENAI_API_KEY",
"models": ["gpt-5", "gpt-5-mini"]
}
]
}This allows you to keep sensitive API keys in environment variables instead of hardcoding them in configuration files. The interpolation works recursively through nested objects and arrays.
Here is a minimal configuration:
{
"APIKEY": "your-secret-key",
"Providers": [
{
"name": "openrouter",
"api_base_url": "https://openrouter.ai/api/v1/chat/completions",
"api_key": "$OPENROUTER_API_KEY",
"models": ["anthropic/claude-sonnet-4"],
"transformer": {
"use": ["openrouter"]
}
}
],
"Router": {
"default": "openrouter,anthropic/claude-sonnet-4"
}
}See also: The complete config reference, per-provider examples, and routing options are in
docs/docs/server/config/basic.md,docs/docs/server/config/providers.md,docs/docs/server/config/transformers.md, anddocs/docs/server/config/routing.md.
If you want to add a new provider and automatically discover its models, follow these steps:
- Add Minimal Config: Add a new entry to the
Providersarray inconfig.jsonwith just the basic details:{ "name": "my-new-provider", "api_base_url": "https://api.example.com/v1/chat/completions", "api_key": "$MY_API_KEY", "models": [] } - Perform Model Discovery: Run the discovery command to fetch available models:
ccr model get my-new-provider
- Sync Models: The command will list remote models and prompt you to append missing ones to your configuration.
- Restart: Restart the service to pick up the updated configuration:
ccr restart
Tip: For a more comprehensive description of model discovery options, custom JSON response formats, and interactive model management, see the CLI Model Management section.
Start Claude Code using the router:
ccr codeYou can also configure Claude Code to always use the router by editing its settings.json file (typically at ~/.claude/settings.json). Models are specified using the <provider>,<model> syntax:
{
"env": {
"ANTHROPIC_BASE_URL": "http://127.0.0.1:3456",
"ANTHROPIC_AUTH_TOKEN": "dummy",
"ANTHROPIC_DEFAULT_HAIKU_MODEL": "gemini,gemma-4-31b-it",
"ANTHROPIC_DEFAULT_SONNET_MODEL": "opencode,minimax-m2.7",
"ANTHROPIC_DEFAULT_OPUS_MODEL": "opencode,glm-5.1"
}
}| Variable | Purpose |
|---|---|
ANTHROPIC_BASE_URL |
Points Claude Code to the router's proxy address |
ANTHROPIC_AUTH_TOKEN |
Must match the APIKEY value set in the router's config.json |
ANTHROPIC_MODEL |
Default model (overrides per-tier defaults below) |
ANTHROPIC_DEFAULT_HAIKU_MODEL |
Fast / cost-effective model (Haiku equivalent) |
ANTHROPIC_DEFAULT_SONNET_MODEL |
Balanced performance model (Sonnet equivalent) |
ANTHROPIC_DEFAULT_OPUS_MODEL |
Maximum capability model (Opus equivalent) |
This approach lets you run claude directly without needing ccr code.
OpenAI SDK clients can use CCR without an Anthropic compatibility layer:
export OPENAI_BASE_URL=http://127.0.0.1:3456/v1
export OPENAI_API_KEY=your-router-api-keyCCR accepts Chat Completions at /v1/chat/completions (alias /chat/completions) and Responses at /v1/responses (alias /responses). Send a model as provider,model to select a destination explicitly, or send a bare model and configure Router.default. Both JSON and SSE responses are converted back to the protocol used by the client.
The compatibility layer supports ordinary text, images, function tools/results, reasoning effort, and usage reporting. Stateful Responses features such as store: true, previous_response_id, conversations, background mode, provider file IDs, and unsupported hosted tools return an explicit 400 error instead of being silently discarded.
Note: After modifying the configuration file, you need to restart the service for the changes to take effect:
ccr restart
For a more intuitive experience, you can use the UI mode to manage your configuration:
ccr uiThis will open a web-based interface where you can easily view and edit your config.json file.
For users who prefer terminal-based workflows, you can use the interactive CLI model selector:
ccr modelccr model lets you view configured models, switch models per scenario, add models, and create providers with transformer configuration — all with validation and prompts.
For non-interactive model discovery from any provider with a model-list endpoint:
ccr model get claude
ccr model get gemini
ccr model get openaiccr model get <provider> fetches remote models, then prompts to append missing ones and remove configured ones the API no longer returns. Built-in endpoint support exists for anthropic/claude, gemini, openai, codex, and cursor. Other providers can use models_api_url plus a models_response_format (listPath, idPath, stripPrefix) to parse custom JSON responses.
See also:
docs/docs/server/guides/model-discovery.mdanddocs/docs/cli/commands/model-get.md.Note: After syncing models into
config.json, restart the service withccr restart.
Note — account OAuth providers: The provider auth flows below (Antigravity, Codex, Claude subscription, Qwen) authenticate through your account-level OAuth session rather than a dedicated API key. See DISCLAIMER.md for the interoperability and compliance notes that apply to those providers.
Route Claude Code through Google's Antigravity gateway (cloudcode-pa) using account OAuth instead of an API key.
ccr antigravity-auth
# or, for headless/remote:
ccr antigravity-auth --manual
ccr antigravity-auth --project <gcp-project-id>This command:
- Prints a Google OAuth URL (PKCE; callback
http://localhost:51121/oauth-callback) - The CCR server handles the public
/oauth-callbackroute (Docker maps51121:3456, like Codex1455:3456) - Tokens land in
~/.claude-code-router/antigravity_auth.json(mounted config dir in Docker)
Example provider:
{
"name": "antigravity",
"api_base_url": "https://daily-cloudcode-pa.sandbox.googleapis.com",
"api_key": "oauth",
"project_id": "$ANTIGRAVITY_PROJECT_ID",
"models": ["gemini-3-flash", "claude-sonnet-4-6", "claude-opus-4-6-thinking"],
"transformer": {
"use": [
["gemini", { "cachedContent": false, "thoughtSignatureFallback": "skip" }],
"antigravity-auth"
]
}
}cachedContent: false is required — Antigravity has no Google cachedContents resource, and leaving the Gemini default (true) causes 404s. The thoughtSignatureFallback option is covered in docs/docs/server/config/transformers.md.
Note: Keep the CCR server running during auth. Using Antigravity IDE OAuth client credentials from a non-IDE client may violate Google's terms.
The Codex provider supports two authentication modes:
- OAuth via
ccr codex-auth— browser flow handled by the CCR server callback on port1455(Docker maps1455:3456); tokens stored in~/.claude-code-router/codex_auth.jsonand auto-refreshed. - PAT via a literal
api_key: "at-..."(or an env var containing anat-token) — skipsccr codex-auth.
An at- value is always treated as a PAT and never silently falls back to OAuth; any other placeholder selects OAuth tokens.
See also: Full Codex setup, both auth modes, provider config, and troubleshooting are in
docs/docs/server/guides/codex.md.
The Cursor provider runs models in-process via the official @cursor/sdk (no browser OAuth CLI). Auth resolves from the provider api_key starting with crsr_, then CURSOR_API_KEY. Default bridge mode keeps Claude Code as the tool host; Cursor built-ins are denied in an isolated workspace. Discover models with ccr model get cursor.
See also: Full Cursor setup, bridge/plan/agent modes, and configuration are in
docs/docs/server/guides/cursor.md.
Route Claude Code through your Claude Pro or Max subscription via OAuth:
ccr claude-authThe OAuth flow is handled by the CCR server callback on port 1455 (Docker maps 1455:3456); tokens are stored in ~/.claude-code-router/claude_auth.json and auto-refreshed. A Claude subscription provider requires the claude-auth + Anthropic transformer chain.
See also: Full setup, the transformer chain, client classification, and billing/identity details are in
docs/docs/server/guides/claude-auth.md.
Authenticate with Qwen Chat by saving a JWT from chat.qwen.ai localStorage:
ccr qwen-authThe CCR server hosts an auth page at /qwen/auth offering a bookmarklet or manual paste. The token is validated, saved to ~/.claude-code-router/qwen_auth.json, and auto-refreshed. The Qwen provider requires the qwen-auth + reasoning + OpenAI transformer chain.
See also: Full Qwen setup and provider config are in
docs/docs/server/guides/qwen.md.
Use Chrome's built-in Gemini Nano (~4GB local model) with zero API cost via a host-side bridge:
ccr chrome-bridge # default: port 3457, CDP 9222
ccr chrome-bridge --port 3457 --cdp 9222The bridge connects to Chrome's Prompt API over CDP, maintains persistent model sessions, and exposes an OpenAI-compatible API (/v1/chat/completions) on 127.0.0.1:3457. It replaces Claude Code's system prompt with a minimal tool-focused one and uses responseConstraint (JSON Schema) to force structured {text, tool_calls[]} output.
Prerequisites: enable chrome://flags/#optimization-guide-on-device-model and chrome://flags/#prompt-api-for-gemini-nano-multimodal-input, restart Chrome, and let the ~4GB model download.
Note for Docker: The bridge runs on the Docker host, not inside the container — set the provider host to
http://host.docker.internal:3457. Full setup, provider config, features, and limitations are indocs/docs/server/guides/chrome-on-device.md.
Save, share, and reuse configurations:
ccr preset export my-preset # export current config as a preset
ccr preset export my-preset --description "My OpenAI config" --author "Your Name" --tags "openai,production"
ccr preset install /path/to/preset # install from a directory
ccr preset list
ccr preset info my-preset
ccr preset delete my-presetPresets store your configuration (plus metadata) as a directory with manifest.json. Sensitive fields are sanitized to {{field}} placeholders on export, and presets can include input schemas to collect required values (e.g. API keys) at install time.
See also:
docs/docs/cli/commands/preset.md.
The activate command allows you to set up environment variables globally in your shell, enabling you to use the claude command directly or integrate Claude Code Router with applications built using the Agent SDK.
To activate the environment variables, run:
eval "$(ccr activate)"This command outputs the necessary environment variables in shell-friendly format, which are then set in your current shell session. After activation, you can:
- Use
claudecommand directly: Runclaudecommands without needing to useccr code. Theclaudecommand will automatically route requests through Claude Code Router. - Integrate with Agent SDK applications: Applications built with the Anthropic Agent SDK will automatically use the configured router and models.
The activate command sets the following environment variables:
ANTHROPIC_AUTH_TOKEN: API key from your configurationANTHROPIC_BASE_URL: The local router endpoint (default:http://127.0.0.1:3456)NO_PROXY: Set to127.0.0.1to prevent proxy interferenceDISABLE_TELEMETRY: Disables telemetryDISABLE_COST_WARNINGS: Disables cost warningsAPI_TIMEOUT_MS: API timeout from your configuration
Note: Make sure the Claude Code Router service is running (
ccr start) before using the activated environment variables. The environment variables are only valid for the current shell session. To make them persistent, you can addeval "$(ccr activate)"to your shell configuration file (e.g.,~/.zshrcor~/.bashrc).
The Providers array defines each provider: name, api_base_url, api_key, models, and an optional transformer object. The transformer.use list applies transformers globally (all models) or per model key, and some transformers accept options via a nested [name, options] array.
See also: Provider schema and per-provider examples are in
docs/docs/server/config/providers.md; the transformer reference and option passing are indocs/docs/server/config/transformers.md.
Available Built-in Transformers:
Anthropic— passes through to an Anthropic endpoint unchanged.OpenAI— registers the/v1/chat/completionsroute (the body is already in OpenAI shape).- Provider adapters:
deepseek,groq,mistral,openrouter,gemini/vertex-gemini,codex,claude-auth,antigravity-auth,qwen-auth,cursor-sdk,chrome-on-device. maxtoken— sets a specificmax_tokens.tooluse— optimizes tool usage viatool_choice.reasoning— replays providerreasoning_contentacross turns.sampling— mapstemperature/top_p/top_k/repetition_penalty.enhancetool— adds error tolerance to tool-call parameters (disables streaming of tool calls).cleancache— clearscache_control.customparams— injects custom request parameters.- Experimental gist/CLI integrations:
gemini-cli,chutes-glm,qwen-cli,rovo-cli.
See also: The full transformer reference — including the
geminicachedContent/thoughtSignatureFallbackoptions and theopenrouterprovider-routing parameter — is indocs/docs/server/config/transformers.md.
Custom Transformers:
Load your own transformers via the transformers field in config.json, e.g. { "transformers": [{ "path": "/User/xxx/.claude-code-router/plugins/gemini-cli.js", "options": { "project": "xxx" } }] }. See docs/docs/server/config/transformers.md for the full custom-transformer guide.
The Router object defines which model to use for different scenarios:
-
default: The default model for general tasks. -
background: A model for background tasks. This can be a smaller, local model to save costs. -
think: A model for reasoning-heavy tasks, like Plan Mode. -
longContext: A model for handling long contexts (e.g., > 60K tokens). -
longContextThreshold(optional): The token count threshold for triggering the long context model. Defaults to 60000 if not specified. -
webSearch: Used for handling web search tasks and this requires the model itself to support the feature. If you're using openrouter, you need to add the:onlinesuffix after the model name. -
image(beta): Used for handling image-related tasks (supported by CCR’s built-in agent). If the model does not support tool calling, you need to set theconfig.forceUseImageAgentproperty totrue. -
You can also switch models dynamically in Claude Code with the
/modelcommand:/model provider_name,model_nameExample:/model openrouter,anthropic/claude-3.5-sonnet
For advanced routing logic, set CUSTOM_ROUTER_PATH in config.json to a JS module exporting an async function(req, config) that returns a "provider,model" string, or null to fall back to the default router. See custom-router.example.js and docs/docs/server/advanced/custom-router.md.
Claude Code subagent requests can be routed with:
- An explicit
<CCR-SUBAGENT-MODEL>provider,model</CCR-SUBAGENT-MODEL>tag in system or message text (the tag is stripped before the upstream request).provider/modelis also accepted. - Or the
CLAUDE_CODE_SUBAGENT_MODEL=provider,modelenvironment variable when Claude Code marks the turn as a subagent.
Tag takes priority over the environment variable. If neither is set, normal Router rules apply.
Example:
<CCR-SUBAGENT-MODEL>openrouter,anthropic/claude-3.5-sonnet</CCR-SUBAGENT-MODEL>
Please help me analyze this code snippet for potential optimizations...
export CLAUDE_CODE_SUBAGENT_MODEL="openrouter,anthropic/claude-3.5-sonnet"CCR translates Claude Code's Anthropic cache intent into each upstream's native caching mechanism automatically:
- Anthropic, Claude Auth, and Vertex Claude use Anthropic automatic prompt caching while preserving bounded explicit block markers.
- OpenAI Chat and Responses use stable
prompt_cache_keyvalues; GPT-5.6+ models also receive explicit content breakpoints. Codex uses its separate native contract for every model: a stable prompt key plus session-routing headers, with no explicit content breakpoints. - OpenRouter uses sticky
session_idrouting plus model-native caching. Vercel AI Gateway receivesproviderOptions.gateway.caching: "auto". - Mistral and Cerebras receive native
prompt_cache_keyvalues. Qwen/DashScope receives a final-content cache marker. DeepSeek, Groq, and Vertex OpenAI retain their native implicit caching. - Gemini and Vertex Gemini use implicit caching and create/reuse native CachedContent resources for sufficiently large stable system/tool prefixes.
- Cursor SDK and Chrome On-Device reuse stable native sessions.
Provider-incompatible cache fields are removed only after translation. Cache read/write usage reported upstream is converted back to Anthropic cache_read_input_tokens and cache_creation_input_tokens for Claude Code.
See the implementation plan and review for the provider matrix and verification scope.
To better monitor the status of claude-code-router at runtime, version v1.0.40 includes a built-in statusline tool, which you can enable in the UI.

Integrate Claude Code Router into your CI/CD pipeline. After setting up Claude Code Actions, modify your .github/workflows/claude.yaml to use the router:
name: Claude Code
on:
issue_comment:
types: [created]
# ... other triggers
jobs:
claude:
if: |
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
# ... other conditions
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: read
issues: read
id-token: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 1
- name: Prepare Environment
run: |
curl -fsSL https://bun.sh/install | bash
mkdir -p $HOME/.claude-code-router
cat << 'EOF' > $HOME/.claude-code-router/config.json
{
"log": true,
"NON_INTERACTIVE_MODE": true,
"OPENAI_API_KEY": "${{ secrets.OPENAI_API_KEY }}",
"OPENAI_BASE_URL": "https://api.deepseek.com",
"OPENAI_MODEL": "deepseek-chat"
}
EOF
shell: bash
- name: Start Claude Code Router
run: |
nohup ~/.bun/bin/bunx @caeliq/claude-code-router@1.0.8 start &
shell: bash
- name: Run Claude Code
id: claude
uses: anthropics/claude-code-action@beta
env:
ANTHROPIC_BASE_URL: http://localhost:3456
with:
anthropic_api_key: "any-string-is-ok"Note: When running in GitHub Actions or other automation environments, make sure to set
"NON_INTERACTIVE_MODE": truein your configuration to prevent the process from hanging due to stdin handling issues.
This setup allows for interesting automations, like running tasks during off-peak hours to reduce API costs.
- Codex API — Developer docs for the ChatGPT backend API used by the
codextransformer (OAuth PKCE, Responses API, streaming, tool calls) - Chrome Prompt API — On-device Gemini Nano API used by the
chrome-on-devicetransformer and bridge - Provider Integration Lessons — Hard-won knowledge for LLM provider integrations (DeepSeek, Mistral, Gemini, Codex, Gemini Nano)



