claude-code-account-manager
v0.3.0
Published
Manage multiple Claude Code accounts as isolated CLAUDE_CONFIG_DIR profiles, and launch Claude Code as any of them.
Downloads
239
Maintainers
Readme
claude-code-account-manager (ccam)
Manage multiple Claude Code accounts as
isolated CLAUDE_CONFIG_DIR profiles, and launch Claude Code as any of
them — without ever logging in and out.
$ ccam add work -d "Day job"
$ ccam add personal
$ ccam use work # launches Claude Code as "work"
$ ccam use personal # a separate account, separate history, separate login
$ ccam list
NAME LOGIN LAST USED DESCRIPTION
work yes 2m ago Day job
personal yes 1d ago(ccam list marks the account active in the current shell with * — see
Switching the current shell. ccam use
launches a child process, so it doesn't change the current shell's marker.)
Why this works
Claude Code keeps everything for an account under one directory — settings,
projects, history, and the login token — and lets you relocate that directory
with the CLAUDE_CONFIG_DIR environment variable.
The subtle part is credentials. On macOS, Claude Code stores its OAuth token in the login Keychain, not in a file. But the Keychain item's name is derived from the config dir:
| Config dir | Keychain service name |
| ----------------------- | -------------------------------------- |
| ~/.claude (default) | Claude Code-credentials |
| a custom CLAUDE_CONFIG_DIR | Claude Code-credentials-<hash> |
where <hash> is the first 8 hex chars of sha256(configDir). So each
account directory automatically gets its own, isolated login — pointing
CLAUDE_CONFIG_DIR at a different folder is all it takes to switch accounts.
On Linux/Windows the token lives in <configDir>/.credentials.json, which is
isolated for the same reason.
ccam just manages a set of these directories and launches claude with the
right one selected.
Install
npm install -g claude-code-account-managerRequires Node.js ≥ 18.18 and the claude CLI on your PATH. Check your setup
any time with ccam doctor.
Quick start
ccam add work # create an account (a fresh config dir)
ccam use work # launch Claude Code as "work"; log in when prompted
ccam use work -- --resume # extra args after `--` pass through to claude
ccam list # see all accounts and which is logged inCommands
| Command | Description |
| --- | --- |
| ccam add <name> | Create an account. -d <desc>, --from <default\|account> to seed settings.json, --use to launch right away. |
| ccam list | List accounts (* marks the one active in this shell). --json, -v for paths. Alias: ls. |
| ccam use [name] [-- args] | Launch Claude Code as an account; args after -- go to claude. |
| ccam run <name> -- <cmd> | Run any command with the account selected, e.g. ccam run work -- claude mcp list. |
| ccam sync [status\|on\|off] | Share conversation history and settings across accounts, so any account can --continue/--resume another's sessions and they share one settings.json. --all, --include-default, --no-settings, --no-future. Alias: share. |
| ccam mcp [list\|sync\|auto] | Copy user-scope MCP servers (claude mcp add -s user) across accounts. --from <default\|account>, --all, --include-default, --no-future. |
| ccam login [name] | Start Claude Code so the account can authenticate. |
| ccam shell [name] | Open a subshell with the account selected. |
| ccam remove <name> | Delete an account and its credentials. -y, --keep-credentials. Aliases: rm, delete. |
| ccam rename <old> <new> | Rename an account (migrates credentials). Alias: mv. |
| ccam current | Show which account this shell is pointed at. |
| ccam which [name] | Print an account's CLAUDE_CONFIG_DIR (for scripts). |
| ccam env [name] | Print an export line for eval/source. --shell, --unset. |
| ccam doctor | Diagnose your setup. |
Run ccam <command> --help for details on any command.
Switching the current shell (optional)
ccam use launches Claude Code directly, so no shell setup is needed. If you'd
rather flip your current shell to an account so that every later claude
invocation uses it, opt into the shell integration:
# bash / zsh — add to ~/.bashrc or ~/.zshrc:
eval "$(ccam shellenv)"
# fish — add to ~/.config/fish/config.fish:
ccam shellenv --shell fish | sourceThen:
ccam switch work # this shell now uses "work"
claude # ...as work
claude mcp list # ...still work
ccam unswitch # back to your default accountWithout the integration you can still do it manually:
eval "$(ccam env work)"Sharing history & settings across accounts (optional)
By default every account is fully isolated — separate login, settings, and
history. That's usually what you want. But sometimes you switch to a new
account (say the old one hit a limit) and want to keep working on the same
project, with the previous conversation right there to --continue and your
usual settings already applied.
ccam sync pools two things so they're shared across accounts:
- conversation history (
projects/) — any account can--continue/--resumea session another account started; - settings (
settings.json) — theme, statusline, permissions, etc. are edited once and apply everywhere.
Never shared: credentials, and .claude.json (MCP servers, project trust,
and the OAuth account identity) — those stay per-account so logins don't mix.
ccam sync on --all # all accounts share one history + settings pool…
# …and new accounts (ccam add) auto-join
ccam add temp # already sharing — no copying needed
ccam sync status # see what each account shares
cd ~/work/my-project
ccam use new-account -- --resume # resume a conversation any account startedHow it works: each participating account's projects/ directory (Claude Code's
transcripts) and settings.json become symlinks to one shared copy under
<CCAM_HOME>/shared/. No copying, no staleness — every account reads and writes
the same files.
ccam sync on <name>... # share only specific accounts
ccam sync on --all --include-default # also fold in your default ~/.claude history,
# and seed the shared settings from it
ccam sync on --all --no-settings # share history only, keep settings per-account
ccam sync on --all --no-future # share existing accounts but don't auto-join new ones
ccam sync off <name>... | --all # stop sharing; each account keeps a private
# copy of the current state and diverges from thereWhen you first enable sharing:
- History from each account is merged into the pool (a session already in the pool is never overwritten), so nothing is lost.
- Settings are a single file, so the first account in seeds the shared copy
and the rest adopt it. Because the (usually richer) default settings make the
best seed,
--include-defaultlinks~/.claudefirst. Any account whosesettings.jsondiffers is backed up tosettings.json.pre-sync.bakbefore it adopts the shared one — settings are never silently discarded.
Removing a shared account (ccam remove) only drops its symlinks — the shared
pool and every other account are left untouched.
MCP servers
User-scope MCP servers (claude mcp add -s user) live in each account's
.claude.json — the same file that holds the OAuth account identity and
per-project trust decisions, which is why ccam sync never shares it. So a
server configured in one account is invisible to the others.
ccam mcp fills that gap by copying just the server definitions (the
top-level mcpServers key — nothing else in the file is touched):
ccam mcp list # matrix: which server is defined in which account
ccam mcp sync --all # copy from the default ~/.claude.json to every account…
# …and new accounts (ccam add) get them automatically
ccam mcp sync work personal # copy to specific accounts only
ccam mcp sync --from work --all --include-default
# copy from account 'work' everywhere, incl. the default
ccam mcp auto [on|off] # show or set the auto-copy for new accountsTwo things to know:
- Copies, not links. Unlike history/settings sharing there's no live sync —
after adding a new server, rerun
ccam mcp sync. (--allkeeps future accounts covered automatically;--no-futureopts out.) - Auth doesn't travel. Server definitions are copied; servers that
authenticate (OAuth via
/mcp) still need a one-time login per account. Copying is additive: servers only defined in the target account are kept, same-name definitions are overwritten by the source.
Avoid syncing into an account while Claude Code is actively running in it —
.claude.json is rewritten as a whole, so a concurrent write from the running
session can be lost.
Configuration
| Variable | Purpose | Default |
| --- | --- | --- |
| CCAM_HOME | Where accounts and metadata are stored. | ~/.claude-accounts |
| CCAM_CLAUDE_BIN | Path to the claude executable. | first claude on PATH |
| CLAUDE_CONFIG_DIR | Set by ccam when launching; you normally don't touch it. | — |
Account directories are created with 0700 permissions; metadata lives in
<CCAM_HOME>/store.json. When history sharing
is enabled, the shared pool lives at <CCAM_HOME>/shared/.
Notes
- The default account. Your existing
~/.claudelogin is untouched and is not managed byccam. Create accounts for the additional logins you want. - Renaming a logged-in account on macOS re-keys its Keychain entry and may
prompt for Keychain access. If migration is declined, just run
ccam login <new>again. - Seeding (
--from) copies onlysettings.json(theme, statusline, permissions, …) — never credentials, so accounts stay independent. - Sharing is opt-in. Accounts are isolated until you run
ccam sync on. Even then only conversation history andsettings.jsonare pooled — credentials and.claude.json(MCP config, project trust, account identity) stay per-account. See Sharing history & settings across accounts. To propagate MCP servers without sharing the identity file, useccam mcp sync. - Uninstall an account's footprint completely with
ccam remove <name>: it deletes the config dir and the associated Keychain entries.
License
MIT
