@wengine-ai/claude-code-router-next 2.1.1

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.
Files changed (62) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +720 -0
  3. package/dist/README.md +763 -0
  4. package/dist/cli.d.ts +2 -0
  5. package/dist/cli.js +1547 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/index.html +231 -0
  8. package/dist/index.js +1539 -0
  9. package/dist/package.json +31 -0
  10. package/dist/tiktoken_bg.wasm +0 -0
  11. package/dist/utils/activateCommand.d.ts +4 -0
  12. package/dist/utils/activateCommand.js +24 -0
  13. package/dist/utils/activateCommand.js.map +1 -0
  14. package/dist/utils/claudeSettings.d.ts +12 -0
  15. package/dist/utils/claudeSettings.js +188 -0
  16. package/dist/utils/claudeSettings.js.map +1 -0
  17. package/dist/utils/codeCommand.d.ts +13 -0
  18. package/dist/utils/codeCommand.js +88 -0
  19. package/dist/utils/codeCommand.js.map +1 -0
  20. package/dist/utils/createEnvVariables.d.ts +5 -0
  21. package/dist/utils/createEnvVariables.js +83 -0
  22. package/dist/utils/createEnvVariables.js.map +1 -0
  23. package/dist/utils/index.d.ts +15 -0
  24. package/dist/utils/index.js +271 -0
  25. package/dist/utils/index.js.map +1 -0
  26. package/dist/utils/installCommand.d.ts +9 -0
  27. package/dist/utils/installCommand.js +47 -0
  28. package/dist/utils/installCommand.js.map +1 -0
  29. package/dist/utils/modelSelector.d.ts +1 -0
  30. package/dist/utils/modelSelector.js +402 -0
  31. package/dist/utils/modelSelector.js.map +1 -0
  32. package/dist/utils/preset/commands.d.ts +8 -0
  33. package/dist/utils/preset/commands.js +267 -0
  34. package/dist/utils/preset/commands.js.map +1 -0
  35. package/dist/utils/preset/export.d.ts +11 -0
  36. package/dist/utils/preset/export.js +97 -0
  37. package/dist/utils/preset/export.js.map +1 -0
  38. package/dist/utils/preset/index.d.ts +8 -0
  39. package/dist/utils/preset/index.js +32 -0
  40. package/dist/utils/preset/index.js.map +1 -0
  41. package/dist/utils/preset/install-github.d.ts +13 -0
  42. package/dist/utils/preset/install-github.js +161 -0
  43. package/dist/utils/preset/install-github.js.map +1 -0
  44. package/dist/utils/preset/install.d.ts +19 -0
  45. package/dist/utils/preset/install.js +239 -0
  46. package/dist/utils/preset/install.js.map +1 -0
  47. package/dist/utils/processCheck.d.ts +17 -0
  48. package/dist/utils/processCheck.js +161 -0
  49. package/dist/utils/processCheck.js.map +1 -0
  50. package/dist/utils/prompt/schema-input.d.ts +26 -0
  51. package/dist/utils/prompt/schema-input.js +183 -0
  52. package/dist/utils/prompt/schema-input.js.map +1 -0
  53. package/dist/utils/status.d.ts +1 -0
  54. package/dist/utils/status.js +28 -0
  55. package/dist/utils/status.js.map +1 -0
  56. package/dist/utils/statusline.d.ts +61 -0
  57. package/dist/utils/statusline.js +924 -0
  58. package/dist/utils/statusline.js.map +1 -0
  59. package/dist/utils/update.d.ts +18 -0
  60. package/dist/utils/update.js +74 -0
  61. package/dist/utils/update.js.map +1 -0
  62. package/package.json +56 -0
