Practical Guides••8 min read

Two Claude Code accounts on one machine — without duplicating your config

Claude Code lacks an account switcher. The token-swap workaround costs you account identity and connectors. Here's a cleaner approach using CLAUDE_CONFIG_DIR that keeps configuration in lockstep while giving each account its own real login.

claude-codeai-coding-toolsdeveloper-toolsmacosvscodemulti-accountconfigurationsymlinkskeychainenv-vars
A developer's desk with two distinct workspaces symbolized by separate credential badges connected to a single laptop

If you've ever tried to switch between work and personal Claude Code accounts on the same machine, you've discovered the quiet frustration: there's no account switcher. One machine, one login. That's it.

The internet's favorite workaround involves swapping long-lived OAuth tokens via a shell function. It works — technically. But it quietly costs you account identity, claude.ai connectors, and any graceful way to switch accounts inside the editor. You're not really switching accounts. You're impersonating a machine credential.

There's a cleaner approach. It requires understanding one thing: where Claude Code actually stores your login.

The OAuth token trick and why it falls short

The token-swap method looks elegant at first. You export a token, write a shell function to swap it, and suddenly you can authenticate as either account. Problem solved?

Not quite.

That token authenticates a machine, not an account. When you swap tokens, Claude Code doesn't know you've changed identities. It has no concept of "you" beyond that credential. Your conversation history doesn't follow you. Your claude.ai connectors — the integrations that let Claude Code talk to your browser sessions, your connected services, your account-specific settings — remain bound to whoever originally logged in.

You're wearing someone else's badge. The building lets you in, but the elevators don't recognize your floor access.

The core insight: isolation lives in the Keychain

Here's what actually matters: Claude Code stores its authentication credential in macOS Keychain, namespaced by a hash of your config directory.

That's the whole trick.

When you launch Claude Code, it looks at the CLAUDE_CONFIG_DIR environment variable (defaulting to ~/.claude if unset). It hashes that path and uses the hash to look up — or create — a Keychain entry. Different config directory? Different Keychain credential. Different account.

This means you can have two completely separate logins, each with its own real OAuth flow, its own Keychain credential, and its own account identity. No token swapping. No impersonation.

What to share and what to separate

The config directory contains several things:

  • Configuration files — your settings, preferences, UI state
  • Skills and plugins — the custom capabilities you've added
  • Agents — any agent configurations you've built
  • Credentials — the Keychain reference that identifies your account
  • History — your conversation logs
  • Connectors — account-bound integrations with claude.ai

You want to share the first three. You want to separate the last three.

Here's the mental model: configuration is yours, regardless of which account you're using. Credentials, history, and connectors are account-specific. They should never cross the boundary.

The setup: symlinks and one real file

Create a second config directory for your secondary account:

mkdir -p ~/.claude-work

Now symlink everything shareable from your primary config:

ln -s ~/.claude/settings.json ~/.claude-work/settings.json
ln -s ~/.claude/skills ~/.claude-work/skills
ln -s ~/.claude/plugins ~/.claude-work/plugins
ln -s ~/.claude/agents ~/.claude-work/agents

Do not symlink these files:

  • credentials.json (if it exists)
  • history/ directory
  • Any file containing account-specific state

The credentials file is the critical one. If it exists in your primary config, don't symlink it. If it doesn't exist yet, don't worry — Claude Code will create it on first login. The point is that each config directory gets its own credentials file, which references its own Keychain entry.

If you symlink the credentials file, both accounts will share the same Keychain credential. You'll have recreated the token-swap problem with extra steps.

Logging in to the secondary account

Set the environment variable and run the login command:

export CLAUDE_CONFIG_DIR=~/.claude-work
claude login

This opens the OAuth flow in your browser. Log in with your secondary account (work account, client account, whatever). Claude Code creates a new Keychain entry, hashed to ~/.claude-work, and stores the credential there.

You now have two real logins. Two real accounts. One machine.

Editor integration: VS Code profiles

Here's where it gets slightly annoying. The claude.configDir setting in the VS Code extension is machine-scoped, not workspace-scoped. You can't set it per-project.

The workaround: VS Code profiles.

