Expert IT Solutions

Discover New Ideas and Solutions with CodeEssence Blogs

Get inspired with our insightful blog posts covering innovative solutions, ideas, and strategies to elevate your business.

shape image
shape image
shape image
shape image
shape image
shape image
shape image
image

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

Your email address will not be published. Required fields are marked *

Author *

Comment *