Skip to main content

Multi-account switcher for Claude Code

Project description

claude-swap

Multi-account switcher for Claude Code. Easily switch between multiple Claude accounts without logging out. Works with both the Claude Code CLI and the VS Code extension.

Installation

Using uv (recommended)

uv tool install claude-swap

Using pipx

pipx install claude-swap

From source

git clone https://github.com/realiti4/claude-swap.git
cd claude-swap
uv sync
uv run cswap --help

Updating

cswap --upgrade        # uv/pipx installs on macOS/Linux: auto-detects and upgrades
# or run your installer directly:
uv tool upgrade claude-swap
pipx upgrade claude-swap

Usage

Add your first account

Log into Claude Code with your first account, then:

cswap --add-account

Add more accounts

Log in with another account, then:

cswap --add-account

Switch accounts

Rotate to the next account:

cswap --switch

Or switch to a specific account:

cswap --switch-to 2
cswap --switch-to user@example.com

Or let claude-swap auto-pick by remaining quota — cswap --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 claude-swap 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:

cswap auto                     # foreground loop, polls every 60s
cswap auto --threshold 80      # switch earlier
cswap auto --once              # single check-and-switch, for cron/scripts
cswap auto --dry-run           # log what it would do, never switch
How it behaves & advanced usage
  • Switches cooperate with Claude Code's own credential locks, so a swap can never collide with a token refresh mid-session.
  • A cooldown (default 5 min) and a hysteresis margin keep it from flip-flopping between accounts near the line; when every account is exhausted it sleeps until the earliest quota reset.
  • An account whose refresh token has died is quarantined — taken out of rotation and reported — until you log in with it and re-run cswap --add-account --slot N.
  • API-key accounts are never rotated onto unless you pass --include-api-key-accounts (they bill per token).

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 * * * * cswap auto --once --json >> ~/.cswap-auto.log 2>&1

Defaults are configurable in settings.json in the backup root (see Data locations) — flags override it:

{ "schemaVersion": 1, "autoswitch": { "threshold": 90, "intervalSeconds": 60, "cooldownSeconds": 300 } }

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.

cswap run 2                     # launch Claude Code as account 2, here only
cswap run user@example.com      # by email
cswap run 2 -- --resume         # everything after '--' is forwarded to claude
cswap 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.

Refresh expired tokens

If an account's token expires, log back into Claude Code with that account and re-run:

cswap --add-account

This will update the stored credentials without creating a duplicate.

Other commands

cswap run 2                     # Run an account in this terminal only (session mode)
cswap auto                      # Auto-switch when nearing rate limits (see above)
cswap --list                    # Show all accounts with 5h/7d usage and reset times
cswap --status                  # Show current account
cswap --add-account --slot 3    # Add account to a specific slot (prompts before overwrite)
cswap --remove-account 2        # Remove an account
cswap --tui                     # Launch the interactive arrow-key menu
cswap --upgrade                 # Upgrade claude-swap to the latest version
cswap --purge                   # Remove all claude-swap data

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 cswap --switch in 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 --resume to 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 OAuth tokens and config when you add an account
  • Swaps credentials when you switch accounts
  • 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 cswap --add-account --slot N)

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 (cswap 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. Data from older installs under ~/.claude-swap-backup/ is migrated automatically on first run.

Advanced

Backup and migration

Move account data between machines or back it up:

cswap --export backup.cswap                  # All accounts to a file
cswap --export backup.cswap --account 2      # One account
cswap --export backup.cswap --full           # Include full local ~/.claude.json (same-PC backup)
cswap --import backup.cswap                  # Skips accounts that already exist
cswap --import backup.cswap --force          # Overwrite existing

The export file is plaintext JSON. If you need encryption, pipe through your tool of choice (e.g. cswap --export - | gpg -c > backup.gpg).

If an imported account is the one you're currently logged in as, activate the imported credentials with cswap --switch-to N --force (a plain --switch-to of the current account is a safe no-op and won't touch the import).

JSON output for scripting

Add --json to --list, --status, --switch, or --switch-to to emit a single machine-readable JSON object on stdout (human-readable notices go to stderr). Useful for scripting auto-swap and quota tracking.

cswap --list --json                 # all accounts with usage/quota
cswap --status --json               # current active account
cswap --switch --strategy best --json   # switch, then report the result
cswap --switch-to 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": …}.

cswap 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:

cswap --add-token sk-ant-oat01-...           # OAuth setup-token
cswap --add-token sk-ant-api03-...           # managed API key
cswap --add-token sk-ant-oat01-... --slot 3
cswap --add-token - --slot 3                 # read token from stdin
cswap --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:

cswap --purge

Then uninstall the tool:

uv tool uninstall claude-swap
# or
pipx uninstall claude-swap

Requirements

  • Python 3.12+
  • Claude Code installed and logged in

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

claude_swap-0.16.0b1.tar.gz (206.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

claude_swap-0.16.0b1-py3-none-any.whl (117.9 kB view details)

Uploaded Python 3

File details

Details for the file claude_swap-0.16.0b1.tar.gz.

File metadata

  • Download URL: claude_swap-0.16.0b1.tar.gz
  • Upload date:
  • Size: 206.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for claude_swap-0.16.0b1.tar.gz
Algorithm Hash digest
SHA256 cb9607fc68efdb9b356fc84990474493a98c13d05d1cb7419748db592008dcb0
MD5 a0e96c34b6eb4a9e14da5cb6c15ef2fa
BLAKE2b-256 c4748b7619b6b1bc90a822fdeee4e02067f53555a8888dd9f2a5261cc4a430b5

See more details on using hashes here.

Provenance

The following attestation bundles were made for claude_swap-0.16.0b1.tar.gz:

Publisher: publish.yml on realiti4/claude-swap

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file claude_swap-0.16.0b1-py3-none-any.whl.

File metadata

  • Download URL: claude_swap-0.16.0b1-py3-none-any.whl
  • Upload date:
  • Size: 117.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for claude_swap-0.16.0b1-py3-none-any.whl
Algorithm Hash digest
SHA256 25988f36382e229c14987f69d5712fc960ecc997b08dcac286db21abc16f4d13
MD5 da89b97a4648b1c6957c98df114e16a2
BLAKE2b-256 19d5d893c3402763649cfdfb201689128dc0aec5ec808972bd43b3ca9bf46ddc

See more details on using hashes here.

Provenance

The following attestation bundles were made for claude_swap-0.16.0b1-py3-none-any.whl:

Publisher: publish.yml on realiti4/claude-swap

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page