Create a profile for your secondary account:

  1. Open the Command Palette and search for "Profiles: Create Profile"
  2. Name it something obvious — "Claude Work" or "Client Account"
  3. In that profile's settings, add:
{
  "claude.configDir": "~/.claude-work"
}

When you switch VS Code profiles, the Claude Code panel automatically uses the corresponding config directory — and therefore the corresponding account.

It's not as smooth as a built-in account switcher, but it's real account separation, not credential impersonation.

Verify it rather than trusting it

Don't assume this works. Prove it.

Step 1: Check Keychain entries

Open Keychain Access and search for "claude". You should see two entries with different names (the hashes of your config directories). If you see only one, something went wrong.

Step 2: Verify account identity in each context

With your primary config:

unset CLAUDE_CONFIG_DIR  # or export CLAUDE_CONFIG_DIR=~/.claude
claude whoami

With your secondary config:

export CLAUDE_CONFIG_DIR=~/.claude-work
claude whoami

These should show different account emails. If they show the same email, your symlinks are wrong — you've probably symlinked the credentials file.

Step 3: Test connector isolation

If you use claude.ai connectors (browser integrations, connected services), verify they're not crossing over. Log into claude.ai with each account and check which connectors appear. They should be different.

The failure mode: login always targets the launching config

Here's the gotcha that bit me during setup.

I had both terminals open. One was set to ~/.claude, the other to ~/.claude-work. I ran claude login in the work terminal, completed the OAuth flow with my work account, and... my primary account got reassigned.

Why? Because I'd run claude (without the environment variable) earlier in that shell session. The process remembered its original config directory. The export I ran afterward only affected new processes, not the already-running shell's idea of where Claude Code lives.

The fix: always start a fresh shell, or verify the environment variable is set before any Claude Code process runs:

echo $CLAUDE_CONFIG_DIR

If it's empty or wrong, fix it before running claude login.

When in doubt, open a brand new terminal window, set the variable as the first command, then run the login. This eliminates any cached state from previous Claude Code invocations.

What you cannot carry over

Some things are account-bound at the server level, not the config level. No file-level trick will transfer them:

  • claude.ai connectors — these are tied to your Anthropic account, not your local machine
  • Conversation history on claude.ai — same deal
  • Account-specific rate limits or plan features — obviously

The symlink approach shares local configuration. It doesn't merge cloud accounts. If you've built elaborate connector setups on your personal account and want them on your work account, you'll need to recreate them.

Honest limitations

This approach has real constraints:

  • macOS only — the Keychain namespacing is macOS-specific. Linux and Windows store credentials differently, and I haven't tested whether the same isolation applies.
  • VS Code profiles are clunky — switching profiles isn't instant, and you might forget which profile you're in.
  • No automatic switching — you still have to manually switch profiles or set environment variables. There's no "detect which account based on the repo" magic.
  • Symlink maintenance — if Claude Code adds new config files in future versions, you'll need to decide whether to symlink them.

When to re-verify

Re-run the verification steps after:

  • Claude Code updates (the config structure might change)
  • macOS updates (Keychain behavior might change)
  • Any time you're unsure which account you're using

The claude whoami command is fast. Use it liberally.

Rollback is simple

If this setup causes problems, rollback is a single command:

rm -rf ~/.claude-work

Your primary config is untouched. Your primary account is unaffected. The symlinks pointed from the secondary directory to the primary, not the other way around.

You're back to single-account mode with no cleanup required.

The bottom line

Claude Code's lack of an account switcher is frustrating, but the architecture actually supports clean multi-account setups — if you understand where the credential boundary lives.

The key insight: CLAUDE_CONFIG_DIR controls Keychain namespacing. Different directory, different credential, different account. Symlink the configuration. Keep the credentials separate.

It's not as elegant as a built-in switcher would be. But it's real account separation, with shared settings, and no token impersonation. For developers juggling work and personal accounts — or client accounts, or test accounts — that's a meaningful upgrade over the alternatives.

Entvas Editorial Team

Entvas Editorial Team

Helping businesses make informed decisions

Related Articles

Ready to Transform Your Business Technology?

Schedule a strategy session to discuss how we can help you build unified, AI-ready systems.