Claude desktop profiles
One real /Applications/Claude.app, one profile folder per account through --user-data-dir, one guarded Dock launcher per account. The existing app, its sign-in and the default profile are never touched. Undo is deleting the launchers and the extra folders.
Derived from Chad Timblin's guide Run a Separate Claude Desktop App for Each Claude Account. macOS only. Windows is unverified; that guide's appendix has the known notes.
Ground rules
- Never modify, move, rename, duplicate or re-sign
/Applications/Claude.app. Not as a fallback either. If step 2 fails, stop and report; do not offer a clone. - Never write into the default profile
~/Library/Application Support/Claude. - Never launch a profile that is already running. The app has no single-instance lock on macOS: two launches of one folder give two live processes sharing one folder (verified 2026-11-04 on v4.16336.0, and 2026-07-11 on v1.20186.1). A launcher's focus path must never fall back to relaunching.
- Sign-ins are the user's job, with exactly one instance running. Google and SSO logins round-trip through the browser and come back by a
claude://link, which macOS hands to whichever instance is already running. With two open, the signed-in one receives it and logsGoogle sign-in code does not answer a sign-in this app started; ignoring, and the other stays on the login screen. Never handle passwords. - Mind your runtime. If this session runs inside the Claude desktop app, quitting it kills the session: hand quit steps to the user as text. If
~/Libraryis unreadable, tell the user to run this from a terminal. - Delete only test artifacts you created this session. The script's smoke test refuses to touch a folder that existed before it ran.
Scope
The whole job is about ten commands plus a README. Facts about the installed version come from the throwaway test in step 2, never from reading app.asar, entitlements, fuses or Electron internals. Custom launcher icons only when the user asks.
Steps
S is scripts/claude-profiles.sh in this skill's directory; bash $S prints usage. AppleScript sources go to CLAUDE_LAUNCHER_SOURCES (default ~/Documents/claude-multi-account/launcher-sources); point it at the README folder from step 5 if the user picks another. If /Applications is not writable, set CLAUDE_LAUNCHER_DIR=$HOME/Applications. verify-mechanism writes and removes /tmp/claude-profile-test-<pid>.
- Inputs. The primary account is whichever is signed in now. It keeps the default profile and gets
Claude (<Label>).app. Every other account gets the folderClaude-<Label>and its ownClaude (<Label>).app. Ask for labels and emails if they were not given. To tell which account is signed in, comparelastKnownAccountUuidin the default profile'sconfig.jsonwithoauthAccountin~/.claude.json; if they differ, ask the user which email the app shows. No profile folder name may be a prefix of another;buildrefuses a clash with existing folders and with folders named by other launcher sources. Folders under Application Support that start withClaudebut hold noCookiesfile (such asClaude-3p) are not profiles; leave them alone. - Preflight and mechanism.
bash $S preflight. Warn the user that a window will appear, thenbash $S verify-mechanism. FAIL means stop and tell the user. - Build and smoke. Primary:
bash $S build <Label> default. Each other account:bash $S build <Label> Claude-<Label>, thenbash $S smoke <Label> Claude-<Label>. Never smoke the primary launcher: its focus path triggers the Automation prompt at a moment the user does not expect. If launchers or a README from an earlier run exist, back the README folder up, rebuild in place (buildoverwrites), and never delete a launcher you did not create this session. - Migration check. claude.ai-side things (conversations, projects, connectors) follow the login. Desktop-side things do not. MCP servers live in
<profile>/claude_desktop_config.json: copy entries selectively, since a wholesale copy doubles every local server process. Scheduled tasks live in<profile>/local-agent-mode-sessions/<uuid>/<uuid>/scheduled-tasks.jsonand<profile>/claude-code-sessions/..., run only while their account is signed in inside a running instance, and migrate with the target instance quit: copy fields exactly, dropnotifySessionId, keeplastRunAt, setenabled: falseon the old copy and keep it. Thepreferencesblock of that same file (Cowork settings, bypass-permissions gate, allowed origins, folder grants, Chrome extension pairing) stays with the default profile; list in the README what the user may want to set again, and note that only one instance should pair with the Chrome extension.~/.claudeis shared by every instance, so the global CLAUDE.md applies to all of them. - README. Fill
references/readme-template.mdinto a folder the user names (default~/Documents/claude-multi-account). - Hand off with the text below, then stop. Before each sign-in the user reports, run
bash $S psand confirm it prints nothing; if it does not, quit the instances yourself (killon their pids, SIGTERM is a clean quit for this app) and only then tell the user to click the one launcher. Every running window looks the same, so "quit the signed-in one" is the step users get wrong. - When the user reports back:
bash $S psmust show every instance on a distinct profile with a distinctaccount=UUID.
Hand-off text
With only one instance open at a time:
- Drag the launchers from Applications into the Dock and remove the plain Claude tile: once several instances run, that tile lights up for all of them and focuses whichever one macOS picks.
- Quit every Claude window: press Cmd+Q in each until none is left. All windows look identical, so do not try to keep one. A sign-in only completes when exactly one instance is running.
- Click
Claude (<Label2>), sign in with that account, then quit it the same way. Repeat for each further account, always with nothing else running.- Click
Claude (<Label1>). The primary account is still signed in.- From now on open any combination. To quit one instance only, click its window first, then Cmd+Q.
The first time a launcher focuses a running instance, macOS asks to let it control System Events. Click Allow; denying only disables auto-focus. Running tiles share one icon and may merge after a Dock restart. Both are harmless.
Gotchas
| Symptom | What to do |
|---|---|
| Two instances show the same Dock icon, or merge into one tile | Cosmetic. Launchers find instances by process, not tile. |
| Quick Entry hotkey fires in only one instance | Both register it. Change or disable it in one instance's settings. |
| "Restart to update" in one instance | Quit all instances, then relaunch through the launchers. One app bundle, one update path. |
| Cowork used in a second profile | It downloads its own VM bundle, about 10 GB per profile. |
kill $pids fails with "illegal pid: 1\n2" | zsh does not word-split. Pipe through xargs kill. The script already does. |
| Test folder deleted while its instance still ran | Kill first, confirm gone, then delete. The script already does. |
| Google or SSO login opens the browser, ends on "Finish sign-in in the Claude app", and "Open Claude" does nothing; the new instance stays on the login screen | Another instance was running and took the callback. Quit every instance (verify with ps), open only that launcher, sign in again. All instances share ~/Library/Logs/Claude/main.log; grep it for [Auth] and sign-in code to see which one got it. Unchanged pids across attempts mean the user never quit. |
| Automation prompt appeared during setup | Someone opened a launcher whose instance was already running. Click Allow; nothing is broken. |
Red flags
- "The app has a single-instance lock, so relaunching on focus failure is safe." It does not. Step 2 is the only source of truth about this version.
- "Sign-in is in-app, so both instances can stay open." One instance during sign-in, always.
- "Plan B: clone and re-sign the app." Forbidden. Stop and report instead.
- "Let me inspect app.asar / entitlements / fuses first." Out of scope.
- "I'll badge the icons while I'm at it." Only on request.
- "I'll test the primary launcher too." Its focus path prompts the user. Pipeline check only.
Recovery
Reset one non-primary instance: quit it, delete its profile folder, click its launcher, sign in again. Undo everything: delete the launchers and the extra profile folders. The real app and the default profile are never involved. Rebuild a launcher from its source with osacompile -o "/Applications/Claude (<Label>).app" <source>.applescript.