@davidwarshawsky/claude-code-router 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +1164 -0
- package/dist/cli.js +1272 -0
- package/dist/index.html +225 -0
- package/dist/tiktoken_bg.wasm +0 -0
- package/package.json +66 -0
package/README.md
ADDED
|
@@ -0,0 +1,1164 @@
|
|
|
1
|
+
# Claude Code Router
|
|
2
|
+
|
|
3
|
+
A powerful tool to route Claude Code requests to different models and customize any request.
|
|
4
|
+
|
|
5
|
+
## About This Fork
|
|
6
|
+
|
|
7
|
+
This is a personal fork of [musistudio/claude-code-router](https://github.com/musistudio/claude-code-router). The original project is an excellent open-source routing solution maintained by the musistudio team.
|
|
8
|
+
|
|
9
|
+
### Differences from the Original
|
|
10
|
+
|
|
11
|
+
- **Advertising Removed**: This version removes promotional content and sponsorship messaging to focus on core functionality documentation.
|
|
12
|
+
- **Pre-configured Providers**: Comes with a broader set of pre-configured LLM providers (Cloudflare, Groq, Google AI Studio, NVIDIA, Mistral, Cohere, Cerebras) with support for multi-account routing.
|
|
13
|
+
- **Local Setup Documentation**: Includes setup instructions tailored for local deployment and development.
|
|
14
|
+
|
|
15
|
+
### Why This Fork Was Created
|
|
16
|
+
|
|
17
|
+
This fork was created to:
|
|
18
|
+
1. Provide a clean, advertising-free version of the documentation
|
|
19
|
+
2. Demonstrate multi-provider routing setup with multiple accounts per provider
|
|
20
|
+
3. Enable rapid local deployment and testing of the Claude Code Router
|
|
21
|
+
4. Serve as a reference implementation for advanced routing configurations
|
|
22
|
+
|
|
23
|
+
### Original Project
|
|
24
|
+
|
|
25
|
+
For the full documentation, upstream updates, and the original community, please visit:
|
|
26
|
+
- **Repository**: https://github.com/musistudio/claude-code-router
|
|
27
|
+
- **Discord**: https://discord.gg/rdftVMaUcS
|
|
28
|
+
- **License**: MIT (see LICENSE file)
|
|
29
|
+
|
|
30
|
+
## ✨ Features
|
|
31
|
+
|
|
32
|
+
### Core Routing
|
|
33
|
+
- **Intelligent Scenario-Based Routing**: Automatically route requests based on context
|
|
34
|
+
- `default`: Standard requests
|
|
35
|
+
- `background`: Lightweight background tasks
|
|
36
|
+
- `think`: Thinking/reasoning-intensive operations (Plan Mode)
|
|
37
|
+
- `longContext`: Automatically triggered for requests exceeding token thresholds
|
|
38
|
+
- `webSearch`: Web search-related operations
|
|
39
|
+
- `image`: Image processing and analysis tasks
|
|
40
|
+
- **Token-Aware Routing**: Automatic token counting (cl100k_base) to intelligently select models based on context length requirements
|
|
41
|
+
- **Multi-Provider Support**: Supports 15+ providers including OpenRouter, DeepSeek, Ollama, Gemini, Volcengine, SiliconFlow, Cloudflare, Groq, NVIDIA, Mistral, Cohere, Cerebras, and more
|
|
42
|
+
- **Multi-Account Routing**: Multiple API keys per provider with automatic rotation and exhaustion detection
|
|
43
|
+
- Automatic account rotation on rate limits and quota exhaustion
|
|
44
|
+
- Usage tracking with daily reset
|
|
45
|
+
- Per-account status monitoring (active/exhausted/rate_limited)
|
|
46
|
+
|
|
47
|
+
### Advanced Features
|
|
48
|
+
- **Request/Response Transformation**: Customize requests and responses for different providers using a flexible transformer system
|
|
49
|
+
- **Dynamic Model Switching**: Switch models on-the-fly within Claude Code using the `/model` command
|
|
50
|
+
- **Custom Router Functions**: Write custom JavaScript routing logic for complex scenarios
|
|
51
|
+
- **Project-Level Configuration**: Define routing rules per project at `~/.claude/projects/<project-id>/claude-code-router.json`
|
|
52
|
+
- **Preset System**: Schema-based configuration templates for easy sharing and reuse
|
|
53
|
+
- Export/import presets with sensitive data protection
|
|
54
|
+
- Marketplace integration for discovering community presets
|
|
55
|
+
- Conditional field support with template interpolation
|
|
56
|
+
|
|
57
|
+
### Developer Tools
|
|
58
|
+
- **Web UI Dashboard**: Full-featured interface for managing providers, accounts, models, and presets
|
|
59
|
+
- **CLI Model Management**: Interactive terminal UI (`ccr model`) for configuration without editing JSON
|
|
60
|
+
- **Usage Tracking & Analytics**: Monitor API consumption per provider and account
|
|
61
|
+
- **Plugin System**: Extend functionality with custom transformers and plugins
|
|
62
|
+
- **Agent System**: Extensible architecture for custom tools and workflows
|
|
63
|
+
- **Non-Interactive Mode**: Full CI/CD support for Docker, GitHub Actions, and automated environments
|
|
64
|
+
|
|
65
|
+
### Deployment & Operations
|
|
66
|
+
- **GitHub Actions Integration**: Trigger Claude Code tasks in your workflows
|
|
67
|
+
- **Logging System**: Dual logging (server-level and application-level) with auto-rotating files
|
|
68
|
+
- **Environment Variable Interpolation**: Secure API key management via `$VAR_NAME` syntax
|
|
69
|
+
- **Health Monitoring**: Built-in health checks and status endpoints
|
|
70
|
+
- **Proxy Support**: Configure proxy for API requests
|
|
71
|
+
|
|
72
|
+
## 🚀 Getting Started
|
|
73
|
+
|
|
74
|
+
### 1. Installation
|
|
75
|
+
|
|
76
|
+
First, ensure you have [Claude Code](https://docs.anthropic.com/en/docs/claude-code/quickstart) installed:
|
|
77
|
+
|
|
78
|
+
```shell
|
|
79
|
+
npm install -g @anthropic-ai/claude-code
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Then, install this Claude Code Router fork:
|
|
83
|
+
|
|
84
|
+
```shell
|
|
85
|
+
npm install -g @davidwarshawsky/claude-code-router
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
**Note**: This package is published under the `@davidwarshawsky` scope. Ensure your `.npmrc` is configured with appropriate authentication if using a private registry.
|
|
89
|
+
|
|
90
|
+
#### .npmrc Configuration
|
|
91
|
+
|
|
92
|
+
If you're installing from a private npm registry, configure your `.npmrc` file in your home directory (`~/.npmrc`):
|
|
93
|
+
|
|
94
|
+
```ini
|
|
95
|
+
# For GitHub Package Registry
|
|
96
|
+
@davidwarshawsky:registry=https://npm.pkg.github.com
|
|
97
|
+
|
|
98
|
+
# For npm token authentication
|
|
99
|
+
//npm.pkg.github.com/:_authToken=YOUR_NPM_TOKEN
|
|
100
|
+
|
|
101
|
+
# For public npm registry (default)
|
|
102
|
+
@davidwarshawsky:registry=https://registry.npmjs.org/
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
To generate an npm token:
|
|
106
|
+
1. Visit https://npmjs.com/settings/tokens
|
|
107
|
+
2. Create a new token with read access
|
|
108
|
+
3. Copy the token and add to your `.npmrc`
|
|
109
|
+
|
|
110
|
+
### 2. Configuration
|
|
111
|
+
|
|
112
|
+
Create and configure your `~/.claude-code-router/config.json` file. For more details, you can refer to `config.example.json`.
|
|
113
|
+
|
|
114
|
+
The `config.json` file has several key sections:
|
|
115
|
+
|
|
116
|
+
- **`PROXY_URL`** (optional): You can set a proxy for API requests, for example: `"PROXY_URL": "http://127.0.0.1:7890"`.
|
|
117
|
+
- **`LOG`** (optional): You can enable logging by setting it to `true`. When set to `false`, no log files will be created. Default is `true`.
|
|
118
|
+
- **`LOG_LEVEL`** (optional): Set the logging level. Available options are: `"fatal"`, `"error"`, `"warn"`, `"info"`, `"debug"`, `"trace"`. Default is `"debug"`.
|
|
119
|
+
- **Logging Systems**: The Claude Code Router uses two separate logging systems:
|
|
120
|
+
- **Server-level logs**: HTTP requests, API calls, and server events are logged using pino in the `~/.claude-code-router/logs/` directory with filenames like `ccr-*.log`
|
|
121
|
+
- **Application-level logs**: Routing decisions and business logic events are logged in `~/.claude-code-router/claude-code-router.log`
|
|
122
|
+
- **`APIKEY`** (optional): You can set a secret key to authenticate requests. When set, clients must provide this key in the `Authorization` header (e.g., `Bearer your-secret-key`) or the `x-api-key` header. Example: `"APIKEY": "your-secret-key"`.
|
|
123
|
+
- **`HOST`** (optional): You can set the host address for the server. If `APIKEY` is not set, the host will be forced to `127.0.0.1` for security reasons to prevent unauthorized access. Example: `"HOST": "0.0.0.0"`.
|
|
124
|
+
- **`NON_INTERACTIVE_MODE`** (optional): When set to `true`, 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`.
|
|
125
|
+
|
|
126
|
+
- **`Providers`**: Used to configure different model providers.
|
|
127
|
+
- **`Router`**: Used to set up routing rules. `default` specifies the default model, which will be used for all requests if no other route is configured.
|
|
128
|
+
- **`API_TIMEOUT_MS`**: Specifies the timeout for API calls in milliseconds.
|
|
129
|
+
|
|
130
|
+
#### Environment Variable Interpolation
|
|
131
|
+
|
|
132
|
+
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:
|
|
133
|
+
|
|
134
|
+
```json
|
|
135
|
+
{
|
|
136
|
+
"OPENAI_API_KEY": "$OPENAI_API_KEY",
|
|
137
|
+
"GEMINI_API_KEY": "${GEMINI_API_KEY}",
|
|
138
|
+
"Providers": [
|
|
139
|
+
{
|
|
140
|
+
"name": "openai",
|
|
141
|
+
"api_base_url": "https://api.openai.com/v1/chat/completions",
|
|
142
|
+
"api_key": "$OPENAI_API_KEY",
|
|
143
|
+
"models": ["gpt-5", "gpt-5-mini"]
|
|
144
|
+
}
|
|
145
|
+
]
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
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.
|
|
150
|
+
|
|
151
|
+
Here is a comprehensive example:
|
|
152
|
+
|
|
153
|
+
```json
|
|
154
|
+
{
|
|
155
|
+
"APIKEY": "your-secret-key",
|
|
156
|
+
"PROXY_URL": "http://127.0.0.1:7890",
|
|
157
|
+
"LOG": true,
|
|
158
|
+
"API_TIMEOUT_MS": 600000,
|
|
159
|
+
"NON_INTERACTIVE_MODE": false,
|
|
160
|
+
"Providers": [
|
|
161
|
+
{
|
|
162
|
+
"name": "openrouter",
|
|
163
|
+
"api_base_url": "https://openrouter.ai/api/v1/chat/completions",
|
|
164
|
+
"api_key": "sk-xxx",
|
|
165
|
+
"models": [
|
|
166
|
+
"google/gemini-2.5-pro-preview",
|
|
167
|
+
"anthropic/claude-sonnet-4",
|
|
168
|
+
"anthropic/claude-3.5-sonnet",
|
|
169
|
+
"anthropic/claude-3.7-sonnet:thinking"
|
|
170
|
+
],
|
|
171
|
+
"transformer": {
|
|
172
|
+
"use": ["openrouter"]
|
|
173
|
+
}
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
"name": "deepseek",
|
|
177
|
+
"api_base_url": "https://api.deepseek.com/chat/completions",
|
|
178
|
+
"api_key": "sk-xxx",
|
|
179
|
+
"models": ["deepseek-chat", "deepseek-reasoner"],
|
|
180
|
+
"transformer": {
|
|
181
|
+
"use": ["deepseek"],
|
|
182
|
+
"deepseek-chat": {
|
|
183
|
+
"use": ["tooluse"]
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
"name": "ollama",
|
|
189
|
+
"api_base_url": "http://localhost:11434/v1/chat/completions",
|
|
190
|
+
"api_key": "ollama",
|
|
191
|
+
"models": ["qwen2.5-coder:latest"]
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
"name": "gemini",
|
|
195
|
+
"api_base_url": "https://generativelanguage.googleapis.com/v1beta/models/",
|
|
196
|
+
"api_key": "sk-xxx",
|
|
197
|
+
"models": ["gemini-2.5-flash", "gemini-2.5-pro"],
|
|
198
|
+
"transformer": {
|
|
199
|
+
"use": ["gemini"]
|
|
200
|
+
}
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
"name": "volcengine",
|
|
204
|
+
"api_base_url": "https://ark.cn-beijing.volces.com/api/v3/chat/completions",
|
|
205
|
+
"api_key": "sk-xxx",
|
|
206
|
+
"models": ["deepseek-v3-250324", "deepseek-r1-250528"],
|
|
207
|
+
"transformer": {
|
|
208
|
+
"use": ["deepseek"]
|
|
209
|
+
}
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
"name": "modelscope",
|
|
213
|
+
"api_base_url": "https://api-inference.modelscope.cn/v1/chat/completions",
|
|
214
|
+
"api_key": "",
|
|
215
|
+
"models": ["Qwen/Qwen3-Coder-480B-A35B-Instruct", "Qwen/Qwen3-235B-A22B-Thinking-2507"],
|
|
216
|
+
"transformer": {
|
|
217
|
+
"use": [
|
|
218
|
+
[
|
|
219
|
+
"maxtoken",
|
|
220
|
+
{
|
|
221
|
+
"max_tokens": 65536
|
|
222
|
+
}
|
|
223
|
+
],
|
|
224
|
+
"enhancetool"
|
|
225
|
+
],
|
|
226
|
+
"Qwen/Qwen3-235B-A22B-Thinking-2507": {
|
|
227
|
+
"use": ["reasoning"]
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
},
|
|
231
|
+
{
|
|
232
|
+
"name": "dashscope",
|
|
233
|
+
"api_base_url": "https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions",
|
|
234
|
+
"api_key": "",
|
|
235
|
+
"models": ["qwen3-coder-plus"],
|
|
236
|
+
"transformer": {
|
|
237
|
+
"use": [
|
|
238
|
+
[
|
|
239
|
+
"maxtoken",
|
|
240
|
+
{
|
|
241
|
+
"max_tokens": 65536
|
|
242
|
+
}
|
|
243
|
+
],
|
|
244
|
+
"enhancetool"
|
|
245
|
+
]
|
|
246
|
+
}
|
|
247
|
+
},
|
|
248
|
+
{
|
|
249
|
+
"name": "aihubmix",
|
|
250
|
+
"api_base_url": "https://aihubmix.com/v1/chat/completions",
|
|
251
|
+
"api_key": "sk-",
|
|
252
|
+
"models": [
|
|
253
|
+
"Z/glm-4.5",
|
|
254
|
+
"claude-opus-4-20250514",
|
|
255
|
+
"gemini-2.5-pro"
|
|
256
|
+
]
|
|
257
|
+
}
|
|
258
|
+
],
|
|
259
|
+
"Router": {
|
|
260
|
+
"default": "deepseek,deepseek-chat",
|
|
261
|
+
"background": "ollama,qwen2.5-coder:latest",
|
|
262
|
+
"think": "deepseek,deepseek-reasoner",
|
|
263
|
+
"longContext": "openrouter,google/gemini-2.5-pro-preview",
|
|
264
|
+
"longContextThreshold": 60000,
|
|
265
|
+
"webSearch": "gemini,gemini-2.5-flash"
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
### Cloudflare Workers AI Multi-Account Example
|
|
271
|
+
|
|
272
|
+
If you want to route Claude Code through multiple Cloudflare Workers AI accounts, use Cloudflare's OpenAI-compatible endpoint and configure each account in the `accounts` array:
|
|
273
|
+
|
|
274
|
+
```json
|
|
275
|
+
{
|
|
276
|
+
"APIKEY": "test",
|
|
277
|
+
"HOST": "127.0.0.1",
|
|
278
|
+
"PORT": 3456,
|
|
279
|
+
"Providers": [
|
|
280
|
+
{
|
|
281
|
+
"name": "cloudflare-large",
|
|
282
|
+
"api_base_url": "https://api.cloudflare.com/client/v4/accounts/{account_id}/ai/v1/chat/completions",
|
|
283
|
+
"accounts": [
|
|
284
|
+
{
|
|
285
|
+
"id": "account-id-1",
|
|
286
|
+
"key": "cf-token-1",
|
|
287
|
+
"email": "",
|
|
288
|
+
"label": "account_1"
|
|
289
|
+
},
|
|
290
|
+
{
|
|
291
|
+
"id": "account-id-2",
|
|
292
|
+
"key": "cf-token-2",
|
|
293
|
+
"email": "user@example.com",
|
|
294
|
+
"label": "account_2"
|
|
295
|
+
}
|
|
296
|
+
],
|
|
297
|
+
"models": [
|
|
298
|
+
"@cf/nvidia/nemotron-3-120b-a12b",
|
|
299
|
+
"@cf/meta/llama-3.3-70b-instruct-fp8-fast",
|
|
300
|
+
"@cf/meta/llama-4-scout-17b-16e-instruct"
|
|
301
|
+
]
|
|
302
|
+
}
|
|
303
|
+
],
|
|
304
|
+
"Router": {
|
|
305
|
+
"default": "cloudflare-large,@cf/nvidia/nemotron-3-120b-a12b",
|
|
306
|
+
"background": "cloudflare-large,@cf/nvidia/nemotron-3-120b-a12b",
|
|
307
|
+
"think": "cloudflare-large,@cf/nvidia/nemotron-3-120b-a12b",
|
|
308
|
+
"longContext": "cloudflare-large,@cf/nvidia/nemotron-3-120b-a12b",
|
|
309
|
+
"webSearch": "cloudflare-large,@cf/meta/llama-4-scout-17b-16e-instruct"
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
Notes:
|
|
315
|
+
|
|
316
|
+
- Use `ai/v1/chat/completions`, not the older `ai/run` endpoint, when routing through CCR.
|
|
317
|
+
- Keep the `{account_id}` placeholder in `api_base_url`; CCR substitutes it per account at request time.
|
|
318
|
+
- After changing the config, restart the service with `ccr restart` before testing `ccr code` or `ccr code -p "Hello"`.
|
|
319
|
+
|
|
320
|
+
### Provider Verification Status
|
|
321
|
+
|
|
322
|
+
The router supports many providers, but the table below reflects the currently verified release surface rather than the full compatibility surface.
|
|
323
|
+
|
|
324
|
+
| Provider | Status | Validation |
|
|
325
|
+
| --- | --- | --- |
|
|
326
|
+
| Cloudflare Workers AI | Verified | Multi-account routing validated with Anthropic `/v1/messages` traffic and `ccr code -p "Hello"` using `cloudflare-large`. |
|
|
327
|
+
| OpenRouter | Supported by configuration surface | Not re-validated in this release pass. |
|
|
328
|
+
| Gemini / Google AI | Supported by configuration surface | Not re-validated in this release pass. |
|
|
329
|
+
| Ollama | Supported by configuration surface | Not re-validated in this release pass. |
|
|
330
|
+
| DeepSeek | Supported by configuration surface | Not re-validated in this release pass. |
|
|
331
|
+
| Volcengine | Supported by configuration surface | Not re-validated in this release pass. |
|
|
332
|
+
| SiliconFlow | Supported by configuration surface | Not re-validated in this release pass. |
|
|
333
|
+
| Cohere | Config imported from external router setup | Not re-validated in this release pass. |
|
|
334
|
+
| NVIDIA | Config imported from external router setup | Not re-validated in this release pass. |
|
|
335
|
+
| Mistral | Config imported from external router setup | Not re-validated in this release pass. |
|
|
336
|
+
| Groq | Config imported from external router setup | Not re-validated in this release pass. |
|
|
337
|
+
| Cerebras | Config imported from external router setup | Not re-validated in this release pass. |
|
|
338
|
+
| AI Studio | Config imported from external router setup | Not re-validated in this release pass. |
|
|
339
|
+
|
|
340
|
+
If you are preparing a release, treat anything outside the verified row as opt-in until you run a live smoke test for that provider against your own credentials.
|
|
341
|
+
|
|
342
|
+
You can run the built-in smoke test against a running CCR instance:
|
|
343
|
+
|
|
344
|
+
```shell
|
|
345
|
+
# Test all configured providers (CCR must be running)
|
|
346
|
+
pnpm test:providers
|
|
347
|
+
|
|
348
|
+
# Test a single provider
|
|
349
|
+
pnpm test:providers -- cloudflare-large
|
|
350
|
+
|
|
351
|
+
# Override host/port/key
|
|
352
|
+
CCR_PORT=4000 CCR_APIKEY=mykey pnpm test:providers
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
The script sends one minimal request per provider and prints a pass/fail matrix.
|
|
356
|
+
|
|
357
|
+
### 3. Running Claude Code with the Router
|
|
358
|
+
|
|
359
|
+
Start Claude Code using the router:
|
|
360
|
+
|
|
361
|
+
```shell
|
|
362
|
+
ccr code
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
> **Note**: After modifying the configuration file, you need to restart the service for the changes to take effect:
|
|
366
|
+
>
|
|
367
|
+
> ```shell
|
|
368
|
+
> ccr restart
|
|
369
|
+
> ```
|
|
370
|
+
|
|
371
|
+
### 4. UI Mode
|
|
372
|
+
|
|
373
|
+
For a more intuitive experience, you can use the UI mode to manage your configuration:
|
|
374
|
+
|
|
375
|
+
```shell
|
|
376
|
+
ccr ui
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
This will open a web-based interface where you can easily view and edit your `config.json` file.
|
|
380
|
+
|
|
381
|
+
### 5. CLI Model Management
|
|
382
|
+
|
|
383
|
+
For users who prefer terminal-based workflows, you can use the interactive CLI model selector:
|
|
384
|
+
|
|
385
|
+
```shell
|
|
386
|
+
ccr model
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
This command provides an interactive interface to:
|
|
390
|
+
|
|
391
|
+
- View current configuration:
|
|
392
|
+
- See all configured models (default, background, think, longContext, webSearch, image)
|
|
393
|
+
- Switch models: Quickly change which model is used for each router type
|
|
394
|
+
- Add new models: Add models to existing providers
|
|
395
|
+
- Create new providers: Set up complete provider configurations including:
|
|
396
|
+
- Provider name and API endpoint
|
|
397
|
+
- API key
|
|
398
|
+
- Available models
|
|
399
|
+
- Transformer configuration with support for:
|
|
400
|
+
- Multiple transformers (openrouter, deepseek, gemini, etc.)
|
|
401
|
+
- Transformer options (e.g., maxtoken with custom limits)
|
|
402
|
+
- Provider-specific routing (e.g., OpenRouter provider preferences)
|
|
403
|
+
|
|
404
|
+
The CLI tool validates all inputs and provides helpful prompts to guide you through the configuration process, making it easy to manage complex setups without editing JSON files manually.
|
|
405
|
+
|
|
406
|
+
### 6. Presets Management
|
|
407
|
+
|
|
408
|
+
Presets allow you to save, share, and reuse configurations easily. You can export your current configuration as a preset and install presets from files or URLs.
|
|
409
|
+
|
|
410
|
+
```shell
|
|
411
|
+
# Export current configuration as a preset
|
|
412
|
+
ccr preset export my-preset
|
|
413
|
+
|
|
414
|
+
# Export with metadata
|
|
415
|
+
ccr preset export my-preset --description "My OpenAI config" --author "Your Name" --tags "openai,production"
|
|
416
|
+
|
|
417
|
+
# Install a preset from local directory
|
|
418
|
+
ccr preset install /path/to/preset
|
|
419
|
+
|
|
420
|
+
# List all installed presets
|
|
421
|
+
ccr preset list
|
|
422
|
+
|
|
423
|
+
# Show preset information
|
|
424
|
+
ccr preset info my-preset
|
|
425
|
+
|
|
426
|
+
# Delete a preset
|
|
427
|
+
ccr preset delete my-preset
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
**Preset Features:**
|
|
431
|
+
- **Export**: Save your current configuration as a preset directory (with manifest.json)
|
|
432
|
+
- **Install**: Install presets from local directories
|
|
433
|
+
- **Sensitive Data Handling**: API keys and other sensitive data are automatically sanitized during export (marked as `{{field}}` placeholders)
|
|
434
|
+
- **Dynamic Configuration**: Presets can include input schemas for collecting required information during installation
|
|
435
|
+
- **Version Control**: Each preset includes version metadata for tracking updates
|
|
436
|
+
|
|
437
|
+
**Preset File Structure:**
|
|
438
|
+
```
|
|
439
|
+
~/.claude-code-router/presets/
|
|
440
|
+
├── my-preset/
|
|
441
|
+
│ └── manifest.json # Contains configuration and metadata
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
### 7. Activate Command (Environment Variables Setup)
|
|
445
|
+
|
|
446
|
+
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.
|
|
447
|
+
|
|
448
|
+
To activate the environment variables, run:
|
|
449
|
+
|
|
450
|
+
```shell
|
|
451
|
+
eval "$(ccr activate)"
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
This command outputs the necessary environment variables in shell-friendly format, which are then set in your current shell session. After activation, you can:
|
|
455
|
+
|
|
456
|
+
- **Use `claude` command directly**: Run `claude` commands without needing to use `ccr code`. The `claude` command will automatically route requests through Claude Code Router.
|
|
457
|
+
- **Integrate with Agent SDK applications**: Applications built with the Anthropic Agent SDK will automatically use the configured router and models.
|
|
458
|
+
|
|
459
|
+
The `activate` command sets the following environment variables:
|
|
460
|
+
|
|
461
|
+
- `ANTHROPIC_AUTH_TOKEN`: API key from your configuration
|
|
462
|
+
- `ANTHROPIC_BASE_URL`: The local router endpoint (default: `http://127.0.0.1:3456`)
|
|
463
|
+
- `NO_PROXY`: Set to `127.0.0.1` to prevent proxy interference
|
|
464
|
+
- `DISABLE_TELEMETRY`: Disables telemetry
|
|
465
|
+
- `DISABLE_COST_WARNINGS`: Disables cost warnings
|
|
466
|
+
- `API_TIMEOUT_MS`: API timeout from your configuration
|
|
467
|
+
|
|
468
|
+
> **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 add `eval "$(ccr activate)"` to your shell configuration file (e.g., `~/.zshrc` or `~/.bashrc`).
|
|
469
|
+
|
|
470
|
+
## 🔀 Advanced Routing Features
|
|
471
|
+
|
|
472
|
+
### Multi-Account Routing
|
|
473
|
+
|
|
474
|
+
Claude Code Router supports multiple API keys per provider with automatic account rotation and exhaustion handling. This allows you to maximize throughput and handle rate limits gracefully.
|
|
475
|
+
|
|
476
|
+
```json
|
|
477
|
+
{
|
|
478
|
+
"name": "cloudflare-large",
|
|
479
|
+
"api_base_url": "https://api.cloudflare.com/client/v4/accounts/{account_id}/ai/v1/chat/completions",
|
|
480
|
+
"accounts": [
|
|
481
|
+
{
|
|
482
|
+
"id": "account-id-1",
|
|
483
|
+
"key": "cf-token-1",
|
|
484
|
+
"email": "user1@example.com",
|
|
485
|
+
"label": "Production Account"
|
|
486
|
+
},
|
|
487
|
+
{
|
|
488
|
+
"id": "account-id-2",
|
|
489
|
+
"key": "cf-token-2",
|
|
490
|
+
"email": "user2@example.com",
|
|
491
|
+
"label": "Backup Account"
|
|
492
|
+
}
|
|
493
|
+
],
|
|
494
|
+
"models": ["@cf/nvidia/nemotron-3-120b-a12b", "@cf/meta/llama-3.3-70b-instruct-fp8-fast"]
|
|
495
|
+
}
|
|
496
|
+
```
|
|
497
|
+
|
|
498
|
+
**Features:**
|
|
499
|
+
- **Automatic Rotation**: Requests are distributed across accounts
|
|
500
|
+
- **Exhaustion Detection**: Detects HTTP 429 (rate limit) and quota errors
|
|
501
|
+
- **Usage Tracking**: Monitor API consumption per account with daily reset
|
|
502
|
+
- **Account Status**: Track which accounts are active, exhausted, or rate-limited
|
|
503
|
+
|
|
504
|
+
### Scenario-Based Routing
|
|
505
|
+
|
|
506
|
+
Claude Code Router intelligently routes requests based on operation type and context:
|
|
507
|
+
|
|
508
|
+
```json
|
|
509
|
+
{
|
|
510
|
+
"Router": {
|
|
511
|
+
"default": "provider-name,model-name",
|
|
512
|
+
"background": "provider-name,lightweight-model",
|
|
513
|
+
"think": "provider-name,reasoning-model",
|
|
514
|
+
"longContext": "provider-name,large-context-model",
|
|
515
|
+
"longContextThreshold": 60000,
|
|
516
|
+
"webSearch": "provider-name,search-capable-model",
|
|
517
|
+
"image": "provider-name,vision-model"
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
```
|
|
521
|
+
|
|
522
|
+
**Routing Types:**
|
|
523
|
+
- **`default`**: Standard requests
|
|
524
|
+
- **`background`**: Lightweight tasks (background processing)
|
|
525
|
+
- **`think`**: Thinking-intensive operations (Plan Mode)
|
|
526
|
+
- **`longContext`**: Automatically used when token count exceeds `longContextThreshold`
|
|
527
|
+
- **`webSearch`**: Web search-related operations
|
|
528
|
+
- **`image`**: Image processing and analysis tasks
|
|
529
|
+
|
|
530
|
+
The router automatically calculates token counts using cl100k_base tokenizer to determine when to use `longContext` models.
|
|
531
|
+
|
|
532
|
+
### Custom Router Functions
|
|
533
|
+
|
|
534
|
+
For complex routing logic, define custom JavaScript functions:
|
|
535
|
+
|
|
536
|
+
```json
|
|
537
|
+
{
|
|
538
|
+
"Router": {
|
|
539
|
+
"customFunction": "~/.claude-code-router/router.js"
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
```
|
|
543
|
+
|
|
544
|
+
Your custom router function receives request context and returns the routing decision:
|
|
545
|
+
|
|
546
|
+
```javascript
|
|
547
|
+
// ~/.claude-code-router/router.js
|
|
548
|
+
module.exports = {
|
|
549
|
+
route: async (context) => {
|
|
550
|
+
// context includes: messages, model, tools, etc.
|
|
551
|
+
if (context.messages.length > 100) {
|
|
552
|
+
return { provider: "groq", model: "llama-3.3-70b-versatile" };
|
|
553
|
+
}
|
|
554
|
+
return { provider: "default", model: "default" };
|
|
555
|
+
}
|
|
556
|
+
};
|
|
557
|
+
```
|
|
558
|
+
|
|
559
|
+
### Project-Level Configuration
|
|
560
|
+
|
|
561
|
+
Define routing rules specific to individual projects:
|
|
562
|
+
|
|
563
|
+
```json
|
|
564
|
+
// ~/.claude/projects/<project-id>/claude-code-router.json
|
|
565
|
+
{
|
|
566
|
+
"Router": {
|
|
567
|
+
"default": "groq,llama-3.3-70b-versatile",
|
|
568
|
+
"think": "cloudflare-large,@cf/meta/llama-3.3-70b-instruct-fp8-fast"
|
|
569
|
+
},
|
|
570
|
+
"Providers": [] // Optional provider overrides
|
|
571
|
+
}
|
|
572
|
+
```
|
|
573
|
+
|
|
574
|
+
Project configurations override global settings, allowing fine-grained control per project.
|
|
575
|
+
|
|
576
|
+
### Usage Tracking & Monitoring
|
|
577
|
+
|
|
578
|
+
Monitor API consumption and provider health:
|
|
579
|
+
|
|
580
|
+
```shell
|
|
581
|
+
# View usage statistics
|
|
582
|
+
curl http://127.0.0.1:3456/api/usage
|
|
583
|
+
|
|
584
|
+
# Check provider account status
|
|
585
|
+
curl http://127.0.0.1:3456/api/providers/cloudflare/accounts
|
|
586
|
+
|
|
587
|
+
# Get server health status
|
|
588
|
+
curl http://127.0.0.1:3456/health
|
|
589
|
+
```
|
|
590
|
+
|
|
591
|
+
Access usage analytics and account status through the Web UI Dashboard.
|
|
592
|
+
|
|
593
|
+
## 📦 Project Architecture
|
|
594
|
+
|
|
595
|
+
Claude Code Router is a **monorepo** consisting of 5 main packages:
|
|
596
|
+
|
|
597
|
+
### Core Packages
|
|
598
|
+
|
|
599
|
+
#### 1. **@musistudio/llms** (packages/core)
|
|
600
|
+
The universal LLM API transformation engine. This is the routing and transformation backbone.
|
|
601
|
+
|
|
602
|
+
**Responsibilities:**
|
|
603
|
+
- Request routing based on configuration and scenarios
|
|
604
|
+
- Provider-agnostic API transformation (converts between Anthropic, OpenAI, and provider-specific formats)
|
|
605
|
+
- Token counting using cl100k_base tokenizer
|
|
606
|
+
- Account rotation and usage tracking for multi-account providers
|
|
607
|
+
- Stream processing and response transformation
|
|
608
|
+
|
|
609
|
+
**Key Features:**
|
|
610
|
+
- Supports 15+ LLM providers
|
|
611
|
+
- Automatic request/response transformation
|
|
612
|
+
- Token-aware routing
|
|
613
|
+
- Multi-account exhaustion handling
|
|
614
|
+
- Custom transformer support
|
|
615
|
+
|
|
616
|
+
#### 2. **@CCR/server** (packages/server)
|
|
617
|
+
Express-based HTTP server wrapping the core routing engine.
|
|
618
|
+
|
|
619
|
+
**Provides:**
|
|
620
|
+
- `/v1/messages` - Claude API compatibility
|
|
621
|
+
- `/v1/chat/completions` - OpenAI API compatibility
|
|
622
|
+
- `/api/providers/*` - Provider management CRUD endpoints
|
|
623
|
+
- `/api/usage` - Usage analytics and statistics
|
|
624
|
+
- `/api/accounts` - Multi-account status tracking
|
|
625
|
+
- `/health` - Health check endpoint
|
|
626
|
+
- RESTful configuration management
|
|
627
|
+
|
|
628
|
+
**Features:**
|
|
629
|
+
- Health monitoring and status tracking
|
|
630
|
+
- Request logging and debugging
|
|
631
|
+
- Provider discovery and validation
|
|
632
|
+
- Dynamic model refresh
|
|
633
|
+
- Preset routing namespaces
|
|
634
|
+
|
|
635
|
+
#### 3. **@CCR/cli** (packages/cli)
|
|
636
|
+
Command-line interface for managing Claude Code Router.
|
|
637
|
+
|
|
638
|
+
**Commands:**
|
|
639
|
+
- `ccr start/stop/restart/status` - Service management
|
|
640
|
+
- `ccr code "prompt"` - Execute Claude Code
|
|
641
|
+
- `ccr model` - Interactive model selector
|
|
642
|
+
- `ccr models` - List available models
|
|
643
|
+
- `ccr preset export/install/list/delete` - Preset management
|
|
644
|
+
- `ccr ui` - Launch web UI
|
|
645
|
+
- `ccr activate` - Setup shell environment variables
|
|
646
|
+
- `ccr install` - GitHub marketplace integration
|
|
647
|
+
- `ccr logs` - View service logs
|
|
648
|
+
|
|
649
|
+
**Features:**
|
|
650
|
+
- Interactive terminal UI using Ink + React
|
|
651
|
+
- Real-time model switching
|
|
652
|
+
- Preset marketplace integration
|
|
653
|
+
- Environment variable setup for shell integration
|
|
654
|
+
- Service lifecycle management
|
|
655
|
+
|
|
656
|
+
#### 4. **@CCR/ui** (packages/ui)
|
|
657
|
+
React + Vite + Tailwind CSS web dashboard.
|
|
658
|
+
|
|
659
|
+
**Pages:**
|
|
660
|
+
- **Dashboard**: Overview and quick actions
|
|
661
|
+
- **Provider Management**: Configure providers, add accounts, manage models
|
|
662
|
+
- **Model Selection**: Choose default models for each scenario
|
|
663
|
+
- **Preset Manager**: Create, export, install, and share presets
|
|
664
|
+
- **Account Manager**: Monitor multi-account status and usage
|
|
665
|
+
- **Configuration Editor**: JSON editor with validation
|
|
666
|
+
- **Request History**: Track and analyze API requests
|
|
667
|
+
- **Debug Console**: System diagnostics and logs
|
|
668
|
+
- **Login**: API key authentication
|
|
669
|
+
|
|
670
|
+
**Features:**
|
|
671
|
+
- Real-time provider status
|
|
672
|
+
- Usage analytics dashboard
|
|
673
|
+
- Multi-language support (English, Chinese)
|
|
674
|
+
- Dark/light theme support
|
|
675
|
+
- Responsive design for desktop and mobile
|
|
676
|
+
|
|
677
|
+
#### 5. **@CCR/shared** (packages/shared)
|
|
678
|
+
Shared utilities and constants used across packages.
|
|
679
|
+
|
|
680
|
+
**Exports:**
|
|
681
|
+
- Type definitions for configuration schema
|
|
682
|
+
- Preset manifest schema and validation
|
|
683
|
+
- Environment variable helpers
|
|
684
|
+
- Logging utilities
|
|
685
|
+
- Constants and enums
|
|
686
|
+
|
|
687
|
+
### Monorepo Scripts
|
|
688
|
+
|
|
689
|
+
**Build Commands:**
|
|
690
|
+
```bash
|
|
691
|
+
pnpm build # Build all packages
|
|
692
|
+
pnpm build:core # Build core LLM routing engine
|
|
693
|
+
pnpm build:shared # Build shared utilities
|
|
694
|
+
pnpm build:cli # Build CLI tool
|
|
695
|
+
pnpm build:server # Build HTTP server
|
|
696
|
+
pnpm build:ui # Build web UI
|
|
697
|
+
pnpm build:docs # Build documentation site
|
|
698
|
+
```
|
|
699
|
+
|
|
700
|
+
**Development Commands:**
|
|
701
|
+
```bash
|
|
702
|
+
pnpm dev:cli # CLI development mode with hot reload
|
|
703
|
+
pnpm dev:server # Server development mode
|
|
704
|
+
pnpm dev:ui # Web UI development mode with hot reload
|
|
705
|
+
pnpm dev:core # Core engine development mode
|
|
706
|
+
pnpm dev:docs # Documentation site development
|
|
707
|
+
```
|
|
708
|
+
|
|
709
|
+
**Other Commands:**
|
|
710
|
+
```bash
|
|
711
|
+
pnpm test:providers # Smoke test all configured providers
|
|
712
|
+
pnpm release # Release all packages
|
|
713
|
+
pnpm release:npm # Release to npm only
|
|
714
|
+
pnpm release:docker # Release Docker image
|
|
715
|
+
```
|
|
716
|
+
|
|
717
|
+
## 🌐 Web UI & Dashboard
|
|
718
|
+
|
|
719
|
+
The Web UI provides a comprehensive management interface accessible at `http://127.0.0.1:3456` (or configured port).
|
|
720
|
+
|
|
721
|
+
**Dashboard Features:**
|
|
722
|
+
- Real-time provider and account status
|
|
723
|
+
- API usage metrics and trends
|
|
724
|
+
- Model switching interface
|
|
725
|
+
- Configuration management
|
|
726
|
+
- Preset creation and sharing
|
|
727
|
+
- Request history and debugging
|
|
728
|
+
|
|
729
|
+
**Key Screens:**
|
|
730
|
+
- **Provider Dashboard**: Overview of all configured providers with account status
|
|
731
|
+
- **Model Manager**: Set default models for each routing scenario
|
|
732
|
+
- **Preset Editor**: Create presets with conditional fields and templates
|
|
733
|
+
- **Usage Analytics**: Monitor API consumption, costs, and performance
|
|
734
|
+
- **System Status**: Health checks, service logs, and diagnostics
|
|
735
|
+
|
|
736
|
+
Access the UI with:
|
|
737
|
+
```bash
|
|
738
|
+
ccr ui
|
|
739
|
+
```
|
|
740
|
+
|
|
741
|
+
## 📋 CLI Commands Reference
|
|
742
|
+
|
|
743
|
+
### Service Management
|
|
744
|
+
```bash
|
|
745
|
+
ccr start # Start the router service
|
|
746
|
+
ccr stop # Stop the router service
|
|
747
|
+
ccr restart # Restart the service
|
|
748
|
+
ccr status # Show service status
|
|
749
|
+
ccr logs # Display service logs
|
|
750
|
+
```
|
|
751
|
+
|
|
752
|
+
### Code Execution
|
|
753
|
+
```bash
|
|
754
|
+
ccr code # Start interactive Claude Code session
|
|
755
|
+
ccr code -p "prompt" # Run non-interactive with prompt
|
|
756
|
+
```
|
|
757
|
+
|
|
758
|
+
### Model Management
|
|
759
|
+
```bash
|
|
760
|
+
ccr model # Interactive model selector
|
|
761
|
+
ccr models # List all available models
|
|
762
|
+
ccr models --json # Output as JSON
|
|
763
|
+
```
|
|
764
|
+
|
|
765
|
+
### Preset Management
|
|
766
|
+
```bash
|
|
767
|
+
ccr preset export <name> [options] # Export current config as preset
|
|
768
|
+
ccr preset install <path> # Install preset from directory
|
|
769
|
+
ccr preset install <url> # Install preset from URL
|
|
770
|
+
ccr preset list # List installed presets
|
|
771
|
+
ccr preset info <name> # Show preset details
|
|
772
|
+
ccr preset delete <name> # Remove a preset
|
|
773
|
+
```
|
|
774
|
+
|
|
775
|
+
### Configuration
|
|
776
|
+
```bash
|
|
777
|
+
ccr activate # Output environment variables
|
|
778
|
+
eval "$(ccr activate)" # Set environment variables in shell
|
|
779
|
+
ccr config # Open config file in editor
|
|
780
|
+
```
|
|
781
|
+
|
|
782
|
+
#### Providers
|
|
783
|
+
|
|
784
|
+
The `Providers` array is where you define the different model providers you want to use. Each provider object requires:
|
|
785
|
+
|
|
786
|
+
- `name`: A unique name for the provider.
|
|
787
|
+
- `api_base_url`: The full API endpoint for chat completions.
|
|
788
|
+
- `api_key`: Your API key for the provider.
|
|
789
|
+
- `models`: A list of model names available from this provider.
|
|
790
|
+
- `transformer` (optional): Specifies transformers to process requests and responses.
|
|
791
|
+
|
|
792
|
+
#### Transformers
|
|
793
|
+
|
|
794
|
+
Transformers allow you to modify the request and response payloads to ensure compatibility with different provider APIs.
|
|
795
|
+
|
|
796
|
+
- **Global Transformer**: Apply a transformer to all models from a provider. In this example, the `openrouter` transformer is applied to all models under the `openrouter` provider.
|
|
797
|
+
```json
|
|
798
|
+
{
|
|
799
|
+
"name": "openrouter",
|
|
800
|
+
"api_base_url": "https://openrouter.ai/api/v1/chat/completions",
|
|
801
|
+
"api_key": "sk-xxx",
|
|
802
|
+
"models": [
|
|
803
|
+
"google/gemini-2.5-pro-preview",
|
|
804
|
+
"anthropic/claude-sonnet-4",
|
|
805
|
+
"anthropic/claude-3.5-sonnet"
|
|
806
|
+
],
|
|
807
|
+
"transformer": { "use": ["openrouter"] }
|
|
808
|
+
}
|
|
809
|
+
```
|
|
810
|
+
- **Model-Specific Transformer**: Apply a transformer to a specific model. In this example, the `deepseek` transformer is applied to all models, and an additional `tooluse` transformer is applied only to the `deepseek-chat` model.
|
|
811
|
+
|
|
812
|
+
```json
|
|
813
|
+
{
|
|
814
|
+
"name": "deepseek",
|
|
815
|
+
"api_base_url": "https://api.deepseek.com/chat/completions",
|
|
816
|
+
"api_key": "sk-xxx",
|
|
817
|
+
"models": ["deepseek-chat", "deepseek-reasoner"],
|
|
818
|
+
"transformer": {
|
|
819
|
+
"use": ["deepseek"],
|
|
820
|
+
"deepseek-chat": { "use": ["tooluse"] }
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
```
|
|
824
|
+
|
|
825
|
+
- **Passing Options to a Transformer**: Some transformers, like `maxtoken`, accept options. To pass options, use a nested array where the first element is the transformer name and the second is an options object.
|
|
826
|
+
```json
|
|
827
|
+
{
|
|
828
|
+
"name": "siliconflow",
|
|
829
|
+
"api_base_url": "https://api.siliconflow.cn/v1/chat/completions",
|
|
830
|
+
"api_key": "sk-xxx",
|
|
831
|
+
"models": ["moonshotai/Kimi-K2-Instruct"],
|
|
832
|
+
"transformer": {
|
|
833
|
+
"use": [
|
|
834
|
+
[
|
|
835
|
+
"maxtoken",
|
|
836
|
+
{
|
|
837
|
+
"max_tokens": 16384
|
|
838
|
+
}
|
|
839
|
+
]
|
|
840
|
+
]
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
```
|
|
844
|
+
|
|
845
|
+
**Available Built-in Transformers:**
|
|
846
|
+
|
|
847
|
+
- `Anthropic`:If you use only the `Anthropic` transformer, it will preserve the original request and response parameters(you can use it to connect directly to an Anthropic endpoint).
|
|
848
|
+
- `deepseek`: Adapts requests/responses for DeepSeek API.
|
|
849
|
+
- `gemini`: Adapts requests/responses for Gemini API.
|
|
850
|
+
- `openrouter`: Adapts requests/responses for OpenRouter API. It can also accept a `provider` routing parameter to specify which underlying providers OpenRouter should use. For more details, refer to the [OpenRouter documentation](https://openrouter.ai/docs/features/provider-routing). See an example below:
|
|
851
|
+
```json
|
|
852
|
+
"transformer": {
|
|
853
|
+
"use": ["openrouter"],
|
|
854
|
+
"moonshotai/kimi-k2": {
|
|
855
|
+
"use": [
|
|
856
|
+
[
|
|
857
|
+
"openrouter",
|
|
858
|
+
{
|
|
859
|
+
"provider": {
|
|
860
|
+
"only": ["moonshotai/fp8"]
|
|
861
|
+
}
|
|
862
|
+
}
|
|
863
|
+
]
|
|
864
|
+
]
|
|
865
|
+
}
|
|
866
|
+
}
|
|
867
|
+
```
|
|
868
|
+
- `groq`: Adapts requests/responses for groq API.
|
|
869
|
+
- `maxtoken`: Sets a specific `max_tokens` value.
|
|
870
|
+
- `tooluse`: Optimizes tool usage for certain models via `tool_choice`.
|
|
871
|
+
- `gemini-cli` (experimental): Unofficial support for Gemini via Gemini CLI [gemini-cli.js](https://gist.github.com/musistudio/1c13a65f35916a7ab690649d3df8d1cd).
|
|
872
|
+
- `reasoning`: Used to process the `reasoning_content` field.
|
|
873
|
+
- `sampling`: Used to process sampling information fields such as `temperature`, `top_p`, `top_k`, and `repetition_penalty`.
|
|
874
|
+
- `enhancetool`: Adds a layer of error tolerance to the tool call parameters returned by the LLM (this will cause the tool call information to no longer be streamed).
|
|
875
|
+
- `cleancache`: Clears the `cache_control` field from requests.
|
|
876
|
+
- `vertex-gemini`: Handles the Gemini API using Vertex authentication.
|
|
877
|
+
- `chutes-glm` Unofficial support for GLM 4.5 model via Chutes [chutes-glm-transformer.js](https://gist.github.com/vitobotta/2be3f33722e05e8d4f9d2b0138b8c863).
|
|
878
|
+
- `qwen-cli` (experimental): Unofficial support for qwen3-coder-plus model via Qwen CLI [qwen-cli.js](https://gist.github.com/musistudio/f5a67841ced39912fd99e42200d5ca8b).
|
|
879
|
+
- `rovo-cli` (experimental): Unofficial support for gpt-5 via Atlassian Rovo Dev CLI [rovo-cli.js](https://gist.github.com/SaseQ/c2a20a38b11276537ec5332d1f7a5e53).
|
|
880
|
+
|
|
881
|
+
**Custom Transformers:**
|
|
882
|
+
|
|
883
|
+
You can also create your own transformers and load them via the `transformers` field in `config.json`.
|
|
884
|
+
|
|
885
|
+
```json
|
|
886
|
+
{
|
|
887
|
+
"transformers": [
|
|
888
|
+
{
|
|
889
|
+
"path": "/User/xxx/.claude-code-router/plugins/gemini-cli.js",
|
|
890
|
+
"options": {
|
|
891
|
+
"project": "xxx"
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
]
|
|
895
|
+
}
|
|
896
|
+
```
|
|
897
|
+
|
|
898
|
+
#### Router
|
|
899
|
+
|
|
900
|
+
The `Router` object defines which model to use for different scenarios:
|
|
901
|
+
|
|
902
|
+
- `default`: The default model for general tasks.
|
|
903
|
+
- `background`: A model for background tasks. This can be a smaller, local model to save costs.
|
|
904
|
+
- `think`: A model for reasoning-heavy tasks, like Plan Mode.
|
|
905
|
+
- `longContext`: A model for handling long contexts (e.g., > 60K tokens).
|
|
906
|
+
- `longContextThreshold` (optional): The token count threshold for triggering the long context model. Defaults to 60000 if not specified.
|
|
907
|
+
- `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 `:online` suffix after the model name.
|
|
908
|
+
- `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 the `config.forceUseImageAgent` property to `true`.
|
|
909
|
+
|
|
910
|
+
- You can also switch models dynamically in Claude Code with the `/model` command:
|
|
911
|
+
`/model provider_name,model_name`
|
|
912
|
+
Example: `/model openrouter,anthropic/claude-3.5-sonnet`
|
|
913
|
+
|
|
914
|
+
#### Custom Router
|
|
915
|
+
|
|
916
|
+
For more advanced routing logic, you can specify a custom router script via the `CUSTOM_ROUTER_PATH` in your `config.json`. This allows you to implement complex routing rules beyond the default scenarios.
|
|
917
|
+
|
|
918
|
+
In your `config.json`:
|
|
919
|
+
|
|
920
|
+
```json
|
|
921
|
+
{
|
|
922
|
+
"CUSTOM_ROUTER_PATH": "/User/xxx/.claude-code-router/custom-router.js"
|
|
923
|
+
}
|
|
924
|
+
```
|
|
925
|
+
|
|
926
|
+
The custom router file must be a JavaScript module that exports an `async` function. This function receives the request object and the config object as arguments and should return the provider and model name as a string (e.g., `"provider_name,model_name"`), or `null` to fall back to the default router.
|
|
927
|
+
|
|
928
|
+
Here is an example of a `custom-router.js` based on `custom-router.example.js`:
|
|
929
|
+
|
|
930
|
+
```javascript
|
|
931
|
+
// /User/xxx/.claude-code-router/custom-router.js
|
|
932
|
+
|
|
933
|
+
/**
|
|
934
|
+
* A custom router function to determine which model to use based on the request.
|
|
935
|
+
*
|
|
936
|
+
* @param {object} req - The request object from Claude Code, containing the request body.
|
|
937
|
+
* @param {object} config - The application's config object.
|
|
938
|
+
* @returns {Promise<string|null>} - A promise that resolves to the "provider,model_name" string, or null to use the default router.
|
|
939
|
+
*/
|
|
940
|
+
module.exports = async function router(req, config) {
|
|
941
|
+
const userMessage = req.body.messages.find((m) => m.role === "user")?.content;
|
|
942
|
+
|
|
943
|
+
if (userMessage && userMessage.includes("explain this code")) {
|
|
944
|
+
// Use a powerful model for code explanation
|
|
945
|
+
return "openrouter,anthropic/claude-3.5-sonnet";
|
|
946
|
+
}
|
|
947
|
+
|
|
948
|
+
// Fallback to the default router configuration
|
|
949
|
+
return null;
|
|
950
|
+
};
|
|
951
|
+
```
|
|
952
|
+
|
|
953
|
+
##### Subagent Routing
|
|
954
|
+
|
|
955
|
+
For routing within subagents, you must specify a particular provider and model by including `<CCR-SUBAGENT-MODEL>provider,model</CCR-SUBAGENT-MODEL>` at the **beginning** of the subagent's prompt. This allows you to direct specific subagent tasks to designated models.
|
|
956
|
+
|
|
957
|
+
**Example:**
|
|
958
|
+
|
|
959
|
+
```
|
|
960
|
+
<CCR-SUBAGENT-MODEL>openrouter,anthropic/claude-3.5-sonnet</CCR-SUBAGENT-MODEL>
|
|
961
|
+
Please help me analyze this code snippet for potential optimizations...
|
|
962
|
+
```
|
|
963
|
+
|
|
964
|
+
## Status Line (Beta)
|
|
965
|
+
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.
|
|
966
|
+

|
|
967
|
+
|
|
968
|
+
The effect is as follows:
|
|
969
|
+

|
|
970
|
+
|
|
971
|
+
## 🤖 GitHub Actions
|
|
972
|
+
|
|
973
|
+
Integrate Claude Code Router into your CI/CD pipeline. After setting up [Claude Code Actions](https://docs.anthropic.com/en/docs/claude-code/github-actions), modify your `.github/workflows/claude.yaml` to use the router:
|
|
974
|
+
|
|
975
|
+
```yaml
|
|
976
|
+
name: Claude Code
|
|
977
|
+
|
|
978
|
+
on:
|
|
979
|
+
issue_comment:
|
|
980
|
+
types: [created]
|
|
981
|
+
# ... other triggers
|
|
982
|
+
|
|
983
|
+
jobs:
|
|
984
|
+
claude:
|
|
985
|
+
if: |
|
|
986
|
+
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
|
|
987
|
+
# ... other conditions
|
|
988
|
+
runs-on: ubuntu-latest
|
|
989
|
+
permissions:
|
|
990
|
+
contents: read
|
|
991
|
+
pull-requests: read
|
|
992
|
+
issues: read
|
|
993
|
+
id-token: write
|
|
994
|
+
steps:
|
|
995
|
+
- name: Checkout repository
|
|
996
|
+
uses: actions/checkout@v4
|
|
997
|
+
with:
|
|
998
|
+
fetch-depth: 1
|
|
999
|
+
|
|
1000
|
+
- name: Prepare Environment
|
|
1001
|
+
run: |
|
|
1002
|
+
curl -fsSL https://bun.sh/install | bash
|
|
1003
|
+
mkdir -p $HOME/.claude-code-router
|
|
1004
|
+
cat << 'EOF' > $HOME/.claude-code-router/config.json
|
|
1005
|
+
{
|
|
1006
|
+
"log": true,
|
|
1007
|
+
"NON_INTERACTIVE_MODE": true,
|
|
1008
|
+
"OPENAI_API_KEY": "${{ secrets.OPENAI_API_KEY }}",
|
|
1009
|
+
"OPENAI_BASE_URL": "https://api.deepseek.com",
|
|
1010
|
+
"OPENAI_MODEL": "deepseek-chat"
|
|
1011
|
+
}
|
|
1012
|
+
EOF
|
|
1013
|
+
shell: bash
|
|
1014
|
+
|
|
1015
|
+
- name: Start Claude Code Router
|
|
1016
|
+
run: |
|
|
1017
|
+
nohup ~/.bun/bin/bunx @musistudio/claude-code-router@1.0.8 start &
|
|
1018
|
+
shell: bash
|
|
1019
|
+
|
|
1020
|
+
- name: Run Claude Code
|
|
1021
|
+
id: claude
|
|
1022
|
+
uses: anthropics/claude-code-action@beta
|
|
1023
|
+
env:
|
|
1024
|
+
ANTHROPIC_BASE_URL: http://localhost:3456
|
|
1025
|
+
with:
|
|
1026
|
+
anthropic_api_key: "any-string-is-ok"
|
|
1027
|
+
```
|
|
1028
|
+
|
|
1029
|
+
> **Note**: When running in GitHub Actions or other automation environments, make sure to set `"NON_INTERACTIVE_MODE": true` in your configuration to prevent the process from hanging due to stdin handling issues.
|
|
1030
|
+
|
|
1031
|
+
This setup allows for interesting automations, like running tasks during off-peak hours to reduce API costs.
|
|
1032
|
+
|
|
1033
|
+
## 📝 Further Reading
|
|
1034
|
+
|
|
1035
|
+
- [Project Motivation and How It Works](blog/en/project-motivation-and-how-it-works.md)
|
|
1036
|
+
- [Maybe We Can Do More with the Router](blog/en/maybe-we-can-do-more-with-the-route.md)
|
|
1037
|
+
- [GLM-4.6 Supports Reasoning and Interleaved Thinking](blog/en/glm-4.6-supports-reasoning.md)
|
|
1038
|
+
|
|
1039
|
+
## ❤️ Support & Sponsoring
|
|
1040
|
+
|
|
1041
|
+
If you find this project helpful, please consider sponsoring its development. Your support is greatly appreciated!
|
|
1042
|
+
|
|
1043
|
+
[](https://ko-fi.com/F1F31GN2GM)
|
|
1044
|
+
|
|
1045
|
+
[Paypal](https://paypal.me/musistudio1999)
|
|
1046
|
+
|
|
1047
|
+
<table>
|
|
1048
|
+
<tr>
|
|
1049
|
+
<td><img src="/blog/images/alipay.jpg" width="200" alt="Alipay" /></td>
|
|
1050
|
+
<td><img src="/blog/images/wechat.jpg" width="200" alt="WeChat Pay" /></td>
|
|
1051
|
+
</tr>
|
|
1052
|
+
</table>
|
|
1053
|
+
|
|
1054
|
+
### Our Sponsors
|
|
1055
|
+
|
|
1056
|
+
A huge thank you to all our sponsors for their generous support!
|
|
1057
|
+
|
|
1058
|
+
|
|
1059
|
+
- [AIHubmix](https://aihubmix.com/)
|
|
1060
|
+
- [BurnCloud](https://ai.burncloud.com)
|
|
1061
|
+
- [302.AI](https://share.302.ai/ZGVF9w)
|
|
1062
|
+
- [Z智谱](https://www.bigmodel.cn/claude-code?ic=FPF9IVAGFJ)
|
|
1063
|
+
- @Simon Leischnig
|
|
1064
|
+
- [@duanshuaimin](https://github.com/duanshuaimin)
|
|
1065
|
+
- [@vrgitadmin](https://github.com/vrgitadmin)
|
|
1066
|
+
- @\*o
|
|
1067
|
+
- [@ceilwoo](https://github.com/ceilwoo)
|
|
1068
|
+
- @\*说
|
|
1069
|
+
- @\*更
|
|
1070
|
+
- @K\*g
|
|
1071
|
+
- @R\*R
|
|
1072
|
+
- [@bobleer](https://github.com/bobleer)
|
|
1073
|
+
- @\*苗
|
|
1074
|
+
- @\*划
|
|
1075
|
+
- [@Clarence-pan](https://github.com/Clarence-pan)
|
|
1076
|
+
- [@carter003](https://github.com/carter003)
|
|
1077
|
+
- @S\*r
|
|
1078
|
+
- @\*晖
|
|
1079
|
+
- @\*敏
|
|
1080
|
+
- @Z\*z
|
|
1081
|
+
- @\*然
|
|
1082
|
+
- [@cluic](https://github.com/cluic)
|
|
1083
|
+
- @\*苗
|
|
1084
|
+
- [@PromptExpert](https://github.com/PromptExpert)
|
|
1085
|
+
- @\*应
|
|
1086
|
+
- [@yusnake](https://github.com/yusnake)
|
|
1087
|
+
- @\*飞
|
|
1088
|
+
- @董\*
|
|
1089
|
+
- @\*汀
|
|
1090
|
+
- @\*涯
|
|
1091
|
+
- @\*:-)
|
|
1092
|
+
- @\*\*磊
|
|
1093
|
+
- @\*琢
|
|
1094
|
+
- @\*成
|
|
1095
|
+
- @Z\*o
|
|
1096
|
+
- @\*琨
|
|
1097
|
+
- [@congzhangzh](https://github.com/congzhangzh)
|
|
1098
|
+
- @\*\_
|
|
1099
|
+
- @Z\*m
|
|
1100
|
+
- @*鑫
|
|
1101
|
+
- @c\*y
|
|
1102
|
+
- @\*昕
|
|
1103
|
+
- [@witsice](https://github.com/witsice)
|
|
1104
|
+
- @b\*g
|
|
1105
|
+
- @\*亿
|
|
1106
|
+
- @\*辉
|
|
1107
|
+
- @JACK
|
|
1108
|
+
- @\*光
|
|
1109
|
+
- @W\*l
|
|
1110
|
+
- [@kesku](https://github.com/kesku)
|
|
1111
|
+
- [@biguncle](https://github.com/biguncle)
|
|
1112
|
+
- @二吉吉
|
|
1113
|
+
- @a\*g
|
|
1114
|
+
- @\*林
|
|
1115
|
+
- @\*咸
|
|
1116
|
+
- @\*明
|
|
1117
|
+
- @S\*y
|
|
1118
|
+
- @f\*o
|
|
1119
|
+
- @\*智
|
|
1120
|
+
- @F\*t
|
|
1121
|
+
- @r\*c
|
|
1122
|
+
- [@qierkang](http://github.com/qierkang)
|
|
1123
|
+
- @\*军
|
|
1124
|
+
- [@snrise-z](http://github.com/snrise-z)
|
|
1125
|
+
- @\*王
|
|
1126
|
+
- [@greatheart1000](http://github.com/greatheart1000)
|
|
1127
|
+
- @\*王
|
|
1128
|
+
- @zcutlip
|
|
1129
|
+
- [@Peng-YM](http://github.com/Peng-YM)
|
|
1130
|
+
- @\*更
|
|
1131
|
+
- @\*.
|
|
1132
|
+
- @F\*t
|
|
1133
|
+
- @\*政
|
|
1134
|
+
- @\*铭
|
|
1135
|
+
- @\*叶
|
|
1136
|
+
- @七\*o
|
|
1137
|
+
- @\*青
|
|
1138
|
+
- @\*\*晨
|
|
1139
|
+
- @\*远
|
|
1140
|
+
- @\*霄
|
|
1141
|
+
- @\*\*吉
|
|
1142
|
+
- @\*\*飞
|
|
1143
|
+
- @\*\*驰
|
|
1144
|
+
- @x\*g
|
|
1145
|
+
- @\*\*东
|
|
1146
|
+
- @\*落
|
|
1147
|
+
- @哆\*k
|
|
1148
|
+
- @\*涛
|
|
1149
|
+
- [@苗大](https://github.com/WitMiao)
|
|
1150
|
+
- @\*呢
|
|
1151
|
+
- @\d*u
|
|
1152
|
+
- @crizcraig
|
|
1153
|
+
- s\*s
|
|
1154
|
+
- \*火
|
|
1155
|
+
- \*勤
|
|
1156
|
+
- \*\*锟
|
|
1157
|
+
- \*涛
|
|
1158
|
+
- \*\*明
|
|
1159
|
+
- \*知
|
|
1160
|
+
- \*语
|
|
1161
|
+
- \*瓜
|
|
1162
|
+
|
|
1163
|
+
|
|
1164
|
+
(If your name is masked, please contact me via my homepage email to update it with your GitHub username.)
|