Switch Between Multiple Claude Code Accounts (Without Losing Your History)
The Problem
If you use more than one Claude Code account, the usual advice is to keep a separate config directory per account. That works, but it splits your chat history in two — each account only sees its own sessions. What most people actually want is the opposite: one shared history, and a quick way to flip which account is logged in.
On macOS this turns out to be easy, because the pieces live in two different places:
- Your login token is stored in the macOS Keychain (service
Claude Code-credentials), not in the config folder. - Your chat history and settings live in
~/.claude. - Your account identity (email, org, user id) sits in
~/.claude.json.
So if we keep ~/.claude shared and swap only the token and identity, history stays intact for every account.
The Script
Save this as ~/bin/claude-account and make it executable:
#!/usr/bin/env bash
# claude-account — switch the Claude Code account while keeping ONE shared
# config dir (~/.claude), so chat history is identical across accounts.
# Only the Keychain token and the identity in ~/.claude.json are swapped.
set -euo pipefail
LIVE_SVC="Claude Code-credentials"
ACCT="${USER}"
STORE="${HOME}/.claude-accounts"
CLAUDE_JSON="${HOME}/.claude.json"
mkdir -p "$STORE"; chmod 700 "$STORE"
die() { printf 'error: %s\n' "$*" >&2; exit 1; }
bkp_svc() { printf 'claude-account:%s' "$1"; }
read_live_token() { security find-generic-password -s "$LIVE_SVC" -a "$ACCT" -w 2>/dev/null; }
write_live_token() {
security delete-generic-password -s "$LIVE_SVC" -a "$ACCT" >/dev/null 2>&1 || true
security add-generic-password -U -s "$LIVE_SVC" -a "$ACCT" -w "$1" >/dev/null
}
save_bkp_token() {
security delete-generic-password -s "$(bkp_svc "$1")" -a "$ACCT" >/dev/null 2>&1 || true
security add-generic-password -U -s "$(bkp_svc "$1")" -a "$ACCT" -w "$2" >/dev/null
}
read_bkp_token() { security find-generic-password -s "$(bkp_svc "$1")" -a "$ACCT" -w 2>/dev/null; }
dump_identity() {
python3 - "$CLAUDE_JSON" <<'PY'
import json,sys
d=json.load(open(sys.argv[1]))
json.dump({k:d[k] for k in ("oauthAccount","userID") if k in d}, sys.stdout)
PY
}
load_identity() {
python3 - "$CLAUDE_JSON" "$1" <<'PY'
import json,sys
p=sys.argv[1]; d=json.load(open(p)); d.update(json.load(open(sys.argv[2])))
json.dump(d, open(p,"w"), indent=2)
PY
}
cmd="${1:-help}"; name="${2:-}"
case "$cmd" in
save) # snapshot the currently logged-in account
blob="$(read_live_token)" || die "not logged in"
save_bkp_token "$name" "$blob"
dump_identity > "$STORE/$name.json"; chmod 600 "$STORE/$name.json"
echo "saved '$name'" ;;
switch) # make a saved account active
blob="$(read_bkp_token "$name")" || die "no saved token for '$name'"
write_live_token "$blob"
load_identity "$STORE/$name.json"
echo "switched to '$name' (restart any running claude session)" ;;
list)
for f in "$STORE"/*.json; do echo " $(basename "$f" .json)"; done ;;
*) echo "usage: claude-account {save|switch|list} " ;;
esac
Setup
# make it runnable and put ~/bin on your PATH
chmod +x ~/bin/claude-account
echo 'export PATH="$HOME/bin:$PATH"' >> ~/.zshrc
source ~/.zshrc
# you're currently logged in — snapshot this account
claude-account save work
# now log in as the second account inside Claude Code
claude # then run: /login
claude-account save personal
Daily Use
claude-account switch work # flip to the work account
claude-account switch personal # flip to the personal account
claude-account list # see saved accounts
After a switch, restart any running claude session so it picks up the new token. Because ~/.claude never changes, both accounts always see the exact same chat history.
Optional: shell aliases
alias claude-work="claude-account switch work"
alias claude-personal="claude-account switch personal"
Why This Beats Directory-Based Profiles
- Shared history — one
~/.claude, so no split sessions. - Secure — tokens stay in the encrypted Keychain, never in a plaintext file.
- Tiny — no gigabytes of duplicated plugins/history per profile.
- Fast — switching is an instant Keychain + JSON swap.
That's the whole thing: a ~40-line script that gives you clean multi-account switching on Claude Code, with your history following you everywhere.

0 Comments:
Leave a Reply