FTCHD/switcheroo

Switch your login/profile/account for 10+ CLIs, including Codex and Claude Code.

1

stars

44

commits

Rust

primary language

Sep 9, 2026

updated

claude
claude-code
cloudflare
codex
copilot
eas
expo
fly-io
flyio
gemini
netlify
npmjs
opencode
railway
turso
vercel
wrangler
Browse cluster: AI-Powered CLI Tools & Agents

README

Switcheroo

Switch the signed-in account of your CLIs.

Work account, personal account, a client's account: most developer CLIs only hold one login at a time, so you end up signing out and back in all day. Switcheroo remembers each login in your OS credential store and puts the one you want back in a second, for Claude Code, Codex, Vercel, Wrangler, npm, Fly.io and more.

It does not create profiles or config directories. It swaps the CLI's live login, so every terminal, editor integration and script that uses that CLI follows along. For CLIs that report it (Claude Code, Codex, GitHub CLI) it also shows how much of each account's allowance is used and when it resets, so you know which account to switch to.

switcheroo save claude-code                 # remember the login you have now
switcheroo login claude-code                # sign in as someone else, remember that too
switcheroo use claude-code work@acme.dev    # switch; the previous login is remembered first
switcheroo tray                             # menu-bar quick switcher + web UI

Switcheroo's Accounts page: each CLI on the machine, who it is signed in as, and the remembered accounts to switch to

Install

macOS and Linux:

curl -fsSL https://raw.githubusercontent.com/ftchd/switcheroo/main/install.sh | sh

Windows (PowerShell):

irm https://raw.githubusercontent.com/ftchd/switcheroo/main/install.ps1 | iex

To build from source you need Rust and Node:

cd web && npm ci && npm run build && cd ..
cargo build --release          # → target/release/switcheroo

Usage

On your laptop

Run switcheroo tray once; it detaches and keeps running in the background (switcheroo tray --stop ends it): a menu-bar item with one submenu per CLI, click an account to switch. switcheroo autostart enable (or the "Start at login" toggle) opens it when you sign in to the machine, and "Open Switcheroo…" gets you the full web UI for renaming, forgetting, settings and diagnostics.

On a remote server

No display needed: switcheroo serve runs the web UI on loopback, and an SSH tunnel (ssh -L 20123:127.0.0.1:20123 host, using the port it prints) puts it in your local browser.

Prefer the terminal?

Everything is a switcheroo subcommand with --json output, so it scripts well: switcheroo --help or the Reference page lists them all.

Supported CLIs

CLIMechanismWhat is touched
Claude Codeswapkeychain item Claude Code-credentials (macOS) or ~/.claude/.credentials.json, plus oauthAccount in ~/.claude.json; running sessions pick the change up
Codex CLIswap~/.codex/auth.json (file credential mode); restart running sessions
GitHub CLInativegh auth switch --user; gh keeps the accounts itself
Vercelswapglobal auth.json token and currentTeam
Cloudflare WranglerswapOAuth login default.toml
npm (also pnpm, yarn v1, bun)swaponly the //registry.npmjs.org/:_authToken line of ~/.npmrc
Fly.ioswap~/.fly/config.yml, taking flyctl's lock first
Netlifynativenetlify switch --email; Netlify keeps the accounts itself
Gemini CLI, Turso, Expo / EAS, Railwayswapexperimental: formats verified from source, not yet on real logins

Swap means Switcheroo captures the CLI's credential into your credential store and writes a remembered one back in its place. Native means the CLI already keeps several accounts and Switcheroo only runs its switch command; nothing is stored.

