Naar inhoud
Frank Spin
Menu
Alle artikelen

Twee Claude-accounts op één Mac, zonder steeds uit te loggen

Eén laptop met een terminalprompt, met stippellijnen verbonden aan twee mappen: één met een huis, één met een koffertje.
Eén laptop met een terminalprompt, met stippellijnen verbonden aan twee mappen: één met een huis, één met een koffertje.

Ik werk voor twee bedrijven vanaf één laptop. Mijn eigen werk loopt via frankspin.nl, klantwerk voor Made by Spin via een apart Claude-account, met een eigen abonnement en eigen limieten.

Een tijdje betekende dat uitloggen en weer inloggen. Vergeet je het één keer, dan gaat een klantproject van het verkeerde budget af. Vergeet je het twee keer, dan vertrouw je de opzet niet meer.

Dus stelde ik een andere vraag. Niet “hoe installeer ik Claude twee keer?”, maar “wat maakt de ene Claude eigenlijk anders dan de andere?”

Claude Code is een map met gegevens

Het antwoord is simpel. Alles wat Claude Code van jóu maakt, staat in één map: ~/.claude. Je login, je sessiegeschiedenis, je projectgeheugen, je instellingen. Het programma zelf maakt het niet uit welke map het leest. Het leest de map die jij aanwijst.

Dat aanwijzen doe je met een omgevingsvariabele: CLAUDE_CONFIG_DIR. Zet die op een andere map en je hebt een tweede, volledig losse Claude. Zelfde programma, zelfde versie, ander account.

Er staat dus één installatie op mijn Mac, niet twee. Er zijn twee mappen. Hieronder staat de hele opzet, stap voor stap: de terminal, de desktop-app, het Dock en Chrome.

Stap 1: een tweede map die deelt wat van mij is

Twee losse mappen betekent ook dat álles dubbel en los is, en dat wil ik niet. Mijn instructies, skills en plugins zijn hoe ík werk. Die horen op beide accounts hetzelfde te zijn.

Dus heb ik het opgesplitst:

  • Gedeeld, via symlinks: CLAUDE.md, settings.json, skills/ en plugins/ in de tweede map wijzen naar die in ~/.claude. Eén bron, één keer aanpassen.
  • Gescheiden, met opzet: login, geschiedenis, sessies en projectgeheugen. Die horen bij het account en bij de klant.
mkdir -p ~/.claude-work
for f in CLAUDE.md settings.json skills plugins; do
  ln -s ~/.claude/$f ~/.claude-work/$f
done

Stap 2: de terminal kiest het account voor mij

Een wegwijzer tussen een map met een huis en een map met een koffertje.

Ik wilde geen tweede commando onthouden. De map waarin ik sta, moest het bepalen. Alles voor Made by Spin staat onder ~/dev/madebyspin, dus dat is de regel.

MCP-servers vragen één extra stap. Die staan in .claude.json, hetzelfde bestand waar ook de login in staat. Een symlink zou de login dus ook delen. In plaats daarvan kopieert een kleine functie met jq alleen de mcpServers (globaal en per project) naar het zakelijke bestand, vlak voordat dat account start.

In mijn .zshrc:

WORK_DIRS=("$HOME/dev/madebyspin")

