🇧🇷 Português (abaixo) · 🇺🇸 English
Trocar de conta no Claude Code CLI sem precisar de /logout, reabrir o navegador, autorizar de novo, etc. Você salva cada conta como um profile uma vez, e a partir daí alterna entre elas com um único comando.
O fluxo nativo pra trocar de conta é:
- Digitar
/logoutdentro do Claude. - Sair, rodar
claudede novo. - Esperar abrir o navegador.
- Fazer login na conta nova.
- Autorizar o OAuth.
- Repetir tudo se quiser voltar pra primeira conta.
Cansativo se você troca várias vezes por dia (ex.: conta pessoal vs. conta da empresa). O claude-switch faz isso em uma linha, sem browser, porque ele só rotaciona os tokens já válidos que o Claude Code guarda.
O Claude Code armazena o estado da conta em dois lugares:
| O que | Onde |
|---|---|
| Tokens OAuth (access + refresh) | macOS Keychain — service Claude Code-credentials, account = $USER; Linux — ~/.claude/.credentials.json |
Metadados da conta (oauthAccount, userID) |
~/.claude.json |
Um profile é só um JSON em ~/.claude/profiles/<nome>.json contendo um snapshot dos dois. O comando use restaura o snapshot — grava os tokens de volta no Keychain (macOS) ou em ~/.claude/.credentials.json (Linux) e substitui oauthAccount + userID em ~/.claude.json. O Claude Code refresca o access token sozinho se estiver vencido, então o navegador não precisa abrir de novo.
O access token vale poucas horas, e o Claude Code rotaciona o refresh token a cada renovação: o token novo vai pro Keychain, o antigo deixa de valer. Um snapshot congelado envelhece — depois de algumas semanas o profile guarda um refresh token já consumido, e use acaba caindo no navegador.
Por isso, antes de sobrescrever as credenciais, o use re-salva os tokens da conta ativa no profile dela (match por accountUuid, com fallback pro e-mail). Cada troca deixa os dois profiles atualizados. Se você passar muito tempo sem alternar, rode claude-switch sync de vez em quando pra atualizar o profile ativo sem trocar de conta.
Os tokens continuam protegidos pelo Keychain do macOS (a senha da sua conta libera o acesso). No Linux, os tokens ficam no arquivo local ~/.claude/.credentials.json. Os profiles ficam em arquivos locais que você não deve versionar — eles contêm refresh tokens válidos.
| Requisito | Como verificar | Como instalar / resolver |
|---|---|---|
| macOS ou Linux | uname -s → Darwin ou Linux |
Windows não é suportado |
| bash | command -v bash |
Já vem no macOS |
security CLI (macOS) |
command -v security |
Já vem no macOS (parte do Security.framework) |
jq |
jq --version |
brew install jq |
| Requisito | Como verificar | Como resolver |
|---|---|---|
| Claude Code CLI instalado | claude --version |
npm i -g @anthropic-ai/claude-code |
~/.claude.json criado |
ls ~/.claude.json |
Rode claude uma vez; o arquivo é criado na inicialização |
| Pelo menos uma conta logada | Conseguir abrir claude sem cair no login |
Rode claude e complete o OAuth no navegador |
Use o comando doctor — checa tudo de uma vez e mostra exatamente o que falta:
claude-switch doctorSaída esperada quando tudo está OK:
[ok] macOS (26.5)
[ok] bash
[ok] security CLI
[ok] jq (jq-1.7.1-apple)
[ok] claude CLI (2.1.142)
[ok] /Users/<seu_usuario>/.claude.json
[ok] credenciais no Keychain (conta ativa: voce@exemplo.com)
[ok] profiles salvos: 2 (em /Users/<seu_usuario>/.claude/profiles)
[ok] ANTHROPIC_API_KEY não definida (OAuth no comando)
tudo ok pra rodar.
No Linux, a linha de credenciais aponta para ~/.claude/.credentials.json em vez do Keychain.
Sobre o check da
ANTHROPIC_API_KEY: essa variável tem precedência sobre as credenciais OAuth em ambos os sistemas. Se ela estiver exportada no seu shell, o Claude Code autentica por ela e ignora o Keychain (macOS) ou o~/.claude/.credentials.json(Linux) — ou seja,claude-switch use <nome>grava o profile corretamente mas não muda a conta que o Claude Code usa de fato. Odoctormarca isso como[aviso]porque é um modo de falha silencioso. Se você precisa da key para scripts/SDK, carregue-a sob demanda (função de shell oudirenv) em vez de exportá-la globalmente.
Se aparecer [falta] em algum item obrigatório, o doctor sai com código de saída 1. Itens marcados [aviso] não bloqueiam o script em si, mas indicam coisas que você vai precisar antes de usar save (ex.: não estar logado em nenhuma conta).
O install.sh roda essas mesmas verificações antes de instalar.
cd ~/Developer/claude-switch
./install.sh # auto-detecta o shell
./install.sh --shell=fish # força fish (recomendado pra quem usa fish)
./install.sh --shell=zsh # força zsh
./install.sh --shell=bash # força bashImportante para usuários de fish: o macOS guarda como "shell de login" o
/bin/bashpor padrão, mesmo se você abre o terminal direto no fish. Auto-detecção pode errar nesse caso — use--shell=fishexplicitamente.Importante para usuários Linux: ao final da instalação, o script recarrega o shell automaticamente quando possível para disponibilizar
claude-switchno terminal atual.
O instalador:
- Roda todas as verificações de pré-requisitos (mesma coisa que
claude-switch doctor). - Copia o script para
~/.claude/bin/claude-switch(deixa executável). - Cria
~/.claude/profiles/se não existir. - Adiciona
~/.claude/binao seuPATH:- fish:
fish_add_path -U ~/.claude/bin(universal, persiste entre sessões). - zsh: adiciona uma linha ao
~/.zshrc(idempotente — só adiciona se não existir). - bash: adiciona ao
~/.bash_profile(se existir) ou~/.bashrc.
- fish:
- Mostra como recarregar o
PATH.
Se preferir instalar à mão, é só copiar claude-switch pra qualquer lugar no PATH e dar chmod +x.
Esse passo só acontece uma vez por conta. Depois você nunca mais vê o navegador (até o refresh token expirar, o que demora bastante).
# 1) Você já está logado em uma conta (ex.: pessoal). Salve como profile:
claude-switch save pessoal
# 2) Saia da conta atual e logue na conta nova:
claude-switch logout
claude # abre o navegador, faz login na outra conta
# 3) Confirme que pegou a conta certa e salve como profile:
claude-switch current
claude-switch save trabalhoDeslogue do claude.ai antes do passo 2. Se o navegador ainda estiver autenticado na conta anterior, o OAuth reautoriza aquela sessão sem perguntar nada e você acaba salvando a mesma conta duas vezes. Faça logout em
https://claude.ai(ou use uma janela anônima / outro perfil do navegador) antes de rodarclaude. Oclaude-switch currentno passo 3 confirma qual conta veio de fato.
claude-switch use pessoal # ativa a conta pessoal
claude-switch use trabalho # ativa a conta de trabalho
claude-switch sync # atualiza o profile da conta ativa com os tokens de agora
claude-switch list # lista profiles ('*' marca o ativo) + validade dos tokens
claude-switch current # mostra qual conta está logada agoraO list mostra o estado dos tokens de cada profile:
* pessoal voce@exemplo.com válido
trabalho voce@empresa.com renovável
cliente-x voce@cliente.com EXPIRADO
| Estado | Significado |
|---|---|
válido |
access token ainda vale — use é instantâneo |
renovável |
access token venceu, mas o refresh token renova sem navegador |
EXPIRADO |
refresh token também venceu — use vai cair no navegador; refaça o save depois de logar |
formato antigo |
profile salvo antes do campo refreshTokenExpiresAt existir; pode estar vencido — refaça o save |
Depois de use, é só rodar claude normalmente — já vai estar na conta certa.
claude-switch logout # remove os tokens do Keychain/arquivo local (profiles ficam)
claude-switch rm <nome> # apaga um profile salvo
claude-switch help # mostra a ajuda| Comando | O que faz |
|---|---|
claude-switch save <nome> |
Salva a conta atualmente logada como profile <nome> |
claude-switch use <nome> |
Ativa o profile <nome> (sem browser); sincroniza o profile da conta ativa antes |
claude-switch sync |
Atualiza o profile da conta ativa com os tokens atuais (sem trocar de conta) |
claude-switch list (ou ls) |
Lista todos os profiles, o e-mail e a validade dos tokens de cada |
claude-switch current |
Mostra qual conta está ativa agora |
claude-switch logout |
Limpa os tokens do Keychain/arquivo local (não apaga profiles) |
claude-switch rm <nome> |
Apaga o profile <nome> do disco |
claude-switch doctor |
Verifica pré-requisitos e estado do ambiente |
claude-switch help |
Mostra a ajuda |
Trocar de conta no meio do dia:
claude-switch use trabalho
claudeAtualizar um profile (porque o token foi renovado e você quer salvar o estado novo):
# basta dar save de novo com o mesmo nome — sobrescreve.
claude-switch save trabalhoLogar em uma terceira conta:
# deslogue de claude.ai no navegador antes, senão o OAuth reusa a conta atual
claude-switch logout
claude # navegador abre, loga na conta nova
claude-switch current # confirme que veio a conta certa
claude-switch save cliente-xRecuperar um profile com token expirado:
claude-switch list # confirma qual está EXPIRADO
# deslogue de claude.ai no navegador
claude-switch logout
claude # login na conta daquele profile
claude-switch current # confirme a conta
claude-switch save trabalho # sobrescreve o profile com tokens vivosVer se você está na conta certa antes de mandar uma pergunta cara:
claude-switch current- Não versione
~/.claude/profiles/. Os arquivos ali dentro contêmrefreshTokenválidos — quem tiver o arquivo loga como você. O.gitignoredeste repositório já bloqueia, mas se você mover os profiles pra outro lugar, lembre disso. - No Linux, não versione
~/.claude/.credentials.json. Esse arquivo também contém tokens válidos. - Backup: se você quiser passar uma conta pra outra máquina sua, copie o JSON do profile via canal seguro (AirDrop, scp). Não cole em chat/email.
- Refresh token expira: o refresh token vale ~30 dias e é rotacionado a cada renovação. O
usemantém o profile ativo fresco automaticamente, mas um profile que ficou meses parado vence —listedoctormarcam isso. Nesse casouseainda restaura o estado, oclaudepede login pelo navegador, e aí você rodaclaude-switch save <nome>pra recuperar o profile. - Conta atual não salva: se você der
useem um profile sem ter salvado a conta atualmente ativa, o script avisa antes — você pode cancelar com Ctrl-C e darsaveprimeiro.
cd ~/Developer/claude-switch
./uninstall.shIsso remove só o binário em ~/.claude/bin/claude-switch. Os profiles em ~/.claude/profiles/ ficam (apague à mão se quiser). A linha de PATH adicionada ao seu shell rc também fica — remova manualmente se quiser.
~/Developer/claude-switch/
├── claude-switch # o script em si
├── README.md # este documento
├── install.sh # instalador
├── uninstall.sh # desinstalador
└── .gitignore # garante que profiles não vazem se você versionar
jq não encontrado → brew install jq.
sem credenciais ativas no Keychain ou sem credenciais ativas em ~/.claude/.credentials.json ao dar save → você não está logado. Rode claude e faça login primeiro.
~/.claude.json não encontrado → você nunca rodou claude nessa máquina. Rode uma vez pra ele inicializar.
use ativou o profile mas o Claude continua na conta antiga → certifique-se de que o processo claude não estava aberto (ele só relê as credenciais ao iniciar). Saia e rode de novo.
use funciona, mas o Claude pede login no navegador toda vez → o profile guarda um refresh token vencido ou já consumido. Rode claude-switch list (ou doctor) pra confirmar: profiles marcados EXPIRADO ou formato antigo precisam de um save novo depois do login. A partir daí o use mantém os tokens frescos sozinho.
use só imprimiu o aviso e não abriu o navegador → é o comportamento esperado. O use apenas grava as credenciais; quem abre o navegador é o claude no próximo start (ou o /login dentro de uma sessão aberta).
Fiz login pra recuperar um profile, mas caí na conta errada → o navegador ainda estava autenticado na conta anterior e o OAuth reautorizou aquela sessão sem perguntar. Deslogue em https://claude.ai (ou use uma janela anônima) e repita. Use claude-switch current pra conferir antes do save — comparar o e-mail é mais confiável que assumir qual conta o navegador escolheu.
Quero rodar comandos diferentes em sessões diferentes ao mesmo tempo (sem mexer no estado global) → não dá com este script (o Claude Code lê de um único lugar). Pra esse caso, melhor usar perfis separados de macOS ou containers.
Switch accounts in the Claude Code CLI without /logout, reopening the browser, authorizing again, and so on. You save each account as a profile once, and from then on you alternate between them with a single command.
The native account-switching flow is:
- Type
/logoutinside Claude. - Quit, run
claudeagain. - Wait for the browser to open.
- Log into the new account.
- Authorize OAuth.
- Repeat everything if you want to go back to the first account.
Tiring if you switch several times a day (e.g. personal account vs. company account). claude-switch does it in one line, with no browser, because it just rotates the already valid tokens that Claude Code stores.
Claude Code stores the account state in two places:
| What | Where |
|---|---|
| OAuth tokens (access + refresh) | macOS Keychain — service Claude Code-credentials, account = $USER; Linux — ~/.claude/.credentials.json |
Account metadata (oauthAccount, userID) |
~/.claude.json |
A profile is just a JSON file at ~/.claude/profiles/<name>.json holding a snapshot of both. The use command restores the snapshot — it writes the tokens back to the Keychain (macOS) or to ~/.claude/.credentials.json (Linux) and replaces oauthAccount + userID in ~/.claude.json. Claude Code refreshes the access token on its own if it has expired, so the browser doesn't have to open again.
The access token is valid for a few hours, and Claude Code rotates the refresh token on every renewal: the new token goes to the Keychain, the old one stops working. A frozen snapshot ages — after a few weeks the profile holds an already-consumed refresh token, and use ends up falling back to the browser.
That's why, before overwriting the credentials, use re-saves the active account's tokens into its own profile (matched by accountUuid, falling back to the email). Every switch leaves both profiles up to date. If you go a long time without alternating, run claude-switch sync once in a while to refresh the active profile without switching accounts.
The tokens remain protected by the macOS Keychain (your account password unlocks access). On Linux, the tokens live in the local file ~/.claude/.credentials.json. Profiles live in local files that you should not commit — they contain valid refresh tokens.
| Requirement | How to check | How to install / fix |
|---|---|---|
| macOS or Linux | uname -s → Darwin or Linux |
Windows is not supported |
| bash | command -v bash |
Ships with macOS |
security CLI (macOS) |
command -v security |
Ships with macOS (part of Security.framework) |
jq |
jq --version |
brew install jq |
| Requirement | How to check | How to fix |
|---|---|---|
| Claude Code CLI installed | claude --version |
npm i -g @anthropic-ai/claude-code |
~/.claude.json created |
ls ~/.claude.json |
Run claude once; the file is created at startup |
| At least one logged-in account | Being able to open claude without hitting the login flow |
Run claude and complete the OAuth in the browser |
Use the doctor command — it checks everything at once and shows exactly what's missing:
claude-switch doctorExpected output when everything is OK:
[ok] macOS (26.5)
[ok] bash
[ok] security CLI
[ok] jq (jq-1.7.1-apple)
[ok] claude CLI (2.1.142)
[ok] /Users/<your_user>/.claude.json
[ok] credentials in Keychain (active account: you@example.com)
[ok] saved profiles: 2 (in /Users/<your_user>/.claude/profiles)
[ok] ANTHROPIC_API_KEY not set (OAuth in use)
all good to go.
On Linux, the credentials line points to ~/.claude/.credentials.json instead of the Keychain.
About the
ANTHROPIC_API_KEYcheck: this variable takes precedence over the OAuth credentials on both systems. If it's exported in your shell, Claude Code authenticates with it and ignores the Keychain (macOS) or~/.claude/.credentials.json(Linux) — meaningclaude-switch use <name>writes the profile correctly but doesn't change the account Claude Code actually uses.doctorflags this as a warning because it's a silent failure mode. If you need the key for scripts/SDK, load it on demand (a shell function ordirenv) instead of exporting it globally.
If any mandatory item shows up as missing, doctor exits with status code 1. Items marked as warnings don't block the script itself, but they point to things you'll need before using save (e.g. not being logged into any account).
install.sh runs these same checks before installing.
cd ~/Developer/claude-switch
./install.sh # auto-detects the shell
./install.sh --shell=fish # forces fish (recommended for fish users)
./install.sh --shell=zsh # forces zsh
./install.sh --shell=bash # forces bashImportant for fish users: macOS keeps
/bin/bashas the "login shell" by default, even if you open the terminal straight into fish. Auto-detection can get it wrong in that case — pass--shell=fishexplicitly.Important for Linux users: at the end of the installation, the script reloads the shell automatically when possible so
claude-switchbecomes available in the current terminal.
The installer:
- Runs all the prerequisite checks (same thing as
claude-switch doctor). - Copies the script to
~/.claude/bin/claude-switch(making it executable). - Creates
~/.claude/profiles/if it doesn't exist. - Adds
~/.claude/binto yourPATH:- fish:
fish_add_path -U ~/.claude/bin(universal, persists across sessions). - zsh: adds a line to
~/.zshrc(idempotent — only adds it if not present). - bash: adds to
~/.bash_profile(if it exists) or~/.bashrc.
- fish:
- Shows how to reload your
PATH.
If you'd rather install by hand, just copy claude-switch anywhere on your PATH and chmod +x it.
This step happens only once per account. After that you never see the browser again (until the refresh token expires, which takes a while).
# 1) You're already logged into one account (e.g. personal). Save it as a profile:
claude-switch save personal
# 2) Log out of the current account and log into the new one:
claude-switch logout
claude # opens the browser, log into the other account
# 3) Confirm you got the right account and save it as a profile:
claude-switch current
claude-switch save workLog out of claude.ai before step 2. If the browser is still authenticated with the previous account, OAuth re-authorizes that session without asking anything and you end up saving the same account twice. Log out at
https://claude.ai(or use a private window / another browser profile) before runningclaude.claude-switch currentin step 3 confirms which account actually came through.
claude-switch use personal # activates the personal account
claude-switch use work # activates the work account
claude-switch sync # updates the active account's profile with the current tokens
claude-switch list # lists profiles ('*' marks the active one) + token validity
claude-switch current # shows which account is logged in right nowlist shows each profile's token state:
* personal you@example.com valid
work you@company.com renewable
client-x you@client.com EXPIRED
| State | Meaning |
|---|---|
valid |
access token still good — use is instant |
renewable |
access token expired, but the refresh token renews it without a browser |
EXPIRED |
the refresh token expired too — use will fall back to the browser; redo the save after logging in |
old format |
profile saved before the refreshTokenExpiresAt field existed; it may be expired — redo the save |
After use, just run claude as usual — it'll already be on the right account.
claude-switch logout # removes the tokens from the Keychain/local file (profiles stay)
claude-switch rm <name> # deletes a saved profile
claude-switch help # shows the help| Command | What it does |
|---|---|
claude-switch save <name> |
Saves the currently logged-in account as profile <name> |
claude-switch use <name> |
Activates profile <name> (no browser); syncs the active account's profile first |
claude-switch sync |
Updates the active account's profile with the current tokens (without switching accounts) |
claude-switch list (or ls) |
Lists all profiles, plus each one's email and token validity |
claude-switch current |
Shows which account is active right now |
claude-switch logout |
Clears the tokens from the Keychain/local file (doesn't delete profiles) |
claude-switch rm <name> |
Deletes profile <name> from disk |
claude-switch doctor |
Checks prerequisites and the state of the environment |
claude-switch help |
Shows the help |
Switching accounts mid-day:
claude-switch use work
claudeUpdating a profile (because the token was renewed and you want to save the new state):
# just save again with the same name — it overwrites.
claude-switch save workLogging into a third account:
# log out of claude.ai in the browser first, otherwise OAuth reuses the current account
claude-switch logout
claude # browser opens, log into the new account
claude-switch current # confirm the right account came through
claude-switch save client-xRecovering a profile with an expired token:
claude-switch list # confirm which one is EXPIRED
# log out of claude.ai in the browser
claude-switch logout
claude # log into that profile's account
claude-switch current # confirm the account
claude-switch save work # overwrite the profile with live tokensChecking whether you're on the right account before sending an expensive prompt:
claude-switch current- Don't commit
~/.claude/profiles/. The files in there contain validrefreshTokens — whoever has the file logs in as you. This repository's.gitignorealready blocks it, but if you move the profiles somewhere else, keep that in mind. - On Linux, don't commit
~/.claude/.credentials.json. That file also contains valid tokens. - Backup: if you want to move an account to another machine of yours, copy the profile JSON over a secure channel (AirDrop, scp). Don't paste it into chat/email.
- Refresh tokens expire: the refresh token lasts ~30 days and is rotated on every renewal.
usekeeps the active profile fresh automatically, but a profile that sat idle for months will expire —listanddoctorflag that. In that caseusestill restores the state,claudeasks for a browser login, and then you runclaude-switch save <name>to recover the profile. - Current account not saved: if you
usea profile without having saved the currently active account, the script warns you first — you can cancel with Ctrl-C andsaveit first.
cd ~/Developer/claude-switch
./uninstall.shThis removes only the binary at ~/.claude/bin/claude-switch. The profiles in ~/.claude/profiles/ stay (delete them by hand if you want). The PATH line added to your shell rc also stays — remove it manually if you want.
~/Developer/claude-switch/
├── claude-switch # the script itself
├── README.md # this document
├── install.sh # installer
├── uninstall.sh # uninstaller
└── .gitignore # makes sure profiles don't leak if you commit
jq not found → brew install jq.
no active credentials in Keychain or no active credentials in ~/.claude/.credentials.json when running save → you're not logged in. Run claude and log in first.
~/.claude.json not found → you've never run claude on this machine. Run it once so it initializes.
use activated the profile but Claude is still on the old account → make sure the claude process wasn't running (it only re-reads the credentials at startup). Quit and run it again.
use works, but Claude asks for a browser login every time → the profile holds an expired or already-consumed refresh token. Run claude-switch list (or doctor) to confirm: profiles marked EXPIRED or old format need a fresh save after logging in. From then on use keeps the tokens fresh on its own.
use only printed the warning and didn't open the browser → that's the expected behavior. use only writes the credentials; the browser is opened by claude on its next start (or by /login inside an open session).
I logged in to recover a profile, but ended up on the wrong account → the browser was still authenticated with the previous account and OAuth re-authorized that session without asking. Log out at https://claude.ai (or use a private window) and try again. Use claude-switch current to check before the save — comparing the email is more reliable than assuming which account the browser picked.
I want to run different commands in different sessions at the same time (without touching the global state) → not possible with this script (Claude Code reads from a single place). For that case, separate macOS profiles or containers are a better fit.