package/README.md ADDED
@@ -0,0 +1,720 @@
1
+ ![](blog/images/claude-code-router-img.png)
2
+
3
+ [![](https://img.shields.io/badge/%F0%9F%87%A8%F0%9F%87%B3-%E4%B8%AD%E6%96%87%E7%89%88-ff0000?style=flat)](README_zh.md)
4
+ [![Discord](https://img.shields.io/badge/Discord-%235865F2.svg?&logo=discord&logoColor=white)](https://discord.gg/rdftVMaUcS)
5
+ [![](https://img.shields.io/github/license/musistudio/claude-code-router)](https://github.com/musistudio/claude-code-router/blob/main/LICENSE)
6
+
7
+ <hr>
8
+
9
+ > [Progressive Disclosure of Agent Tools from the Perspective of CLI Tool Style](/blog/en/progressive-disclosure-of-agent-tools-from-the-perspective-of-cli-tool-style.md)
10
+
11
+ > A powerful tool to route Claude Code requests to different models and customize any request.
12
+
13
+ ![](blog/images/claude-code.png)
14
+
15
+ ## ✨ Features
16
+
17
+ - **Model Routing**: Route requests to different models based on your needs (e.g., background tasks, thinking, long context).
18
+ - **Multi-Provider Support**: Supports various model providers like OpenRouter, DeepSeek, Ollama, Gemini, Volcengine, and SiliconFlow.
19
+ - **Request/Response Transformation**: Customize requests and responses for different providers using transformers.
20
+ - **Dynamic Model Switching**: Switch models on-the-fly within Claude Code using the `/model` command.
21
+ - **CLI Model Management**: Manage models and providers directly from the terminal with `ccr model`.
22
+ - **GitHub Actions Integration**: Trigger Claude Code tasks in your GitHub workflows.
23
+ - **Plugin System**: Extend functionality with custom transformers.
24
+
25
+ ## 🚀 Getting Started
26
+
27
+ ### 1. Installation
28
+
29
+ You can install Claude Code Router either from the npm registry or directly from this GitHub repository for the latest development version.
30
+
31
+ #### Option A: Install from npm registry (Stable)
32
+
33
+ First, ensure you have [Claude Code](https://docs.anthropic.com/en/docs/claude-code/quickstart) installed:
34
+
35
+ ```shell
36
+ npm install -g @anthropic-ai/claude-code
37
+ ```
38
+
39
+ Then, install Claude Code Router:
40
+
41
+ ```shell
42
+ npm install -g claude-code-router-next
43
+ ```
44
+
45
+ #### Option B: Install from GitHub (Latest Development Version)
46
+
47
+ If you want to use the latest features and bug fixes directly from the source code:
48
+
49
+ 1. **Uninstall the current version first** (to prevent command conflicts):
50
+ ```shell
51
+ npm uninstall -g claude-code-router-next @musistudio/claude-code-router @wengine-ai/claude-code-router
52
+ ```
53
+
54
+ 2. **Clone and link locally** (recommended for developers):
55
+ ```shell
56
+ git clone https://github.com/xiaoliu10/claude-code-router-next.git
57
+ cd claude-code-router-next
58
+ pnpm install
59
+ pnpm build
60
+ npm link
61
+ ```
62
+
63
+ *Alternatively, install directly from GitHub globally:*
64
+ ```shell
65
+ npm install -g github:xiaoliu10/claude-code-router-next
66
+ ```
67
+
68
+ #### 🔄 Migrating from the Official Upstream (@musistudio/claude-code-router)
69
+
70
+ If you are currently using the upstream community version `@musistudio/claude-code-router` and want to switch to this repository's version (`claude-code-router-next`) for advanced features (e.g. enhanced token-limit UI bars, DeepSeek thinking compatibilities, active health probes):
71
+
72
+ 1. **Uninstall the upstream community version**:
73
+ ```shell
74
+ npm uninstall -g @musistudio/claude-code-router
75
+ ```
76
+
77
+ 2. **Install this version**:
78
+ ```shell
79
+ npm install -g claude-code-router-next
80
+ ```
81
+
82
+ ### 2. Configuration
83
+
84
+ Create and configure your `~/.claude-code-router/config.json` file. For more details, you can refer to `config.example.json`.
85
+
86
+ The `config.json` file has several key sections:
87
+
88
+ - **`PROXY_URL`** (optional): You can set a proxy for API requests, for example: `"PROXY_URL": "http://127.0.0.1:7890"`.
89
+ - **`LOG`** (optional): You can enable logging by setting it to `true`. When set to `false`, no log files will be created. Default is `true`.
90
+ - **`LOG_LEVEL`** (optional): Set the logging level. Available options are: `"fatal"`, `"error"`, `"warn"`, `"info"`, `"debug"`, `"trace"`. Default is `"debug"`.
91
+ - **Logging Systems**: The Claude Code Router uses two separate logging systems:
92
+ - **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`
93
+ - **Application-level logs**: Routing decisions and business logic events are logged in `~/.claude-code-router/claude-code-router.log`
94
+ - **`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"`.
95
+ - **`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"`.
96
+ - **`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`.
97
+
98
+ - **`Providers`**: Used to configure different model providers.
99
+ - **`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.
100
+ - **`API_TIMEOUT_MS`**: Specifies the timeout for API calls in milliseconds.
101
+
102
+ #### Environment Variable Interpolation
103
+
104
+ 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:
105
+
106
+ ```json
107
+ {
108
+ "OPENAI_API_KEY": "$OPENAI_API_KEY",
109
+ "GEMINI_API_KEY": "${GEMINI_API_KEY}",
110
+ "Providers": [
111
+ {
112
+ "name": "openai",
113
+ "api_base_url": "https://api.openai.com/v1/chat/completions",
114
+ "api_key": "$OPENAI_API_KEY",
115
+ "models": ["gpt-5", "gpt-5-mini"]
116
+ }
117
+ ]
118
+ }
119
+ ```
120
+
121
+ 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.
122
+
123
+ Here is a comprehensive example:
124
+
125
+ ```json
126
+ {
127
+ "APIKEY": "your-secret-key",
128
+ "PROXY_URL": "http://127.0.0.1:7890",
129
+ "LOG": true,
130
+ "API_TIMEOUT_MS": 600000,
131
+ "NON_INTERACTIVE_MODE": false,
132
+ "Providers": [
133
+ {
134
+ "name": "openrouter",
135
+ "api_base_url": "https://openrouter.ai/api/v1/chat/completions",
136
+ "api_key": "sk-xxx",
137
+ "models": [
138
+ "google/gemini-2.5-pro-preview",
139
+ "anthropic/claude-sonnet-4",
140
+ "anthropic/claude-3.5-sonnet",
141
+ "anthropic/claude-3.7-sonnet:thinking"
142
+ ],
143
+ "transformer": {
144
+ "use": ["openrouter"]
145
+ }
146
+ },
147
+ {
148
+ "name": "deepseek",
149
+ "api_base_url": "https://api.deepseek.com/chat/completions",
150
+ "api_key": "sk-xxx",
151
+ "models": ["deepseek-chat", "deepseek-reasoner"],
152
+ "transformer": {
153
+ "use": ["deepseek"],
154
+ "deepseek-chat": {
155
+ "use": ["tooluse"]
156
+ }
157
+ }
158
+ },
159
+ {
160
+ "name": "ollama",
161
+ "api_base_url": "http://localhost:11434/v1/chat/completions",
162
+ "api_key": "ollama",
163
+ "models": ["qwen2.5-coder:latest"]
164
+ },
165
+ {
166
+ "name": "gemini",
167
+ "api_base_url": "https://generativelanguage.googleapis.com/v1beta/models/",
168
+ "api_key": "sk-xxx",
169
+ "models": ["gemini-2.5-flash", "gemini-2.5-pro"],
170
+ "transformer": {
171
+ "use": ["gemini"]
172
+ }
173
+ },
174
+ {
175
+ "name": "volcengine",
176
+ "api_base_url": "https://ark.cn-beijing.volces.com/api/v3/chat/completions",
177
+ "api_key": "sk-xxx",
178
+ "models": ["deepseek-v3-250324", "deepseek-r1-250528"],
179
+ "transformer": {
180
+ "use": ["deepseek"]
181
+ }
182
+ },
183
+ {
184
+ "name": "modelscope",
185
+ "api_base_url": "https://api-inference.modelscope.cn/v1/chat/completions",
186
+ "api_key": "",
187
+ "models": ["Qwen/Qwen3-Coder-480B-A35B-Instruct", "Qwen/Qwen3-235B-A22B-Thinking-2507"],
188
+ "transformer": {
189
+ "use": [
190
+ [
191
+ "maxtoken",
192
+ {
193
+ "max_tokens": 65536
194
+ }
195
+ ],
196
+ "enhancetool"
197
+ ],
198
+ "Qwen/Qwen3-235B-A22B-Thinking-2507": {
199
+ "use": ["reasoning"]
200
+ }
201
+ }
202
+ },
203
+ {
204
+ "name": "dashscope",
205
+ "api_base_url": "https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions",
206
+ "api_key": "",
207
+ "models": ["qwen3-coder-plus"],
208
+ "transformer": {
209
+ "use": [
210
+ [
211
+ "maxtoken",
212
+ {
213
+ "max_tokens": 65536
214
+ }
215
+ ],
216
+ "enhancetool"
217
+ ]
218
+ }
219
+ },
220
+ {
221
+ "name": "aihubmix",
222
+ "api_base_url": "https://aihubmix.com/v1/chat/completions",
223
+ "api_key": "sk-",
224
+ "models": [
225
+ "Z/glm-4.5",
226
+ "claude-opus-4-20250514",
227
+ "gemini-2.5-pro"
228
+ ]
229
+ }
230
+ ],
231
+ "Router": {
232
+ "default": "deepseek,deepseek-chat",
233
+ "background": "ollama,qwen2.5-coder:latest",
234
+ "think": "deepseek,deepseek-reasoner",
235
+ "longContext": "openrouter,google/gemini-2.5-pro-preview",
236
+ "longContextThreshold": 60000,
237
+ "webSearch": "gemini,gemini-2.5-flash"
238
+ }
239
+ }
240
+ ```
241
+
242
+ ### 🔑 API Key / Token Guide
243
+
244
+ To use the router, you need to acquire API Keys from your preferred LLM providers. Below are guides for some popular providers:
245
+
246
+ #### 1. Zhipu AI (BigModel / GLM CODING PLAN)
247
+ * **Platform**: Zhipu BigModel Platform (sponsored partner)
248
+ * **Link**: [Zhipu AI BigModel Platform](https://www.bigmodel.cn/claude-code?ic=RRVJPB5SII) (Use this referral link for a 10% discount on GLM CODING PLAN)
249
+ * **Acquisition Method**:
250
+ 1. Register and log in using the link above.
251
+ 2. Go to the top-right **Console** -> **API Keys**.
252
+ 3. Copy your API Key.
253
+
254
+ GLM CODING PLAN quota information is fetched with this API Key, so you no longer need to configure a web token or `quotaToken`.
255
+
256
+ #### 2. Alibaba Cloud (DashScope / Bailian / Qwen-Coder)
257
+ * **Platform**: Alibaba Cloud Bailian (highly capable Qwen-Coder models)
258
+ * **Link**: [Alibaba Cloud Bailian Console](https://bailian.console.aliyun.com/)
259
+ * **Acquisition Methods**:
260
+ * **Method A: Standard Developer API Key (For Request Routing)**
261
+ 1. Log in to Alibaba Cloud and enable the "Bailian" model service.
262
+ 2. Go to the Bailian Console, click on your **profile icon** in the top-right corner.
263
+ 3. Click on **API-KEY** in the dropdown.
264
+ 4. Click **Create New API-KEY** and copy the generated key.
265
+ * **Method B: Aliyun Console Cookie (For Quota Visualization in UI)**
266
+ If you want the Claude Code Router UI to fetch and display your monthly **Qwen Coding Plan** quota progress bars, you need to configure your console session `Cookie` as `quotaToken` in your configuration:
267
+ 1. Log in to the [Alibaba Cloud Bailian Console](https://bailian.console.aliyun.com/).
268
+ 2. Open your browser's Developer Tools (F12) and switch to the **Network** tab.
269
+ 3. Click the **Refresh** (用量刷新) button on the console's usage cards.
270
+ 4. Look for an API request starting with `api.json?action=BroadScope...` in the network log.
271
+ 5. Select the request, find the **`Cookie`** header under **Request Headers**, and copy its entire value.
272
+ 6. Paste this copied cookie string as the **`quotaToken`** property inside the Alibaba Cloud provider block in your `config.json`.
273
+
274
+ ![Alibaba Cloud Quota Cookie Acquisition](blog/images/aliyun-quota-auth.png)
275
+
276
+ ### 3. Running Claude Code with the Router
277
+
278
+ Start Claude Code using the router:
279
+
280
+ ```shell
281
+ ccr code
282
+ ```
283
+
284
+ > **Note**: After modifying the configuration file, you need to restart the service for the changes to take effect:
285
+ >
286
+ > ```shell
287
+ > ccr restart
288
+ > ```
289
+
290
+ ### 4. UI Mode
291
+
292
+ For a more intuitive experience, you can use the UI mode to manage your configuration:
293
+
294
+ ```shell
295
+ ccr ui
296
+ ```
297
+
298
+ This will open a web-based interface where you can easily view and edit your `config.json` file.
299
+
300
+ ![UI](/blog/images/ui.png)
301
+
302
+ #### Usage Statistics
303
+
304
+ The dashboard includes a built-in **Usage Statistics** panel at the bottom of the main page. Once your requests are routed through Claude Code Router, usage records are collected automatically and displayed in the UI.
305
+
306
+ You can use it to view:
307
+
308
+ - Total requests
309
+ - Input and output tokens
310
+ - Average TTFT
311
+ - Average generation speed
312
+ - Success rate
313
+ - Daily usage chart
314
+ - Detailed request records with filters and pagination
315
+
316
+ How to use it:
317
+
318
+ 1. Start the router service with `ccr start`
319
+ 2. Open the UI with `ccr ui`
320
+ 3. Send requests through Claude Code Router, for example with `ccr code`
321
+ 4. Return to the main dashboard and check the **Usage Statistics** panel
322
+
323
+ Usage data is stored in:
324
+
325
+ ```shell
326
+ ~/.claude-code-router/data/usage.jsonl
327
+ ```
328
+
329
+ You can also filter records by date range, provider, model, and scenario directly in the UI.
330
+
331
+ If the `token-speed` plugin is enabled, the panel will also show TTFT and tokens-per-second metrics. Without that plugin, token counts and request statistics still work, but TTFT and speed may appear as `-`.
332
+
333
+ For API-based access, Claude Code Router also provides:
334
+
335
+ - `GET /api/usage` — paginated records with summary
336
+ - `GET /api/usage/summary` — summary only
337
+ - `DELETE /api/usage` — clear usage data
338
+
339
+ ### 5. CLI Model Management
340
+
341
+ For users who prefer terminal-based workflows, you can use the interactive CLI model selector:
342
+
343
+ ```shell
344
+ ccr model
345
+ ```
346
+ ![](blog/images/models.gif)
347
+
348
+ This command provides an interactive interface to:
349
+
350
+ - View current configuration:
351
+ - See all configured models (default, background, think, longContext, webSearch, image)
352
+ - Switch models: Quickly change which model is used for each router type
353
+ - Add new models: Add models to existing providers
354
+ - Create new providers: Set up complete provider configurations including:
355
+ - Provider name and API endpoint
356
+ - API key
357
+ - Available models
358
+ - Transformer configuration with support for:
359
+ - Multiple transformers (openrouter, deepseek, gemini, etc.)
360
+ - Transformer options (e.g., maxtoken with custom limits)
361
+ - Provider-specific routing (e.g., OpenRouter provider preferences)
362
+
363
+ 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.
364
+
365
+ ### 6. Presets Management
366
+
367
+ 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.
368
+
369
+ ```shell
370
+ # Export current configuration as a preset
371
+ ccr preset export my-preset
372
+
373
+ # Export with metadata
374
+ ccr preset export my-preset --description "My OpenAI config" --author "Your Name" --tags "openai,production"
375
+
376
+ # Install a preset from local directory
377
+ ccr preset install /path/to/preset
378
+
379
+ # List all installed presets
380
+ ccr preset list
381
+
382
+ # Show preset information
383
+ ccr preset info my-preset
384
+
385
+ # Delete a preset
386
+ ccr preset delete my-preset
387
+ ```
388
+
389
+ **Preset Features:**
390
+ - **Export**: Save your current configuration as a preset directory (with manifest.json)
391
+ - **Install**: Install presets from local directories
392
+ - **Sensitive Data Handling**: API keys and other sensitive data are automatically sanitized during export (marked as `{{field}}` placeholders)
393
+ - **Dynamic Configuration**: Presets can include input schemas for collecting required information during installation
394
+ - **Version Control**: Each preset includes version metadata for tracking updates
395
+
396
+ **Preset File Structure:**
397
+ ```
398
+ ~/.claude-code-router/presets/
399
+ ├── my-preset/
400
+ │ └── manifest.json # Contains configuration and metadata
401
+ ```
402
+
403
+ ### 7. Activate Command (Environment Variables Setup)
404
+
405
+ 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.
406
+
407
+ To activate the environment variables, run:
408
+
409
+ ```shell
410
+ eval "$(ccr activate)"
411
+ ```
412
+
413
+ This command outputs the necessary environment variables in shell-friendly format, which are then set in your current shell session. After activation, you can:
414
+
415
+ - **Use `claude` command directly**: Run `claude` commands without needing to use `ccr code`. The `claude` command will automatically route requests through Claude Code Router.
416
+ - **Integrate with Agent SDK applications**: Applications built with the Anthropic Agent SDK will automatically use the configured router and models.
417
+
418
+ The `activate` command sets the following environment variables:
419
+
420
+ - `ANTHROPIC_AUTH_TOKEN`: API key from your configuration
421
+ - `ANTHROPIC_BASE_URL`: The local router endpoint (default: `http://127.0.0.1:3456`)
422
+ - `NO_PROXY`: Set to `127.0.0.1` to prevent proxy interference
423
+ - `DISABLE_TELEMETRY`: Disables telemetry
424
+ - `DISABLE_COST_WARNINGS`: Disables cost warnings
425
+ - `API_TIMEOUT_MS`: API timeout from your configuration
426
+
427
+ > **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`).
428
+
429
+ #### Providers
430
+
431
+ The `Providers` array is where you define the different model providers you want to use. Each provider object requires:
432
+
433
+ - `name`: A unique name for the provider.
434
+ - `api_base_url`: The full API endpoint for chat completions.
435
+ - `api_key`: Your API key for the provider.
436
+ - `models`: A list of model names available from this provider.
437
+ - `transformer` (optional): Specifies transformers to process requests and responses.
438
+
439
+ #### Transformers
440
+
441
+ Transformers allow you to modify the request and response payloads to ensure compatibility with different provider APIs.
442
+
443
+ - **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.
444
+ ```json
445
+ {
446
+ "name": "openrouter",
447
+ "api_base_url": "https://openrouter.ai/api/v1/chat/completions",
448
+ "api_key": "sk-xxx",
449
+ "models": [
450
+ "google/gemini-2.5-pro-preview",
451
+ "anthropic/claude-sonnet-4",
452
+ "anthropic/claude-3.5-sonnet"
453
+ ],
454
+ "transformer": { "use": ["openrouter"] }
455
+ }
456
+ ```
457
+ - **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.
458
+
459
+ ```json
460
+ {
461
+ "name": "deepseek",
462
+ "api_base_url": "https://api.deepseek.com/chat/completions",
463
+ "api_key": "sk-xxx",
464
+ "models": ["deepseek-chat", "deepseek-reasoner"],
465
+ "transformer": {
466
+ "use": ["deepseek"],
467
+ "deepseek-chat": { "use": ["tooluse"] }
468
+ }
469
+ }
470
+ ```
471
+
472
+ - **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.
473
+ ```json
474
+ {
475
+ "name": "siliconflow",
476
+ "api_base_url": "https://api.siliconflow.cn/v1/chat/completions",
477
+ "api_key": "sk-xxx",
478
+ "models": ["moonshotai/Kimi-K2-Instruct"],
479
+ "transformer": {
480
+ "use": [
481
+ [
482
+ "maxtoken",
483
+ {
484
+ "max_tokens": 16384
485
+ }
486
+ ]
487
+ ]
488
+ }
489
+ }
490
+ ```
491
+
492
+ **Available Built-in Transformers:**
493
+
494
+ - `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).
495
+ - `deepseek`: Adapts requests/responses for DeepSeek API.
496
+ - `gemini`: Adapts requests/responses for Gemini API.
497
+ - `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:
498
+ ```json
499
+ "transformer": {
500
+ "use": ["openrouter"],
501
+ "moonshotai/kimi-k2": {
502
+ "use": [
503
+ [
504
+ "openrouter",
505
+ {
506
+ "provider": {
507
+ "only": ["moonshotai/fp8"]
508
+ }
509
+ }
510
+ ]
511
+ ]
512
+ }
513
+ }
514
+ ```
515
+ - `groq`: Adapts requests/responses for groq API.
516
+ - `maxtoken`: Sets a specific `max_tokens` value.
517
+ - `tooluse`: Optimizes tool usage for certain models via `tool_choice`.
518
+ - `gemini-cli` (experimental): Unofficial support for Gemini via Gemini CLI [gemini-cli.js](https://gist.github.com/musistudio/1c13a65f35916a7ab690649d3df8d1cd).
519
+ - `reasoning`: Used to process the `reasoning_content` field.
520
+ - `sampling`: Used to process sampling information fields such as `temperature`, `top_p`, `top_k`, and `repetition_penalty`.
521
+ - `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).
522
+ - `cleancache`: Clears the `cache_control` field from requests.
523
+ - `vertex-gemini`: Handles the Gemini API using Vertex authentication.
524
+ - `chutes-glm` Unofficial support for GLM 4.5 model via Chutes [chutes-glm-transformer.js](https://gist.github.com/vitobotta/2be3f33722e05e8d4f9d2b0138b8c863).
525
+ - `qwen-cli` (experimental): Unofficial support for qwen3-coder-plus model via Qwen CLI [qwen-cli.js](https://gist.github.com/musistudio/f5a67841ced39912fd99e42200d5ca8b).
526
+ - `rovo-cli` (experimental): Unofficial support for gpt-5 via Atlassian Rovo Dev CLI [rovo-cli.js](https://gist.github.com/SaseQ/c2a20a38b11276537ec5332d1f7a5e53).
527
+
528
+ **Custom Transformers:**
529
+
530
+ You can also create your own transformers and load them via the `transformers` field in `config.json`.
531
+
532
+ ```json
533
+ {
534
+ "transformers": [
535
+ {
536
+ "path": "/User/xxx/.claude-code-router/plugins/gemini-cli.js",
537
+ "options": {
538
+ "project": "xxx"
539
+ }
540
+ }
541
+ ]
542
+ }
543
+ ```
544
+
545
+ #### Router
546
+
547
+ The `Router` object defines which model to use for different scenarios:
548
+
549
+ - `default`: The default model for general tasks.
550
+ - `background`: A model for background tasks. This can be a smaller, local model to save costs.
551
+ - `think`: A model for reasoning-heavy tasks, like Plan Mode.
552
+ - `longContext`: A model for handling long contexts (e.g., > 60K tokens).
553
+ - `longContextThreshold` (optional): The token count threshold for triggering the long context model. Defaults to 60000 if not specified.
554
+ - `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.
555
+ - `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`.
556
+
557
+ - You can also switch models dynamically in Claude Code with the `/model` command:
558
+ `/model provider_name,model_name`
559
+ Example: `/model openrouter,anthropic/claude-3.5-sonnet`
560
+
561
+ #### Custom Router
562
+
563
+ 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.
564
+
565
+ In your `config.json`:
566
+
567
+ ```json
568
+ {
569
+ "CUSTOM_ROUTER_PATH": "/User/xxx/.claude-code-router/custom-router.js"
570
+ }
571
+ ```
572
+
573
+ 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.
574
+
575
+ Here is an example of a `custom-router.js` based on `custom-router.example.js`:
576
+
577
+ ```javascript
578
+ // /User/xxx/.claude-code-router/custom-router.js
579
+
580
+ /**
581
+ * A custom router function to determine which model to use based on the request.
582
+ *
583
+ * @param {object} req - The request object from Claude Code, containing the request body.
584
+ * @param {object} config - The application's config object.
585
+ * @returns {Promise<string|null>} - A promise that resolves to the "provider,model_name" string, or null to use the default router.
586
+ */
587
+ module.exports = async function router(req, config) {
588
+ const userMessage = req.body.messages.find((m) => m.role === "user")?.content;
589
+
590
+ if (userMessage && userMessage.includes("explain this code")) {
591
+ // Use a powerful model for code explanation
592
+ return "openrouter,anthropic/claude-3.5-sonnet";
593
+ }
594
+
595
+ // Fallback to the default router configuration
596
+ return null;
597
+ };
598
+ ```
599
+
600
+ ##### Subagent Routing
601
+
602
+ 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.
603
+
604
+ **Example:**
605
+
606
+ ```
607
+ <CCR-SUBAGENT-MODEL>openrouter,anthropic/claude-3.5-sonnet</CCR-SUBAGENT-MODEL>
608
+ Please help me analyze this code snippet for potential optimizations...
609
+ ```
610
+
611
+ ## Status Line (Beta)
612
+
613
+ To better monitor the status of Claude Code Router at runtime, the project includes a built-in status line tool that can be enabled from the UI.
614
+
615
+ ![statusline-config.png](/blog/images/statusline-config.png)
616
+
617
+ How to use it:
618
+
619
+ 1. Open the UI with `ccr ui`
620
+ 2. Enable **StatusLine** in the configuration panel
621
+ 3. Save the configuration and restart the service with `ccr restart`
622
+ 4. Start Claude Code with `ccr code`
623
+
624
+ > The built-in status line is injected automatically when Claude Code is launched with `ccr code`.
625
+
626
+ The status line supports token-related variables such as:
627
+
628
+ - `{{inputTokens}}`
629
+ - `{{outputTokens}}`
630
+ - `{{tokenSpeed}}`
631
+
632
+ This makes it possible to display input tokens, output tokens, and streaming speed directly in the terminal while requests are running.
633
+
634
+ The effect is as follows:
635
+
636
+ ![statusline](/blog/images/statusline.png)
637
+
638
+ ## 🤖 GitHub Actions
639
+
640
+ 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:
641
+
642
+ ```yaml
643
+ name: Claude Code
644
+
645
+ on:
646
+ issue_comment:
647
+ types: [created]
648
+ # ... other triggers
649
+
650
+ jobs:
651
+ claude:
652
+ if: |
653
+ (github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
654
+ # ... other conditions
655
+ runs-on: ubuntu-latest
656
+ permissions:
657
+ contents: read
658
+ pull-requests: read
659
+ issues: read
660
+ id-token: write
661
+ steps:
662
+ - name: Checkout repository
663
+ uses: actions/checkout@v4
664
+ with:
665
+ fetch-depth: 1
666
+
667
+ - name: Prepare Environment
668
+ run: |
669
+ curl -fsSL https://bun.sh/install | bash
670
+ mkdir -p $HOME/.claude-code-router
671
+ cat << 'EOF' > $HOME/.claude-code-router/config.json
672
+ {
673
+ "log": true,
674
+ "NON_INTERACTIVE_MODE": true,
675
+ "OPENAI_API_KEY": "${{ secrets.OPENAI_API_KEY }}",
676
+ "OPENAI_BASE_URL": "https://api.deepseek.com",
677
+ "OPENAI_MODEL": "deepseek-chat"
678
+ }
679
+ EOF
680
+ shell: bash
681
+
682
+ - name: Start Claude Code Router
683
+ run: |
684
+ nohup ~/.bun/bin/bunx claude-code-router-next@latest start &
685
+ shell: bash
686
+
687
+ - name: Run Claude Code
688
+ id: claude
689
+ uses: anthropics/claude-code-action@beta
690
+ env:
691
+ ANTHROPIC_BASE_URL: http://localhost:3456
692
+ with:
693
+ anthropic_api_key: "any-string-is-ok"
694
+ ```
695
+
696
+ > **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.
697
+
698
+ This setup allows for interesting automations, like running tasks during off-peak hours to reduce API costs.
699
+
700
+ ## 📝 Further Reading
701
+
702
+ - [Project Motivation and How It Works](blog/en/project-motivation-and-how-it-works.md)
703
+ - [Maybe We Can Do More with the Router](blog/en/maybe-we-can-do-more-with-the-route.md)
704
+ - [GLM-4.6 Supports Reasoning and Interleaved Thinking](blog/en/glm-4.6-supports-reasoning.md)
705
+
706
+ ## ❤️ Support & Sponsoring
707
+
708
+ If you find this project helpful, please consider sponsoring its development. Your support is greatly appreciated!
709
+
710
+ [![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/F1F31GN2GM)
711
+
712
+ [Paypal](https://paypal.me/musistudio1999)
713
+
714
+ <table>
715
+ <tr>
716
+ <td><img src="/blog/images/alipay.jpg" width="200" alt="Alipay" /></td>
717
+ <td><img src="/blog/images/wechat.jpg" width="200" alt="WeChat Pay" /></td>
718
+ </tr>
719
+ </table>
720
+