{"slug": "uma-maquina-duas-contas-claude-zero-estado-compartilhado", "title": "Uma Máquina, Duas Contas Claude, Zero Estado Compartilhado", "summary": "A developer describes running two separate Claude Code accounts on the same machine with zero shared state, using distinct CLAUDE_CONFIG_DIR directories to keep personal and work environments isolated. The approach uses shell functions to switch between accounts, avoiding symlinks or merge scripts, at the cost of manually duplicating skills across accounts.", "body_md": "Vi um post legal esses dias sobre rodar duas contas do Claude Code na mesma máquina compartilhando tudo entre elas: mesmas skills, mesmos servidores MCP, mesmos hooks.\n\nO artigo era: [\"Um cérebro, duas carteiras\"](https://dev.to/daksh-gargas/one-brain-two-wallets-two-claude-code-accounts-on-one-machine-5ejb)\n\nEu rodo, exatamente o oposto, e acho que pra muita gente o oposto é a escolha certa.\n\nMinhas duas contas não são uma pessoal e uma reserva pra quando os créditos acabam. Uma é pessoal, outra é de trabalho.\n\nA última coisa que eu quero é meus MCP servers de trabalho, meus hooks de trabalho e meu histórico de projeto de trabalho vazando pras sessões pessoais.\n\nEntão em vez de ligar as duas, eu mantenho elas **separadas de propósito**.\n\nO Claude Code guarda o estado num diretório de config (`~/.claude`\n\npor padrão) e lê a variável `CLAUDE_CONFIG_DIR`\n\npra apontar pra outro lugar. Esse é o único mecanismo que você precisa. Sem shim, sem symlink, sem `jq`\n\n.\n\n```\nbash\n# ~/.zshrc\n# Claude Code: contas isoladas (pessoal vs trabalho)\n# Cada uma usa um CLAUDE_CONFIG_DIR proprio -> credenciais/sessao separadas.\n# ~/.claude       = pessoal (default)\n# ~/.claude-work  = trabalho\nclaude-work()     { CLAUDE_CONFIG_DIR=\"$HOME/.claude-work\" claude \"$@\"; }\nclaude-personal() { CLAUDE_CONFIG_DIR=\"$HOME/.claude\"      claude \"$@\"; }\n# 'claude' sozinho continua sendo a conta pessoal.\nsource ~/.zshrc\nclaude-work   # pede login OAuth da conta de trabalho, uma vez só\n```\n\nUsei funções de shell em vez de alias por um motivo:\n\n`\"$@\"`\n\nlimpo, então `claude-work --resume abc`\n\ne `claude-work chat`\n\nfuncionam sem a variável de ambiente vazar pra nada mais no shell.\nUm alias faria quase o mesmo aqui, mas a função deixa a passagem de argumentos explícita.É isso. `claude`\n\npuro é pessoal. `claude-work`\n\né trabalho. Nada é compartilhado, e é aí que mora a graça.\n\nA versão de cérebro compartilhado faz symlink de `skills`\n\n, `plugins`\n\n, `settings.json`\n\ne dá merge no bloco `mcpServers`\n\nentre as duas contas pra elas se comportarem igual. Se as suas duas contas são de fato a mesma pessoa com duas assinaturas, tranquilo.\n\nO trabalho tem MCP servers apontando pra sistemas internos. O trabalho tem hooks e permissões que eu nunca ia querer disparando numa sessão pessoal em algum projeto paralelo aleatório.\n\nHistórico de trabalho é histórico de trabalho.\n\nQuando eu abro um Claude pessoal, quero um ambiente pessoal limpo. Manter os diretórios de config totalmente separados me dá isso de graça. Sem script de merge pra manter, sem risco de um token de trabalho aparecer onde não devia.\n\n**O custo é real**: se eu adiciono uma skill na conta pessoal, a de trabalho não recebe.\n\nPreciso adicionar nos dois lugares. Em quatro meses isso me custou uns dez minutos no total, o'que eu acho aceitável.\n\nNa versão compartilhada, a maior cilada é o `.claude.json`\n\n. Esse arquivo de nível de usuário (MCP servers, confiança de pasta, estado de onboarding) normalmente fica ao lado de `~/.claude`\n\n, mas no instante em que `CLAUDE_CONFIG_DIR`\n\nestá setado, o Claude lê ele de *dentro* do diretório de config. Ou seja, apontar um segundo alias pro seu `~/.claude`\n\nexistente pode criar um `.claude.json`\n\nnovo e vazio, apagando seus MCP servers debaixo de você. A solução deles é um symlink de volta pro arquivo mestre.\n\nEu desvio disso inteiro. Cada conta tem o seu próprio `~/.claude/.claude.json`\n\ne `~/.claude-work/.claude.json`\n\n, os dois arquivos reais, cada um da sua conta. Nada aponta pra nada, então nada é sobrescrito.\n\n`--resume`\n\n?\nÉ o único ponto onde o setup compartilhado precisa mesmo do shim. Os transcripts de sessão ficam em `<config-dir>/projects/<projeto>/<session-id>.jsonl`\n\n. Se um script em background ou um restore de crash chama `claude --resume <id>`\n\npuro e a sessão pertence à outra conta, o Claude diz que ela não existe. O shim deles olha o ID, descobre qual conta é dona e seta o `CLAUDE_CONFIG_DIR`\n\nde acordo.\n\nEu não rodo esse shim, então assumo a pequena disciplina que ele compraria: retomo uma sessão de trabalho com `claude-work --resume`\n\n, e uma pessoal com `claude`\n\n. Como eu já penso nas duas como contextos diferentes, pegar o comando certo é automático, do mesmo jeito que eu não dou `git push`\n\nno repo errado.\n\nFaça uma pergunta só: suas duas contas são o mesmo você, ou dois contextos diferentes?\n\n`jq`\n\ndaquele outro post são exatamente certos, e o shim de `--resume`\n\nvale a pena.Em resumo:\n\n```\nclaude                   # pessoal (default)\nclaude-work              # conta de trabalho, cada coisa dela\nclaude-work --resume X   # retoma uma sessão de trabalho\n```\n\n", "url": "https://wpnews.pro/news/uma-maquina-duas-contas-claude-zero-estado-compartilhado", "canonical_source": "https://dev.to/ogoul4rt/uma-maquina-dois-claudes-zero-estado-compartilhado-5f74", "published_at": "2026-07-20 21:31:18+00:00", "updated_at": "2026-07-20 22:00:38.657704+00:00", "lang": "en", "topics": ["developer-tools", "artificial-intelligence", "large-language-models"], "entities": ["Claude Code", "Anthropic"], "alternates": {"html": "https://wpnews.pro/news/uma-maquina-duas-contas-claude-zero-estado-compartilhado", "markdown": "https://wpnews.pro/news/uma-maquina-duas-contas-claude-zero-estado-compartilhado.md", "text": "https://wpnews.pro/news/uma-maquina-duas-contas-claude-zero-estado-compartilhado.txt", "jsonld": "https://wpnews.pro/news/uma-maquina-duas-contas-claude-zero-estado-compartilhado.jsonld"}}