# Kopieer MCP-servers uit het hoofdaccount, laat de login met rust
claude-work-sync() {
  local main="$HOME/.claude.json" work="$HOME/.claude-work/.claude.json"
  [[ -f "$main" ]] || return
  [[ -f "$work" ]] || echo '{}' > "$work"
  jq --slurpfile m "$main" '
    .mcpServers = ($m[0].mcpServers // {})
    | reduce ($m[0].projects // {} | to_entries[] | select(.value.mcpServers)) as $p
        (.; .projects[$p.key].mcpServers = $p.value.mcpServers)
  ' "$work" > "$work.tmp" && mv "$work.tmp" "$work"
}

claude-work() {
  claude-work-sync
  CLAUDE_CONFIG_DIR="$HOME/.claude-work" command claude "$@"
}

claude() {
  local dir
  for dir in "${WORK_DIRS[@]}"; do
    if [[ "$PWD/" == "$dir/"* ]]; then
      claude-work "$@"
      return
    fi
  done
  command claude "$@"
}

command claude slaat de functie over en start het echte programma. Sta ik in een klantmap, dan wordt claude ongemerkt het zakelijke account. Overal anders is het mijn eigen account. Ik typ overal hetzelfde.

De sync heeft jq nodig. Die zit tegenwoordig in macOS. Controleer het met which jq, of installeer hem via Homebrew.

Stap 3: één keer inloggen met het tweede account

Open een nieuwe terminal (of draai source ~/.zshrc), ga naar een klantmap en start Claude:

cd ~/dev/madebyspin
claude

Omdat ~/.claude-work nog geen login heeft, vraagt Claude je om in te loggen. Gebruik het zakelijke account. Die login komt alleen in de zakelijke map te staan, en vanaf dan gebruikt elke claude in een klantmap dat account.

Stap 4: de desktop-app werkt hetzelfde

De Claude desktop-app is een Electron-app, en Electron heeft zijn eigen versie van dezelfde truc: --user-data-dir. Wijs een andere map aan en je krijgt een tweede instantie met een eigen login, eigen cookies en eigen gebruik.

Twee keer starten zou telkens een nieuw venster openen. Daarom schreef ik een klein script dat een instantie naar voren haalt als die al draait. Dat staat in ~/.local/bin/claude-instance:

#!/bin/zsh
# Gebruik: claude-instance [user-data-dir]   (zonder argument = de gewone Claude)
dir="$1"
pid=""
for p in $(pgrep -f '^/Applications/Claude.app/Contents/MacOS/Claude( |$)'); do
  cmd=$(ps -o command= -p $p)
  if [[ -n "$dir" ]]; then
    [[ "$cmd" == *"--user-data-dir=$dir"* ]] && pid=$p && break
  else
    [[ "$cmd" != *"--user-data-dir="* ]] && pid=$p && break
  fi
done
if [[ -n "$pid" ]]; then
  osascript -e "tell application \"System Events\" to set frontmost of (first process whose unix id is $pid) to true"
elif [[ -n "$dir" ]]; then
  open -n -a /Applications/Claude.app --args --user-data-dir="$dir"
else
  open -n -a /Applications/Claude.app
fi

open -n start een nieuwe instantie, ook als Claude al draait.

Een tweede script, ~/.local/bin/claude-work-desktop, kopieert eerst de instellingen die gedeeld mogen worden uit het hoofdprofiel: lokale MCP-servers, desktop-extensies en SSH-hosts. Login en cookies blijven achter. Daarna start het de zakelijke instantie:

#!/bin/zsh
main="$HOME/Library/Application Support/Claude"
work="$HOME/Library/Application Support/Claude-Work"
mkdir -p "$work"
for f in claude_desktop_config.json extensions-installations.json extensions-blocklist.json \
         mcp-user-tool-toggles.json ssh_configs.json; do
  [[ -f "$main/$f" ]] && cp -p "$main/$f" "$work/$f"
done
for d in "Claude Extensions" "Claude Extensions Settings"; do
  [[ -d "$main/$d" ]] && rsync -a --delete "$main/$d/" "$work/$d/"
done
exec "$HOME/.local/bin/claude-instance" "$work"

Maak ze allebei uitvoerbaar met chmod +x ~/.local/bin/claude-instance ~/.local/bin/claude-work-desktop. De eerste keer dat de zakelijke instantie opent, is die leeg. Log daar in met het zakelijke account. Ook hier: één login, één keer.

Stap 5: twee apps met een eigen icoon in het Dock

Een getekend Dock: twee Claude-iconen, één oranje en één gearceerd, tussen twee kleinere apps. De muis staat op de oranje, die groter wordt.

Scripts werken prima, maar ik wilde klikken. Dus werd elke instantie een mini-app.

In Scripteditor maakte ik een nieuw script van één regel en exporteerde ik het als app (Archief › Exporteer):

do shell script "$HOME/.local/bin/claude-work-desktop > /dev/null 2>&1 &"

Dat bewaarde ik als Claude Werk in /Applications. Voor Claude Privé roept de regel claude-instance aan zonder argument. Die opent dus het gewone profiel, of haalt het naar voren:

do shell script "$HOME/.local/bin/claude-instance > /dev/null 2>&1 &"

Geëxporteerde apps krijgen het standaard scripticoon. Twee dezelfde iconen in het Dock vraagt om vergissingen, dus kreeg elke app een eigen icoon. Dat icoon zit in de app als Contents/Resources/applet.icns:

  • Claude Privé kreeg het icoon van Claude zelf, rechtstreeks gekopieerd uit de app:

    cp /Applications/Claude.app/Contents/Resources/electron.icns \
       "/Applications/Claude Privé.app/Contents/Resources/applet.icns"
  • Claude Werk kreeg hetzelfde icoon in het blauw. Pak het uit met iconutil -c iconset electron.icns, kleur de PNG’s om in een willekeurig beeldprogramma, pak ze weer in met iconutil -c icns en zet het resultaat over applet.icns heen.

Een bestand in de app aanpassen breekt de handtekening. Onderteken de app dus opnieuw, lokaal en zonder ontwikkelaarsaccount:

codesign --force --deep -s - "/Applications/Claude Werk.app"
codesign --force --deep -s - "/Applications/Claude Privé.app"

Sleep daarna beide apps naar het Dock. Toont het Dock nog het oude icoon, dan ververst killall Dock het. Nu heb ik een oranje Claude voor mijn eigen werk en een blauwe voor Made by Spin, en Spotlight vindt ze allebei op naam.

Stap 6: twee Chrome-profielen, één per Claude

Twee browservensters naast elkaar, elk met een eigen profielfoto.

Het laatste stuk was de browser. Claude kan Chrome bedienen via de extensie Claude in Chrome, en daar wordt het persoonlijk: in de browser zit je ingelogd op van alles. Ik wil niet dat mijn eigen Claude rondklikt in het dashboard van een klant, of andersom.

Chrome kreeg dus dezelfde splitsing. Via het profielicoon in Chrome maak je met Toevoegen een tweede profiel. Ik heb er twee: privé en werk. In elk profiel installeerde ik de Claude-extensie en logde ik in met het bijbehorende account. Elke Claude werkt zo in zijn eigen browser, met eigen cookies en eigen ingelogde tools. Zelfde Chrome, zelfde extensie, twee gescheiden werelden.

Waar je op moet letten

  • Eenrichtingsverkeer is een keuze, geen bug. Pas gedeelde instellingen alleen aan in het hoofdaccount. Doe je het in het tweede account, dan overschrijft de volgende sync het weer.
  • Kijk naar je PATH. Tijdens het opzetten vond ik nog een oude globale pnpm-installatie van Claude Code, versie 2.0.5. Die draaide nooit, omdat de huidige installatie eerder in het PATH staat. Maar het is precies het soort ding waardoor je gaat twijfelen met welke Claude je eigenlijk praat. Draai één keer which -a claude.
  • Deel het loginbestand niet. Het is verleidelijk om de hele map te symlinken. Niet doen. Dat is het enige dat écht gescheiden moet blijven.

Waarom de moeite

Het is een kleine opzet. Een paar shellfuncties, een handvol symlinks, twee scripts, twee mini-apps en twee Chrome-profielen. Maar het haalde een dagelijks irritatiemoment weg, en een echt risico om klantwerk en eigen werk door elkaar te halen.

En het veranderde hoe ik naar deze tools kijk. Claude Code is geen magische doos. Het is een programma met een map vol gegevens. Zie je dat eenmaal, dan is twee Claudes draaien gewoon een kwestie van de juiste map kiezen.