I have multiple Claude Pro accounts, because ones limits runs out. Switching between them in the desktop app is annoying:

Sign out, which throws the sign-in away.
Sign in with the other address and go find the email code.
Notice your Claude Code chat is gone from the sidebar, because chats are listed per account.
Guess which account still has room, since usage only shows for the one you are signed in to.
So I went digging in the app's data folder to see what a "sign-in" actually is. Here is what I found, on Windows with the Microsoft Store version (it is an Electron app, so most of this carries over to the direct download and macOS).

Finding the data folder is the first puzzle
The direct download keeps its data in %APPDATA%\Claude. The Store version is an MSIX package, and MSIX apps get their AppData virtualized. For a long time the real folder was:

%LOCALAPPDATA%\Packages\Claude_pzs8sxrjxfjjc\LocalCache\Roaming\Claude
The fun part: every process Claude starts, including the terminals Claude Code opens, sees that folder as %APPDATA%\Claude, and their own AppData writes get redirected into the package too. The registry is virtualized the same way. If a tool runs from inside a Claude Code shell and writes to HKCU...\Run, real Windows never sees it. The way out is to launch through explorer.exe, which starts the process outside the package.

Then in version 2.42304 Claude moved its data out of the package to:

%LOCALAPPDATA%\Claude-Data\claude_pzs8sxrjxfjjc
leaving only a small marker file behind. Anything that hardcoded the old path broke overnight, and a few people who ran several profiles with --user-data-dir lost that setup with the same update. Lesson: look the folder up every time, never cache it.

What a sign-in actually is
It lives in two places inside that folder.

config.json holds three entries that matter:

oauth:tokenCacheV2, the token cache, encrypted
oauth:tokenCache, the older format
lastKnownAccountUuid
The encryption is Chromium's standard scheme: the value starts with v10, followed by AES-256-GCM. The AES key sits in the Local State file next to it, and that key is itself protected with DPAPI for the current Windows user (on macOS it lives in the keychain instead). So nothing is readable by another user or on another machine, but your own user can decrypt it with one CryptUnprotectData call.

Network/Cookies holds the web session. On macOS it sits directly in the data folder, without the Network subfolder (a contributor found that one, I had only tested Windows).

The tokens last about a month. That is the useful bit: if you save those three entries plus the cookie file while Claude is closed, you can put them back later and the app starts up signed in to that account. No email code.

Chats are just files
Claude Code chats in the desktop app are listed per account and organization:

claude-code-sessions///local_.json
Each entry is a small JSON file with no account id inside, so copying it into the other account's folder simply makes the chat show up there. The actual conversations live in ~/.claude/projects and are already shared by every account. Deleted chats leave a deleted_ file, which you have to respect, or deleted chats keep coming back.

Projects work the same way, in local-agent-mode-sessions///spaces.json.

Quitting the app cleanly is harder than it sounds
To swap files, Claude has to be fully closed. Sending the window a normal close message only hides it in the tray. What works is telling it Windows is ending the session (WM_ENDSESSION), the way an installer does. Claude then quits properly in about a second.

There is one more detail. When Claude quits in the middle of a reply, it marks that chat with interruptedByQuitAt and continues it on the next start. But it only does that on its own clean quit. So a switcher has to find the chats that were mid-reply itself (by reading the end of recently written conversation files) and set that mark, otherwise the chat just stands still after the switch.

So I built a tray tool for it
All of this became Claude Account Switcher, a small open source tray app written in Go:

Right-click the tray icon, pick an account. Claude quits, the sign-in is swapped, Claude starts again. A few seconds.
Your Claude Code chats and projects come along, and chats that were mid-reply continue on the new account.
It shows 5-hour and weekly usage for every saved account at once, with reset times.
Optional auto-switch when the active account passes a threshold you pick.
Tokens stay encrypted exactly as Claude stored them and are only sent to api.anthropic.com. Before every switch it backs up config.json and the cookies, and rolls back if a step fails.

Install on Windows:

winget install SnlperStripes.ClaudeAccountSwitcher
or grab the exe from the releases. There is a macOS build too, but it has not been tested on a real Mac yet, so reports are very welcome.

It is unofficial and not affiliated with Anthropic, and it is Apache 2.0. If you have hit one of these walls yourself, I would love to hear how you dealt with it in the comments.