@timo972/cc-router 0.12.1-rc.1 → 0.12.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 (3) hide show
  1. package/CHANGELOG.md +9 -1
  2. package/README.md +99 -643
  3. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -8,13 +8,16 @@ This project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
8
8
 
9
9
  ## [Unreleased]
10
10
 
11
+ ---
12
+
13
+ ## [0.12.1] — 2026-09-14
14
+
11
15
  ### Added
12
16
 
13
17
  - Dashboard `Ctrl+R` confirms redemption of one banked usage-limit reset for
14
18
  the focused ChatGPT account, with duplicate-submission protection and stable
15
19
  retry IDs for uncertain outcomes. No custom Meta key mapping is needed.
16
20
  Account usage is refreshed after redemption.
17
-
18
21
  - Dashboard `[R]` reloads account usage and due tokens without restarting the
19
22
  router or dropping active requests and sticky sessions. It also refreshes
20
23
  Grok snapshots, CLI routing state, and an already-loaded model list, with
@@ -28,6 +31,10 @@ This project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
28
31
 
29
32
  ### Changed
30
33
 
34
+ - Streamlined the README and split detailed setup and reference material into
35
+ dedicated guides, including the full dashboard UI and keybindings, first-class
36
+ Codex CLI setup, and Grok/xAI account monitoring (overview-only, not proxied).
37
+ Updated the dashboard screenshot with anonymized account names.
31
38
  - The configured proxy request timeout now bounds Codex response headers and
32
39
  upstream stream inactivity on both `/v1/responses` and OpenAI-routed
33
40
  `/v1/messages`, including failover attempts. Progressing streams can outlive
@@ -714,6 +721,7 @@ cache-aware session routing and a round of security hardening.
714
721
  - `http-proxy-middleware` 3.0.5 → 3.0.7 for GHSA-gcq2-9pq2-cxqm (high). The
715
722
  affected APIs are not used here.
716
723
 
724
+ [0.12.1]: https://github.com/Timo972/cc-router/releases/tag/v0.12.1
717
725
  [0.12.0]: https://github.com/Timo972/cc-router/releases/tag/v0.12.0
718
726
  [0.11.0]: https://github.com/Timo972/cc-router/releases/tag/v0.11.0
719
727
  [0.9.0]: https://github.com/Timo972/cc-router/releases/tag/v0.9.0
package/README.md CHANGED
@@ -1,695 +1,151 @@
1
+ <div align="center">
2
+
1
3
  # CC-Router
2
4
 
3
- **Local multi-account router for Claude Max and OpenAI ChatGPT/Codex subscriptions.**
4
- Distribute Claude Code requests across Claude subscriptions, and expose an OpenAI Responses-compatible route for Codex CLI through the same proxy.
5
+ **One local proxy. All of your Claude and ChatGPT subscriptions.**
6
+
7
+ Route Claude Code, Codex CLI and Claude Desktop across every subscription you own —
8
+ cache-aware, with automatic failover, and without changing how you work.
5
9
 