switcheroo providers prints this list with the exact files for your OS. Only CLIs found on PATH are managed; a tool installed inside a single project (for example wrangler in a repo's node_modules/.bin) is not visible until it is installed globally or its directory is on PATH. Doctor explains this next to the list of directories searched.

Updates

switcheroo update fetches the latest release for your platform, verifies it against the release's SHA256SUMS, replaces the binary in place and restarts the tray if it was running. switcheroo update --check only reports. The CLI, the web UI and the tray all point out a newer release until it is installed.

How a switch works

  1. Acquire an exclusive lock so a terminal command and the tray never interleave.
  2. Read the live credential and re-remember it under the account that is currently signed in. Tokens rotate, so the remembered copy must always be the freshest one.
  3. Write the target account's credential into the slot.
  4. Ask the CLI who is signed in. On a mismatch, the previous login is restored.

Before switching, Switcheroo warns about anything that would make it a no-op: environment variables the CLI prefers over its stored login (GH_TOKEN, CLOUDFLARE_API_TOKEN, VERCEL_TOKEN, ANTHROPIC_API_KEY, …), a CLI that caches credentials at startup, or an unsupported storage mode such as Codex's keyring option.

Security

  • Secrets live only in the OS credential store: macOS Keychain, Windows Credential Manager, or Linux Secret Service. --vault file opts into a 0600 JSON file for machines without one. Switcheroo's own state.json holds emails, labels and timestamps, never tokens.
  • On macOS the keychain is accessed through /usr/bin/security, the same tool Claude Code uses. Items created that way never trigger access prompts, and updating the binary does not break access.
  • The web UI listens on loopback only. Every mutation needs a per-launch session token in a custom header, which cross-site requests cannot supply, and the API never returns credential bytes.
  • Nothing leaves your machine. There is no telemetry and no network access beyond the CLIs' own whoami commands.

Command reference

CommandWhat it does
switcheroo / status [--refresh]Every detected CLI, who it is signed in as, remembered accounts
save <provider> [--label NAME]Remember the current login
login <provider> [--label NAME]Run the CLI's sign-in here, then remember the result
use <provider> [account]Switch; account by email, label or unique fragment, picker if omitted
list [provider] · rename · removeManage remembered accounts
usage [provider] [--refresh]Used quota and reset times for signed-in accounts
doctor · providersDiagnostics and the provider catalog
tray · serve [--bind] · openRun the tray, the web server, or open the UI
autostart enable|disable|statusStart the tray at login
completions <shell>Shell completions

Global: --json, --vault auto|keychain|file, --data-dir DIR, -v, -q. Exit codes: 0 ok, 1 error, 2 usage, 3 CLI not installed, 4 nothing signed in.

Development

cargo test                                          # Rust unit tests, incl. a real keychain round trip on macOS
cd web && npm install && npm run dev                # Vite on :5173, proxies /api to :7777
cargo run -- serve --dev --bind 127.0.0.1:7777      # dev server with a fixed session token

The architecture, invariants and the checklist for adding a provider are in CLAUDE.md. A provider is one file under src/providers/ built from a few slot adapters and an identity resolver, plus one line in the registry; the CLI, API, tray and web UI pick it up without changes.

License

MIT

Contributors

FTCHD

44 commits

FTCHD/switcheroo

Switch your login/profile/account for 10+ CLIs, including Codex and Claude Code.

1

stars

44

commits

Rust

primary language

Sep 9, 2026

updated

claude
claude-code
cloudflare
codex
copilot
eas
expo
fly-io
flyio
gemini
netlify
npmjs
opencode
railway
turso
vercel
wrangler
Browse cluster: AI-Powered CLI Tools & Agents

README

Switcheroo

Switch the signed-in account of your CLIs.

Work account, personal account, a client's account: most developer CLIs only hold one login at a time, so you end up signing out and back in all day. Switcheroo remembers each login in your OS credential store and puts the one you want back in a second, for Claude Code, Codex, Vercel, Wrangler, npm, Fly.io and more.

It does not create profiles or config directories. It swaps the CLI's live login, so every terminal, editor integration and script that uses that CLI follows along. For CLIs that report it (Claude Code, Codex, GitHub CLI) it also shows how much of each account's allowance is used and when it resets, so you know which account to switch to.

switcheroo save claude-code                 # remember the login you have now
switcheroo login claude-code                # sign in as someone else, remember that too
switcheroo use claude-code work@acme.dev    # switch; the previous login is remembered first
switcheroo tray                             # menu-bar quick switcher + web UI

Switcheroo's Accounts page: each CLI on the machine, who it is signed in as, and the remembered accounts to switch to

Install

macOS and Linux:

curl -fsSL https://raw.githubusercontent.com/ftchd/switcheroo/main/install.sh | sh

Windows (PowerShell):

irm https://raw.githubusercontent.com/ftchd/switcheroo/main/install.ps1 | iex

To build from source you need Rust and Node:

cd web && npm ci && npm run build && cd ..
cargo build --release          # → target/release/switcheroo

Usage

On your laptop

Run switcheroo tray once; it detaches and keeps running in the background (switcheroo tray --stop ends it): a menu-bar item with one submenu per CLI, click an account to switch. switcheroo autostart enable (or the "Start at login" toggle) opens it when you sign in to the machine, and "Open Switcheroo…" gets you the full web UI for renaming, forgetting, settings and diagnostics.

On a remote server

No display needed: switcheroo serve runs the web UI on loopback, and an SSH tunnel (ssh -L 20123:127.0.0.1:20123 host, using the port it prints) puts it in your local browser.

Prefer the terminal?

Everything is a switcheroo subcommand with --json output, so it scripts well: switcheroo --help or the Reference page lists them all.

Supported CLIs

CLIMechanismWhat is touched
Claude Codeswapkeychain item Claude Code-credentials (macOS) or ~/.claude/.credentials.json, plus oauthAccount in ~/.claude.json; running sessions pick the change up
Codex CLIswap~/.codex/auth.json (file credential mode); restart running sessions
GitHub CLInativegh auth switch --user; gh keeps the accounts itself
Vercelswapglobal auth.json token and currentTeam
Cloudflare WranglerswapOAuth login default.toml
npm (also pnpm, yarn v1, bun)swaponly the //registry.npmjs.org/:_authToken line of ~/.npmrc
Fly.ioswap~/.fly/config.yml, taking flyctl's lock first
Netlifynativenetlify switch --email; Netlify keeps the accounts itself
Gemini CLI, Turso, Expo / EAS, Railwayswapexperimental: formats verified from source, not yet on real logins

Swap means Switcheroo captures the CLI's credential into your credential store and writes a remembered one back in its place. Native means the CLI already keeps several accounts and Switcheroo only runs its switch command; nothing is stored.

switcheroo providers prints this list with the exact files for your OS. Only CLIs found on PATH are managed; a tool installed inside a single project (for example wrangler in a repo's node_modules/.bin) is not visible until it is installed globally or its directory is on PATH. Doctor explains this next to the list of directories searched.

Updates

switcheroo update fetches the latest release for your platform, verifies it against the release's SHA256SUMS, replaces the binary in place and restarts the tray if it was running. switcheroo update --check only reports. The CLI, the web UI and the tray all point out a newer release until it is installed.

How a switch works

  1. Acquire an exclusive lock so a terminal command and the tray never interleave.
  2. Read the live credential and re-remember it under the account that is currently signed in. Tokens rotate, so the remembered copy must always be the freshest one.
  3. Write the target account's credential into the slot.
  4. Ask the CLI who is signed in. On a mismatch, the previous login is restored.

Before switching, Switcheroo warns about anything that would make it a no-op: environment variables the CLI prefers over its stored login (GH_TOKEN, CLOUDFLARE_API_TOKEN, VERCEL_TOKEN, ANTHROPIC_API_KEY, …), a CLI that caches credentials at startup, or an unsupported storage mode such as Codex's keyring option.

Security

  • Secrets live only in the OS credential store: macOS Keychain, Windows Credential Manager, or Linux Secret Service. --vault file opts into a 0600 JSON file for machines without one. Switcheroo's own state.json holds emails, labels and timestamps, never tokens.
  • On macOS the keychain is accessed through /usr/bin/security, the same tool Claude Code uses. Items created that way never trigger access prompts, and updating the binary does not break access.
  • The web UI listens on loopback only. Every mutation needs a per-launch session token in a custom header, which cross-site requests cannot supply, and the API never returns credential bytes.
  • Nothing leaves your machine. There is no telemetry and no network access beyond the CLIs' own whoami commands.

Command reference

CommandWhat it does
switcheroo / status [--refresh]Every detected CLI, who it is signed in as, remembered accounts
save <provider> [--label NAME]Remember the current login
login <provider> [--label NAME]Run the CLI's sign-in here, then remember the result
use <provider> [account]Switch; account by email, label or unique fragment, picker if omitted
list [provider] · rename · removeManage remembered accounts
usage [provider] [--refresh]Used quota and reset times for signed-in accounts
doctor · providersDiagnostics and the provider catalog
tray · serve [--bind] · openRun the tray, the web server, or open the UI
autostart enable|disable|statusStart the tray at login
completions <shell>Shell completions

Global: --json, --vault auto|keychain|file, --data-dir DIR, -v, -q. Exit codes: 0 ok, 1 error, 2 usage, 3 CLI not installed, 4 nothing signed in.

Development

cargo test                                          # Rust unit tests, incl. a real keychain round trip on macOS
cd web && npm install && npm run dev                # Vite on :5173, proxies /api to :7777
cargo run -- serve --dev --bind 127.0.0.1:7777      # dev server with a fixed session token

The architecture, invariants and the checklist for adding a provider are in CLAUDE.md. A provider is one file under src/providers/ built from a few slot adapters and an identity resolver, plus one line in the registry; the CLI, API, tray and web UI pick it up without changes.

License

MIT

Contributors

FTCHD

44 commits

Languages

Rust

63.9%

TypeScript

33.0%

CSS

1.5%