Claude Codex Swap — multi-account and usage manager for Claude Code and OpenAI Codex
Project description
ccswap (Claude Codex Swap)
Multi-account and usage manager for Claude Code and OpenAI Codex. Save multiple logins, check their quota windows, switch manually or automatically before you hit a rate limit, and manage both providers from one dashboard.
ccswap began as a fork of claude-swap (cswap) by Onur Cetinkol, and still carries the original MIT license and credit for that. Since then it's grown into its own project: no more tracking upstream, no cswap compatibility, its own package and release line, and adds Codex support. It's MIT-licensed too, so fork it, file issues, send PRs — whatever's useful to you.
Installation
Using uv (recommended)
uv tool install ccswap
Using pipx
pipx install ccswap
From source
git clone https://github.com/errhythm/cc-swap.git
cd cc-swap
uv sync
uv run ccswap help
Updating
ccswap upgrade # uv/pipx installs on macOS/Linux: auto-detects and upgrades
# or run your installer directly:
uv tool upgrade ccswap
pipx upgrade ccswap
Usage
Add your first account
Log into Claude Code with your first account, then:
ccswap add
Add more accounts
Log in with another account, then:
ccswap add
Switch accounts
Rotate to the next account:
ccswap switch
Or switch to a specific account:
ccswap switch 2
ccswap switch user@example.com
Not sure which one? ccswap list is the dashboard — every account's 5-hour and 7-day usage and reset times at a glance:
ccswap list
Or ccswap auto-picks by remaining quota — ccswap switch --strategy best (most quota left) or --strategy next-available (skip rate-limited accounts).
Note: You usually don't need to restart — on Linux/Windows the new account is picked up automatically, and on macOS after the Keychain cache expires. To apply it instantly, restart Claude Code or reopen the VS Code extension tab. See Tips for the per-platform details.
Automatic switching
Let ccswap watch your usage and switch for you. When the active account's 5-hour or 7-day window reaches the threshold (default 90%), it switches to the account with the most quota left — before you hit the limit, and safe to run while Claude Code is working:
ccswap auto # foreground loop, polls every 60s
ccswap auto --threshold 80 # switch earlier
ccswap auto --once # single check-and-switch, for cron/scripts
ccswap auto --dry-run # log what it would do, never switch
How it behaves & advanced usage
- Runs safely alongside Claude Code: switches take the same credential locks Claude Code uses, so a swap never collides with a token refresh.
- A cooldown (default 5 min) and a hysteresis margin stop it flip-flopping near the threshold; when every account is exhausted it sleeps until the earliest reset.
- Usage polling is adaptive — a couple of accounts per check, busy alternates watched more closely, exhausted ones left alone until they reset — so API traffic stays flat no matter how many accounts you manage.
- It fails safe: if a usage check errors it keeps trusting the last-known numbers while retries back off, and an expired token on an idle machine makes it hold rather than fail over (Claude Code refreshes the token on your next message).
- An account whose refresh token has died is quarantined and reported until you log in with it and re-run
ccswap add --slot N. API-key accounts are never rotated onto unless you pass--include-api-key-accounts.
For cron/systemd timers, --once reports the outcome in its exit code (0 switched, 1 error, 2 nothing to do, 3 blocked — no viable target), and --json emits one JSON event per line:
*/5 * * * * ccswap auto --once --json >> ~/.ccswap-auto.log 2>&1
Defaults like the threshold and cooldown are configurable with ccswap config set autoswitch.threshold 80 — flags override them (see Configuration).
Run multiple accounts at the same time (session mode)
Launch Claude Code as a specific account in the current terminal only — every other terminal and the VS Code extension stay on your default account, so two accounts can work in parallel.
ccswap run 2 # launch Claude Code as account 2, here only
ccswap run user@example.com # by email
ccswap run 2 -- --resume # everything after '--' is forwarded to claude
ccswap run 2 --share-history # share your chat history with this account too
Sessions use your normal ~/.claude setup (settings, CLAUDE.md, skills, etc.), but each account keeps its own chat history. Pass --share-history if you want your accounts to continue the same conversations — a session started under one account shows up in --resume under the others, and nothing already saved is lost. Not supported on Windows yet.
Interactive dashboard (TUI)
Run ccswap on its own (or ccswap tui) for the full-screen dashboard: live usage, switching, and auto-switching for Claude Code and Codex, all keyboard-driven. Use Provider: Claude Code… in the menu to change providers. Arrow-key and Vim-style menu navigation wraps at both ends. ccswap watch opens straight into the live monitor. Works on macOS, Linux, and Windows.
Codex accounts
ccswap can also save and switch Codex CLI logins. Log into each account with codex login, then save it before logging into the next one:
codex login
ccswap codex add
# Log in to the next Codex account, then save it too.
codex login
ccswap codex add
ccswap codex list
ccswap codex usage # fetch 5h/7d windows; prints diagnostic errors
ccswap codex switch 1
ccswap codex switch # rotate to the next saved account
ccswap codex auto --once # switch when active quota reaches the threshold
ccswap codex remove 2
Codex switching preserves the rest of CODEX_HOME (configuration, skills, sessions, and history) and replaces only auth.json. Restart Codex after switching so its running process loads the selected login. For ChatGPT-backed file logins, the dashboard reads the same read-only Codex rate-limit endpoint used by Codex and shows its primary (5h) and secondary (7d) windows. API-key accounts have no ChatGPT subscription quota, so they remain status-only. ccswap codex auto uses the same threshold, cooldown, --once, --dry-run, and JSON event controls as Claude auto-switching; it prepares the account for the next Codex launch and reports when a restart is needed.
Codex must use its documented file credential store. If your ~/.codex/config.toml says cli_auth_credentials_store = "keyring", change it to "file", run codex login, then add the account. This deliberate restriction avoids writing a guessed OS-keyring entry.
Refresh expired tokens
If an account's token expires, log back into Claude Code with that account and re-run:
ccswap add
This will update the stored credentials without creating a duplicate.
Other commands
ccswap run 2 # Run an account in this terminal only (session mode)
ccswap auto # Auto-switch when nearing rate limits (see above)
ccswap codex list # List saved Codex CLI accounts
ccswap codex switch 2 # Switch the file-backed Codex login
ccswap config # Show or edit settings (see Configuration below)
ccswap list # Show all accounts with 5h/7d usage and reset times
ccswap status # Show current account
ccswap add --slot 3 # Add account to a specific slot (prompts before overwrite)
ccswap remove 2 # Remove an account
ccswap tui # Interactive dashboard (also: bare `ccswap`)
ccswap watch # Dashboard, opened on the live watch page
ccswap upgrade # Upgrade ccswap to the latest version
ccswap purge # Remove all ccswap data
The legacy cswap command remains available as a compatibility alias; use ccswap for new scripts.
Tips
- Do you need to restart after switching? Usually not. On Linux and Windows, credentials are stored in a file and Claude Code re-reads them whenever that file changes, so the new account takes effect on your next message — no restart needed. On macOS, credentials live in the Keychain, which Claude Code caches for about 30 seconds; a running session picks up the switch once that cache expires. Restart Claude Code (or close and reopen the VS Code extension tab) only if you want the change to apply instantly.
- Continuing sessions after switching: You can keep using the same Claude Code session after switching — run
ccswap switchin any terminal and carry on. If you'd prefer a clean start, close and reopen Claude Code (or the VS Code extension tab) and use--resumeto pick your previous session. Either way, the first message on the new account may use extra usage as its conversation cache rebuilds.
How it works
- Backs up provider credentials when you add an account
- Swaps Claude Code credentials or Codex's file-backed
auth.jsonwhen you switch - Account credentials stored securely using platform-appropriate methods
- Switches (manual and automatic) hold Claude Code's own credential locks while writing, so a swap never interleaves with a token refresh
- Auto-switch freshens a target's token before activating it, and quarantines accounts whose refresh token has died (recover with
ccswap add --slot N) - Codex usage checks refresh inactive saved logins when possible; running Codex sessions must be restarted after a Codex account switch
Data locations
| Platform | Credentials | Config backups |
|---|---|---|
| Windows | File-based (inside the backup directory, under credentials/) |
~/.claude-swap-backup/ |
| macOS | macOS Keychain | ~/.claude-swap-backup/ |
| Linux / WSL | File-based (inside the backup directory, under credentials/) |
${XDG_DATA_HOME:-~/.local/share}/claude-swap/ |
Session-mode profiles (ccswap run) live under the backup directory in sessions/. Tool preferences (settings.json) and auto-switch state (autoswitch_state.json — cooldown and quarantined accounts; delete it to reset) live in the backup directory root.
On Linux/WSL, set XDG_DATA_HOME to override the default location.
Menu bar (macOS)
Optional macOS menu bar app — usage at a glance, click to switch
Needs the menubar extra (macOS only):
uv tool install 'ccswap[menubar]' # or: pipx install 'ccswap[menubar]'
ccswap menubar
Shows every account's 5h / 7d / spend usage and switches with a click (specific / rotate / best / next-available), plus the TUI's add / remove / refresh actions. Enable Settings → Auto-switch accounts to run the same engine as ccswap auto in the background; it shares the autoswitch.* settings, so the menu bar and CLI stay in sync. Off until you turn it on.
Advanced
Configuration
Tool preferences live in settings.json in the backup root; ccswap config reads and edits it with validation, so you never have to find the file or guess valid ranges.
Commands & usage
ccswap config # list effective settings ("(default)" = not set)
ccswap config get autoswitch.threshold
ccswap config set autoswitch.threshold 80 # validated: rejects out-of-range values loudly
ccswap config unset autoswitch.threshold # back to the default
ccswap config path # where settings.json lives
ccswap config --help lists every key with its valid range and default. Hand-editing the file still works — ccswap config is just a safer front door. list and get take --json for scripting.
Backup and migration
Move account data between machines or back it up:
ccswap export backup.cswap # All accounts to a file
ccswap export backup.cswap --account 2 # One account
ccswap export backup.cswap --full # Include full local ~/.claude.json (same-PC backup)
ccswap import backup.cswap # Skips accounts that already exist
ccswap import backup.cswap --force # Overwrite existing
The export file is plaintext JSON. If you need encryption, pipe through your tool of choice (e.g. ccswap export - | gpg -c > backup.gpg).
If an imported account is the one you're currently logged in as, activate the imported credentials with ccswap switch N --force (a plain switch to the current account is a safe no-op and won't touch the import).
JSON output for scripting
Add --json to list, status, or switch to emit a single machine-readable JSON object on stdout (human-readable notices go to stderr). Useful for scripting auto-swap and quota tracking.
ccswap list --json # all accounts with usage/quota
ccswap status --json # current active account
ccswap switch --strategy best --json # switch, then report the result
ccswap switch 2 --json
Example output & schema notes
{
"schemaVersion": 1,
"activeAccountNumber": 2,
"accounts": [
{ "number": 2, "email": "you@example.com", "active": true, "usageStatus": "ok",
"usage": { "fiveHour": { "pct": 25.0, "resetsAt": "2026-06-22T23:29:59Z" },
"sevenDay": { "pct": 16.0, "resetsAt": "2026-06-26T17:59:59Z" } } }
]
}
Every payload carries a schemaVersion (currently 1); on a handled error stdout is {"schemaVersion":1,"error":{...}} with a non-zero exit code. --switch/--switch-to report {"switched": true|false, "from": …, "to": …, "reason": …}.
Usage is served from a per-account cache: when the usage API is briefly unreachable, the last-known numbers are shown instead of nothing (the human view marks them with their age, e.g. · 2m ago). Rows with usage carry additive usageFetchedAt/usageAgeSeconds fields telling you how old the measurement is.
ccswap auto --json emits an event stream instead — one JSON object per line ({"schemaVersion":1,"event":"switch","ts":…, …} with kinds like poll, switch, no-switch, account-quarantined, all-exhausted, error). The contract is additive: new kinds and fields may appear, so scripts should ignore unknown ones.
Add an account from a raw token or API key
If you only have a long-lived setup-token (e.g., produced by claude setup-token)
or a managed API key (sk-ant-api...) and you don't want to log in via the browser
flow first — useful on headless servers or when receiving a token from another
machine — register it directly. The token type is auto-detected:
ccswap add-token sk-ant-oat01-... # OAuth setup-token
ccswap add-token sk-ant-api03-... # managed API key
ccswap add-token sk-ant-oat01-... --slot 3
ccswap add-token - --slot 3 # read token from stdin
ccswap add-token --email user@example.com # optional label override
--email is optional; omitted values use setup-token-{slot}@token.local
(or api-key-{slot}@token.local for API keys). No Anthropic API calls are made.
API-key accounts. An sk-ant-api... value registers a managed API-key account
(the kind Claude Code uses after /login with a key) rather than an OAuth
setup-token. It switches like any other account; since API keys have no subscription
quota, they show no usage and the usage-aware switch strategies never skip them as
rate-limited.
Uninstall
Remove all data:
ccswap purge
Then uninstall the tool:
uv tool uninstall ccswap
# or
pipx uninstall ccswap
Requirements
- Python 3.12+
- Claude Code and/or Codex CLI
- A file-backed login for managed Codex accounts
License
MIT. This fork retains the original project's copyright and license notice; see LICENSE. Upstream: realiti4/claude-swap.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ccswap-0.20.0.tar.gz.
File metadata
- Download URL: ccswap-0.20.0.tar.gz
- Upload date:
- Size: 587.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.16 {"installer":{"name":"uv","version":"0.11.16","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1b6ff2b23d7c5999a2d9b3c696a6d6f1785ce56a3ef0a427a41cd9360ecc4111
|
|
| MD5 |
6118134b4b0d20b553619e81eb4215db
|
|
| BLAKE2b-256 |
bce74c0d4d6851d7c0de330f842ea4f0cf27f25a116dfe4a12b1fe3e6396d7bb
|
File details
Details for the file ccswap-0.20.0-py3-none-any.whl.
File metadata
- Download URL: ccswap-0.20.0-py3-none-any.whl
- Upload date:
- Size: 199.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.16 {"installer":{"name":"uv","version":"0.11.16","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d86e23b6247e5cebedf162eb957dfb575a09382ac937479c88dffb317d9ebd21
|
|
| MD5 |
49d8cc7beabb07f2c18dec023fb7757f
|
|
| BLAKE2b-256 |
16b542d3da93faa6cb0898e94bfc4e40c2d39f862b53f338f58ebd572192b8ab
|