If you use Claude Code with more than one account, you know the pain.
Switch from work to personal? /logout, /login, lose your session state, watch your MCP servers vanish. Do it again tomorrow. And the day after.
195+ developers https://github.com/anthropics/claude-code/issues/18435. It's been months. No native solution.
So I built one.
The problem
Claude Code stores everything in two places:
- ~/.claude.json — your OAuth token and session
- ~/.claude/settings.json — your preferences
One set of files. One account. Want to switch? Destroy the first session, create a new one. Every time.
For developers working with a corporate account during the day and a personal account at night, this is a daily annoyance.
The discovery
Buried in Claude Code's https://code.claude.com/docs/en/env-vars, there's a variable called CLAUDE_CONFIG_DIR. It redirects where Claude Code reads and writes its config files.
An Anthropic team member https://github.com/anthropics/claude-code/issues/261:
▎ "As an immediate workaround you can use CLAUDE_CONFIG_DIR env var to set the directory to keep your profile data in."
The variable exists. It works. But using it manually is clunky — you have to remember paths, set environment variables, and manage directories yourself.
The solution: Cloak
I built https://github.com/synth1s/cloak — a CLI addon that wraps CLAUDE_CONFIG_DIR into a friendly interface.
npm install -g @synth1s/cloak
Save your current session:
cloak create work
Log out, log in with another account, save it too:
cloak create home
Switch instantly:
cloak switch work
cloak switch home
That's it. No logout. No login. Tokens, MCP servers, settings — all preserved.
How it works
Each account gets its own isolated directory:
~/.cloak/
└── profiles/
├── work/
│ ├── .claude.json
│ ├── settings.json
│ └── ...
└── home/
├── .claude.json
└── ...
When you switch, Cloak sets CLAUDE_CONFIG_DIR to point to the right directory. Claude Code reads from there. Nothing is copied, moved, or overwritten.
Concurrent sessions
Different terminal, different account. At the same time.
# Terminal A:
claude -a work
# Terminal B:
claude -a home
No conflicts. Each terminal has its own environment variable pointing to a different directory.
The shell integration story
Here's something I learned the hard way: a child process can't modify its parent's environment variables. This is an OS-level constraint.
When you run cloak switch work, the cloak binary sets the variable inside itself — but when it exits, the parent shell still has the old value.
The solution is a shell function that runs inside the shell:
eval "$(cloak init)"
This injects two functions — cloak() and claude() — that intercept the switch command and apply the export in the current shell. First time you run cloak switch, it offers to set this up automatically.
Built with TDD
Every feature was test-first. The project has 113 tests across 13 suites, all using Node.js native node:test runner — zero test framework dependencies.
The TDD discipline caught real bugs:
- A shell eval was trying to execute "You're already wearing..." as bash code (the apostrophe in "You're" broke it)
- A --print-env flag was leaking user-facing messages to stdout, corrupting the shell eval
Both would have been invisible without tests that specifically checked "stdout must contain only eval-safe shell code."
Security
The project went through a security audit before publishing:
- Path traversal: account names validated against ^[a-zA-Z0-9][a-zA-Z0-9_-]{0,63}$
- Credential files: created with 0o700 (dirs) and 0o600 (files) permissions
- Shell injection: export paths are double-quoted in eval output
- Token safety: OAuth tokens are never read, logged, or transmitted — only copied as files
- RC file safety: .bashrc modifications include a backup file and marker comment
Update — August 2026
Since this post went up: 5,300+ downloads on npm and 35 stars on GitHub — up from 13 when this was written. Three of those stars came with pull requests attached.
Cloak is at v3.1.0 now. What changed since this post:
Auto-switch by directory. Bind a cloak to a project folder and stop thinking about it:
cd ~/work/api && cloak bind work
cd ~/side-project && cloak bind home
From then on, claude picks the right account per directory.
cloak switch with no arguments now opens a picker instead of erroring — the first community contribution to land in the project, from @thekvn.
Node.js 20 is the minimum as of v3.0.0. The dependency tree had quietly outgrown the Node 18 the package advertised, and shipping a promise the code no longer honoured wasn't worth keeping. On Node 18 npm will warn and install anyway, but upgrade when you can.
135 tests across 15 suites, up from the 113 above — including a suite that pins the prompt library's contract, added after a dependency upgrade slipped through with every interactive path untested. The tests were green the whole time; they just weren't testing that.
That same release cleared a high-severity advisory inherited through a transitive dependency. npm audit is clean.
The IDE gap is still a gap.
What's next
The tool is live on npm and solving the problem for 700+ developers who installed it in the first day. The main gap is IDE support — VSCode and JetBrains extensions don't respect CLAUDE_CONFIG_DIR yet
(https://github.com/anthropics/claude-code/issues/4739).
If you're juggling multiple Claude Code accounts, give it a try:
npm i -g @synth1s/cloak
cloak create work
cloak create home
cloak switch work
The source is on GitHub: https://github.com/synth1s/cloak
Built because 195+ developers asked for it and nobody had built it yet.
Top comments (1)
Been fighting this for a week now! Appreciate you taking the time to break this down.