claude-code
ccswitch juggles Claude Code accounts from one config
Claude News
claude-codeccswitch swaps the signed-in Claude Code account with a single command and keeps one shared ~/.claude, moving only two pieces of state: the OAuth credential file and the identity keys that say who it belongs to. The tool was released as a Show HN post, with the code and documentation published on GitHub.
At a glance
- Per-account data lives in a vault under ~/.config/ccswitch as credentials.json and identity.json, while every other key in ~/.claude.json, including mcpServers and per-project trust decisions, stays untouched during a switch.
- Access tokens last about eight hours and renew themselves while an account is in use, but a parked account's refresh token, good for roughly 28 days, can lapse and force a fresh browser sign-in.
- Only one account can be active at a time, so anyone needing two sessions running in parallel terminals is pointed back at CLAUDE_CONFIG_DIR, which the project names as the alternative.
The split between shared configuration and per-account credentials is the whole argument here. MCP servers, plugins, subagents and CLAUDE.md are the expensive part of a Claude Code setup, and duplicating them per login means keeping several copies in sync by hand while each one drifts. ccswitch appears to trade multi-account concurrency away for a single global identity switch, which reads as a fit for solo work across several plans rather than for sessions running side by side.
A switch rewrites .credentials.json and two keys inside ~/.claude.json
Claude Code keeps account state in two places: ~/.claude/.credentials.json holds the OAuth access and refresh tokens, and ~/.claude.json mixes the sign-in identity with MCP servers, per-project trust decisions and other configuration. ccswitch stores only the credential file and the oauthAccount and userID keys per account, then writes both back on a switch.
Before switching away, the tool saves the live credential back into the account being left, because Claude Code renews tokens during a session and a stale copy would otherwise be restored later. Accounts are registered with ccswitch login, which opens Claude Code for /login, or with ccswitch add for an account already signed in.
ccswitch refresh --all keeps a parked account's 28-day refresh token from lapsing
An access token lasts about eight hours and refreshes itself whenever its account is active, but a stored account sits untouched, so its refresh token can expire and force a full re-authentication with a browser round-trip.
ccswitch refresh --all restores each stored account in turn, makes one small tool-free API call to exercise the token, saves the renewed credential and returns to the account it started on. Accounts whose access token is still valid are skipped with no API call at all.
The documentation suggests a daily cron entry or a systemd user timer, where Persistent=true catches up on a run missed while a laptop was asleep. Two pitfalls are flagged: cron needs PATH set so it can find both ccswitch and claude, and refresh will not run while a claude process is alive.
The vault is created mode 700 with files mode 600
Installation is a curl pipe to install.sh from the repository or a git clone followed by ./install.sh, and the tool requires bash, python3 and Claude Code. The command set also covers list, current, save, rm, rename, backup, restore, doctor and completion scripts for bash and zsh.
ccswitch backup produces an archive containing live session tokens, which the project says should be encrypted if it is kept anywhere but a local disk. ccswitch use refuses to run while a claude process is detected, unless --force is passed.
If CLAUDE_CONFIG_DIR is set, ccswitch operates on that directory instead of ~/.claude and doctor warns about it, with a documented migration path for users leaving per-account config directories. Repository-level .mcp.json, .claude/settings.json and CLAUDE.md load from the repo whichever account is active. The code is MIT licensed, and CI runs shellcheck on every push.
Keychain path still unverified
On macOS, Claude Code keeps the OAuth credential in the login keychain, so ccswitch reads and writes it with security(1), deriving the item from the service name Claude Code-credentials and the $USER account, or claude-code-user when that value is unset or contains unsupported characters. That path has been exercised against a security(1) stand-in rather than a real keychain, and confirmation on hardware is tracked in issue #1. Windows and WSL remain untested.
Comments
No comments yet. Be the first.
Join the conversation
Sign in with Google to leave a comment. Your name and avatar come from your Google profile, and the comment appears after moderation.
We only use your name and avatar from Google. We never store your email address.
