Merge branch 'dev/3.1' into dev/extensions

# Conflicts:
#	packages/core/src/agents/codex/cli-middleware-runtime.ts
#	packages/core/src/config/config.ts
#	packages/core/src/gateway/service.ts
#	packages/ui/src/pages/home/App.tsx
#	packages/ui/src/pages/home/shared/controls.tsx
#	tests/main/codex-cli-middleware-runtime.test.mjs
This commit is contained in:
musistudio
2026-07-15 10:14:30 +08:00
206 changed files with 29262 additions and 12134 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

@@ -11,8 +11,9 @@ lead: Add a Bot, bind it to Agent Config, and choose message forwarding or hando
2. Select a platform and fill in the required token, secret, signing secret, robot code, or OAuth fields.
3. Save the Bot.
4. Open the target **Agent Config** and enable **Bot**.
5. Choose **Forward agent messages** or **Handoff**, then reopen the agent from CCR.
5. Configure forwarding, handoff, language, timeout, attachments, streaming, and **Allow Agent shell tools** as needed.
6. Reopen Claude, Codex, ZCode, or OpenCode App from CCR. The Bot is online only while the App is alive.
## Verification
Open the agent from CCR and send a test message. Confirm that Logs include Bot records and the IM side receives the message.
Open the Agent App from CCR, then send `/project current`, `/session list`, and one plain message from IM. The Profile card shows connection state, the last event and delivery, pending outbox count, and redacted errors; `/session doctor` provides the same runtime diagnostics. Closing the App should move the Bot to offline state.
+51 -1
View File
@@ -5,11 +5,61 @@ eyebrow: Detailed Configuration
lead: Forward agent messages to instant-messaging platforms or hand off active work after desktop idle.
---
CCR App Relay shares the lifecycle of an Agent App opened by CCR. Opening Claude, Codex, ZCode, or OpenCode App starts its companion worker; closing the App stops both the worker and Bot connection.
## Common Modes
- **Forward agent messages**: mirror agent messages into IM.
- **Handoff**: relay the interaction into IM after desktop idle.
- **Reply only**: with forwarding and handoff disabled, reply only to turns initiated from IM.
Natural-language turns are serialized per IM conversation. `/project`, `/session status`, and `/session cancel` remain immediately responsive; queueing, timeout, cancellation, and worker-restart recovery have explicit states.
## Projects And Sessions
A Project is an Agent-native project or working directory, and a Session is an Agent-native conversation inside that Project.
### Project Commands
| Command | Purpose |
| --- | --- |
| `/project` | Show Project help and the App-online boundary. |
| `/project list [page]` | List known Agent projects with pagination. |
| `/project find <text>` | Search project names and paths. |
| `/project current` | Show the current Project. |
| `/project use <n>` | Change Project and clear the previous Session selection. |
| `/project name <label>` | Set the Bot display label for this Project. |
### Session Commands
| Command | Purpose |
| --- | --- |
| `/session` | Show all Session commands. |
| `/session list [page]`, `/session find <text>` | Browse Sessions only in the current Project. |
| `/session current`, `new [title]`, `use <n>`, `reset` | Inspect, create, continue, or clear a Session selection. |
| `/session status`, `cancel` | Inspect the active turn/queue, or cancel it and clear the queue. |
| `/session approve [session]`, `deny`, `answer <text>` | Answer an Agent-generated permission or input request; every platform has text commands, and card-capable platforms also show action buttons. |
| `/session name <label>` | Rename the current Session. |
| `/session archive <n>`, `restore <n>`, `delete <n> confirm` | Archive, restore, or permanently delete with confirmation. |
| `/session history [count]`, `usage` | Show recent history and token/cache/cost summaries. |
| `/session models`, `model`, `effort`, `mode` | Inspect or change this conversation's Session runtime settings. |
| `/session memory ...`, `skills`, `skill`, `shortcut ...` | Manage persistent context, Agent skills, and shortcuts. |
| `/session doctor`, `deliveries` | Show connection, outbox, recent-delivery, and redacted-error diagnostics. |
The public Bot command domains are `/project` and `/session`. Other slash commands return the unknown-command response, while plain natural language such as `help` or `list` enters the Agent as a prompt.
## Bot Settings
- **Bot language**: automatic, English, or Simplified Chinese.
- **Maximum turn time**: interrupt timed-out turns and return a final state.
- **Session idle reset**: prepare a new Session in the same Project after inactivity; `0` disables it.
- **Message chunk and attachment limits**: adapt to platform limits and bound inbound files.
- **Streaming replies and progress**: forward visible text and tool stages.
- **Send and receive attachments**: accept inbound images/files and return artifacts from the current workspace.
- **Allow Agent shell tools**: controls Agent shell-tool permission; the Bot command surface remains `/project` and `/session`.
The local state keeps bounded deduplication records, pending turns, a durable outbox, and recent delivery results. Event idempotency gives each Agent turn one execution, and pending delivery resumes while the App is online again.
## Platform Pages
Slack, Discord, Telegram, LINE, Weixin, WeCom, Feishu, and DingTalk each have a dedicated page.
Slack, Discord, Telegram, LINE, Weixin, WeCom, Feishu, and DingTalk each have a dedicated page; iMessage uses a local integration. The SDK selects Markdown, cards, streaming updates, file messages, or text according to platform capabilities.
@@ -8,7 +8,9 @@ lead: Locate the SQLite configuration database maintained by the CCR desktop app
## Default Locations
- **macOS/Linux**: `~/.claude-code-router/config.sqlite`
- **Windows**: `%APPDATA%\Claude Code Router\config.sqlite`
- **Windows**: `%APPDATA%\claude-code-router\config.sqlite`
Docker sets `HOME=/data`, so its configuration database is `/data/.claude-code-router/config.sqlite`. Persist the complete `/data` directory rather than mounting only one database file.
## Applying Changes
@@ -2,7 +2,7 @@
title: Agent Config
pageTitle: Agent Config
eyebrow: Detailed Configuration
lead: Create reusable launch configurations for Claude Code, Codex, and ZCode, and open separate agent instances from different configs.
lead: Create reusable launch configurations for Claude Code, Codex, Grok CLI, and ZCode, and open separate agent instances from different configs.
---
## Configuration Flow
@@ -14,7 +14,7 @@ lead: Create reusable launch configurations for Claude Code, Codex, and ZCode, a
5. If the entry mode includes App, optionally bind a Bot and choose whether to forward agent messages or enable handoff.
6. Save the config, then open it from the Agent Config card: the terminal button copies the CLI command, and the play button starts the App instance.
During trial, prefer **Only opened from CCR** and always open the agent from CCR. That keeps the config limited to CCR-launched instances and avoids changing the Claude Code, Codex, or ZCode setup you open directly from the system.
During trial, prefer **Only opened from CCR** and always open the agent from CCR. That keeps the config limited to CCR-launched instances and avoids changing the Claude Code, Codex, Grok CLI, or ZCode setup you open directly from the system.
## Multi-Instance Mechanism
@@ -23,7 +23,7 @@ Every Agent Config has its own `id` and name. When CCR opens an agent, it finds
| Mechanism | Actual behavior |
| --- | --- |
| Separate config files | With **Only opened from CCR**, Claude Code and Codex write CCR-managed config files in directories separated by config `id` |
| Separate launchers | Claude Code uses a separate launch wrapper; Codex and ZCode use separate middleware launchers; filenames are also separated by config `id` or name |
| Separate launchers | Claude Code and Grok CLI use separate launch wrappers; Codex and ZCode use separate middleware launchers; filenames are also separated by config `id` or name |
| Separate app data directories | When opening App mode, Claude App, ChatGPT (the renamed Codex desktop app), and ZCode App use user-data directories separated by config `id` |
| Runtime state | CCR tracks running app instances by entry mode and config `id`; reopening the same config activates the existing window, while a different config can open a separate instance |
@@ -33,11 +33,11 @@ This lets you create multiple configs for the same agent, such as "Claude Code -
| Option | Applies to | Description |
| --- | --- | --- |
| Agent | All | Claude Code, Codex, or ZCode. ZCode supports App only. |
| Config name | All | Identifies the config in CCR and can be used as the `ccr <config-name>` launch target. Names can contain spaces; copied commands are quoted automatically. |
| Agent | All | Claude Code, Codex, OpenCode, Grok CLI, or ZCode. Grok CLI supports CLI only; ZCode supports App only. |
| Config name | All | Identifies the config in CCR and can be used as the `ccr-app <config-name>` launch target. Names can contain spaces; copied commands are quoted automatically. |
| Enabled | All | Disabled configs are not exposed as active launch entries and are not applied as effective startup configs. |
| Effect scope | All | **Only opened from CCR** uses CCR-managed isolated config; **System default** writes the agent's default config. Only one enabled system-default config is allowed per agent. |
| Entry mode | Claude Code, Codex | `CLI & APP` exposes both CLI and App entry points; `CLI only` only generates a CLI command; `App only` only exposes the App entry point. |
| Entry mode | Claude Code, Codex, OpenCode, Grok CLI | `CLI & APP` exposes both CLI and App entry points; `CLI only` only generates a CLI command; `App only` only exposes the App entry point. Grok CLI is fixed to `CLI only`. |
| Model | All | Default model for the opened agent, either a provider model or Fusion model. For Claude Code, leaving it empty keeps the Claude Code default. |
| Bot | App entry | Bot forwarding only works for App mode opened from CCR. CLI does not forward Bot messages yet. |
| Environment variables | All | Extra environment variables injected into this config. Claude Code includes `CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY=1` by default so gateway model discovery is enabled. |
@@ -65,6 +65,21 @@ Claude App and Claude Code CLI use different model-list adapters:
| Claude Code CLI | CCR gateway model discovery | Use `/model` in the CLI to view the list; selected requests still go through CCR providers, routing, and Fusion. |
| Claude App | CCR-generated Claude App inference models | Claude App needs Claude-compatible model names. CCR maps `Provider/model` and Fusion models into model entries Claude App can recognize, while display labels keep the real model meaning visible. |
### OpenCode
| Option | What it does |
| --- | --- |
| Provider ID | Writes the OpenCode provider reference, defaulting to `claude-code-router`. |
| Provider name | Display name shown in OpenCode, defaulting to `Claude Code Router`. |
| OpenCode model | Default model for OpenCode CLI and App. It can be a provider model or Fusion model. |
| Config file | System-default mode uses OpenCode's default config; Only opened from CCR writes a profile-specific config under CCR's config directory. |
| Environment variables | Injected into OpenCode CLI, OpenCode App, and its Bot worker. |
| Bot | Applies to the OpenCode App entry opened from CCR. Incoming Bot messages run through OpenCode CLI and replies are sent back to the same Bot conversation. |
CCR keeps one OpenCode Bot worker next to the OpenCode App process. The worker stores a project and optional session for each Bot conversation. Send `/project list|current|use` to select an Agent project, then use `/session list|current|new|use|reset` to manage sessions inside that project. Selecting another project clears the previous session, and sessions from another project cannot be selected. Only these slash-command domains are intercepted; removed `/task` and legacy flat commands are not supported.
The OpenCode CLI must be available as `opencode` in the CCR Desktop process environment. If it is installed elsewhere, set `CCR_OPENCODE_BIN` in the Agent Config environment variables. Bot sessions default to the filesystem root used by a fresh OpenCode Desktop workspace; set `CCR_OPENCODE_BOT_CWD` to the same project directory currently opened in OpenCode App when using another workspace. CCR passes that directory explicitly through `opencode run --dir`, so the resulting session appears under the matching App project. Permissions are not auto-approved by default; `CCR_OPENCODE_BOT_AUTO_APPROVE=true` enables OpenCode's dangerous `--auto` mode and should be used only in a trusted environment.
### Codex
| Option | What it does |
@@ -77,10 +92,16 @@ Claude App and Claude Code CLI use different model-list adapters:
| Environment variables | Injected into Codex CLI or ChatGPT. Claude Code-specific model discovery variables are not passed to Codex. |
| Bot | Applies only to the ChatGPT app entry. |
After saving, use the terminal button on the config card to copy the Codex CLI command, for example `ccr "Codex - Work"`. Use the play button to open ChatGPT. Following the CodexL launch model, CCR starts the Electron executable inside the ChatGPT app bundle directly, gives it an isolated user-data directory, and points `CODEX_CLI_PATH` at the CCR middleware. The middleware forwards app-server traffic to ChatGPT's bundled Codex CLI and only adapts the account display: an existing valid ChatGPT token is shown as the real ChatGPT account, while a profile without credentials uses a tokenless ChatGPT-shaped workspace identity so the desktop renderer keeps model selection available without storing a real user login. To make the native app-server select its official API marketplace, CCR creates the exact `ccr-local-profile` bootstrap only during process startup and removes it after the first native response; it is also cleaned after startup or abnormal exit and is never retained as login state. Every other authentication file is preserved. Older `Codex.app` installations remain supported.
After saving, use the terminal button on the config card to copy the Codex CLI command, for example `ccr-app "Codex - Work"`. Use the play button to open ChatGPT. Following the CodexL launch model, CCR starts the Electron executable inside the ChatGPT app bundle directly, gives it an isolated user-data directory, and points `CODEX_CLI_PATH` at the CCR middleware. The middleware forwards app-server traffic to ChatGPT's bundled Codex CLI and only adapts the account display: an existing valid ChatGPT token is shown as the real ChatGPT account, while a profile without credentials uses a tokenless ChatGPT-shaped workspace identity so the desktop renderer keeps model selection available without storing a real user login. To make the native app-server select its official API marketplace, CCR creates the exact `ccr-local-profile` bootstrap only during process startup and removes it after the first native response; it is also cleaned after startup or abnormal exit and is never retained as login state. Every other authentication file is preserved. Older `Codex.app` installations remain supported.
Model and public plugin listings are not synthesized by the middleware. The native Codex app-server reads the generated `model_catalog_json` and handles `model/list` plus public `plugin/list` requests unchanged. This lets Codex refresh the official public [`openai/plugins`](https://github.com/openai/plugins) Git marketplace over the network. In a virtual workspace, only account-private marketplace requests are answered with an explicit empty result because the native service requires real ChatGPT authentication for those sections; they are never replaced with local plugins. Any downloaded Git checkout is owned only by Codex as its normal last-known-good data, not used by CCR as a replacement catalog.
### Grok CLI
Grok CLI profiles are fixed to **Only opened from CCR** and **CLI only**. After saving, copy and run the card command, for example `ccr-app "Grok - Work"`.
The generated wrapper sets Grok's model base URL and model-list URL to CCR's `/v1` gateway, supplies the profile-specific CCR API key, and sets the selected CCR model as the default. If the CCR Desktop gateway is not running, `ccr-app` starts a shared temporary service for Grok sessions and cleans it up after the last session exits. Grok CLI does not expose a separate user-config-file option, so CCR points `GROK_HOME` at a profile-specific directory. Its `config.toml` starts as a private copy of the user's config and can change independently, while `auth.json` is excluded to prevent a local xAI OAuth token from overriding the CCR key. Plugins, skills, and sessions remain shared with the original Grok home. Inside Grok CLI, use `/model` to switch among the provider and Fusion models returned by CCR; switched requests continue through CCR.
### ZCode
| Option | What it does |
@@ -98,8 +119,8 @@ ZCode supports App only, so its entry mode is fixed to `App only`. The `Show all
| Mode | How to open | Best for | Key differences |
| --- | --- | --- | --- |
| CLI | Click the terminal button to copy the command, then run `ccr <config-name>` in a terminal | Working inside a project directory, shell workflows, scripting | Uses the config-specific wrapper or middleware launcher; usually stays in the terminal without opening a desktop window; Bot forwarding support is pending. |
| App | Click the play button in the CCR desktop app | Desktop windows, side-by-side instances, Bot forwarding, handoff | Uses a separate user-data directory per Agent Config; reopening the same config activates the existing window, while different configs can run in parallel. |
| CLI | Click the terminal button to copy the command, then run `ccr-app <config-name>` in a terminal | Working inside a project directory, shell workflows, scripting | Uses the config-specific wrapper or middleware launcher; usually stays in the terminal without opening a desktop window; Bot forwarding support is pending. |
| App | Click the play button in the CCR desktop app | Desktop windows, Bot forwarding, handoff | Reopening the same config activates the existing window. Multi-instance behavior depends on the Agent; OpenCode Desktop is single-instance, so CCR stops the managed instance before switching OpenCode profiles. |
| CLI & APP | One config exposes both CLI and App entry points | Reusing the same model config in both terminal and desktop App workflows | Both entries share the config name, model, effect scope, and environment variables, but launch differently. |
## Agent Differences
@@ -110,16 +131,32 @@ Claude Code CLI config writes a settings file. With **Only opened from CCR**, CC
When opening Claude App from the desktop app, CCR also prepares a separate user-data directory for that config. Different Agent Config entries use different directories, so multiple Claude App instances can run at the same time.
With a Bot bound, Claude App's companion worker exposes Projects/Sessions, streaming replies, attachments, Session usage, and native permission/Ask User requests to IM. The worker stops with the App.
### Codex
Codex config writes `config.toml` and a model catalog file. With **Only opened from CCR**, CCR stores those files in a directory separated by config `id`.
Codex supports CLI and App. CLI opens through the launcher for the selected config; App launches ChatGPT, uses a separate user-data directory, and passes the selected model and provider into the app.
With a Bot bound, the Codex App companion worker uses native Codex rollout Sessions for Project/Session browsing and continuation, queueing, cancellation, model settings, usage, attachments, and diagnostics. It exists only alongside the managed App.
### OpenCode
OpenCode config writes a JSON/JSONC config that routes the selected provider and model through CCR. CLI opens through a profile-specific wrapper; App launches the installed OpenCode Desktop executable with the same effective config.
When a Bot is selected and the App is opened from CCR, CCR starts a companion worker using OpenCode-native Sessions and the same Project/Session, queue, media, settings, and diagnostics contract as the other Apps. The worker stops when the managed OpenCode App exits or the profile is switched.
### Grok CLI
Grok CLI supports CLI only. CCR opens it through a profile-specific wrapper that injects the CCR model gateway, model discovery endpoint, API key, and default model. A profile-specific Grok home excludes xAI OAuth credentials so inference reliably uses the CCR key without rewriting the user's original Grok home.
### ZCode
ZCode supports App only. CCR writes ZCode CLI config, v2 config, and model cache based on ZCode home or a custom config file, then starts the App with the current Agent Config's model, provider, and separate user-data directory.
With a Bot bound, ZCode uses the Codex-compatible companion worker and native Session discovery. Closing ZCode App immediately takes the relay offline.
## Multi-Instance Suggestions
1. Create one Agent Config for each agent instance that should run independently.
@@ -78,14 +78,26 @@ Choose a provider below to get started. CCR shows what will be added before savi
<span class="provider-import-icon-shell"><img src="../../../provider-icons/teamorouter.png" alt="" loading="lazy" /></span>
<span class="provider-import-copy"><span class="provider-import-name">TeamoRouter</span><span class="provider-import-meta">Anthropic / Chat / Responses</span></span>
</a>
<a class="provider-import-button provider-code0" href="ccr://provider?name=code0.ai&amp;base_url=https%3A%2F%2Fconsole.code0.ai&amp;protocol=anthropic_messages&amp;source=https%3A%2F%2Fcode0.ai%3Fsource%3Dclaudecoderouter" aria-label="Import code0.ai provider">
<a class="provider-import-button provider-unity2" href="ccr://provider?name=Unity2.Ai&amp;base_url=https%3A%2F%2Funity2.ai%2Fv1&amp;protocol=openai_chat_completions&amp;source=https%3A%2F%2Funity2.ai%2Fregister%3Fsource%3Dclaudecoderouter" aria-label="Import Unity2.Ai provider">
<span class="provider-import-icon-shell"><img src="../../../provider-icons/unity2.jpg" alt="" loading="lazy" /></span>
<span class="provider-import-copy"><span class="provider-import-name">Unity2.Ai</span><span class="provider-import-meta">OpenAI compatible gateway</span></span>
</a>
<a class="provider-import-button provider-code0" href="ccr://provider?name=code0.ai&amp;base_url=https%3A%2F%2Fconsole.code0.ai&amp;protocol=anthropic_messages&amp;source=https%3A%2F%2Fcode0.ai%2Fagent%2Fregister%2F9n9jOsSnYQoemIVL%3Futm_source%3Dclaudecoderouter%26utm_medium%3Dpartner%26utm_campaign%3Dclaudecoderouter_2026%26utm_content%3Ddefault" aria-label="Import code0.ai provider">
<span class="provider-import-icon-shell"><img src="../../../provider-icons/code0.png" alt="" loading="lazy" /></span>
<span class="provider-import-copy"><span class="provider-import-name">code0.ai</span><span class="provider-import-meta">Anthropic / Chat / Responses</span></span>
</a>
<a class="provider-import-button provider-claudeapi" href="ccr://provider?name=claudeapi&amp;base_url=https%3A%2F%2Fgw.claudeapi.com&amp;protocol=anthropic_messages&amp;source=https%3A%2F%2Fwww.claudeapi.com%3Fsource%3Dclaudecoderouter" aria-label="Import claudeapi provider">
<a class="provider-import-button provider-claudeapi" href="ccr://provider?name=claudeapi&amp;base_url=https%3A%2F%2Fgw.claudeapi.com&amp;protocol=anthropic_messages&amp;source=https%3A%2F%2Fconsole.claudeapi.com%2Fagent%2Fregister%2FLbmB7Y9kPloyzhwF%3Futm_source%3Dclaudecoderouter%26utm_medium%3Dpartner%26utm_campaign%3Dclaudecoderouter_2026%26utm_content%3Ddefault" aria-label="Import claudeapi provider">
<span class="provider-import-icon-shell"><img src="../../../provider-icons/claudeapi.png" alt="" loading="lazy" /></span>
<span class="provider-import-copy"><span class="provider-import-name">claudeapi</span><span class="provider-import-meta">Anthropic Messages</span></span>
</a>
<a class="provider-import-button provider-qiniu-ai" href="ccr://provider?name=%E4%B8%83%E7%89%9B%E4%BA%91+AI&amp;base_url=https%3A%2F%2Fapi.qnaigc.com&amp;protocol=openai_chat_completions&amp;source=https%3A%2F%2Fs.qiniu.com%2FAVjMVf" aria-label="Import Qiniu Cloud AI provider">
<span class="provider-import-icon-shell"><img src="../../../provider-icons/qiniu-ai.png" alt="" loading="lazy" /></span>
<span class="provider-import-copy"><span class="provider-import-name">Qiniu Cloud AI</span><span class="provider-import-meta">Chat / Responses / Anthropic / Gemini Generate</span></span>
</a>
<a class="provider-import-button provider-fenno" href="ccr://provider?name=Fenno.ai&amp;base_url=https%3A%2F%2Fapi.fenno.ai&amp;protocol=openai_chat_completions&amp;source=https%3A%2F%2Fapi.fenno.ai%2Fregister%3Fredirect%3D%2Fpurchase%3Ftab%3Dsubscription%2526group%3D16%26aff%3D9HHHAB5QLAES" aria-label="Import Fenno.ai provider">
<span class="provider-import-icon-shell"><img src="../../../provider-icons/fenno.jpg" alt="" loading="lazy" /></span>
<span class="provider-import-copy"><span class="provider-import-name">Fenno.ai</span><span class="provider-import-meta">Chat / Responses / Anthropic</span></span>
</a>
</div>
## Embeddable Button Component
@@ -5,6 +5,18 @@ eyebrow: Detailed Configuration
lead: Configure the CCR gateway host, port, and Proxy mode for MITM interception and proxying into CCR.
---
## Management And Gateway Addresses Are Separate
The Host/Port fields under **Server** configure the model gateway, not the browser management page:
| Distribution | Management entry | Model gateway |
| --- | --- | --- |
| Desktop | App window | `http://127.0.0.1:3456` by default |
| npm CLI | `http://127.0.0.1:3458` by default | `http://127.0.0.1:3456` by default |
| Docker | Public `http://127.0.0.1:3458` by default | Combined into the same public Nginx endpoint |
CLI `--host`/`--port` options configure management; this page configures the gateway. Docker internal listeners should not be published separately. See [Docker Deployment](../../guides/docker/).
## Main Fields
| Field | Capability |
@@ -12,6 +24,20 @@ lead: Configure the CCR gateway host, port, and Proxy mode for MITM interception
| Host | Host address the CCR gateway listens on. Common values are `127.0.0.1` and `0.0.0.0`. |
| Port | Gateway listening port. Clients should point their API base URL to this port. |
`127.0.0.1` allows local access only; `0.0.0.0` listens on every IPv4 interface. Use a wildcard only for intentional LAN/remote access, together with CCR client API keys, firewall/private-network controls, and TLS at a reverse proxy.
Management tokens, CCR client API keys, and upstream credentials are separate. Gateway clients use keys created under **API Keys** and should never receive upstream provider credentials.
## Start And Verify
1. Add at least one provider and model.
2. Create a client key under **API Keys**.
3. Click **Start** or **Restart**.
4. Confirm Running status and request the gateway `/health` route.
5. Send a minimal model request and inspect the resolved provider/model under Logs.
A reachable management UI does not prove the gateway is running. Docker returns `502` from `/health` until the gateway starts, and desktop/CLI can keep management available without usable models.
## Proxy Mode
Proxy mode is the local proxy capability. When enabled, clients can send HTTP/HTTPS traffic to CCR. CCR uses MITM interception to identify and decrypt HTTPS requests, then proxies supported model requests into the CCR gateway path.
@@ -26,3 +52,5 @@ Proxy mode is the local proxy capability. When enabled, clients can send HTTP/HT
| Check Trust | Checks again whether the proxy CA is trusted by the system. |
| Proxy status | Shows whether the proxy service is running. |
| Restart Proxy | Restarts the proxy service when proxy mode is enabled. |
Proxy mode changes local networking and certificate trust and is primarily a desktop feature. Container deployments should normally point clients directly at the public CCR Nginx gateway instead of trying to change the host system proxy or install a host CA from inside the container.
+13 -11
View File
@@ -7,17 +7,15 @@ lead: Start from installation, connect a provider, let agents send requests thro
## Install And Start CCR
### Download And Install
CCR is available as a desktop app, a Node.js 22+ npm CLI, and a single-entrypoint Docker deployment.
1. Open the [GitHub Releases](https://github.com/musistudio/claude-code-router/releases) page.
2. Download the package for your system: `.dmg` or `.zip` for macOS, `.exe` for Windows, and `.AppImage` for Linux.
3. Install and open **Claude Code Router** like a normal desktop app.
| Distribution | Start entry | Default management | Default model gateway |
| --- | --- | --- | --- |
| Desktop | App UI / `ccr-app` | In-app window | `http://127.0.0.1:3456` |
| npm CLI | `ccr ui` / `ccr serve` | `http://127.0.0.1:3458` | `http://127.0.0.1:3456` |
| Docker | `docker compose up -d --build` | Shared `http://127.0.0.1:3458` | Shared Nginx endpoint |
### Start The Service
Open the **Server** page and click **Start**. After the page shows Running, CCR listens on the default local address `http://localhost:8080`.
If you want the service to start when the app opens, enable **Auto start** on the Server page.
Use the [installation page](install/) to choose a distribution. See the [CLI reference](cli/) for terminal commands and [Docker Deployment](docker/) for container ports, authentication, persistence, and upgrades.
## Add A Provider
@@ -57,7 +55,7 @@ If you want the overview to show balance or remaining quota, open the provider's
## Connect Agent Config
Agent Config lets Claude Code, Codex, ZCode, and other agents use CCR's providers, routing, and model selection.
Agent Config lets Claude Code, Codex, Grok CLI, ZCode, and other agents use CCR's providers, routing, and model selection.
General guidance:
@@ -73,13 +71,17 @@ In **Agent Config**, choose Claude Code, set the model, small fast model, and se
In **Agent Config**, choose Codex and confirm Provider ID, Provider Name, model, and config file. Only fill Codex CLI path and Codex home when you need a specific CLI or home directory.
### Grok CLI
Choose Grok CLI and select a default model, then run the copied `ccr-app <profile-name>` command. The command starts a shared temporary gateway service when CCR Desktop is not already serving one; concurrent Grok sessions keep it alive until the last session exits. CCR points Grok model discovery and inference at the local gateway; use `/model` inside Grok to switch CCR models.
### ZCode
ZCode mainly uses model, Provider ID, Provider Name, and whether it is launched from CCR. It uses the App surface and does not need Codex CLI path fields.
### Reuse A Locally Logged-In Agent
If Claude Code, Codex, or ZCode is already logged in on this machine, import it as a **Local Agent Provider** from **Providers** to reuse the existing authorization without applying for another key.
If Claude Code, Codex, Grok CLI, or ZCode is already logged in on this machine, import it as a **Local Agent Provider** from **Providers** to reuse the existing authorization without applying for another key.
## Logs & Observability
@@ -2,7 +2,7 @@
title: Connect Agent Config
pageTitle: Connect Agent Config
eyebrow: Quick Start
lead: Let Claude Code, Codex, ZCode, and other agents use CCR's providers, routing, and model selection.
lead: Let Claude Code, Codex, Grok CLI, ZCode, and other agents use CCR's providers, routing, and model selection.
---
## General Guidance
@@ -23,10 +23,14 @@ In **Agent Config**, choose Codex and confirm Provider ID, Provider Name, model,
Only fill Codex CLI path and Codex home when you need a specific CLI or home directory.
## Grok CLI
Choose Grok CLI, select a model, and run the copied `ccr-app <profile-name>` command. When the CCR Desktop gateway is not running, the command starts a shared temporary gateway service that remains available until the last concurrent Grok session exits. Use `/model` inside Grok to switch among models exposed by CCR.
## ZCode
ZCode mainly uses model, Provider ID, Provider Name, and whether it is launched from CCR. It uses the App surface and does not need Codex CLI path fields.
## Reuse A Locally Logged-In Agent
If Claude Code, Codex, or ZCode is already logged in on this machine, import it as a **Local Agent Provider** from **Providers** to reuse the existing authorization without applying for another key.
If Claude Code, Codex, Grok CLI, or ZCode is already logged in on this machine, import it as a **Local Agent Provider** from **Providers** to reuse the existing authorization without applying for another key.
+161
View File
@@ -0,0 +1,161 @@
---
title: CLI Installation And Reference
pageTitle: CLI Installation And Reference
eyebrow: Quick Start
lead: Run the browser management UI and model gateway from npm, and launch locally installed agents through CCR profiles without Electron.
---
## `ccr` And `ccr-app`
CCR has two related commands:
| Command | Source | Primary use |
| --- | --- | --- |
| `ccr` | npm package `@musistudio/claude-code-router` | Electron-free management UI, gateway service, and profile launches. |
| `ccr-app` | CCR desktop application | Desktop-managed profile launcher used by commands copied from Agent Config cards. |
Both distributions use the same local configuration directory, but their command names are not interchangeable. Use the desktop app for tray features, notifications, automatic app updates, and desktop-only browser integrations. Use the npm CLI for headless hosts or external process supervision.
## Install, Upgrade, Or Remove
Node.js 22 or newer is required:
```sh
node --version
npm install -g @musistudio/claude-code-router
ccr --help
```
Upgrade or uninstall with npm:
```sh
npm install -g @musistudio/claude-code-router@latest
npm uninstall -g @musistudio/claude-code-router
```
Uninstalling the package does not delete local configuration or databases. If `ccr` is not found, run `npm prefix -g`, add npm's global binary directory to `PATH`, and open a new shell.
## First Start
Start the background service and open the UI:
```sh
ccr ui
```
For SSH or headless sessions:
```sh
ccr ui --no-open
```
Then add a provider/model, create a CCR client key under **API Keys**, configure routing if needed, and confirm the gateway is running under **Server**. The management UI defaults to `http://127.0.0.1:3458`; the model gateway defaults to `http://127.0.0.1:3456`.
The management token and CCR client keys are separate credentials. The first protects UI/RPC access; the second authenticates model gateway requests.
## Service Command Summary
| Command | Mode | Purpose |
| --- | --- | --- |
| `ccr start` | Background | Starts management and the gateway, then prints the authenticated management URL. |
| `ccr ui` | Background | Reuses or starts the background service and opens a browser. |
| `ccr stop` | One-shot | Stops the service created by `start` or `ui`. |
| `ccr serve` | Foreground | Runs in the current terminal for logs or process supervision. |
| `ccr web` | Foreground | Alias of `serve`. |
| `ccr <profile>` | Foreground | Launches an enabled Agent Config profile. |
## Service Options
```text
ccr start [--host <host>] [--port <port>] [--open|--no-open] [--gateway|--no-gateway]
ccr ui [--host <host>] [--port <port>] [--open|--no-open] [--gateway|--no-gateway]
ccr serve [--host <host>] [--port <port>] [--open|--no-open] [--gateway|--no-gateway]
ccr stop
```
| Option | Description |
| --- | --- |
| `--host <host>` | Management listener, default `127.0.0.1`. `--host=value` is also accepted. |
| `--port <port>` | Preferred management port, default `3458`. `--port=value` is also accepted. |
| `--open` / `--no-open` | Enables or disables browser opening. `ui` opens by default. |
| `--gateway` | Explicitly requests model gateway startup; this is the default. |
| `--no-gateway` | Starts management without starting the model gateway during service startup. |
When the preferred port is occupied, CCR tries following ports and prints the actual URL. `serve` handles `SIGINT` and `SIGTERM`; `ccr stop` manages only detached services.
## Background Service Reuse
`start` and `ui` store the process ID, URL, and a private service token in `service.json`. A later invocation verifies both the process and RPC identity before reuse.
- A valid service is reused rather than duplicated.
- New host, port, or `--no-gateway` options do not reconfigure an already running service.
- A command that requires the gateway can ask the existing management process to start it.
- Stale state is removed before a replacement service starts.
Stop first when changing listener settings:
```sh
ccr stop
ccr start --host 127.0.0.1 --port 3458
```
## Launch Agent Config Profiles
Create and enable a profile under **Agent Config**, then use:
```text
ccr <profile-name-or-id> [cli|app] [-- <agent arguments>]
```
Examples:
```sh
ccr "Codex - Work"
ccr "Codex - Work" app
ccr "Claude - Review" cli -- --model sonnet
ccr profile-id -- --help
```
- `--cli` and `--app` are alternatives to the positional surface.
- Put agent arguments after `--` to avoid ambiguity.
- Claude Code, Codex, and Grok default to CLI; ZCode defaults to App.
- Grok supports CLI only; ZCode supports App only.
- Claude App and ZCode App reject trailing agent arguments.
- App launches require a locally installed application and graphical session.
- Only enabled profiles are launchable. Use the profile ID when names are ambiguous.
Most profiles require the CCR gateway to be running. Grok CLI can create a managed temporary shared service and stops it after the final managed Grok session exits.
## Configuration And Data
| Platform | Configuration directory |
| --- | --- |
| macOS / Linux | `~/.claude-code-router` |
| Windows | `%APPDATA%\claude-code-router` |
Important paths include `config.sqlite`, `app-data/`, `service.json`, `gateway.config.json`, `profiles/`, and generated launch wrappers under `bin/`. Do not edit or copy live SQLite files. Use **Settings → Export data**, or stop CCR before taking a filesystem backup.
## Authentication And Remote Access
`CCR_WEB_HOST` and `CCR_WEB_PORT` provide defaults when command-line listener options are omitted. Set `CCR_WEB_AUTH_TOKEN` to keep a stable management UI/RPC token; otherwise a random token is generated for the process. The authenticated management URL contains `ccr_web_token`; treat the full URL as a password.
Keep the listener on `127.0.0.1` unless remote access is intentional. A remote deployment should use a strong fixed token, firewall/private network controls, and TLS at a trusted reverse proxy. Create separate CCR client API keys for gateway access and protect the data directory because it contains upstream credentials.
## Process Supervisors
Use `ccr serve --no-open` with an external supervisor. Fix the service user, `HOME`, listener, and `CCR_WEB_AUTH_TOKEN`. Do not also run a detached `ccr start` service, which can create a second management listener or make both processes compete for the same configuration.
## Troubleshooting
- **UI works but gateway requests fail:** add a provider/model and CCR client key, start the gateway under **Server**, and use `ccr serve` to inspect startup errors.
- **The UI is not on port 3458:** the preferred port was occupied; use the printed URL or stop the conflict.
- **Profile not found:** confirm it is enabled, use its ID when names are ambiguous, and re-save it if generated launchers are missing.
- **Old background options remain active:** run `ccr stop`, then start again with the new options.
- **A foreground service does not stop through `ccr stop`:** stop `ccr serve` from its terminal or supervisor.
## Related Pages
- [Install And Start CCR](../install/)
- [Agent Config](../../configuration/profiles/)
- [Server](../../configuration/server/)
- [Docker Deployment](../docker/)
+198
View File
@@ -0,0 +1,198 @@
---
title: Docker Deployment
pageTitle: Docker Deployment
eyebrow: Quick Start
lead: Run CCR Core and the browser UI behind a single Nginx entrypoint with documented ports, authentication, persistence, upgrades, and troubleshooting.
---
## Scope And Limitations
The image contains CCR Core, the built management UI, PM2, and Nginx. It is intended for a persistent model gateway and browser administration. It does not include Electron, the npm `ccr` command, tray features, host desktop Agent/App launching, desktop automatic updates, or desktop-only browser integrations.
Use the desktop distribution for local app profiles and tray workflows, or the [CLI](../cli/) for an Electron-free host command.
## Process And Port Topology
```text
host 3458 -> container Nginx 8080
|-> static management UI
|-> management RPC: 127.0.0.1:3459
|-> model gateway: 127.0.0.1:3456
`-> core runtime: 127.0.0.1:3457
```
Publish only container port `8080`. The other listeners are implementation details and should remain private.
| Public route | Purpose |
| --- | --- |
| `/`, `/pages/home/index.html` | Management UI. The root redirects to a tokenized page URL. |
| `/api/ccr/rpc` | Authenticated management RPC. |
| `/health` | Model gateway health, not UI/container health. |
| `/v1/*`, `/v1beta/*`, `/messages`, `/chat/completions`, `/responses`, `/interactions`, `/mcp/*` | Model and MCP gateway routes. |
## Start With Compose
From the repository root:
```sh
docker compose up -d --build
docker compose logs -f ccr
```
Open <http://127.0.0.1:3458>. Add a provider/model, create a CCR client key under **API Keys**, and start the gateway under **Server**. A fresh UI is available immediately, but `/health` can return `502` until the gateway has usable models.
Stop or remove the container without deleting its volume:
```sh
docker compose stop
docker compose down
```
Do not add `--volumes` unless all persisted CCR data should be deleted.
The repository mapping `3458:8080` binds every host interface. For local-only access, use:
```yaml
ports:
- "127.0.0.1:3458:8080"
```
## Authentication
CCR uses three distinct credential types:
| Credential | Purpose | Location |
| --- | --- | --- |
| `CCR_WEB_AUTH_TOKEN` | Management UI/RPC | Container environment |
| CCR client API key | Model gateway requests | **API Keys** page |
| Upstream credential | Requests from CCR to a provider | **Providers** page |
Without `CCR_WEB_AUTH_TOKEN`, the entrypoint generates a new random token for every container start. Opening `/` still works because Nginx redirects to a URL containing the current token. Use a fixed strong token for persistent or remote deployments.
Keep secrets out of shell history by using an ignored environment file:
```dotenv
CCR_WEB_AUTH_TOKEN=replace-with-a-long-random-value
CCR_PUBLIC_BASE_URL=http://127.0.0.1:3458
```
Pass it through `docker run --env-file` or the Compose service `environment`. Treat the complete management URL as a secret because `ccr_web_token` can be captured in browser history, proxy logs, screenshots, and tickets.
## Change The Public Address
Changing the host-facing port, hostname, or scheme also requires the exact client URL in `CCR_PUBLIC_BASE_URL`:
```yaml
services:
ccr:
ports:
- "127.0.0.1:8088:8080"
environment:
CCR_PUBLIC_BASE_URL: http://127.0.0.1:8088
CCR_WEB_AUTH_TOKEN: ${CCR_WEB_AUTH_TOKEN:?set CCR_WEB_AUTH_TOKEN}
```
`CCR_PUBLIC_BASE_URL` updates CCR's public router endpoint. It does not publish a Docker port.
For TLS at a reverse proxy or ingress, set the HTTPS URL and keep the host port private:
```yaml
environment:
CCR_PUBLIC_BASE_URL: https://ccr.example.com
CCR_WEB_AUTH_TOKEN: ${CCR_WEB_AUTH_TOKEN:?set CCR_WEB_AUTH_TOKEN}
```
Proxy every path, allow long-lived requests and adequate body sizes, and disable buffering for SSE/model streams. Add firewall, private-network, or equivalent access controls before exposing management to an untrusted network.
## Persistent Data
The entrypoint sets `HOME=/data`; CCR data is under `/data/.claude-code-router/`, including `config.sqlite`, `gateway.config.json`, `app-data/`, `profiles/`, and generated files under `bin/`.
Prefer a named volume. A bind mount must be writable by the container, and two running CCR containers must not share the same data directory.
On a completely empty volume, the entrypoint writes minimal bootstrap `config.json`. Once the UI saves configuration, SQLite is authoritative. Startup also synchronizes persisted listener/router endpoint fields to the Docker public address unless disabled.
## Backup, Restore, And Upgrade
Use **Settings → Export data** for an application-level backup. For a complete copy, stop writes first:
```sh
docker compose stop ccr
docker compose cp ccr:/data/. ./ccr-data-backup/
docker compose start ccr
```
The backup contains secrets and may contain request/response data. Restore into a new empty volume or empty `/data` while the container is stopped. Do not overlay an old copy onto populated live data because SQLite WAL/SHM and newer runtime files can be mixed.
Upgrade after backing up:
```sh
git pull
docker compose build --pull
docker compose up -d
docker compose ps
docker compose logs --tail=200 ccr
```
Rollback should pair the previous image/source revision with a pre-upgrade backup; an older build may not understand a newer database.
## Environment Reference
Most installations should change only `CCR_WEB_AUTH_TOKEN`, `CCR_PUBLIC_BASE_URL`, and the Docker port mapping.
| Variable | Default | Description |
| --- | --- | --- |
| `CCR_WEB_AUTH_TOKEN` | Random per start | Management UI/RPC token. |
| `CCR_PUBLIC_BASE_URL` | `http://127.0.0.1:3458` | Exact public URL written to CCR configuration. |
| `CCR_PUBLIC_HOST` | `127.0.0.1` | Used only to derive the public URL when the full URL is unset. |
| `CCR_PUBLIC_PORT` | `3458` | Used only to derive the public URL when the full URL is unset. |
| `CCR_DATA_DIR` | `/data` | Data root and process `HOME`. |
| `CCR_NGINX_PORT` | `8080` | Container-private Nginx port. |
| `CCR_WEB_HOST` | `127.0.0.1` | Container-private management host. |
| `CCR_WEB_PORT` | `3459` | Container-private management port. |
| `CCR_GATEWAY_HOST` | `127.0.0.1` | Container-private model gateway host. |
| `CCR_GATEWAY_PORT` | `3456` | Container-private model gateway port used by Nginx. |
| `CCR_GATEWAY_CORE_PORT` | `3457` | Container-private core runtime port. |
| `CCR_NO_GATEWAY` | `0` | `1`, `true`, or `yes` starts management without the gateway at boot. |
| `CCR_DOCKER_INIT_CONFIG` | `1` | `0` disables empty-volume bootstrap `config.json`. |
| `CCR_DOCKER_SYNC_PUBLIC_ENDPOINT` | `1` | `0` disables startup synchronization of persisted listener/public endpoint fields. |
Internal ports normally should not change. Publish only `CCR_NGINX_PORT`.
## Build And Smoke Test
```sh
docker build \
--build-arg NODE_IMAGE=node:22-bookworm \
--build-arg RUNTIME_NODE_IMAGE=node:22-bookworm-slim \
-t claude-code-router:local .
npm run test:docker
```
The smoke test creates temporary resources and verifies the single Nginx entrypoint, UI/RPC auth, public endpoint migration, gateway startup, and `/health`. Set `CCR_DOCKER_TEST_SKIP_BUILD=1` to reuse an image or `CCR_DOCKER_TEST_IMAGE` to select another local tag.
## Operations And Troubleshooting
```sh
docker compose ps
docker compose logs -f ccr
docker compose restart ccr
docker compose config
```
- **`/` returns `302`:** expected tokenized management-page redirect.
- **`/health` returns `502`:** the model gateway is not yet configured/running; this is separate from container health.
- **UI returns `401` after a token change:** reopen the bare root URL and close tabs/bookmarks containing the old token.
- **Clients use an old host/port:** update `CCR_PUBLIC_BASE_URL` and recreate the container with endpoint synchronization enabled.
- **Data disappears after recreation:** verify the same `/data` volume is mounted; `docker compose down --volumes` deletes it.
- **Bind mount permission errors:** ensure the host directory exists and is writable, or use a named volume.
- **Container is healthy but requests fail:** inspect Server status, provider connectivity, CCR client-key auth, routing, request logs, and `docker compose logs --tail=200 ccr`.
## Related Pages
- [Install And Start CCR](../install/)
- [CLI Installation And Reference](../cli/)
- [Server](../../configuration/server/)
- [API Keys](../../configuration/api-keys/)
+57 -8
View File
@@ -2,17 +2,66 @@
title: Install And Start CCR
pageTitle: Install And Start CCR
eyebrow: Quick Start
lead: Download the desktop app, install it, and start the local CCR service.
lead: Choose the desktop app, npm CLI, or Docker for the deployment, and distinguish the management address from the model gateway address.
---
## Download And Install
## Choose A Distribution
1. Open the [GitHub Releases](https://github.com/musistudio/claude-code-router/releases) page.
2. Download the package for your system: `.dmg` or `.zip` for macOS, `.exe` for Windows, and `.AppImage` for Linux.
3. Install and open **Claude Code Router** like a normal desktop app.
| Distribution | Best for | Entry | Default management address | Default gateway address |
| --- | --- | --- | --- | --- |
| Desktop app | Daily local use, tray, multi-instance Agent Apps, desktop integrations | App UI, `ccr-app` | In-app window | `http://127.0.0.1:3456` |
| npm CLI | Terminal, SSH, no Electron, external process supervisors | `ccr` | `http://127.0.0.1:3458` | `http://127.0.0.1:3456` |
| Docker | Persistent servers and container operations | Nginx | Shared public endpoint | `http://127.0.0.1:3458` with the default mapping |
## Start The Service
In desktop/CLI deployments, management and the model gateway do not use the same port. Do not use CLI management port `3458` as the default model gateway. Docker intentionally combines both through one Nginx endpoint.
Open the **Server** page and click **Start**. After the page shows Running, CCR listens on the default local address `http://localhost:8080`.
## Install The Desktop App
If you want the service to start when the app opens, enable **Auto start** on the Server page.
1. Open [GitHub Releases](https://github.com/musistudio/claude-code-router/releases).
2. Download `.dmg`/`.zip` for macOS, `.exe` for Windows, or `.AppImage` for Linux.
3. Install and open **Claude Code Router**.
4. Add a provider/model, create a client key under **API Keys**, then click **Start** under **Server**.
When Server shows Running, the model gateway defaults to `http://127.0.0.1:3456`. Enable automatic startup under Server if the gateway should start whenever the app opens.
## Install The npm CLI
Node.js 22 or newer is required:
```sh
npm install -g @musistudio/claude-code-router
ccr ui
```
`ccr ui` starts a background service and opens the browser. Use `ccr ui --no-open` on a headless host or `ccr serve --no-open` under a process supervisor. See [CLI Installation And Reference](../cli/) for all commands and profile launches.
## Use Docker
From a source checkout:
```sh
docker compose up -d --build
```
Open <http://127.0.0.1:3458>. Docker publishes one Nginx endpoint shared by management and the gateway. Add a provider/model, create a CCR client key, and start the gateway under Server. See [Docker Deployment](../docker/) for ports, authentication, persistence, backups, and remote access.
## Verify The Installation
After configuring a provider, model, and CCR client key:
1. Confirm Server shows Running.
2. Request `/health` on the deployment's gateway address and expect a `200` running response.
3. Send one minimal model request to a compatible endpoint using the CCR client key.
4. Confirm requested/resolved model, provider, status, and latency under Logs.
A reachable management UI does not prove that the model gateway is usable. Docker `/health` returning `502` is expected before a provider/model has been configured.
## Data Locations
| Distribution | Configuration location |
| --- | --- |
| Desktop / CLI on macOS or Linux | `~/.claude-code-router` |
| Desktop / CLI on Windows | `%APPDATA%\claude-code-router` |
| Docker | `/data/.claude-code-router`; persist `/data` |
Current configuration is stored in `config.sqlite`. Legacy `config.json` is only a migration source when SQLite does not exist, or an initial Docker bootstrap. Do not edit live SQLite files.
+6 -5
View File
@@ -12,7 +12,7 @@ The top navigation is split into four standalone pages:
| Page | Contents |
| --- | --- |
| [Documentation](./) | Product positioning, architecture overview, and reading path |
| [Quick Start](guides/) | From installation and provider setup to connecting an agent |
| [Quick Start](guides/) | Desktop, CLI, and Docker installation plus provider and Agent setup |
| [Detailed Configuration](configuration/overview/) | Overview dashboard, API keys, server, providers, routing, Agent Config, Fusion, Bots, tray, and config database location |
| [Q&A](troubleshooting/) | Request logs, observability panel, and common questions |
@@ -22,7 +22,8 @@ Bot platform guides are child pages under Detailed Configuration. Each platform
If this is your first time using CCR:
1. Start with [Quick Start](guides/) to connect a provider and Agent Config.
2. Use the app's request logs to confirm whether requests are passing through CCR.
3. Open [Detailed Configuration](configuration/overview/) for the overview dashboard, API keys, server, providers, vision, web search, MCP tools, tray, and IM relay.
4. Use [Q&A](troubleshooting/) for 401, 404, timeout, wrong-routing, or Bot delivery questions.
1. Choose desktop, npm CLI, or Docker on the [installation page](guides/install/), then use the dedicated [CLI](guides/cli/) or [Docker](guides/docker/) guide.
2. Continue through [Quick Start](guides/) to connect a provider and Agent Config.
3. Use request logs to confirm whether requests are passing through CCR.
4. Open [Detailed Configuration](configuration/overview/) for the overview dashboard, API keys, server, providers, vision, web search, MCP tools, tray, and IM relay.
5. Use [Q&A](troubleshooting/) for 401, 404, timeout, wrong-routing, or Bot delivery questions.
@@ -5,11 +5,61 @@ eyebrow: 详细配置
lead: 通过 IM Bot 转发 Agent 消息,或在桌面空闲后把任务接力到手机。
---
CCR App Relay 的在线周期与由 CCR 打开的 Agent App 保持一致。打开 Claude、Codex、ZCode 或 OpenCode App 时,CCR 启动对应的伴生 workerApp 退出时 worker 和 Bot 连接同步停止。
## 常见模式
- **转发 Agent 消息**:把消息同步到 IM。
- **接力**:桌面空闲后,把交互接力到 IM。
- **仅回复**:关闭“转发 Agent 消息”和接力后,只回复从 IM 主动发起的 turn。
同一个 IM conversation 中的普通消息按顺序执行。`/project``/session status``/session cancel` 等管理命令保持即时响应;排队、取消、超时和 worker 重启恢复都有明确状态。
## Project 与 Session
Project 对应 Agent 的项目或工作目录,Session 对应该 Project 下的 Agent 原生会话。
### Project 命令
| 命令 | 作用 |
| --- | --- |
| `/project` | 查看 Project 命令帮助和 App 在线边界。 |
| `/project list [page]` | 分页列出 Agent 已知项目。 |
| `/project find <text>` | 搜索项目名称或路径。 |
| `/project current` | 查看当前 Project。 |
| `/project use <n>` | 切换 Project,并清除原 Session 选择。 |
| `/project name <label>` | 设置当前 Project 的 Bot 显示名称。 |
### Session 命令
| 命令 | 作用 |
| --- | --- |
| `/session` | 查看全部 Session 命令。 |
| `/session list [page]``/session find <text>` | 只浏览当前 Project 中的 Sessions。 |
| `/session current``new [title]``use <n>``reset` | 查看、新建、继续或清除 Session 选择。 |
| `/session status``cancel` | 查看当前 turn/队列,或取消当前 turn 并清空队列。 |
| `/session approve [session]``deny``answer <text>` | 响应 Agent 已经产生的权限或输入请求;所有平台提供文本命令,具备卡片能力的平台同时显示操作按钮。 |
| `/session name <label>` | 重命名当前 Session。 |
| `/session archive <n>``restore <n>``delete <n> confirm` | 归档、恢复或确认永久删除。 |
| `/session history [count]``usage` | 查看最近历史和 Token/缓存/成本摘要。 |
| `/session models``model``effort``mode` | 查看或调整当前 conversation 的 Session 运行设置。 |
| `/session memory ...``skills``skill``shortcut ...` | 管理持久上下文、Agent Skills 和快捷指令。 |
| `/session doctor``deliveries` | 查看连接、outbox、最近投递和脱敏错误。 |
Bot 的公开命令域为 `/project``/session`。其他 slash command 统一返回未知命令;普通自然语言(包括 `help``list`)作为 prompt 进入 Agent。
## Bot 设置
- **Bot 语言**:自动、English 或简体中文。
- **最长 turn 时间**:超时后中断 Agent turn 并回报最终状态。
- **Session 空闲重置**:超过指定时间后在当前 Project 中准备新 Session;设为 `0` 关闭。
- **消息分片与附件上限**:适配平台消息长度并限制入站文件大小。
- **流式回复与进度**:仅发送可见文本和工具阶段。
- **收发附件**:允许入站图片/文件和当前工作区产物回传。
- **允许 Agent 使用 Shell 工具**:控制 Agent 的 Shell 工具权限;Bot 命令域保持为 `/project``/session`
状态文件持久保存有界的去重记录、待处理 turn、outbox 和最近投递结果。事件幂等保证每个 Agent turn 执行一次;再次打开 App 后,在 App 在线期间恢复待投递消息。
## 平台页面
Slack、Discord、Telegram、LINE、微信、企业微信、飞书和钉钉都有独立页面。
Slack、Discord、Telegram、LINE、微信、企业微信、飞书和钉钉都有独立页面iMessage 使用本机接入。SDK 按平台能力选择 Markdown、卡片、流式更新、文件消息或文本消息
@@ -11,8 +11,9 @@ lead: 添加 Bot、绑定 Agent配置,并选择消息转发或接力模式。
2. 选择平台并填写 Token、Secret、Signing Secret、Robot Code 或 OAuth 信息。
3. 保存 Bot。
4. 打开目标 Agent配置,开启 **Bot**
5. 选择 **转发 Agent 消息****接力**,并重新从 CCR 打开 Agent
5. 按需设置转发、接力、语言、超时、附件、流式回复和 **允许 Agent 使用 Shell 工具**
6. 从 CCR 重新打开 Claude、Codex、ZCode 或 OpenCode App。Bot 只在 App 存活期间在线。
## 验证方式
从 CCR 打开 Agent 后发一条测试消息,确认请求日志中有 Bot 相关记录,IM 端也能收到消息
从 CCR 打开 Agent App 后,在 IM 发送 `/project current``/session list` 和一条普通消息。Profile 卡片会显示 Bot 连接、最后事件、最后投递、待投递数量和脱敏错误;也可发送 `/session doctor` 查看诊断。关闭 App 后,Bot 状态应切换为离线
@@ -8,7 +8,9 @@ lead: 找到 CCR 桌面 App 默认维护的 SQLite 配置数据库。
## 默认位置
- macOS/Linux`~/.claude-code-router/config.sqlite`
- Windows`%APPDATA%\Claude Code Router\config.sqlite`
- Windows`%APPDATA%\claude-code-router\config.sqlite`
Docker 设置 `HOME=/data`,因此配置数据库位于 `/data/.claude-code-router/config.sqlite`;需要持久化挂载整个 `/data`,而不是只挂载单个数据库文件。
## 生效方式
@@ -2,7 +2,7 @@
title: Agent配置
pageTitle: Agent配置
eyebrow: 详细配置
lead: 为 Claude Code、Codex、ZCode 创建可复用的启动配置,并通过不同配置打开不同的 Agent 实例。
lead: 为 Claude Code、Codex、Grok CLI、ZCode 创建可复用的启动配置,并通过不同配置打开不同的 Agent 实例。
---
## 配置流程
@@ -14,7 +14,7 @@ lead: 为 Claude Code、Codex、ZCode 创建可复用的启动配置,并通过
5. 如果入口模式包含 App,可以绑定 Bot,并选择是否转发 Agent 消息或开启接力。
6. 保存后,从 Agent配置卡片打开:终端图标会复制 CLI 命令,播放图标会启动 App 实例。
试用阶段建议选择 **仅从 CCR 打开时生效**,并且总是从 CCR 打开 Agent。这样配置只影响 CCR 启动的实例,不会改掉你系统里原本直接打开的 Claude Code、Codex 或 ZCode。
试用阶段建议选择 **仅从 CCR 打开时生效**,并且总是从 CCR 打开 Agent。这样配置只影响 CCR 启动的实例,不会改掉你系统里原本直接打开的 Claude Code、Codex、Grok CLI 或 ZCode。
## 多开机制
@@ -23,7 +23,7 @@ lead: 为 Claude Code、Codex、ZCode 创建可复用的启动配置,并通过
| 机制 | 实际行为 |
| --- | --- |
| 独立配置文件 | 选择“仅从 CCR 打开时生效”时,Claude Code 和 Codex 会写入 CCR 管理的独立配置目录,路径按配置 `id` 区分 |
| 独立启动器 | Claude Code 使用独立启动包装器,Codex 和 ZCode 使用独立中间层启动器,文件名同样按配置 `id` 或名称区分 |
| 独立启动器 | Claude Code 和 Grok CLI 使用独立启动包装器,Codex 和 ZCode 使用独立中间层启动器,文件名同样按配置 `id` 或名称区分 |
| 独立 App 数据目录 | 从 App 打开时,Claude App、ChatGPTCodex 桌面端的新名称)、ZCode App 都会使用按配置 `id` 区分的用户数据目录 |
| 运行状态 | CCR 按打开入口和配置 `id` 记录运行中的 App 实例;同一个配置再次打开会激活已有窗口,不同配置可以打开不同实例 |
@@ -33,11 +33,11 @@ lead: 为 Claude Code、Codex、ZCode 创建可复用的启动配置,并通过
| 选项 | 适用范围 | 说明 |
| --- | --- | --- |
| Agent | 全部 | 选择 Claude Code、Codex 或 ZCode。ZCode 只支持 App。 |
| 配置名称 | 全部 | 用于在 CCR 中识别配置,也会作为 `ccr <配置名称>` 的打开目标。名称可以有空格,复制命令时 CCR 会自动加引号。 |
| Agent | 全部 | 选择 Claude Code、Codex、OpenCode、Grok CLI 或 ZCode。Grok CLI 只支持 CLIZCode 只支持 App。 |
| 配置名称 | 全部 | 用于在 CCR 中识别配置,也会作为 `ccr-app <配置名称>` 的打开目标。名称可以有空格,复制命令时 CCR 会自动加引号。 |
| 启用开关 | 全部 | 关闭后该配置不会出现在打开入口中,也不会被应用为有效启动配置。 |
| 作用范围 | 全部 | **仅从 CCR 打开时生效** 会使用 CCR 管理的独立配置;**系统默认** 会写入对应 Agent 的默认配置。同一个 Agent 同时只能有一个启用的系统默认配置。 |
| 入口模式 | Claude Code、Codex | `CLI & APP` 同时显示 CLI 和 App 打开入口;`CLI only` 只生成 CLI 命令;`App only` 只显示 App 打开入口。 |
| 入口模式 | Claude Code、Codex、OpenCode、Grok CLI | `CLI & APP` 同时显示 CLI 和 App 打开入口;`CLI only` 只生成 CLI 命令;`App only` 只显示 App 打开入口。Grok CLI 固定为 `CLI only` |
| 模型 | 全部 | 该 Agent 打开后的默认模型,可以选择普通供应商模型或 Fusion 模型。Claude Code 留空表示保留 Claude Code 默认模型。 |
| Bot | App 入口 | 只有从 CCR 打开的 App 模式会转发 Bot 消息。CLI 当前不转发 Bot 消息。 |
| 环境变量 | 全部 | 为该配置注入额外环境变量。Claude Code 默认带 `CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY=1`,用于启用网关模型发现。 |
@@ -65,6 +65,21 @@ Claude App 和 Claude Code CLI 的模型列表适配方式不同:
| Claude Code CLI | CCR 网关模型发现 | CLI 内使用 `/model` 查看列表;选择后请求仍走 CCR 的供应商、路由和 Fusion。 |
| Claude App | CCR 生成的 Claude App inference models | Claude App 需要 Claude 兼容的模型名。CCR 会把 `供应商/模型` 和 Fusion 模型映射成 Claude App 可识别的模型项,并用显示名称保留真实模型含义。 |
### OpenCode
| 配置项 | 作用 |
| --- | --- |
| Provider ID | 写入 OpenCode 的供应商引用,默认是 `claude-code-router`。 |
| Provider name | OpenCode 中展示的供应商名称,默认是 `Claude Code Router`。 |
| OpenCode model | OpenCode CLI 和 App 的默认模型,可以选择普通供应商模型或 Fusion 模型。 |
| 配置文件 | 系统默认模式使用 OpenCode 默认配置;仅从 CCR 打开时生效会在 CCR 配置目录下写入配置专属文件。 |
| 环境变量 | 注入 OpenCode CLI、OpenCode App 以及对应的 Bot worker。 |
| Bot | 在从 CCR 打开的 OpenCode App 入口生效。收到 Bot 消息后会通过 OpenCode CLI 执行,并把回复发回同一个 Bot 会话。 |
CCR 会为 OpenCode App 启动一个配套 Bot worker,并为每个 Bot conversation 分别保存 Project 与可选 Session。先用 `/project list|current|use` 选择 Agent Project,再用 `/session list|current|new|use|reset` 管理该 Project 下的 Agent Session。切换 Project 会清除原 Session,其他 Project 的 Session 无法被选中。Bot 只拦截这两个 slash 命令域;已移除的 `/task` 和旧平铺命令不再兼容。
CCR Desktop 进程环境中必须能够执行 `opencode`。如果 CLI 安装在其他位置,可以在 Agent配置环境变量中设置 `CCR_OPENCODE_BIN`。Bot session 默认使用全新 OpenCode Desktop 工作区对应的文件系统根目录;如果 App 当前打开了其他项目,应通过 `CCR_OPENCODE_BOT_CWD` 设置同一个项目目录。CCR 会把该目录显式传给 `opencode run --dir`,使新 session 出现在 App 对应的项目下。默认不会自动批准权限;只有在可信环境中才应设置 `CCR_OPENCODE_BOT_AUTO_APPROVE=true`,因为它会启用 OpenCode 的高风险 `--auto` 模式。
### Codex
| 配置项 | 作用 |
@@ -77,10 +92,16 @@ Claude App 和 Claude Code CLI 的模型列表适配方式不同:
| 环境变量 | 注入 Codex CLI 或 ChatGPT。Claude Code 专用的模型发现变量不会传给 Codex。 |
| Bot | 只在 ChatGPT App 入口生效。 |
保存后,Codex CLI 使用配置卡片里的终端图标复制命令,例如 `ccr "Codex - Work"`。ChatGPT 使用播放图标打开。CCR 按照 CodexL 的启动方式,直接运行 ChatGPT App bundle 内的 Electron 可执行文件,为它设置隔离的用户数据目录,并把 `CODEX_CLI_PATH` 指向 CCR 中间层。中间层把 app-server 流量转发给 ChatGPT 内置的 Codex CLI,只适配账号展示:隔离目录已有有效 ChatGPT token 时显示真实账号;没有凭据时使用无 token、ChatGPT 形态的虚拟工作区身份,让桌面端在不保存真实用户登录的情况下仍可使用模型选择。为让原生 app-server 选择官方 API marketplace,CCR 只在进程启动阶段创建精确的 `ccr-local-profile` 引导标记,收到第一条原生响应后立即删除;正常启动后或异常退出时也会清理,不会把它保留成登录状态。其他认证文件全部保留。旧版 `Codex.app` 仍然兼容。
保存后,Codex CLI 使用配置卡片里的终端图标复制命令,例如 `ccr-app "Codex - Work"`。ChatGPT 使用播放图标打开。CCR 按照 CodexL 的启动方式,直接运行 ChatGPT App bundle 内的 Electron 可执行文件,为它设置隔离的用户数据目录,并把 `CODEX_CLI_PATH` 指向 CCR 中间层。中间层把 app-server 流量转发给 ChatGPT 内置的 Codex CLI,只适配账号展示:隔离目录已有有效 ChatGPT token 时显示真实账号;没有凭据时使用无 token、ChatGPT 形态的虚拟工作区身份,让桌面端在不保存真实用户登录的情况下仍可使用模型选择。为让原生 app-server 选择官方 API marketplace,CCR 只在进程启动阶段创建精确的 `ccr-local-profile` 引导标记,收到第一条原生响应后立即删除;正常启动后或异常退出时也会清理,不会把它保留成登录状态。其他认证文件全部保留。旧版 `Codex.app` 仍然兼容。
模型和公共插件列表不再由中间层合成。原生 Codex app-server 读取生成的 `model_catalog_json`,并原样处理 `model/list` 与公共 `plugin/list` 请求,因此 Codex 可以自行联网刷新官方公开 [`openai/plugins`](https://github.com/openai/plugins) Git marketplace。虚拟 workspace 中,只有必须使用真实 ChatGPT 鉴权的账号私有 marketplace 请求会得到明确空结果,绝不会用本地插件替代。下载后的 Git checkout 只作为 Codex 自己的常规 last-known-good 数据,CCR 不会拿它替代远端目录。
### Grok CLI
Grok CLI 配置固定为 **仅从 CCR 打开时生效****CLI only**。保存后复制并运行配置卡片上的命令,例如 `ccr-app "Grok - Work"`
生成的包装器会把 Grok 的模型网关和模型列表地址指向 CCR 的 `/v1`,注入该配置专属的 CCR API Key,并把选中的 CCR 模型设为默认模型。如果 CCR Desktop 网关尚未运行,`ccr-app` 会为 Grok 会话启动一个可共享的临时服务,并在最后一个会话退出后清理。Grok CLI 没有单独指定用户配置文件的选项,因此 CCR 会把 `GROK_HOME` 指向配置专属目录;其中的 `config.toml` 初始复制自用户配置,之后可以独立修改,不会回写原文件,同时隔离 `auth.json`,避免本机 xAI OAuth token 覆盖 CCR Key。插件、技能和会话目录仍与原 Grok home 共享。进入 Grok CLI 后可以使用 `/model` 切换 CCR 返回的普通供应商模型或 Fusion 模型,切换后的请求仍然经过 CCR。
### ZCode
| 配置项 | 作用 |
@@ -98,8 +119,8 @@ ZCode 只支持 App 打开,因此入口模式固定为 `App only`,也不会
| 模式 | 如何打开 | 适合场景 | 主要差异 |
| --- | --- | --- | --- |
| CLI | 点击终端图标复制命令,然后在终端运行 `ccr <配置名称>` | 在项目目录中运行 Agent、需要 shell 工作流、需要把命令放进脚本 | 使用对应配置的包装器或中间层启动;通常不启动桌面窗口;当前不转发 Bot 消息。 |
| App | 点击播放图标从 CCR 桌面 App 启动 | 需要桌面窗口、多实例并存、Bot 消息转发或接力 | 每个 Agent配置使用独立用户数据目录;同一配置重复打开会激活已有窗口,不同配置可以并行打开。 |
| CLI | 点击终端图标复制命令,然后在终端运行 `ccr-app <配置名称>` | 在项目目录中运行 Agent、需要 shell 工作流、需要把命令放进脚本 | 使用对应配置的包装器或中间层启动;通常不启动桌面窗口;当前不转发 Bot 消息。 |
| App | 点击播放图标从 CCR 桌面 App 启动 | 需要桌面窗口、Bot 消息转发或接力 | 同一配置重复打开会激活已有窗口。是否支持多开取决于 AgentOpenCode Desktop 是单实例应用,切换 OpenCode 配置时 CCR 会先停止其管理的旧实例。 |
| CLI & APP | 同一个配置同时提供 CLI 和 App 入口 | 同一套模型配置既用于终端,也用于桌面 App | 两个入口共用配置名称、模型、作用范围和环境变量,但启动方式不同。 |
## 各 Agent 的差异
@@ -110,16 +131,32 @@ Claude Code CLI 配置会写入设置文件。选择“仅从 CCR 打开时生
从桌面 App 打开 Claude App 时,CCR 还会为该配置准备独立用户数据目录。不同 Agent配置使用不同目录,因此可以同时打开多个 Claude App 实例。
绑定 Bot 后,Claude App 的伴生 worker 会把 Project/Session、流式回复、附件、会话用量和原生权限/Ask User 请求接入 IMApp 退出时 worker 同步停止。
### Codex
Codex 配置会写入 `config.toml`,并生成模型目录文件。选择“仅从 CCR 打开时生效”时,CCR 会把这些文件放在按配置 `id` 区分的目录中。
Codex 支持 CLI 和 App。CLI 会通过对应配置的启动器打开;App 会启动 ChatGPT、使用独立用户数据目录,并把当前配置中的模型和供应商信息带入 App。
绑定 Bot 后,Codex App 的伴生 worker 使用 Codex 原生 rollout Session,实现 Project/Session 浏览、续接、队列、取消、模型设置、用量、附件和诊断。该 worker 只随受管 App 存活。
### OpenCode
OpenCode 配置会写入 JSON/JSONC 文件,把当前选择的供应商和模型路由到 CCR。CLI 通过配置专属包装器启动;App 使用相同的有效配置启动已安装的 OpenCode Desktop。
选择 Bot 并从 CCR 打开 App 后,CCR 会启动配套 worker,通过 OpenCode 原生 Session 处理收到的 Bot 消息,并提供与其他 App 一致的 Project/Session、队列、媒体、设置和诊断合同。受管 OpenCode App 退出或切换配置时,该 worker 也会同步停止。
### Grok CLI
Grok CLI 只支持 CLI。CCR 通过配置专属包装器启动它,注入 CCR 模型网关、模型发现地址、API Key 和默认模型,并通过不含 xAI OAuth 凭据的配置专属 Grok home 保证推理使用 CCR Key;用户原有的 Grok home 不会被改写。
### ZCode
ZCode 只支持 App 打开。CCR 会根据 ZCode home 或自定义配置文件写入 ZCode 的 CLI 配置、v2 配置和模型缓存,并在 App 启动时使用当前 Agent配置的模型、供应商和独立用户数据目录。
绑定 Bot 后,ZCode 使用与 Codex 同类的 App 伴生 worker 和原生 Session 扫描;ZCode App 关闭时接力立即离线。
## 多开建议
1. 为每个需要独立运行的 Agent 实例创建一个 Agent配置。
@@ -78,14 +78,26 @@ lead: 快速添加常见模型供应商,确认无误后即可保存,减少
<span class="provider-import-icon-shell"><img src="../../provider-icons/teamorouter.png" alt="" loading="lazy" /></span>
<span class="provider-import-copy"><span class="provider-import-name">TeamoRouter</span><span class="provider-import-meta">Anthropic / Chat / Responses</span></span>
</a>
<a class="provider-import-button provider-code0" href="ccr://provider?name=code0.ai&amp;base_url=https%3A%2F%2Fconsole.code0.ai&amp;protocol=anthropic_messages&amp;source=https%3A%2F%2Fcode0.ai%3Fsource%3Dclaudecoderouter" aria-label="导入 code0.ai 供应商">
<a class="provider-import-button provider-unity2" href="ccr://provider?name=Unity2.Ai&amp;base_url=https%3A%2F%2Funity2.ai%2Fv1&amp;protocol=openai_chat_completions&amp;source=https%3A%2F%2Funity2.ai%2Fregister%3Fsource%3Dclaudecoderouter" aria-label="导入 Unity2.Ai 供应商">
<span class="provider-import-icon-shell"><img src="../../provider-icons/unity2.jpg" alt="" loading="lazy" /></span>
<span class="provider-import-copy"><span class="provider-import-name">Unity2.Ai</span><span class="provider-import-meta">OpenAI 兼容网关</span></span>
</a>
<a class="provider-import-button provider-code0" href="ccr://provider?name=code0.ai&amp;base_url=https%3A%2F%2Fconsole.code0.ai&amp;protocol=anthropic_messages&amp;source=https%3A%2F%2Fcode0.ai%2Fagent%2Fregister%2F9n9jOsSnYQoemIVL%3Futm_source%3Dclaudecoderouter%26utm_medium%3Dpartner%26utm_campaign%3Dclaudecoderouter_2026%26utm_content%3Ddefault" aria-label="导入 code0.ai 供应商">
<span class="provider-import-icon-shell"><img src="../../provider-icons/code0.png" alt="" loading="lazy" /></span>
<span class="provider-import-copy"><span class="provider-import-name">code0.ai</span><span class="provider-import-meta">Anthropic / Chat / Responses</span></span>
</a>
<a class="provider-import-button provider-claudeapi" href="ccr://provider?name=claudeapi&amp;base_url=https%3A%2F%2Fgw.claudeapi.com&amp;protocol=anthropic_messages&amp;source=https%3A%2F%2Fwww.claudeapi.com%3Fsource%3Dclaudecoderouter" aria-label="导入 claudeapi 供应商">
<a class="provider-import-button provider-claudeapi" href="ccr://provider?name=claudeapi&amp;base_url=https%3A%2F%2Fgw.claudeapi.com&amp;protocol=anthropic_messages&amp;source=https%3A%2F%2Fconsole.claudeapi.com%2Fagent%2Fregister%2FLbmB7Y9kPloyzhwF%3Futm_source%3Dclaudecoderouter%26utm_medium%3Dpartner%26utm_campaign%3Dclaudecoderouter_2026%26utm_content%3Ddefault" aria-label="导入 claudeapi 供应商">
<span class="provider-import-icon-shell"><img src="../../provider-icons/claudeapi.png" alt="" loading="lazy" /></span>
<span class="provider-import-copy"><span class="provider-import-name">claudeapi</span><span class="provider-import-meta">Anthropic Messages</span></span>
</a>
<a class="provider-import-button provider-qiniu-ai" href="ccr://provider?name=%E4%B8%83%E7%89%9B%E4%BA%91+AI&amp;base_url=https%3A%2F%2Fapi.qnaigc.com&amp;protocol=openai_chat_completions&amp;source=https%3A%2F%2Fs.qiniu.com%2FAVjMVf" aria-label="导入七牛云 AI 供应商">
<span class="provider-import-icon-shell"><img src="../../provider-icons/qiniu-ai.png" alt="" loading="lazy" /></span>
<span class="provider-import-copy"><span class="provider-import-name">七牛云 AI</span><span class="provider-import-meta">Chat / Responses / Anthropic / Gemini Generate</span></span>
</a>
<a class="provider-import-button provider-fenno" href="ccr://provider?name=Fenno.ai&amp;base_url=https%3A%2F%2Fapi.fenno.ai&amp;protocol=openai_chat_completions&amp;source=https%3A%2F%2Fapi.fenno.ai%2Fregister%3Fredirect%3D%2Fpurchase%3Ftab%3Dsubscription%2526group%3D16%26aff%3D9HHHAB5QLAES" aria-label="导入 Fenno.ai 供应商">
<span class="provider-import-icon-shell"><img src="../../provider-icons/fenno.jpg" alt="" loading="lazy" /></span>
<span class="provider-import-copy"><span class="provider-import-name">Fenno.ai</span><span class="provider-import-meta">Chat / Responses / Anthropic</span></span>
</a>
</div>
## 嵌入式按钮组件
@@ -29,7 +29,7 @@ Claude Code 的 Agent / Task / Workflow 可以派生新的模型请求。CCR 使
4. Claude Code 调用 `Agent` / `Task`,或 Workflow 内部创建 Agent 时,prompt 第一行会携带 `<CCR-SUBAGENT-MODEL>供应商/模型</CCR-SUBAGENT-MODEL>`
5. 派生请求进入 CCR 后,CCR 从 system 或前两条 user message 中提取并删除这个标签,然后把该请求路由到标签里的模型。
因此,Subagent / Workflow 的自动路由不是靠 `x-claude-code-agent-id` 之类的 Header 决定模型,而是靠 prompt 标签。Header 只能作为观测线索,真正的模型选择来自标签
因此,Subagent / Workflow 的自动路由由 prompt 标签决定模型。`x-claude-code-agent-id` 等 Header 用于观测,模型选择以标签为准
##### 与模型页配合
@@ -5,6 +5,18 @@ eyebrow: 详细配置
lead: 配置 CCR 网关监听地址、端口,以及通过代理模式进行 MITM 劫持并代理到 CCR 的能力。
---
## 先区分管理地址和网关地址
**服务配置** 中的 Host / Port 指模型网关,不是浏览器管理页面:
| 运行方式 | 管理入口 | 模型网关 |
| --- | --- | --- |
| 桌面应用 | 应用窗口 | 默认 `http://127.0.0.1:3456` |
| npm CLI | 默认 `http://127.0.0.1:3458` | 默认 `http://127.0.0.1:3456` |
| Docker | 默认公开入口 `http://127.0.0.1:3458` | 由 Nginx 合并到同一公开入口 |
CLI 的 `--host` / `--port` 配置管理服务;本页字段配置模型网关。Docker 的内部管理和网关端口不应单独发布,详见 [Docker 部署](../../guides/docker/)。
## 主字段
| 字段 | 代表的能力 |
@@ -12,6 +24,20 @@ lead: 配置 CCR 网关监听地址、端口,以及通过代理模式进行 MI
| Host | CCR 网关监听的主机地址。常见值是 `127.0.0.1``0.0.0.0`。 |
| Port | CCR 网关监听端口。客户端需要把 API Base URL 指向这个端口。 |
Host 使用 `127.0.0.1` 时仅本机可访问;`0.0.0.0` 会监听所有 IPv4 网卡。只有在确实需要局域网或远程访问时才使用通配地址,并同时配置 CCR 客户端 API Key、防火墙 / 私网和 TLS 反向代理。
管理 Token、CCR 客户端 API Key 和上游供应商凭据彼此独立。客户端访问网关时使用 **API 密钥** 页面创建的 CCR Key,不要直接暴露上游凭据。
## 启动和验证
1. 至少添加一个供应商和模型。
2.**API 密钥** 页面创建客户端 Key。
3. 点击 **启动****重启**
4. 确认状态显示运行中,并请求网关的 `/health`
5. 发出最小模型请求,再到请求日志核对最终供应商 / 模型。
管理 UI 可访问不代表模型网关已运行。Docker 在网关未启动时会让 `/health` 返回 `502`;桌面版 / CLI 也可能在没有可用模型时只保留管理服务。
## 代理模式
代理模式是本地代理能力。开启后,客户端可以把 HTTP/HTTPS 流量交给 CCRCCR 会通过 MITM 劫持识别和解密 HTTPS 请求,并把可处理的模型请求代理到 CCR 网关链路。
@@ -26,3 +52,5 @@ lead: 配置 CCR 网关监听地址、端口,以及通过代理模式进行 MI
| 检查信任 | 重新检测代理 CA 是否已被系统信任。 |
| 代理状态 | 显示代理服务当前是否运行。 |
| 重启代理 | 代理模式开启时,重新启动代理服务。 |
代理模式需要操作本机网络和证书信任,主要面向桌面环境。容器部署通常应把客户端直接指向 CCR 的 Nginx 网关入口,不建议依赖容器修改宿主机系统代理或安装宿主机 CA。
+13 -11
View File
@@ -7,17 +7,15 @@ lead: 从安装开始,逐步接入供应商、让 Agent 通过 CCR 发请求
## 安装并启动 CCR
### 下载安装
CCR 提供三种发行方式:桌面应用、Node.js 22+ 的 npm CLI,以及 Docker 单入口部署。
1. 打开 [GitHub Releases](https://github.com/musistudio/claude-code-router/releases) 页面。
2. 按你的系统下载安装包:macOS 使用 `.dmg``.zip`Windows 使用 `.exe`Linux 使用 `.AppImage`
3. 像普通桌面软件一样安装并打开 **Claude Code Router**
| 方式 | 启动入口 | 默认管理地址 | 默认模型网关 |
| --- | --- | --- | --- |
| 桌面应用 | 应用界面 / `ccr-app` | 应用内窗口 | `http://127.0.0.1:3456` |
| npm CLI | `ccr ui` / `ccr serve` | `http://127.0.0.1:3458` | `http://127.0.0.1:3456` |
| Docker | `docker compose up -d --build` | 与网关共用 `http://127.0.0.1:3458` | 与管理界面共用 Nginx 入口 |
### 启动服务
进入 **服务** 页面,点击 **启动**。页面显示运行中后,CCR 会在本机监听默认地址 `http://localhost:8080`
如果希望打开 App 后自动启动服务,可以在服务页面开启自动启动。
先阅读[安装页](install/)选择发行方式;完整终端命令见 [CLI 参考](cli/),容器端口、鉴权、持久化和升级见 [Docker 部署](docker/)。
## 接入供应商
@@ -57,7 +55,7 @@ lead: 从安装开始,逐步接入供应商、让 Agent 通过 CCR 发请求
## 接入 Agent配置
Agent配置让 Claude Code、Codex、ZCode 等 Agent 使用 CCR 的供应商、路由和模型选择配置。
Agent配置让 Claude Code、Codex、Grok CLI、ZCode 等 Agent 使用 CCR 的供应商、路由和模型选择配置。
通用建议:
@@ -73,13 +71,17 @@ Agent配置让 Claude Code、Codex、ZCode 等 Agent 使用 CCR 的供应商、
**Agent配置** 中选择 Codex,确认供应商 ID、供应商名称、模型和配置文件。需要特定 CLI 时再填写 Codex CLI path 和 Codex home。
### Grok CLI
选择 Grok CLI 并设置默认模型,然后运行复制出的 `ccr-app <配置名称>` 命令。即使 CCR Desktop 网关尚未运行,该命令也会启动一个可共享的临时网关服务;并发 Grok 会话会共同保持服务运行,直到最后一个会话退出。CCR 会把 Grok 的模型发现和推理请求指向本地网关;进入 Grok 后可以用 `/model` 切换 CCR 模型。
### ZCode
ZCode 主要关注模型、供应商 ID、供应商名称,以及是否从 CCR 启动。它走 App surface,不需要 Codex CLI 的路径字段。
### 复用本机已登录的 Agent
如果本机已经登录过 Claude Code、Codex 或 ZCode,可以在 **供应商** 中导入为 **本机 Agent 供应商**,复用已有授权,不必额外申请 Key。
如果本机已经登录过 Claude Code、Codex、Grok CLI 或 ZCode,可以在 **供应商** 中导入为 **本机 Agent 供应商**,复用已有授权,不必额外申请 Key。
## 日志&观测
@@ -2,7 +2,7 @@
title: 接入 Agent配置
pageTitle: 接入 Agent配置
eyebrow: 快速开始
lead: 让 Claude Code、Codex、ZCode 等 Agent 使用 CCR 的供应商、路由和模型选择配置。
lead: 让 Claude Code、Codex、Grok CLI、ZCode 等 Agent 使用 CCR 的供应商、路由和模型选择配置。
---
## 通用建议
@@ -23,10 +23,14 @@ lead: 让 Claude Code、Codex、ZCode 等 Agent 使用 CCR 的供应商、路由
需要特定 CLI 时再填写 Codex CLI path 和 Codex home。
## Grok CLI
选择 Grok CLI、设置模型,然后运行复制出的 `ccr-app <配置名称>` 命令。CCR Desktop 网关尚未运行时,该命令会启动一个可共享的临时网关服务,并保持运行到最后一个并发 Grok 会话退出。进入 Grok 后可以使用 `/model` 切换 CCR 暴露的模型。
## ZCode
ZCode 主要关注模型、供应商 ID、供应商名称,以及是否从 CCR 启动。它走 App surface,不需要 Codex CLI 的路径字段。
## 复用本机已登录的 Agent
如果本机已经登录过 Claude Code、Codex 或 ZCode,可以在 **供应商** 中导入为 **本机 Agent 供应商**,复用已有授权,不必额外申请 Key。
如果本机已经登录过 Claude Code、Codex、Grok CLI 或 ZCode,可以在 **供应商** 中导入为 **本机 Agent 供应商**,复用已有授权,不必额外申请 Key。
+220
View File
@@ -0,0 +1,220 @@
---
title: CLI 安装与命令参考
pageTitle: CLI 安装与命令参考
eyebrow: 快速开始
lead: 使用 npm 版 CCR 在开发机或无桌面服务器上运行管理界面、模型网关,并按 Agent 配置启动本机工具。
---
## CLI 与桌面版命令的区别
CCR 有两个相关命令:
| 命令 | 来源 | 主要用途 |
| --- | --- | --- |
| `ccr` | npm 包 `@musistudio/claude-code-router` | 不依赖 Electron,启动浏览器管理界面、模型网关和 Agent 配置。 |
| `ccr-app` | CCR 桌面应用 | 桌面版生成的配置启动器;Agent配置卡片复制的命令使用这个名称。 |
两个发行版会读取同一套本机配置目录,但不要把命令名混用。需要托盘、桌面通知、自动更新和桌面专属浏览器集成时,使用桌面版;需要无桌面部署或由进程管理器托管时,使用 npm CLI。
## 安装、升级与卸载
CLI 要求 Node.js 22 或更高版本:
```sh
node --version
npm install -g @musistudio/claude-code-router
ccr --help
```
升级和卸载:
```sh
npm install -g @musistudio/claude-code-router@latest
npm uninstall -g @musistudio/claude-code-router
```
卸载 npm 包不会删除 CCR 的本地配置和数据库。
如果安装成功但找不到命令,执行 `npm prefix -g`,确认 npm 全局可执行目录已经加入 `PATH`,然后打开一个新终端。
## 第一次启动
在后台启动 CCR 并打开管理界面:
```sh
ccr ui
```
SSH 或无桌面环境使用:
```sh
ccr ui --no-open
```
随后按这个顺序完成配置:
1. 添加供应商和至少一个模型。
2.**API 密钥** 页面创建用于访问网关的 CCR 客户端 Key。
3. 按需要设置默认模型、路由规则和 Fallback。
4.**服务** 页面确认网关已经运行。
5. 把客户端 Base URL 指向界面显示的网关地址。
管理界面默认使用 `http://127.0.0.1:3458`,模型网关默认使用 `http://127.0.0.1:3456`。管理 Token 与 CCR 客户端 Key 是两种独立凭据:前者保护 UI / RPC,后者验证模型请求。
## 服务命令总览
| 命令 | 运行方式 | 用途 |
| --- | --- | --- |
| `ccr start` | 后台 | 启动管理服务和模型网关,打印带认证信息的管理 URL。 |
| `ccr ui` | 后台 | 复用或启动后台服务,并打开浏览器。 |
| `ccr stop` | 一次性 | 停止由 `start``ui` 启动的后台服务。 |
| `ccr serve` | 前台 | 在当前终端运行,适合查看日志或交给进程管理器。 |
| `ccr web` | 前台 | `serve` 的别名。 |
| `ccr <配置名称或 ID>` | 前台 | 启动一个已启用的 Agent 配置。 |
## `ccr start`
```text
ccr start [--host <host>] [--port <port>] [--open|--no-open] [--gateway|--no-gateway]
```
| 选项 | 说明 |
| --- | --- |
| `--host <host>` | 管理服务监听地址,默认 `127.0.0.1`。也接受 `--host=value`。 |
| `--port <port>` | 管理服务首选端口,默认 `3458`。也接受 `--port=value`。 |
| `--open` | 启动后打开浏览器。 |
| `--no-open` | 不打开浏览器。 |
| `--gateway` | 明确要求启动模型网关;这是默认行为。 |
| `--no-gateway` | 只启动管理服务,不在启动阶段拉起模型网关。 |
如果首选端口被占用,CCR 会继续尝试后续端口并打印实际 URL。端口必须是 `1``65535` 的整数。
## `ccr ui`
```text
ccr ui [--host <host>] [--port <port>] [--open|--no-open] [--gateway|--no-gateway]
```
`ui``start` 使用同一个后台服务,但默认会打开浏览器。管理 URL 包含 `ccr_web_token` 查询参数;请把完整 URL 当作密码,不要粘贴到日志、工单或公开截图。
## `ccr serve`
```text
ccr serve [--host <host>] [--port <port>] [--open|--no-open] [--gateway|--no-gateway]
```
`serve` 留在前台,收到 `SIGINT``SIGTERM` 后关闭管理服务和已配置服务。排查启动错误时优先使用它,因为错误会直接输出到当前终端。
`ccr stop` 只管理后台服务。前台 `serve` 应通过当前终端或外部进程管理器停止。
## 后台服务的复用规则
`start``ui` 会把进程 ID、URL 和私有服务 Token 写入 `service.json`。再次执行时,CCR 会先验证对应进程和 RPC 身份:
- 服务有效时直接复用,不会再启动第二个后台进程。
- 新传入的 Host、Port 和 `--no-gateway` 不会重配已经运行的进程。
- 如果新命令要求网关运行,CCR 会尝试在现有管理进程中启动网关。
- 状态文件失效或进程已经退出时,CCR 会清理旧状态并启动新服务。
需要修改监听参数时先执行:
```sh
ccr stop
ccr start --host 127.0.0.1 --port 3458
```
## 按 Agent 配置启动
先在 **Agent配置** 中创建并启用配置,然后使用:
```text
ccr <配置名称或 ID> [cli|app] [-- <Agent 参数>]
```
示例:
```sh
ccr "Codex - Work"
ccr "Codex - Work" app
ccr "Claude - Review" cli -- --model sonnet
ccr profile-id -- --help
```
规则如下:
- `--cli``--app` 可以替代位置形式的 `cli` / `app`
- Agent 自己的参数放到 `--` 后,避免与 CCR 选项或入口名冲突。
- 省略入口时,Claude Code、Codex、Grok CLI 默认使用 CLIZCode 默认使用 App。
- Grok 只支持 CLIZCode 只支持 App。
- Claude App 和 ZCode App 不支持额外 Agent 参数。
- 启动 App 需要本机安装对应桌面应用,并且当前环境有图形会话。
- 只有已启用的配置可以启动。名称产生歧义时使用配置 ID。
大多数配置要求 CCR 网关已经运行。Grok CLI 是例外:如果服务不存在,它可以自动启动一个受管的临时共享服务,并在最后一个 Grok 会话退出后关闭。
## 配置和数据位置
| 平台 | 配置目录 |
| --- | --- |
| macOS / Linux | `~/.claude-code-router` |
| Windows | `%APPDATA%\claude-code-router` |
常见文件和目录:
| 路径 | 用途 |
| --- | --- |
| `config.sqlite` | 当前应用配置。 |
| `app-data/` | API Key、用量、请求日志、证书等运行数据。 |
| `service.json` | 后台 CLI 服务状态和私有 Token。 |
| `gateway.config.json` | 生成的网关运行配置。 |
| `profiles/` | 按 Agent 配置隔离的文件。 |
| `bin/` | CCR 生成的 Agent 启动包装器。 |
不要在 CCR 运行时直接编辑或复制活跃 SQLite 文件。优先使用 **Settings → Export data**;文件级备份前先停止 CLI 和桌面应用。
## 环境变量与远程访问
公开的管理认证变量是:
| 变量 | 说明 |
| --- | --- |
| `CCR_WEB_HOST` | 省略 `--host` 时使用的管理服务监听地址。 |
| `CCR_WEB_PORT` | 省略 `--port` 时使用的管理服务端口。 |
| `CCR_WEB_AUTH_TOKEN` | 固定管理 UI / RPC Token;不设置时进程会生成随机 Token。 |
监听到 `0.0.0.0` 会让管理界面进入局域网或外部网络。只有在确实需要时才这样配置,并同时使用固定强 Token、主机防火墙或私网,以及可信反向代理提供的 TLS。
模型网关还需要单独创建 CCR 客户端 Key。上游供应商凭据保存在本地数据目录,因此目录和备份都应按敏感数据保护。
## 进程管理器示例
生产环境应使用 `ccr serve --no-open`,让外部管理器负责重启和日志。启动命令至少应固定工作用户、`HOME`、监听地址和 `CCR_WEB_AUTH_TOKEN`。不要同时运行由 `ccr start` 创建的后台服务,否则可能得到两个管理端口或竞争同一套配置。
## 常见问题
### UI 能打开,但 `/health` 或模型请求失败
管理服务可以在没有可用模型网关时运行。添加供应商和模型、创建 CCR 客户端 Key,然后从 **服务** 页面启动或重启网关。使用 `ccr serve` 查看启动错误。
### 实际管理端口不是 3458
3458 已被占用,CCR 使用了后续可用端口。以命令打印的 URL 为准;需要固定端口时,先停止冲突进程。
### 找不到 Agent 配置
确认配置已启用,并检查名称是否重复。CCR 会按 ID、名称、忽略大小写的名称和清理后的名称匹配;多个结果时必须使用 ID。
### 提示启动器不存在
先打开一次 CCR 或重新保存该 Agent 配置,让 CCR 重新生成 `bin/` 下的启动包装器。
### 后台服务无法停止
先运行 `ccr stop`。如果状态文件已经失效,命令会清理它并报告服务未运行。前台 `ccr serve` 不受 `ccr stop` 管理,应回到对应终端或进程管理器停止。
## 相关页面
- [安装并启动 CCR](../install/)
- [Agent配置](../../configuration/profile/)
- [服务配置](../../configuration/server/)
- [Docker 部署](../docker/)
+297
View File
@@ -0,0 +1,297 @@
---
title: Docker 部署
pageTitle: Docker 部署
eyebrow: 快速开始
lead: 使用 Nginx 单入口运行 CCR Core 和浏览器管理界面,并正确处理端口、鉴权、持久化、远程访问、备份和升级。
---
## 适用范围与限制
Docker 镜像适合常驻模型网关和浏览器管理。它包含 CCR Core、构建后的管理 UI、PM2 和 Nginx,但不包含:
- Electron 桌面应用、系统托盘和桌面通知;
- npm 发行版的 `ccr` 命令;
- 从容器中启动宿主机 Claude App、ChatGPT、ZCode 等桌面 App
- 桌面自动更新和桌面专属的内置浏览器集成。
如果主要需求是本机 Agent 多开、托盘或桌面 App 启动,请使用桌面版;如果需要终端命令但不需要容器,请使用 [CLI](../cli/)。
## 进程和端口拓扑
```text
宿主机 3458 -> 容器 Nginx 8080
|-> 静态管理 UI
|-> 管理 RPC127.0.0.1:3459
|-> 模型网关:127.0.0.1:3456
`-> Core Runtime127.0.0.1:3457
```
只应发布 Nginx 的容器端口 `8080``3459``3456``3457` 都是容器内部实现端口,不要分别映射到宿主机。
Nginx 对外提供:
| 路径 | 用途 |
| --- | --- |
| `/``/pages/home/index.html` | 管理 UI。根路径会跳转到带管理 Token 的页面。 |
| `/api/ccr/rpc` | 需要管理 Token 的管理 RPC。 |
| `/health` | 模型网关健康状态,不是容器或 UI 健康状态。 |
| `/v1/*``/v1beta/*``/messages``/chat/completions``/responses``/interactions``/mcp/*` | 模型和 MCP 网关接口。 |
## 使用 Compose 快速启动
在仓库根目录执行:
```sh
docker compose up -d --build
docker compose logs -f ccr
```
打开 <http://127.0.0.1:3458>。新数据卷上管理 UI 会立即可用;模型网关要在添加供应商和模型后才能正常启动。
首次配置顺序:
1. 添加供应商和至少一个模型。
2.**API 密钥** 页面创建 CCR 客户端 Key。
3.**服务** 页面启动网关。
4. 请求 `/health`,确认返回 `200` 和运行状态。
5. 把客户端 Base URL 指向 `http://127.0.0.1:3458`,并使用刚创建的 CCR 客户端 Key。
停止或移除容器不会自动删除命名卷:
```sh
docker compose stop
docker compose down
```
不要给 `docker compose down` 添加 `--volumes`,除非你明确要删除全部 CCR 数据。
## 只允许本机访问
仓库默认映射 `3458:8080` 会监听宿主机所有网卡。如果只从当前机器访问,修改为:
```yaml
services:
ccr:
ports:
- "127.0.0.1:3458:8080"
```
端口映射左侧是宿主机地址和端口,右侧是 Nginx 容器端口。不要把右侧改为内部网关的 `3456`
## 使用 `docker run`
不使用 Compose 时:
```sh
docker build -t claude-code-router:local .
docker run -d \
--name claude-code-router \
--restart unless-stopped \
-p 127.0.0.1:3458:8080 \
-e CCR_PUBLIC_BASE_URL=http://127.0.0.1:3458 \
-v ccr-data:/data \
claude-code-router:local
```
仓库也提供 `npm run docker:build``npm run docker:run`。后者使用 `3458``ccr-data`,但容器带 `--rm`,没有固定名称和自动重启策略,更适合临时验证。
## 三类凭据不要混用
| 凭据 | 用途 | 配置位置 |
| --- | --- | --- |
| `CCR_WEB_AUTH_TOKEN` | 管理 UI / RPC 鉴权 | 容器环境变量 |
| CCR 客户端 API Key | 模型网关请求鉴权 | UI 的 **API 密钥** 页面 |
| 上游供应商凭据 | CCR 调用模型供应商 | UI 的 **供应商** 页面 |
不设置 `CCR_WEB_AUTH_TOKEN` 时,EntryPoint 每次启动容器都会生成新的随机 Token。打开根地址仍可工作,因为 Nginx 会跳转到包含当前 Token 的 URL;但持久部署和远程部署应固定一个足够长的强 Token。
不要把 Token 直接写进 Shell 历史。可以创建不进入版本控制的环境文件:
```dotenv
CCR_WEB_AUTH_TOKEN=replace-with-a-long-random-value
CCR_PUBLIC_BASE_URL=http://127.0.0.1:3458
```
通过 `docker run --env-file` 使用,或把同名变量映射到 Compose 服务的 `environment`。包含 `ccr_web_token` 的完整管理 URL 也应按密码保护,因为它可能出现在浏览器历史、反向代理日志、截图和工单中。
## 修改外部端口或地址
宿主机对外地址与容器内部端口是两层配置。修改宿主机端口时,还要把 `CCR_PUBLIC_BASE_URL` 设置为客户端真实使用的完整地址:
```yaml
services:
ccr:
ports:
- "127.0.0.1:8088:8080"
environment:
CCR_PUBLIC_BASE_URL: http://127.0.0.1:8088
CCR_WEB_AUTH_TOKEN: ${CCR_WEB_AUTH_TOKEN:?set CCR_WEB_AUTH_TOKEN}
```
`CCR_PUBLIC_BASE_URL` 会同步到 CCR 的公开 Router Endpoint。它本身不会发布 Docker 端口,也不会改变 Nginx 监听地址。
## 域名、HTTPS 与反向代理
由反向代理或 Ingress 终止 TLS 时:
```yaml
services:
ccr:
ports:
- "127.0.0.1:3458:8080"
environment:
CCR_PUBLIC_BASE_URL: https://ccr.example.com
CCR_WEB_AUTH_TOKEN: ${CCR_WEB_AUTH_TOKEN:?set CCR_WEB_AUTH_TOKEN}
```
反向代理应把全部路径交给 CCR Nginx,并满足:
- 支持长时间模型请求;
- 不缓冲 SSE 和流式模型响应;
- 允许足够的请求体大小;
- 只有反向代理入口对外公开,宿主机 `3458` 保持仅本机监听;
- 配合防火墙、VPN / 私网或额外访问控制,避免管理界面直接暴露到不可信网络。
## 持久化目录
EntryPoint 会设置 `HOME=/data`,实际数据位于:
```text
/data/.claude-code-router/
├── config.sqlite
├── gateway.config.json
├── app-data/
│ ├── api-keys.sqlite
│ ├── request-logs.sqlite
│ ├── usage.sqlite
│ └── certs/
├── profiles/
└── bin/
```
优先使用命名卷。Bind Mount 目录必须允许容器写入,而且不能让两个运行中的 CCR 容器共享同一份数据。
全新数据目录中既没有 `config.json` 也没有 `config.sqlite` 时,EntryPoint 默认写入最小的旧格式 `config.json` 作为首次引导。UI 保存后 SQLite 成为权威配置。每次启动默认还会把 JSON / SQLite 中的网关监听字段和 `routerEndpoint` 同步到当前 Docker 公开地址。
## 备份与恢复
应用级备份优先使用 **Settings → Export data**。做完整文件备份时,先停止写入:
```sh
docker compose stop ccr
docker compose cp ccr:/data/. ./ccr-data-backup/
docker compose start ccr
```
备份包含供应商凭据、CCR 客户端 Key,并可能包含请求 / 响应数据,必须按敏感数据保存。
完整恢复时,应把备份复制到新的空卷或空 `/data` 目录,并确保容器已停止。不要把旧备份直接覆盖到仍有新数据的活动目录,否则旧 SQLite WAL / SHM 和新运行文件可能混合。替换现有数据前再做一份备份。
## 升级与回滚
先备份 `/data`,再更新源码、刷新基础镜像并重建:
```sh
git pull
docker compose build --pull
docker compose up -d
docker compose ps
docker compose logs --tail=200 ccr
```
升级会对持久化数据执行当前版本需要的迁移。回滚时应同时使用旧镜像 / 旧源码和升级前备份,不要假设旧版本一定能读取新版本数据库。
## 环境变量完整参考
一般部署只需要设置 `CCR_WEB_AUTH_TOKEN``CCR_PUBLIC_BASE_URL` 和 Docker Port Mapping。内部监听变量通常不需要修改。
| 变量 | 默认值 | 说明 |
| --- | --- | --- |
| `CCR_WEB_AUTH_TOKEN` | 每次启动随机生成 | 管理 UI / RPC Token。持久或远程部署应设置固定强值。 |
| `CCR_PUBLIC_BASE_URL` | `http://127.0.0.1:3458` | 写入 CCR 配置的完整公开地址;设置后优先于 Public Host / Port。 |
| `CCR_PUBLIC_HOST` | `127.0.0.1` | 仅在没有完整公开 URL 时用于拼接公开地址,不会改变 Docker 端口绑定。 |
| `CCR_PUBLIC_PORT` | `3458` | 仅在没有完整公开 URL 时用于拼接公开地址。 |
| `CCR_DATA_DIR` | `/data` | 数据根目录,同时作为进程 `HOME`。 |
| `CCR_NGINX_PORT` | `8080` | Nginx 容器内监听端口,应与 Port Mapping 右侧一致。 |
| `CCR_WEB_HOST` | `127.0.0.1` | 管理服务容器内监听地址。 |
| `CCR_WEB_PORT` | `3459` | 管理服务容器内端口。 |
| `CCR_GATEWAY_HOST` | `127.0.0.1` | 模型网关容器内监听地址。 |
| `CCR_GATEWAY_PORT` | `3456` | Nginx 转发到的模型网关容器内端口。 |
| `CCR_GATEWAY_CORE_PORT` | `3457` | Core Gateway Runtime 容器内端口。 |
| `CCR_NO_GATEWAY` | `0` | 设为 `1``true``yes` 时,启动阶段只运行管理 UI。 |
| `CCR_DOCKER_INIT_CONFIG` | `1` | 设为 `0` 时禁用首次最小 `config.json` 引导。 |
| `CCR_DOCKER_SYNC_PUBLIC_ENDPOINT` | `1` | 设为 `0` 时不再在启动时同步已有 JSON / SQLite 的监听和公开地址字段。 |
修改内部端口需要同时保证 PM2 和 Nginx 变量一致,正常部署没有收益。对外仍然只发布 `CCR_NGINX_PORT`
## 构建和烟雾测试
默认使用 `node:22-bookworm` 构建原生依赖,再把生产依赖和构建产物复制到 `node:22-bookworm-slim`。需要替换基础镜像时:
```sh
docker build \
--build-arg NODE_IMAGE=node:22-bookworm \
--build-arg RUNTIME_NODE_IMAGE=node:22-bookworm-slim \
-t claude-code-router:local .
```
运行 Docker 烟雾测试:
```sh
npm run test:docker
```
测试会创建临时容器和数据卷,检查单一 Nginx 端口、UI / RPC 鉴权、公开地址迁移、网关启动和 `/health`,最后自动清理。使用 `CCR_DOCKER_TEST_SKIP_BUILD=1` 复用已有镜像,或通过 `CCR_DOCKER_TEST_IMAGE` 指定本地 Tag。
## 日常运维命令
```sh
docker compose ps
docker compose logs -f ccr
docker compose restart ccr
docker compose config
```
`docker compose ps` 显示的是容器健康;`/health` 显示的是模型网关健康。两者不能互相替代。
## 常见问题
### 根地址返回 `302`
这是正常行为。Nginx 正在把根地址跳转到带 URL 编码管理 Token 的页面。
### `/health` 返回 `502`
它检查模型网关,不检查 Nginx 或 UI。新数据卷尚未配置供应商 / 模型时会返回 `502`。先打开 UI 完成配置并启动网关。
### 修改 Token 后 UI 返回 `401`
重新打开不带参数的根地址,让 Nginx 生成包含新 Token 的 URL;关闭仍使用旧 `ccr_web_token` 的标签页和书签。
### 客户端仍使用旧端口或域名
更新 `CCR_PUBLIC_BASE_URL` 并重新创建容器。保持 `CCR_DOCKER_SYNC_PUBLIC_ENDPOINT=1`,让已有 SQLite 配置在启动时同步。
### 重建后配置消失
确认 `/data` 仍挂载同一个命名卷或 Bind Mount。`docker compose down` 保留卷,`docker compose down --volumes` 删除卷。
### Bind Mount 权限错误
确认宿主机目录存在、容器可写且没有只读挂载。命名卷通常可以避免宿主机 UID、所有权和安全标签问题。
### 容器健康,但模型请求失败
容器健康只代表 Nginx / UI 可访问。继续检查 **服务** 状态、供应商连通性、CCR 客户端 Key、路由和请求日志,并查看:
```sh
docker compose logs --tail=200 ccr
```
## 相关页面
- [安装并启动 CCR](../install/)
- [CLI 安装与命令参考](../cli/)
- [服务配置](../../configuration/server/)
- [API 密钥](../../configuration/api-keys/)
+56 -7
View File
@@ -2,17 +2,66 @@
title: 安装并启动 CCR
pageTitle: 安装并启动 CCR
eyebrow: 快速开始
lead: 下载桌面应用,安装后启动本地 CCR 服务
lead: 根据桌面版、npm CLI 或 Docker 的运行场景选择安装方式,并确认管理界面与模型网关的不同地址
---
## 下载安装
## 选择发行方式
| 方式 | 适合场景 | 入口 | 默认管理地址 | 默认网关地址 |
| --- | --- | --- | --- | --- |
| 桌面应用 | 日常本机使用、托盘、多开 Agent App、桌面集成 | 应用界面、`ccr-app` | 应用内窗口 | `http://127.0.0.1:3456` |
| npm CLI | 终端、SSH、无 Electron 环境、进程管理器 | `ccr` | `http://127.0.0.1:3458` | `http://127.0.0.1:3456` |
| Docker | 常驻服务器、容器运维、统一浏览器入口 | Nginx | 与网关共用公开地址 | `http://127.0.0.1:3458`(默认端口映射) |
管理 UI 地址和模型网关地址在桌面版 / CLI 中不是同一个端口。不要把 CLI 的管理端口 `3458` 当成默认模型网关端口;Docker 才通过 Nginx 把两者合并到同一公开入口。
## 安装桌面应用
1. 打开 [GitHub Releases](https://github.com/musistudio/claude-code-router/releases) 页面。
2.你的系统下载安装包macOS 使用 `.dmg``.zip`Windows 使用 `.exe`Linux 使用 `.AppImage`
3. 像普通桌面软件一样安装并打开 **Claude Code Router**
2. 按系统下载:macOS 使用 `.dmg``.zip`Windows 使用 `.exe`Linux 使用 `.AppImage`
3. 安装并打开 **Claude Code Router**
4. 添加供应商和模型,在 **API 密钥** 中创建客户端 Key,然后从 **服务** 页面点击 **启动**
## 启动服务
页面显示运行中后,模型网关默认监听 `http://127.0.0.1:3456`。需要打开应用时自动启动网关,可在 **服务** 页面开启自动启动。
进入 **Server** 页面,点击 **Start**。页面显示 Running 后,CCR 会在本机监听默认地址 `http://localhost:8080`
## 安装 npm CLI
如果希望打开 App 后自动启动服务,可以在 Server 页面开启 **Auto start**
要求 Node.js 22 或更高版本:
```sh
npm install -g @musistudio/claude-code-router
ccr ui
```
`ccr ui` 会启动后台服务并打开浏览器。无桌面环境使用 `ccr ui --no-open`,生产前台托管使用 `ccr serve --no-open`。完整命令和 Profile 启动说明见 [CLI 安装与命令参考](../cli/)。
## 使用 Docker
在源码仓库根目录执行:
```sh
docker compose up -d --build
```
打开 <http://127.0.0.1:3458>。Docker 只发布 Nginx 单入口,管理 UI 和模型网关共用该地址。首次启动后仍需添加供应商 / 模型、创建 CCR 客户端 Key,并从 **服务** 页面启动网关。端口、鉴权、持久化、备份和远程部署见 [Docker 部署](../docker/)。
## 验证安装
完成供应商、模型和 CCR 客户端 Key 配置后:
1.**服务** 页面确认状态为运行中。
2. 请求当前部署的 `/health`;成功时应返回 `200` 和运行状态。
3. 用 CCR 客户端 Key 向兼容路径发送一个最小模型请求。
4.**日志** 页面确认请求模型、最终供应商 / 模型、状态码和耗时。
管理界面能打开并不代表模型网关已经可用。没有供应商 / 模型时,Docker 的 `/health` 返回 `502` 属于预期行为。
## 数据位置
| 方式 | 配置位置 |
| --- | --- |
| 桌面 / CLImacOS、Linux | `~/.claude-code-router` |
| 桌面 / CLIWindows | `%APPDATA%\claude-code-router` |
| Docker | `/data/.claude-code-router`,应持久化挂载 `/data` |
CCR 当前配置存储在 `config.sqlite` 中;`config.json` 只在没有 SQLite 配置时作为旧版迁移或 Docker 首次引导来源。不要在 CCR 运行时直接编辑 SQLite。
+6 -5
View File
@@ -12,7 +12,7 @@ lead: 了解 CCR 的定位、能力边界和文档结构。需要动手配置时
| 分类 | 内容 |
| --- | --- |
| [文档](./) | 产品定位、架构概览、阅读路径 |
| [快速开始](guides/) | 从安装、接供应商,到接入 Agent 的上手流程 |
| [快速开始](guides/) | 桌面版、CLI、Docker 安装部署,以及供应商和 Agent 接入流程 |
| [详细配置](configuration/overview/) | 概览仪表盘、API 密钥、服务、供应商、路由、Agent配置、Fusion、Bot、托盘和配置数据库位置 |
| [Q&A](troubleshooting/) | 请求日志、观测面板和常见问题 |
@@ -22,9 +22,10 @@ Bot 平台教程是「详细配置」分类下的子页面,每个平台有独
第一次使用时可以从这些页面了解 CCR 的主要流程:
1. [快速开始](guides/) 覆盖供应商接入和 Agent配置
2. App 的请求日志页面展示请求是否经过 CCR
3. [详细配置](configuration/overview/) 覆盖概览仪表盘、API 密钥、服务、供应商、图像、联网搜索、MCP 工具、托盘和 IM 接力
4. [Q&A](troubleshooting/) 覆盖 401、404、超时、路由不对或 Bot 收不到消息等常见问题
1. [安装页](guides/install/)选择桌面版、npm CLI 或 Docker;对应细节见 [CLI](guides/cli/) 和 [Docker](guides/docker/) 页面
2. [快速开始](guides/) 继续覆盖供应商接入和 Agent配置
3. App 的请求日志页面展示请求是否经过 CCR
4. [详细配置](configuration/overview/) 覆盖概览仪表盘、API 密钥、服务、供应商、图像、联网搜索、MCP 工具、托盘和 IM 接力
5. [Q&A](troubleshooting/) 覆盖 401、404、超时、路由不对或 Bot 收不到消息等常见问题。
这样文档不会挤在一个长页面里,后续也能按顶部分类逐步扩展。
+8
View File
@@ -40,6 +40,8 @@ export const docsContent = {
icon: "book",
items: [
"安装并启动 CCR",
"CLI 安装与命令参考",
"Docker 部署",
"接入供应商",
"接入 Agent配置",
"日志&观测",
@@ -51,6 +53,8 @@ export const docsContent = {
sidebarChildren: {},
sidebarLinks: {
"安装并启动 CCR": "/guides/install/",
"CLI 安装与命令参考": "/guides/cli/",
"Docker 部署": "/guides/docker/",
: "/guides/provider/",
"接入 Agent配置": "/guides/agent-profile/",
"日志&观测": "/guides/observability/",
@@ -197,6 +201,8 @@ export const docsContent = {
icon: "book",
items: [
"Install And Start CCR",
"CLI Installation And Reference",
"Docker Deployment",
"Add A Provider",
"Connect Agent Config",
"Logs & Observability",
@@ -208,6 +214,8 @@ export const docsContent = {
sidebarChildren: {},
sidebarLinks: {
"Install And Start CCR": "/en/guides/install/",
"CLI Installation And Reference": "/en/guides/cli/",
"Docker Deployment": "/en/guides/docker/",
"Add A Provider": "/en/guides/provider/",
"Connect Agent Config": "/en/guides/agent-profile/",
"Logs & Observability": "/en/guides/observability/",
+2
View File
@@ -5,6 +5,8 @@ import { enGuideDocs, sectionSlugFromPath } from "../../../section-docs";
export function getStaticPaths() {
const activeLabels: Record<string, string> = {
install: "Install And Start CCR",
cli: "CLI Installation And Reference",
docker: "Docker Deployment",
provider: "Add A Provider",
"agent-profile": "Connect Agent Config",
observability: "Logs & Observability",
+2
View File
@@ -5,6 +5,8 @@ import { sectionSlugFromPath, zhGuideDocs } from "../../section-docs";
export function getStaticPaths() {
const activeLabels: Record<string, string> = {
install: "安装并启动 CCR",
cli: "CLI 安装与命令参考",
docker: "Docker 部署",
provider: "接入供应商",
"agent-profile": "接入 Agent配置",
observability: "日志&观测",
+6
View File
@@ -1318,6 +1318,12 @@ h1 {
--provider-brand-3: #f4f4f5;
}
.doc-markdown a.provider-import-button.provider-unity2 {
--provider-brand: #050505;
--provider-brand-2: #7a7f85;
--provider-brand-3: #f4f5f6;
}
.doc-markdown a.provider-import-button.provider-code0 {
--provider-brand: #101214;
--provider-brand-2: #267dff;