6
10
  [![npm](https://img.shields.io/npm/v/@timo972/cc-router)](https://www.npmjs.com/package/@timo972/cc-router)
7
11
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
12
+ [![Node](https://img.shields.io/badge/node-%E2%89%A520-brightgreen)](https://nodejs.org)
8
13
 
9
- > **An actively maintained fork of [VictorMinemu/CC-Router](https://github.com/VictorMinemu/CC-Router)**, published as
10
- > [`@timo972/cc-router`](https://www.npmjs.com/package/@timo972/cc-router) with bug fixes and added features — most
11
- > notably **cache-aware sticky session routing**, which pins each Claude Code session to one account so a conversation
12
- > keeps hitting the same prompt cache instead of scattering its shared prefix across accounts. Also includes
13
- > load-aware account leases, byte-transparent streaming fixes, and a round of security hardening.
14
- > See [CHANGELOG.md](CHANGELOG.md) for the full list.
14
+ [Quickstart](#quickstart) · [Documentation](docs/) · [Changelog](CHANGELOG.md) · [Disclaimer](#disclaimer)
15
15
 
16
16
  ![CC-Router Dashboard](assets/dashboard.png)
17
17
 
18
- ### Features
19
-
20
- - **Cache-aware session routing** — keep each Claude Code session on one account while distributing new sessions across 2-20 Claude Max accounts
21
- - **Multi-provider routing** — route `openai/*` and unprefixed `gpt-*` models to OpenAI ChatGPT/Codex subscription accounts and Claude models to Claude subscriptions
22
- - **Transparent Claude proxy** — Claude Code works normally; streaming, thinking, tool use, prompt caching all pass through
23
- - **Codex CLI support** — configure Codex to use CC-Router as a Responses-compatible provider
24
- - **Automatic token refresh** — OAuth tokens are refreshed before they expire, saved atomically to disk
25
- - **Model-aware rate limits** — avoids accounts whose requested-model or global allowance is exhausted, and respects scoped cooldowns
26
- - **Automatic failover & retry** — a 429 fails over to another account and a 5xx is retried inside the router, before any response byte is relayed, on both the Claude and Codex routes; on by default, opt out with `"autoFailover": false`
27
- - **Client mode** — connect another device you own to your private CC-Router (`cc-router client connect <url>`)
28
- - **Claude Desktop support** — route Cowork / Agent-mode traffic through CC-Router via mitmproxy interception (macOS, Windows, Linux)
29
- - **Guided setup wizard** — interactive `cc-router setup` extracts tokens from Keychain or credentials file, configures everything
30
- - **Live dashboard** — real-time terminal UI showing account health, request counts, token usage, recent activity
31
- - **Proxy authentication** — Bearer / x-api-key secret; required when binding a non-loopback interface
32
- - **Update notifications** — new releases are announced in the CLI; installing is opt-in (`autoUpdate: true`)
33
- - **Multiple deployment modes** — background daemon, native OS auto-start (launchd/systemd), foreground, Docker Compose
34
- - **Cross-platform** — macOS, Linux, Windows; Node.js 20+
18
+ </div>
35
19
 
36
20
  ---
37
21
 
38
- > **Warning**
39
- > Read the [disclaimer](#disclaimer) before using this tool.
22
+ ## Why
40
23
 
41
- ---
24
+ One Claude Max subscription is one rate limit. If you spend your day in Claude Code you
25
+ know the shape of it: a long session, a wall of `429`, and a cooldown you have to sit out.
26
+ Current Claude Code builds no longer retry rate limits themselves, so it surfaces as an
27
+ error mid-conversation.
42
28
 
43
- ## How it works
29
+ CC-Router is a local proxy that sits between your tooling and the providers. It spreads
30
+ sessions across every subscription you own and fails a rate-limited request over to
31
+ another account *before a single response byte reaches the client*.
44
32
 
33
+ ```text
34
+ 1 account → hit the limit, the session errors out
35
+ 3 accounts → sessions spread across all three; a 429 fails over mid-flight
45
36
  ```
46
- Claude Code (terminal) ─┐
47
- │ ANTHROPIC_BASE_URL=http://localhost:3456
48
-
49
- Claude Desktop ─[mitmproxy]─┐ (optional — intercepts api.anthropic.com)
50
-
51
-
52
- ┌─────────────────────────────────────┐
53
- │ CC-Router :3456 │
54
- │ │
55
- │ 1. Receives /v1/messages or │
56
- │ /v1/responses │
57
- │ 2. Parses model provider prefix │
58
- │ 3. Picks a Claude or OpenAI account│
59
- │ 4. Refreshes token if expiring │
60
- │ 5. Injects Authorization: Bearer │
61
- │ 6. Forwards to Anthropic, OpenAI │
62
- │ Codex backend, or LiteLLM │
63
- └──────────────┬──────────────────────┘
64
-
65
-
66
- api.anthropic.com
67
- (authenticated with
68
- OAuth token of account N)
69
- ```
70
-
71
- All standard Claude Code features work transparently on the Claude route: streaming, extended thinking, tool use, prompt caching. OpenAI subscription routing is available for Codex-compatible Responses requests and Claude Code cross-routing with the limitations documented below.
72
37
 
73
- ### Cache-aware Claude account routing
38
+ The part that makes it usable day to day: each conversation stays **pinned to one
39
+ account**. A Claude Code turn resends its whole prior context, and Anthropic caches that
40
+ prefix *per account* — scatter the turns and you re-pay for the cache every time. CC-Router
41
+ distributes *new* sessions instead of individual requests, so your cache stays warm.
74
42
 
75
- CC-Router keeps requests from one Claude Code session on the same eligible Anthropic subscription account. This session affinity remains account-based and preserves prompt-cache locality instead of scattering a conversation's shared prefix across account-specific caches. The model requested by each Messages call affects whether the bound account is still eligible; changing models does not create a second binding, but it can make the existing binding fail over when that account cannot serve the new model. New sessions prefer the account with the fewest in-flight requests, then the fewest bound sessions, then included allowance over paid extra usage, then the most applicable global and requested-model headroom; exact ties use a rotating round-robin order.
43
+ Everything else is unchanged. Same `claude`, same `codex`, same streaming, extended
44
+ thinking, tool use and prompt caching — passed through byte for byte.
76
45
 
77
- Anthropic cooldowns, effective global or requested-model quota exhaustion, disabled accounts, invalid authentication, and unhealthy accounts are hard exclusions. The configured per-account percentage caps are softer policy controls: when at least one account is otherwise usable but every usable account is over a configured cap, CC-Router may explicitly fall back to the least-loaded capped account. It never uses that fallback to bypass an Anthropic cooldown or exhausted effective quota.
46
+ ## Features
78
47
 
79
- If an upstream account returns 429 or any 5xx before a single response byte has been relayed, CC-Router applies the failure's cooldown and affinity bookkeeping and then retries the request itself, up to 3 upstream attempts per request. A 429 (or an overload the provider cools down: Anthropic 529; Codex 503/529) always fails over to a *different* account. Any other 5xx keeps a session-bound request on its own account, retrying after a short pause; a session-less request re-routes the way a fresh request would typically an idle other account, exactly where the client's own retry used to land. The failover is on by default; set `"autoFailover": false` in `~/.cc-router/config.json` (and restart the router) to opt out — every upstream failure then passes through unchanged and clients own all retries, as before. Be aware that current Claude Code builds no longer retry 429s themselves, so with failover off a rate limit surfaces directly in the session as an error. One trade-off worth knowing: once the router commits to a retry it abandons the original failure response, so a network error on the retry attempt surfaces as a local 502 rather than the original 429. When no other account is eligible or the budget is exhausted, the last failed upstream response is passed through unchanged, exactly as before. A 401 is always passed through (with a background token refresh), and the router never retries after response bytes have started — mid-stream failures reach the client untouched. If no account is usable before forwarding begins, the router instead returns a local Anthropic-shaped 429 whenever any account is blocked by a rate limit or exhausted quota. That 429 includes `Retry-After` only when a trustworthy unblock time is known. A local 503 is reserved for entirely non-rate-limit unavailability, such as all accounts being disabled or unhealthy. Either local response makes no Anthropic Messages request. Affinity mappings exist only in process memory, expire after one hour of inactivity, and are capped in size. Session IDs are never persisted or logged.
48
+ - **Cache-aware session routing**pins each session to one account, spreads new sessions across 2–20 accounts ([details](docs/session-routing.md))
49
+ - **Automatic failover & retry** — a `429` moves to another account, a `5xx` is retried in-router, always before the first response byte
50
+ - **Multi-provider routing** — model prefixes send `claude/*` to Claude subscriptions and `openai/*` / `gpt-*` to ChatGPT/Codex ([details](docs/codex.md))
51
+ - **Model-aware rate limits** — skips accounts whose global or per-model allowance is spent, and respects scoped cooldowns
52
+ - **Automatic token refresh** — OAuth tokens refresh before expiry and are written atomically ([details](docs/oauth-tokens.md))
53
+ - **Live dashboard** — terminal UI for account health, usage windows, live activity, and routing toggles ([details](docs/dashboard.md))
54
+ - **Grok CLI overview** — your Grok/xAI subscription's plan and session state in the same dashboard, alongside the accounts that are routed ([details](docs/grok.md))
55
+ - **Guided setup** — `cc-router setup` pulls tokens from the Keychain or credentials file and wires up your clients
56
+ - **Client mode** — point another device you own at your private router ([details](docs/client-mode.md))
57
+ - **Flexible deployment** — background daemon, native auto-start (launchd/systemd), foreground, or Docker Compose ([details](docs/installation.md))
58
+ - **Locked down by default** — tokens stay on your machine, proxy auth is required on non-loopback binds ([details](docs/security.md))
80
59
 
81
- Streaming remains byte-transparent. In particular, CC-Router never appends a synthetic `message_stop` event. `proxyRequestTimeoutMs` protects only the phase before Anthropic response headers arrive; once a response starts, its body continues through the native byte-exact proxy pipe. Automatic `cc-router configure` setup manages Claude Code's event-level and byte-level stream idle watchdogs at 30 minutes. Restart any existing Claude Code process after configuration so it inherits those values.
60
+ ## Supported platforms and harnesses
82
61
 
83
- **Claude Desktop support** is opt-in and requires a small interceptor (mitmproxy) because Claude Desktop doesn't expose a custom API endpoint setting. See [Claude Desktop support](#claude-desktop-support).
62
+ **Routed** requests are proxied to these:
84
63
 
85
- ---
64
+ | Platform | Auth | Route |
65
+ |---|---|---|
66
+ | Claude Max / Pro subscriptions | OAuth (subscription) | `/v1/messages` |
67
+ | OpenAI ChatGPT / Codex subscriptions | OAuth device code | `/v1/responses` |
68
+ | Anything LiteLLM supports (optional) | API keys, via LiteLLM | `/v1/messages` ([setup](docs/litellm-setup.md)) |
86
69
 
87
- ## Use cases
70
+ **Monitored** tracked and shown in the dashboard, not proxied:
88
71
 
89
- ### Heavy user one account isn't enough
72
+ | Platform | Auth | What you get |
73
+ |---|---|---|
74
+ | Grok / xAI subscriptions | Device code, or import from Grok CLI | Plan, code access, active sessions, token health ([details](docs/grok.md)) |
90
75
 
91
- Claude Max has rate limits per account. If you hit them regularly mid-session — waiting for cooldowns, getting 429s — you're a good candidate.
76
+ **Harnesses**
92
77
 
93
- With two accounts you double your effective rate limit. With three, you triple it. The proxy distributes requests automatically; you don't change how you use Claude Code at all.
94
-
95
- ```text
96
- 1 account → hit limit, session errors out (current Claude Code no longer retries 429s)
97
- 3 accounts → sessions spread across all three; a rate-limited request fails over mid-flight
98
- ```
99
-
100
- ---
78
+ | Harness | Support | Notes |
79
+ |---|---|---|
80
+ | Claude Code | First class | Configured automatically by `cc-router setup` |
81
+ | Codex CLI | First class | Configured by `cc-router configure codex` ([setup](docs/codex.md)) |
82
+ | Claude Desktop (chat + Cowork) | Opt-in | Needs a mitmproxy interceptor ([setup](docs/claude-desktop.md)) |
83
+ | Any Anthropic Messages client | Works | Point `ANTHROPIC_BASE_URL` at the router |
84
+ | Any OpenAI Responses client | Works | Point the base URL at `/v1` |
101
85
 
102
86
  ## Quickstart
103
87
 
88
+ Requires **Node.js 20 or 22** on macOS, Linux or Windows.
89
+
104
90
  ```bash
105
91
  # 1. Install
106
92
  npm install -g @timo972/cc-router
107
93
 
108
- # 2. Wizard: extract tokens + configure Claude Code automatically
94
+ # 2. Extract tokens and configure your clients
109
95
  cc-router setup
110
96
 
111
97
  # 3. Start the proxy
112
98
  cc-router start
113
99
 
114
- # 4. Use Claude Code normally — the proxy is transparent
100
+ # 4. Use Claude Code as usual — the proxy is transparent
115
101
  claude
116
102
  ```
117
103
 
118
- That's it. Claude Code will route through the proxy without any further changes.
119
-
120
- On first run, `cc-router start` asks how you want to run (background/foreground, auto-start on boot, server mode) and remembers your choice. Next time, it just starts. To change preferences later:
121
- ```bash
122
- cc-router start --reconfigure
123
- ```
124
-
125
- ---
126
-
127
- ## Installation
128
-
129
- **Requirements:** Node.js 20 or 22.
130
-
131
- ```bash
132
- npm install -g @timo972/cc-router
133
- ```
134
-
135
- Verify:
136
- ```bash
137
- cc-router --version
138
- ```
139
-
140
- ---
141
-
142
- ## Setup by platform
143
-
144
- ### macOS
145
-
146
- cc-router can extract OAuth tokens directly from the macOS Keychain — no manual copy-pasting needed.
147
-
148
- ```bash
149
- cc-router setup
150
- # Select "Extract automatically from macOS Keychain"
151
- ```
152
-
153
- For multiple accounts, you need to switch accounts in Claude Code between extractions:
154
- ```bash
155
- # Account 1 is already logged in — run setup and extract
156
- cc-router setup
157
-
158
- # To add account 2:
159
- claude logout && claude login # log in with account 2
160
- cc-router setup --add # extract and merge
161
- claude logout && claude login # log back in with account 1
162
- ```
163
-
164
- ### Linux
165
-
166
- Tokens are read from `~/.claude/.credentials.json`:
167
- ```bash
168
- cc-router setup
169
- # Select "Read from ~/.claude/.credentials.json"
170
- ```
171
-
172
- Make sure Claude Code is installed and you have run `claude login` at least once.
173
-
174
- ### Windows
175
-
176
- Same as Linux — tokens are read from `~/.claude/.credentials.json` (Windows path: `%USERPROFILE%\.claude\.credentials.json`).
177
-
178
- ```bash
179
- cc-router setup
180
- ```
181
-
182
- ---
183
-
184
- ## CLI Reference
185
-
186
- ```text
187
- cc-router setup Interactive wizard: extract tokens + configure Claude Code
188
- cc-router setup --add Add another account to an existing configuration
189
-
190
- cc-router start Start proxy (asks preferences on first run, then remembers)
191
- cc-router start --foreground Run in the foreground (stays in terminal)
192
- cc-router start --reconfigure Re-ask run preferences (background/service/server mode)
193
- cc-router start --litellm Start with LiteLLM in Docker (advanced mode)
194
-
195
- cc-router stop Stop proxy (offers to remove auto-start / config)
196
- cc-router stop --keep-config Stop proxy only (keep settings.json)
197
- cc-router stop --full Stop + remove auto-start + revert Claude Code (no prompts)
198
- cc-router revert Same as stop --full
199
-
200
- cc-router status Live dashboard (updates every 2s, press q to quit)
201
- cc-router status --json Print current stats as JSON and exit
202
-
203
- cc-router models list List models discovered live from provider APIs
204
- cc-router models list --json Print discovered models + routing as JSON
205
- cc-router models set --claude-model anthropic/claude-sonnet-4-6
206
- cc-router models set --openai-model openai/gpt-5-codex
207
-
208
- cc-router logs View proxy logs (background mode)
209
- cc-router logs -f Follow log output in real time
210
- cc-router logs --lines 100 Show last 100 lines
211
-
212
- cc-router accounts list List configured accounts (live stats if proxy is running)
213
- cc-router accounts add Add an account interactively
214
- cc-router accounts login-openai Sign in to OpenAI subscription auth with device code
215
- cc-router accounts add-openai Add an OpenAI subscription account manually (experimental)
216
- cc-router accounts remove <id> Remove a Claude or OpenAI account
217
-
218
- cc-router configure (Re)write ~/.claude/settings.json
219
- cc-router configure codex (Re)write ~/.codex/config.toml for Codex CLI
220
- cc-router configure codex --model openai/gpt-5-codex
221
- cc-router configure models --claude-model claude-sonnet-4-6 --openai-model gpt-5-codex
222
- cc-router configure --show Show current Claude Code proxy settings
223
- cc-router configure --remove Remove cc-router settings from Claude Code (proxy stays up)
224
- cc-router configure codex --remove Remove the Codex managed block (proxy stays up)
225
-
226
- cc-router cli Show whether Claude Code and Codex are routing through the proxy
227
- cc-router cli claude start Point Claude Code at the running proxy
228
- cc-router cli claude stop Restore Claude Code to native Anthropic auth (proxy stays up)
229
- cc-router cli claude resume Same as cli claude start
230
- cc-router cli codex start Point Codex CLI at the running proxy
231
- cc-router cli codex stop Restore Codex CLI to native OpenAI auth (proxy stays up)
232
- cc-router cli codex resume Same as cli codex start
233
- cc-router claude … / cc-router codex … Hidden shortcuts for the same commands
234
-
235
- cc-router client connect <url> Connect Claude Code to a remote CC-Router
236
- cc-router client connect --desktop Also configure Claude Desktop interception
237
- cc-router client disconnect Revert all client configuration
238
- cc-router client status Show connection + remote server health
239
- cc-router client start-desktop Start mitmproxy interceptor for Claude Desktop
240
- cc-router client stop-desktop Stop mitmproxy interceptor
241
-
242
- cc-router docker up Start full Docker stack (cc-router + LiteLLM)
243
- cc-router docker up --build Rebuild cc-router image before starting
244
- cc-router docker down Stop Docker containers
245
- cc-router docker logs Tail all Docker logs
246
- cc-router docker ps Show container status
247
- cc-router docker restart [service] Restart a service
248
- ```
249
-
250
- ---
251
-
252
- ## Modes of operation
253
-
254
- ### Standalone (default — no Docker)
255
-
256
- ```text
257
- Claude Code → cc-router:3456 → api.anthropic.com
258
- ```
259
-
260
- Best for personal use. No Docker required. Runs in the background by default, auto-starts on boot if you choose.
261
-
262
- ```bash
263
- cc-router start
264
- ```
265
-
266
- ### Full mode with LiteLLM (optional — requires Docker)
267
-
268
- ```text
269
- Claude Code → cc-router:3456 → LiteLLM:4000 → api.anthropic.com
270
- ```
271
-
272
- Adds a LiteLLM layer for usage logging, rate limiting, and a web dashboard at `http://localhost:4000/ui`.
273
-
274
- ```bash
275
- cc-router docker up
276
- # or: cc-router start --litellm
277
- ```
278
-
279
- See [docs/litellm-setup.md](docs/litellm-setup.md) for details.
280
-
281
- ---
282
-
283
- ## Codex CLI support (experimental)
284
-
285
- CC-Router exposes an OpenAI Responses-compatible endpoint for Codex CLI at `/v1/responses`. This lets Codex use OpenAI ChatGPT/Codex subscription accounts through the same local router that Claude Code uses for Claude subscriptions.
286
-
287
- **Features:** Sticky sessions pin each Codex conversation to one account for prompt-cache locality. Load- and headroom-aware account selection spreads new sessions across available capacity. Usage tracking from response headers reports account-level 5-hour and 7-day windows, dynamically discovered model-scoped metered buckets, credits, and plan. User caps (`sessionLimitPercent`/`weeklyLimitPercent`) apply to the default Codex bucket. The dashboard shows per-bucket rows, usage bars, credits, plan, and cooldown state for OpenAI accounts.
288
-
289
- Configure Codex:
290
-
291
- ```bash
292
- cc-router configure codex --model openai/gpt-5-codex
293
- ```
294
-
295
- This writes a managed provider block to `~/.codex/config.toml`:
296
-
297
- ```toml
298
- model = "openai/gpt-5-codex"
299
- model_provider = "cc-router"
300
-
301
- [model_providers.cc-router]
302
- name = "CC-Router"
303
- base_url = "http://localhost:3456/v1"
304
- wire_api = "responses"
305
- env_key = "CC_ROUTER_TOKEN"
306
- ```
307
-
308
- Configure router-side model defaults and aliases:
309
-
310
- ```bash
311
- cc-router configure models \
312
- --claude-model claude-sonnet-4-6 \
313
- --openai-model gpt-5-codex
314
- ```
315
-
316
- This writes `modelRouting` to `~/.cc-router/config.json`. It sets the Claude default, the OpenAI default, and practical aliases so `claude/sonnet`, `sonnet`, `openai/default`, and `openai/codex` resolve to the models you selected. Restart the router after changing these values.
317
-
318
- Model discovery is dynamic. `GET /v1/models` returns an OpenAI-compatible model list by querying the configured Anthropic and OpenAI subscription APIs live:
319
-
320
- ```bash
321
- curl http://localhost:3456/v1/models
322
- ```
323
-
324
- Results are provider-prefixed, for example `anthropic/claude-sonnet-4-6` and `openai/gpt-5-codex`. Configured aliases such as `openai/codex` are added when their upstream model is available. If one provider is temporarily unavailable, CC-Router still returns the models discovered from the other providers.
325
-
326
- Then run Codex with the proxy secret in `CC_ROUTER_TOKEN` when your router is password-protected:
327
-
328
- ```bash
329
- CC_ROUTER_TOKEN=cc-rtr-your-secret codex -m openai/gpt-5.5
330
- ```
331
-
332
- Model prefixes:
333
-
334
- | Model | Upstream |
335
- |--------|----------|
336
- | `openai/*` | OpenAI ChatGPT/Codex subscription route |
337
- | `gpt-*` (no prefix) | OpenAI ChatGPT/Codex subscription route |
338
- | `claude/*` | Claude subscription route |
339
- | `anthropic/*` | Claude subscription route |
340
- | anything else with no prefix | Claude subscription route |
341
-
342
- The unprefixed `gpt-*` rule exists for clients that do not speak this
343
- convention. The Codex CLI writes the bare slug from its own registry — either
344
- `model = "gpt-5.6-sol"` in `~/.codex/config.toml` or whatever its `/model`
345
- picker selects — so those names arrive without a prefix and would otherwise be
346
- routed to Claude, where `/v1/responses` answers `501`. Configured
347
- `openAIAliases` apply to the bare form too.
348
-
349
- Examples after the configuration above:
350
-
351
- | Public model | Routed upstream model |
352
- |--------------|----------------------|
353
- | `openai/codex` | `gpt-5-codex` |
354
- | `openai/default` | `gpt-5-codex` |
355
- | `claude/sonnet` | `claude-sonnet-4-6` |
356
-
357
- Claude Code can also send a `/v1/messages` request with an `openai/*` model. CC-Router translates that Anthropic Messages request into an OpenAI Responses request and converts JSON or basic text SSE responses back into Anthropic-shaped message responses.
358
-
359
- OpenAI-to-Anthropic conversion supports text and function tool calls in both streaming and non-streaming responses.
360
-
361
- OpenAI subscription account records are separated from Claude accounts with `provider: "openai_subscription"` so they do not enter the Anthropic token pool:
362
-
363
- ```json
364
- {
365
- "id": "openai-primary",
366
- "provider": "openai_subscription",
367
- "accessToken": "eyJ...",
368
- "refreshToken": "...",
369
- "expiresAt": 1999999999000,
370
- "scopes": ["openid", "profile", "email", "offline_access"]
371
- }
372
- ```
373
-
374
- Recommended OpenAI subscription login:
375
-
376
- ```bash
377
- cc-router accounts login-openai
378
- ```
379
-
380
- This uses the Codex device-code auth flow: the CLI prints a verification URL and one-time code, you approve the login in your browser, and CC-Router saves the resulting OpenAI subscription account record.
381
-
382
- Manual account entry is also available for debugging:
383
-
384
- ```bash
385
- cc-router accounts add-openai
386
- ```
387
-
388
- This prompts for the OpenAI access token, refresh token, expiry timestamp, and scopes, validates the record shape, and saves it without overwriting Claude accounts.
389
-
390
- ---
391
-
392
- ## Client mode — connecting your own devices
393
-
394
- Client mode lets you connect another device you own to your private CC-Router over a trusted private network. It is not intended for sharing subscription accounts or proxy access with other people, or for exposing CC-Router to the public internet.
395
-
396
- The setup wizard asks about this at the very first step:
397
-
398
- ```bash
399
- cc-router setup
400
- # → What do you want to do?
401
- # • Host CC-Router on this machine
402
- # • Connect to your existing CC-Router server ← pick this
403
- ```
404
-
405
- Or use the dedicated command directly:
406
-
407
- ```bash
408
- # Connect another device you own over your private network
409
- cc-router client connect http://192.168.1.50:3456 --secret cc-rtr-abc123...
410
-
411
- # Check status
412
- cc-router client status
413
-
414
- # Disconnect (restores Claude Code defaults)
415
- cc-router client disconnect
416
- ```
417
-
418
- Client mode writes `ANTHROPIC_BASE_URL` and `ANTHROPIC_AUTH_TOKEN` into `~/.claude/settings.json`, so Claude Code talks directly to the remote proxy. Nothing runs locally — no accounts, no proxy process, no resources.
419
-
420
- ### CLI reference
421
-
422
- ```text
423
- cc-router client connect <url> Connect Claude Code to a CC-Router server
424
- cc-router client connect --desktop Also configure Claude Desktop interception
425
- cc-router client connect -s <secret> Pass the proxy secret inline (or use --secret)
426
- cc-router client disconnect Revert all client configuration
427
- cc-router client status Show current connection + remote server health
428
- cc-router client start-desktop Start the Claude Desktop mitmproxy interceptor
429
- cc-router client stop-desktop Stop the Claude Desktop interceptor
430
- ```
431
-
432
- ---
433
-
434
- ## Claude Desktop support
435
-
436
- Claude Desktop (chat + Cowork) **can be routed through CC-Router**, but unlike Claude Code it does not respect `ANTHROPIC_BASE_URL`. It talks directly to `api.anthropic.com` via an embedded Anthropic SDK. To redirect its traffic, CC-Router uses [mitmproxy](https://mitmproxy.org/) in *local redirect mode* — a process-scoped interceptor that only captures Claude Desktop's network traffic and forwards it to the proxy.
437
-
438
- This is **opt-in** — the setup wizard will ask if you want it.
439
-
440
- ### Requirements
441
-
442
- - **mitmproxy ≥ 10.1.5** (macOS, Windows) or **≥ 11.1** (Linux — requires kernel ≥ 6.8)
443
- - Admin access to install the mitmproxy CA certificate
444
- - On macOS: manual approval of mitmproxy's Network Extension (one time, via System Settings)
445
-
446
- ### Installing mitmproxy
447
-
448
- ```bash
449
- # macOS
450
- brew install mitmproxy
451
-
452
- # Windows
453
- # Download the installer from https://mitmproxy.org/downloads/
454
- # (or: pip install mitmproxy)
455
-
456
- # Linux
457
- pip install mitmproxy # kernel 6.8+ required for local mode
458
- ```
459
-
460
- ### Enabling Desktop interception
461
-
462
- During `cc-router setup` or `cc-router client connect`, answer **Yes** when asked about Claude Desktop. The wizard will:
463
-
464
- 1. Check that mitmproxy is installed
465
- 2. Generate the mitmproxy CA certificate (if not already present)
466
- 3. Install the CA into the OS trust store (requires sudo/admin)
467
- 4. Write the redirect addon to `~/.cc-router/interceptor/addon.py`
468
- 5. On macOS, prompt you to approve the Network Extension
469
-
470
- Then start the interceptor:
471
-
472
- ```bash
473
- cc-router client start-desktop
474
- ```
475
-
476
- Open Claude Desktop and send a message. The request will be intercepted and redirected to CC-Router. Requests carrying exactly one valid `X-Claude-Code-Session-Id` receive cache-aware sticky affinity; requests without one valid session header use load-aware **unscoped** routing and do not receive sticky affinity. Claude Desktop traffic normally follows the unscoped path.
477
-
478
- ### Stopping / removing Desktop interception
479
-
480
- ```bash
481
- cc-router client stop-desktop # Stop the interceptor (keep configuration)
482
- cc-router client disconnect # Stop + remove all client config
483
- ```
484
-
485
- ### How it works under the hood
486
-
487
- ```
488
- Claude Desktop
489
-
490
- │ tries to connect to api.anthropic.com:443
491
-
492
- mitmproxy (local mode)
493
- │ addon.py rewrites scheme/host to CC-Router
494
-
495
- CC-Router :3456 ──► api.anthropic.com (with OAuth Bearer token)
496
- ```
497
-
498
- mitmproxy's local mode is *process-scoped* — it only intercepts traffic from the Claude process, not your browser, curl, or any other app. The OS-level interception uses:
499
-
500
- | Platform | Mechanism |
501
- |----------|-----------|
502
- | macOS | Network Extension (App Proxy Provider API) |
503
- | Windows | WinDivert (WFP kernel driver) |
504
- | Linux | eBPF (kernel ≥ 6.8) |
505
-
506
- ### Troubleshooting
507
-
508
- - **macOS: "provider rejected new flow"** — re-enable Mitmproxy Redirector in System Settings → General → Login Items & Extensions → Network Extensions, then restart mitmproxy.
509
- - **Windows: UAC prompt every start** — expected; mitmproxy's redirector needs admin at runtime.
510
- - **Linux: "eBPF program failed to load"** — check your kernel version with `uname -r`. You need ≥ 6.8.
511
- - **Chat shows "failed to connect"** — make sure CC-Router is reachable from the mitmproxy process. Run `curl http://localhost:3456/cc-router/health` to verify the proxy is up.
512
-
513
- ---
514
-
515
- ## Toggle Claude Code or Codex while the proxy stays up
516
-
517
- `cc-router start` / `stop` control the proxy process. To send only one CLI back to native auth (or point it at the proxy again) without tearing the router down:
518
-
519
- ```bash
520
- cc-router cli # Claude Code + Codex routing state
521
- cc-router cli claude stop # Claude Code → native Anthropic auth
522
- cc-router cli claude resume # Claude Code → running proxy (alias of start)
523
- cc-router cli codex start # Codex CLI → running proxy
524
- cc-router cli codex stop # Codex CLI → native OpenAI auth
525
- ```
526
-
527
- `cc-router claude …` and `cc-router codex …` are shortcuts for the same commands. `cli` is the grouping — not `provider`, which already means the Anthropic/OpenAI account pool. `cc-router client` remains remote client-mode (connect this machine to another CC-Router).
528
-
529
- These rewrite `~/.claude/settings.json` or the managed block in `~/.codex/config.toml`. The proxy keeps listening. Restart any already-running Claude Code or Codex process so it picks up the new config. From `cc-router status`, `[c]` / `[x]` do the same toggles.
530
-
531
- ---
532
-
533
- ## Reverting to normal Claude Code
534
-
535
- To stop using cc-router and go back to normal Claude Code authentication:
536
-
537
- ```bash
538
- cc-router revert
539
- ```
540
-
541
- This stops the proxy process, removes the auto-start service (if installed), and removes cc-router's settings from `~/.claude/settings.json`. Claude Code will use its own authentication on the next launch.
542
-
543
- For a gentler approach, `cc-router stop` interactively asks what you want to clean up.
544
-
545
- ---
546
-
547
- ## Status dashboard
548
-
549
- ```bash
550
- cc-router status
551
- ```
552
-
553
- ```text
554
- CC-Router · standalone → api.anthropic.com · up 2h 14m · [q] quit
555
-
556
- OPERATIONS base http://localhost:3456 · auth protected · models dynamic
557
- Claude 2/2 healthy OpenAI 1/1 healthy · cross-route ready
558
- endpoints /v1/messages /v1/responses /v1/models /cc-router/accounts
559
- routing claude=claude-sonnet-4-6 aliases[sonnet] openai=gpt-5-codex aliases[codex]
560
- cli Claude on Codex off [c]/[x] · models [m] then [c]/[o] defaults
561
-
562
- MODELS [m/r] refresh [↑/↓] select [c] Claude default [o] OpenAI default
563
- current claude=claude-sonnet-4-6 openai=gpt-5-codex
564
- ▶ anthropic/claude-sonnet-4-6 Claude
565
- openai/gpt-5-codex OpenAI
566
-
567
- ACCOUNTS 2/2 healthy
568
-
569
- ● max-account-1 ok req 142 err 0 expires 6h 48m last 2s ago
570
- ● max-account-2 ok req 139 err 0 expires 6h 51m last 5s ago
571
-
572
- TOTALS requests 281 · errors 0 · refreshes 2
573
-
574
- RECENT ACTIVITY
575
- 14:23:01 → max-account-1 route
576
- 14:22:58 → max-account-2 route
577
- 14:22:45 ↻ max-account-1 refresh
578
- ```
579
-
580
- Press `q` to quit. Run with `--json` for non-interactive output; the JSON includes an `operational` block with capabilities, endpoints, provider readiness, auth status, and model routing. Secrets and account tokens are never included.
581
-
582
- The dashboard is also a control surface. In local mode it controls the local proxy; in client mode it controls the remote CC-Router configured by `cc-router client connect`. Authenticated account views include dynamic model-scoped allowance rows, their reset times, applicable global or requested-model cooldowns, paid-extra state, and whether the usage snapshot is fresh, stale, or unavailable. A stale row is shown as unknown rather than as authoritative available capacity.
583
-
584
- | Key | Action |
585
- |-----|--------|
586
- | `Tab` | Switch focus between logs, accounts, and models |
587
- | `n` | Add a Claude account |
588
- | `e` | Enable/disable selected Claude account |
589
- | `w` / `s` | Change selected Claude account weekly/session cap |
590
- | `d` | Delete selected Claude account |
591
- | `Ctrl+R` | Confirm redeeming one banked usage-limit reset for the focused ChatGPT account |
592
- | `R` | Reload account usage and due credentials without restarting the router |
593
- | `m` / `r` | Load or refresh discovered provider models |
594
- | `c` | Toggle Claude Code routing (or set Claude model default when MODELS is focused) |
595
- | `x` | Toggle Codex CLI routing (proxy stays up) |
596
- | `o` | Set selected `openai/*` model as OpenAI default |
597
-
598
- To redeem a ChatGPT reset, press `Tab` to focus accounts, select the account
599
- with the arrow keys, then press `Ctrl+R` and confirm with `y` (`n` or `Esc`
600
- cancels). The `rst` column shows banked reset credits. Accounts with zero or
601
- unknown credits cannot start a new redemption. This spends a real reset credit;
602
- it is not the same as refreshing usage with uppercase `R`.
603
-
604
- Press **Control + R** (not Command + R or Shift + R). This uses the standard
605
- terminal Ctrl+R sequence and does not require a custom Meta/Option key mapping.
606
-
607
- Redemption targets only that account and refreshes its usage afterward. If the
608
- network outcome is unknown, keep the dashboard open and retry the shortcut: it
609
- reuses the same redemption ID instead of spending another credit. Those retry
610
- IDs are held for the current dashboard session only; after restarting it,
611
- inspect usage before requesting another reset. A successful redemption with a
612
- failed usage refresh is reported separately. Confirmed resets plus fresh usage clear only superseded quota cooldowns.
613
- Overload holds, unreported/exhausted limits, and newer quota signals are preserved.
614
-
615
- List and change models without waiting for a package update:
616
-
617
- ```bash
618
- cc-router models list
619
- cc-router models set --claude-model anthropic/claude-sonnet-4-6
620
- cc-router models set --openai-model openai/gpt-5-codex
621
- ```
622
-
623
- When the proxy is running, `models set` updates the live router and persists the new defaults. If the proxy is offline, it writes the configuration for the next start.
624
-
625
- ---
626
-
627
- ## Security
628
-
629
- - Tokens are stored locally in `~/.cc-router/accounts.json`, **never in the repository**
630
- - The file is excluded by `.gitignore`
631
- - Writes are atomic (write to `.tmp`, then rename) — no corruption on crash
632
- - Keychain reads use `execFile` with a fixed argument array — no shell injection
633
- - Anonymous opt-out telemetry via [Aptabase](https://aptabase.com) (see [Telemetry](#telemetry) below)
634
-
635
- See [docs/security.md](docs/security.md) for details.
636
-
637
- ---
638
-
639
- ## Telemetry
640
-
641
- CC-Router sends a handful of anonymous lifecycle events to [Aptabase](https://aptabase.com) (privacy-first, open source, EU-hosted). The goal is simple: know how many people use the project, which versions are live, and roughly how many instances are running — so we can prioritize fixes and features.
642
-
643
- **What we send** — the entire payload lives in [`src/utils/telemetry.ts`](src/utils/telemetry.ts), audit it yourself:
644
-
645
- | Event | When | Custom props |
646
- | -------------------- | ------------------------------------------------ | ---------------------------------------- |
647
- | `app_started` | First proxy start after install | `first_run: true` |
648
- | `setup_completed` | Setup wizard finishes successfully | `account_count` |
649
- | `proxy_started` | Each `cc-router start` | `account_count`, `mode` |
650
- | `proxy_heartbeat` | Every hour while the proxy is running | `uptime_minutes`, `account_count` |
651
- | `telemetry_disabled` | When you run `cc-router telemetry off` | — |
652
-
653
- Plus anonymous system props with every event: `appVersion`, `osName` (macOS/Linux/Windows), `osVersion`, `locale`, `engineVersion` (Node), and an anonymous `installId` (random UUID generated on first run, stored in `~/.cc-router/telemetry.json`).
654
-
655
- **What we never send**: IPs, OAuth tokens, account names, request content, prompts, responses, URLs, hostnames, usernames, file paths — nothing that could identify you or your usage patterns.
656
-
657
- **Disable it** — three ways, any one works:
658
-
659
- ```bash
660
- # 1. Persistent opt-out (recommended)
661
- cc-router telemetry off
662
-
663
- # 2. Respect the de-facto standard (honored by many OSS tools)
664
- export DO_NOT_TRACK=1
665
-
666
- # 3. Project-specific override
667
- export CC_ROUTER_TELEMETRY=0
668
- ```
669
-
670
- Check status anytime: `cc-router telemetry status`.
671
-
672
- ---
104
+ That's it. On first `start` you're asked how to run the router (background, foreground, or
105
+ auto-start on boot) and the choice is remembered; `cc-router start --reconfigure` changes
106
+ it later. Adding more accounts is `cc-router setup --add`, and `cc-router status` opens the
107
+ dashboard.
108
+
109
+ Per-platform token extraction, Codex CLI, Docker and everything else lives in
110
+ [the docs](docs/).
111
+
112
+ ## Documentation
113
+
114
+ | Guide | What's in it |
115
+ |---|---|
116
+ | [Installation & deployment](docs/installation.md) | Per-platform token setup, run modes, Docker |
117
+ | [CLI reference](docs/cli-reference.md) | Every command and flag |
118
+ | [Session routing](docs/session-routing.md) | How an account gets picked, failover, team operation |
119
+ | [Architecture](docs/architecture.md) | Request path and components |
120
+ | [Dashboard](docs/dashboard.md) | Live TUI, keybindings, model management |
121
+ | [Codex CLI & OpenAI](docs/codex.md) | Responses endpoint, model prefixes, OpenAI accounts |
122
+ | [Grok / xAI](docs/grok.md) | Adding Grok accounts, and why they're overview-only |
123
+ | [Claude Desktop](docs/claude-desktop.md) | mitmproxy interception setup |
124
+ | [Client mode](docs/client-mode.md) | Connecting your other devices |
125
+ | [LiteLLM](docs/litellm-setup.md) | Optional logging and rate-limiting layer |
126
+ | [OAuth tokens](docs/oauth-tokens.md) | How subscription tokens and refresh rotation work |
127
+ | [Security](docs/security.md) | Token storage, proxy auth, threat model |
128
+ | [Telemetry](docs/telemetry.md) | Opt-in analytics: what's sent if you enable it |
129
+ | [Troubleshooting](docs/troubleshooting.md) | When something doesn't connect |
673
130
 
674
131
  ## Disclaimer
675
132
 
676
- > CC-Router uses the OAuth tokens of your own Claude Max subscriptions.
133
+ > CC-Router uses the OAuth tokens of **your own** Claude Max and ChatGPT subscriptions.
677
134
  >
678
- > **Read Anthropic's Terms of Service before using this tool.**
679
- > Using multiple Max subscriptions to increase throughput may violate the ToS. Anthropic has been known to ban accounts for unusual OAuth usage patterns.
680
- > Do not share subscription accounts, OAuth credentials, or CC-Router proxy access with other people.
135
+ > **Read Anthropic's and OpenAI's Terms of Service before using this tool.** Using multiple
136
+ > subscriptions to increase throughput may violate them. Anthropic has been known to ban
137
+ > accounts for unusual OAuth usage patterns.
681
138
  >
682
- > The authors are not responsible for any account bans, loss of access, or other consequences resulting from the use of this software. Use at your own risk.
683
-
684
- ---
139
+ > Do not share subscription accounts, OAuth credentials, or CC-Router proxy access with
140
+ > other people.
141
+ >
142
+ > The authors are not responsible for account bans, loss of access, or any other
143
+ > consequence of using this software. Use at your own risk.
685
144
 
686
145
  ## Contributing
687
146
 
688
- See [CONTRIBUTING.md](CONTRIBUTING.md).
689
-
690
- Bug reports → [GitHub Issues](https://github.com/Timo972/cc-router/issues)
691
-
692
- ---
147
+ Bug reports and feature requests go to [GitHub Issues](https://github.com/Timo972/cc-router/issues).
148
+ For development setup, code conventions and the PR process, see [CONTRIBUTING.md](CONTRIBUTING.md).
693
149
 
694
150
  ## License
695
151
 
@@ -697,5 +153,5 @@ Bug reports → [GitHub Issues](https://github.com/Timo972/cc-router/issues)
697
153
 
698
154
  This project began as a fork of [VictorMinemu/CC-Router](https://github.com/VictorMinemu/CC-Router)
699
155
  and is now maintained independently as [`@timo972/cc-router`](https://www.npmjs.com/package/@timo972/cc-router).
700
- It is not affiliated with the upstream project, and issues should be filed here rather than upstream.
156
+ It is not affiliated with the upstream project please file issues here rather than upstream.
701
157
  The original MIT copyright notice is retained in [LICENSE](LICENSE).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@timo972/cc-router",
3
- "version": "0.12.1-rc.1",
3
+ "version": "0.12.1",
4
4
  "description": "Cache-aware session router for Claude Max OAuth tokens — use multiple Claude Max accounts with Claude Code",
5
5
  "type": "module",
6
6
  "bin": {