-
1.0The wall.
It’s 4 p.m., the refactor is half-landed, and Claude Code stops mid-thought: the 5-hour window just closed. So you type
/login, squint at the account picker, swap to the other subscription, and try to remember where you were.If you keep two or three Claude Max plans around precisely for this moment, you know the ritual. The plans aren’t the problem — the swapping is. Routing is a job for software, not for muscle memory.
-
2.0The trick.
Claude Code and Codex expose different isolation and command contracts.
crkeeps those differences behind provider adapters: Claude accounts useCLAUDE_CONFIG_DIR; Codex accounts useCODEX_HOME. On every launch it:- keeps Claude as the default, accepts
--provider codex, or infers the provider from a named account, - picks an account from that provider's own policy pool,
- points the provider's isolated home at the chosen account,
- prints a one-line banner to stderr, and
execs the realclaudeorcodex— native arguments, TTY, signals, and exit code pass straight through.
- keeps Claude as the default, accepts
-
3.0The setup.
Three lines to install, one browser login per account. macOS-first, because Keychain isolation is the clean path there; it runs on Linux too, where credentials come from
.credentials.jsoninstead. The only hard dependency isjq.git clone https://github.com/dennisonbertram/claw-router.git cd claw-router ./install.sh # symlinks `cr` into ~/.local/binThen teach it your accounts. Your existing
~/.claudelogin can remain the Claude default. Codex accounts get isolated homes and the official browser login flow.cr register-default # adopt your current ~/.claude login cr add work # create + browser-login a second account cr add personal # …and a third cr --provider codex add openai-work # isolated CODEX_HOME + codex login cr --provider codex add-api openai-api --from-env # optional API-key login cr list # all accounts, labeled by provider -
4.0The flow.
Plain
crremains a drop-in Claude route. Usecr --provider codexfor Codex, orcr @nameto infer the provider from an account. Provider-native commands stay native: Claude--resume, Codexexecandresume, and each CLI's own flags.$ cr -p "explain this repo" ◆ work you@work.com (claude_max) · round-robin …claude runs normally… $ cr -p "and the tests?" ◆ personal you@gmail.com (claude_max) · round-robin …next call, next account… $ cr --provider codex exec "and the Codex tests?" ◆ openai-work [codex] · round-robin …codex runs normally…Four ways to pick the next account:
- round-robin— the default
- An even spread across every enabled account.
- lru
- Whichever account has rested longest.
- random
- Uniform random.
- usage-aware
- Whichever account has the most headroom right now, by the numbers from
cr usage.
Policies and pins are provider-scoped:
cr policy usage-awaretargets Claude, whilecr --provider codex policy lrutargets Codex. Force one account withcr @work; its provider is inferred. -
5.0The balance.
cr usagedraws how much is left in each provider-supported window. Claude keeps its existing meters; Codex ChatGPT usage, when available through the official app-server interface, is normalized into the same display. API-key and no-data accounts degrade gracefully instead of blocking routing.usage left per window — from the README’s own example default you@work.com
5h session 42% left resets in 1h17m7d total 88% left resets in 2d13hpersonal you@gmail.com
5h session 100% left resets in 4h47m7d total 100% left resets in 4d22hWithin each provider, policies skip exhausted accounts when current usage is available. Before routing,
crrefreshes stale usage data and drops any account at or above the exhaustion threshold. If every account is spent, it falls back to the full set rather than failing. Tune it to taste:cr config exhausted-at 90 # treat ≥90% used as "out", leave headroom cr config auto-refresh off # don't auto-poll before routing cr config ttl 600 # cached usage goes stale after 10 min -
6.0The Claude handoff.
Routing well at launch still leaves one wall: the Claude account you’re on can run dry mid-session. Add
--watch(or-w) andcrstays at the helm — a background watcher polls usage, waits for a quiet moment, then restarts Claude Code under a fresher account with--resume. Watch and cross-account session adoption are Claude-only. Codex keeps its nativeresumeworkflow and session ownership.$ cr --watch ◆ work you@work.com (claude_max) · round-robin …hours pass… ↻ work at 93% — continuing on personal (resuming 5fe702a8…) ◆ personal you@gmail.com (claude_max) · watch …same conversation, fresher account…Honest fine print: a reply can’t be handed off mid-stream — the watcher waits until the session has been idle for a beat (30 seconds by default) before it moves. Tune all three knobs:
cr config watch-at 90 # hand off when the account hits 90% used cr config watch-interval 120 # poll usage every 2 minutes cr config watch-idle 30 # only move after 30s of quiet
The reference.
The complete surface. Provider-native arguments belong to the selected claude or codex CLI.
| Launch | |
|---|---|
| cr [args…] | Route by policy, then run claude with your args. |
| cr --provider codex [args…] | Route within Codex accounts, then run native codex arguments. |
| cr @<name> [args…] | Force an account and infer its provider — spaced shorthand for --account. |
| cr --watch · -w | Claude only: auto-handoff to a fresher account near the limit. |
| cr --sandbox · -s | Claude uses cco; Codex receives its native sandbox flag and value. |
| cr … -- [args…] | -- ends router flags; everything after belongs to the selected provider CLI. |
| Manage | |
|---|---|
| cr add <name> | New account: directory, shared settings, browser login. |
| cr --provider codex add <name> | New isolated CODEX_HOME using official codex login. |
| cr --provider codex add-api <name> [--from-env] [--rotate] | Pipe an API key to codex login --with-api-key; explicit-only unless --rotate is supplied. |
| cr register-default | Adopt your existing ~/.claude login in place. |
| cr list | All accounts: provider, identity, last used, usage, and rotation state. |
| cr use <name> · unuse | Pin the rotation to one account, or release it. |
| cr [--provider p] policy <policy> | Provider-scoped round-robin · lru · random · usage-aware. |
| cr config [key val] | Tune the knobs: exhausted-at, ttl, auto-refresh, watch-at, watch-interval, watch-idle. |
| cr [--provider p] usage [name] | Provider-scoped windows; no-data and API-key accounts degrade gracefully. |
| cr [--provider p] status [--refresh·--json] | Provider-scoped dashboard or JSON: next pick plus account usage. |
| cr [--provider p] doctor [name] | Provider health; Codex delegates to codex login status. |
| cr add-api <name> | Register an Anthropic API key — explicit-only by default. |
| cr rotate <name> on·off | Opt an api-key account in or out of the rotation. |
| cr add-backend <name> | Register an alt-model endpoint, e.g. DeepSeek. |
| cr adopt <id> <account> | Claude only: link a session into another account. |
| cr [--provider p] login · logout · remove | Provider-native re-auth, sign out, or unregister. |
Also aboard.
Provider-specific tools stay available without blurring their safety boundaries.
Codex, natively.cr --provider codex
Add accounts with cr --provider codex add <name>. Each gets an isolated CODEX_HOME; login, logout, and doctor use official Codex commands, and Claw Router never reads Codex credentials. Native exec, resume, exec resume, profiles, and sandbox flags pass through unchanged. Watch and cross-account adoption remain Claude-only.
A Codex API key, Codex-owned.cr --provider codex add-api
cr --provider codex add-api <name> [--from-env] [--rotate] supplies a hidden or environment-provided key to codex login --with-api-key. Claw Router never persists or reads the key; Codex owns the login under the isolated CODEX_HOME. The account is explicit-only unless --rotate is supplied, and API-key accounts have no subscription usage windows.
An API key, on a leash.cr add-api work-key
Register an Anthropic API key as an account of its own — separate directory, separate history, billed per token. Explicit-only by default: a plain cr never picks it, so a work key can’t bleed into personal projects. Reach it by name — cr @work-key — or opt a personal key into the rotation with cr rotate personal-key on. API keys have no usage windows, so they’re excluded from the meters and never a --watch handoff target.
Backends, explicit-only.cr add-backend deepseek
cr can point Claude Code at any Anthropic-compatible endpoint — DeepSeek, say — registered as a backend account. Backends are never in the rotation: a plain cr sticks to your rotation pool. You reach one by naming it — cr @deepseek — so an inferior fallback model stays out of your flow until you ask for it.
Provider-native sandboxing.cr --sandbox · -s
For Claude, --sandbox runs the session inside a container via cco. For Codex, -s / --sandbox and its value are forwarded to Codex unchanged. The router never translates one provider's sandbox contract into the other's.
Claude sessions that follow you.cr --resume <id>
Claude Code stores each conversation under the account that created it. cr --resume links that Claude session into the selected Claude account. Codex sessions remain Codex-owned: use cr --provider codex resume or exec resume; Claw Router does not inspect or symlink them.
A watcher in your menu bar.menubar/clawrouter.30s.sh
A small SwiftBar plugin puts provider-scoped headroom in the macOS menu bar. Set CLAWROUTER_PROVIDER to claude or codex; rows carry provider labels, no-data accounts remain visible, and older schema-1 snapshots without a provider safely default to Claude.
Stop watching the meter.
git clone https://github.com/dennisonbertram/claw-router.git && cd claw-router && ./install.sh