-
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 keys its credentials off a single environment variable. Each distinct
CLAUDE_CONFIG_DIRgets its own isolated macOS Keychain login — socrkeeps one directory per account, and on every launch it:- picks an account by policy — or your forced
--account, - unsets
ANTHROPIC_API_KEYand friends, which would otherwise override your subscription login, - points
CLAUDE_CONFIG_DIRat the chosen account, - prints a one-line banner to stderr, and
execs the realclaude— TTY, signals, and exit code pass straight through, with zero overhead.
- picks an account by policy — or your forced
-
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 is adopted asdefault— never moved, never modified.cr register-default # adopt your current ~/.claude login cr add work # create + browser-login a second account cr add personal # …and a third cr list # see them all -
4.0The flow.
From here on, type
crwherever you typedclaude. Anything it doesn’t recognize is forwarded verbatim — flags, prompts,--resume, all of it. The only visible difference is one quiet line saying who’s at the helm.$ 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…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.
Pin one with
cr use workwhen you want stillness; force a single launch withcr@workwhen you don’t. -
5.0The balance.
cr usagedraws how much is left in each window — the 5-hour session, the 7-day total — with reset countdowns, so you can see at a glance which subscription to lean on.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 4d22hAnd every policy skips exhausted accounts. Before routing,
crrefreshes stale usage data and drops any account at or above the exhaustion threshold from the rotation — a maxed-out subscription is never chosen. 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 handoff.
Routing well at launch still leaves one wall: the account you’re on can run dry mid-session. Add
--watch(or-w) andcrstays at the helm — a background watcher polls usage, and when the account in use crosses the threshold (90% by default) while another has headroom, it waits for a quiet moment, then restarts Claude Code under the fresher account with--resume. The conversation follows; you lose a few seconds of restart, not your context.$ 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. Anything cr doesn’t recognize belongs to claude.
| Launch | |
|---|---|
| cr [args…] | Route by policy, then run claude with your args. |
| cr@<name> [args…] | Force an account — shorthand for --account <name>. |
| cr --watch · -w | Stay aboard; auto-handoff to a fresher account near the limit. |
| cr --sandbox · -s | Run the session inside a cco container. |
| cr … -- [args…] | -- ends cr’s flags; everything after belongs to claude. |
| Manage | |
|---|---|
| cr add <name> | New account: directory, shared settings, browser login. |
| cr register-default | Adopt your existing ~/.claude login in place. |
| cr list | Every account: email, plan, last used, usage, enabled. |
| cr use <name> · unuse | Pin the rotation to one account, or release it. |
| cr policy <p> | 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 usage [name] | Per-window meters with reset countdowns. |
| cr status [--refresh·--json] | Dashboard or JSON: next pick, plus per-account usage. |
| cr doctor [name] | Verify each account’s directory and Keychain credential. |
| 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> | Link a session into another account ahead of time. |
| cr login · logout · remove | Re-auth, sign out, or unregister an account. |
Also aboard.
Five more things the router carries, for the days you need them.
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.
A sandbox, one flag away.cr --sandbox · -s
--sandbox runs the session inside a container via cco, so Claude Code can’t touch anything outside your project. cr still does the routing — policies, pins, backends, and --resume all compose unchanged.
Sessions that follow you.cr --resume <id>
Claude Code stores each conversation under the account that created it. cr --resume just works: whichever account the rotation picks, cr transparently links the session in from the account that owns it. You never see “No conversation found” again.
A watcher in your menu bar.menubar/clawrouter.30s.sh
A small SwiftBar plugin puts your headroom in the macOS menu bar — 🦞 58%, the least-free of your accounts, colored by how much is left. The dropdown breaks it down per account and window with reset countdowns, and switches policy or pins an account in a click. It reads the cached snapshot through a new cr status --json, so it draws instantly, while a tiny background agent keeps the numbers fresh. Pour yourself a coffee; it’ll tell you which plan to lean on.
Stop watching the meter.
git clone https://github.com/dennisonbertram/claw-router.git && cd claw-router && ./install.sh