12 July 2026

Running a second Claude subscription without unpicking the first

I have two Claude subscriptions. One is mine, the other belongs to a work account, and like most people who end up in this position I'd already spent a good while getting the first one comfortable — settings just so, a memory directory full of hard-won notes, a working tree I actually trust. The last thing I wanted was to log out, log in as the other account, and discover I'd quietly traded all of that away.

So the goal was narrow and a little stubborn: use the second subscription's login, keep absolutely everything else. Here's how that turned out, in case you're staring at the same problem.

Where Claude Code keeps the thing that matters

Claude Code stores its subscription login as an OAuth token in a single file:

$CLAUDE_CONFIG_DIR/.credentials.json

Peek inside (carefully — it's mode 0600 for a reason) and you'll find one key, claudeAiOauth, holding the access token, a refresh token, the expiry, and your subscription tier. That's the whole identity. Anthropic's own authentication docs spell out the location: on Linux, credentials live in ~/.claude/.credentials.json at mode 0600, and Claude Code manages that file through /login and /logout. There is exactly one active credential per config directory, and that directory defaults to ~/.claude.

The crucial line in those same docs is this: "If you've set the CLAUDE_CONFIG_DIR environment variable on Linux or Windows, the .credentials.json file lives under that directory instead." (authentication docs) That's the entire trick. The account isn't pinned to your machine or your home directory — it's pinned to that one file inside whichever config directory is active. Point Claude Code at a different config directory and it's a clean slate: no token, so it asks you to log in.

(I'll note in passing that I confirmed all of the above on my own machine before trusting it — the file really does hold just claudeAiOauth, and a fresh config dir really does start tokenless. Documentation is lovely, but I like to see it work.)

The obvious approach, and why it's not quite right

The tidy answer is "just set CLAUDE_CONFIG_DIR to a second folder and log in there." And it works — you get a completely separate profile for the work account. (Josh Grossman wrote up this very approach for two accounts on one Windows PC, which is worth a read if you're on Windows and happy with full separation.)

The trouble is completely separate is too much. That second folder gets its own settings, its own plugins, and — the one that actually stings — its own memory and project history. All the notes I'd accumulated would be sitting back in ~/.claude, invisible to the work account. I'd have swapped one annoyance for another.

What I actually wanted was a profile that shares everything except the credential.

The fix: share the environment, isolate only the login

The pieces inside ~/.claude split cleanly into two groups. The credential is account-specific. Almost everything else — settings.json, your plugins, and the projects/ directory where the per-project memory and history live — is account-agnostic. There's no reason the work account can't read the very same files.

So the script gives the work account its own config dir, then symlinks the shared pieces back to my personal one. Only .credentials.json is left to stand on its own.

I called mine claude-work (it launches the work subscription — name yours whatever makes sense):

#!/usr/bin/env bash
set -euo pipefail

CLAUDE_WORK_ACCOUNT="${CLAUDE_WORK_ACCOUNT:-m.j.southgate@salford.ac.uk}"
PERSONAL_DIR="${CLAUDE_CONFIG_DIR:-$HOME/.claude}"
WORK_DIR="${CLAUDE_WORK_DIR:-$HOME/.claude-work}"

mkdir -p "$WORK_DIR"; chmod 700 "$WORK_DIR"

# Account-agnostic config to SHARE. Note .credentials.json is NOT here.
SHARE=(settings.json settings.local.json projects plugins CLAUDE.md)
for item in "${SHARE[@]}"; do
  src="$PERSONAL_DIR/$item"; dst="$WORK_DIR/$item"
  [[ -e "$src" || -L "$src" ]] || continue
  [[ -L "$dst" ]] && continue
  [[ -e "$dst" ]] && { echo "claude-work: $dst exists, leaving as-is" >&2; continue; }
  ln -s "$src" "$dst"
done

export CLAUDE_CONFIG_DIR="$WORK_DIR"
exec claude "$@"

(The real version has a bit more belt-and-braces — it finds the claude binary if it isn't on PATH, and prints a reminder to log in on first run — but that's the heart of it.)

Run it, and on the very first launch the work config dir has no token, so Claude Code drops you straight into the login flow. Run /login, sign in as the work account, and you're done — the token lands in the work dir's own .credentials.json and is refreshed automatically from then on. Your personal login back in ~/.claude is never so much as opened.

A quick ls of the new directory is reassuring: nothing but symlinks pointing home, and (after you log in) one real .credentials.json that belongs to the work account alone.

One small convenience while you're here: drop a symlink somewhere on your PATH and you can run it as a bare command, exactly like claude itself:

ln -s ~/path/to/claude-work ~/.local/bin/claude-work

Skip this and you'll be typing ./claude-work from the right directory forever, and wondering why claude-work on its own says "command not found" (don't ask me how I know).

One caveat worth knowing

Because projects/ is shared, both accounts write their session history and memory into the same place. That's exactly what you want for continuity — but it does mean you shouldn't run both accounts at the same time in the same project, or they'll be scribbling in the same notebook at once. Run them one after the other and it's a non-issue. If you'd rather keep sessions fully separate, just drop projects from that SHARE list and it reverts to an isolated history (you'll keep shared settings and plugins).

There's also a third thing in the config directory that I glossed over, and it's worth being honest about: a file called .claude.json. Unlike settings.json, it's not in the share list — each account gets its own — and it holds account-local state like your workspace-trust decisions, some per-project bits, and any user-scoped MCP servers you've configured. So the work account won't inherit those: it'll ask you to trust a workspace the first time, and user-level MCP servers won't follow it across. (In my case there were none configured at that level, so nothing was lost — but check yours before you assume.) Project-scoped MCP servers, the ones in a repo's own .mcp.json, live in your working directory and are available to both, because they were never in the config directory to begin with.

One more thing the docs are worth reading for: there's an authentication precedence order, and ANTHROPIC_API_KEY sits above your subscription login. So if you've got that variable exported somewhere (a leftover from some API experiment, say), it'll quietly override the /login you just did and you'll wonder why nothing took. If /status shows the wrong account, unset ANTHROPIC_API_KEY is the first thing to try.

A wrinkle if the second account is a work one

This one caught me out, and it's worth flagging precisely because it's the situation this whole post is about: your two subscriptions may not have the same features, even though one script logs into both. My personal account can drive a running session from my phone with Remote Control; my work account — signed in by the very same script, authenticating cleanly — cannot. Claude Code reports it's disabled by my organisation's policy.

That's not the script misbehaving, and it's not a bug. Remote Control is off by default on Team and Enterprise plans until an admin enables the toggle, and some data-retention or compliance configurations grey that toggle out entirely. The difference between my two accounts isn't on my machine at all — it's a server-side entitlement attached to the credential. If you live in a terminal (I reach this box over SSH), you'll never notice. If you were hoping to pick the work session up on your phone, that's the one thing that won't come across. A quick /status tells you which account and login method are actually active.

Worth knowing if you do want Remote Control on every session (on the account that's allowed it): the toggle is in /config under "Enable Remote Control for all sessions", which persists as a settings.json key, remoteControlAtStartup: true. (That key isn't in the published settings reference — I dug it out of the binary — but it's read straight from your settings.) Here's the sharp edge that follows from the design above: because settings.json is shared between both accounts, flipping it on means the work account will also try to start Remote Control every session and hit the policy wall each time. Harmless — a one-line notice — but if it nags, move that one key into the personal-only project-local settings rather than the shared file.

And the bit that pleasantly surprised me: your actual repos and notes don't enter into any of this. They live in your working directory, not the config dir, so they're available no matter which account you're running. The whole exercise really does come down to that one credential file.

Ta ta for now, and I hope this saves you from unpicking a setup you were happy with. Enjoy!


References

No comments:

Post a Comment