Skip to content

countzero/windows_switch_claude_account

Repository files navigation

Switch Claude Account

Latest release Last commit License: MIT PowerShell 7.2+ GitHub Sponsors Ko-fi

A zero-dependency PowerShell utility for Claude Code on Windows that combines secure multi-account management with a live usage dashboard and automated limit-based rotation.

sca monitor: pool-aggregate Session bar at 22% (green) and Week bar at 62% (yellow), then a five-row slot table with the active 'work' row in green, two inactive 'ok' rows, one yellow 'near limit' row, one red 'limited 7d' row, a right-aligned '▶ switching slot at 95%' header indicator, and a '[Monitor] Rotated from \

Features

Account & identity

  • Identity-aware slots: each slot's OAuth email is captured at save time, baked into the filename, and locked in a sidecar; what you see in list is guaranteed to be who the tokens actually belong to
  • Named slots with rotation: unlimited accounts under any name (Windows-invalid characters auto-sanitized); sca switch with no name cycles through them alphabetically

Live usage monitoring

  • Live plan-usage dashboard: sca usage -Watch polls Anthropic's /api/oauth/usage and renders a flicker-free, auto-refreshing view of Session (5h) and Week (7d) limits across every slot; the terminal-tab title is updated each poll so a backgrounded watch is glanceable from the taskbar / Alt-Tab
  • Transparent token refresh: expired access tokens are refreshed before usage queries and mirrored back into the active credentials file

Automation

  • Auto-reconcile: silently captures Claude Code's hourly token refreshes into the tracked slot; auto-saves cross-account swaps under a timestamped name so you never lose state
  • Smart rotation (OpenCode only): sca monitor auto-rotates to the next eligible slot when the active one hits a usage threshold (default 95%); refuses to run while Claude Code is open
  • Cold-slot warmup: sca warmup (and sca monitor -KeepWarm) opens each dormant slot's 5h window by running the real Claude Code CLI, so Anthropic reports usage data for every account (billable)

Reliability & footprint

  • Atomic-safe writes: slot-file updates use MoveFileEx with retry so they survive a running Claude Code on .credentials.json; save / switch still refuse to run while it's open to protect ~/.claude.json
  • Zero dependencies: pure PowerShell 7.2+, no external packages, no companion assets

Installation

Requisite

Requires PowerShell 7.2+. Stock Windows ships PowerShell 5.1, which is not supported. Install PS 7 via winget install Microsoft.PowerShell, then run from pwsh.

Download

Download latest switch_claude_account.ps1 and place it anywhere on disk.

Tip

Check the releases page for older versions.

Manual (run once)

.\switch_claude_account.ps1 install

This adds sca (short) and switch-claude-account (long) aliases to your PowerShell profile. Close and reopen your terminal to activate them.

Without alias

.\switch_claude_account.ps1 <action> [name]

Usage

Save an account

Log into an account in Claude Code, close Claude Code, then save:

sca save work
sca save personal
sca save test-project

save refuses to run while Claude Code is open and refuses to save a slot whose identity it cannot resolve from ~/.claude.json (primary) or /api/oauth/profile (fallback). There are no unlabeled-no-identity slots. To rename a slot: sca switch old-name; sca save new-name; sca remove old-name.

List saved slots

sca list

The active slot is marked with * (sourced from ~/.claude/.sca-state.json). Slots whose identity sidecar is missing or invalid are hidden from the list, from rotation, and from switch; re-running sca save <name> while that slot is active recaptures the sidecar.

Switch to a slot

sca switch work

switch refuses to run while Claude Code is open. It atomically writes the slot's bytes into .credentials.json AND restores the slot's captured oauthAccount block into ~/.claude.json so Claude Code's /status shows the matching email.

Rotate to the next slot

sca switch

Without a name, switch activates the next slot in alphabetical order and wraps from the last back to the first. The current position comes from state.active_slot.

Remove a slot

sca remove test-project

remove refuses to delete the slot tracked as currently active.

Identity capture: who is each slot actually logged in as?

Slot names are user-assigned labels; nothing stops you from naming a slot work and later overwriting it with credentials for a completely different account. At sca save time the tool pulls the OAuth email from ~/.claude.json's oauthAccount block (Claude Code's own cache) and embeds it in the slot filename:

%USERPROFILE%\.claude\.credentials.work(ada.lovelace@arpa.net).json

A paired sidecar .credentials.work(ada.lovelace@arpa.net).account.json holds the full whitelisted identity (accountUuid, emailAddress, organizationUuid, displayName, organizationName) so sca switch can restore the matching oauthAccount block to ~/.claude.json. Because the email is captured at save time and carried in both the filename and sidecar, it cannot drift from the OAuth tokens; the only way to update a slot's email label is to re-run sca save.

When the slot name already equals the OAuth email, the filename is deduplicated to .credentials.alice@example.com.json and the Account column shows .

Check plan usage

sca usage                         # one-shot table for every slot
sca usage work                    # verbose single-slot block (Session / Week, absolute reset times)
sca usage -Json                   # machine-readable per-slot output
sca usage -NoColor                # strip ANSI color (also: $env:NO_COLOR='1')

The output shows the 5-hour session limit (Session column, "Current session" in Claude Code's /usage) and the 7-day weekly all-models limit (Week column, "Current week (all models)") as percentages of each account's Claude.ai subscription:

sca usage one-shot: green pool-aggregate Session bar at 10% and Week bar at 24%, then a two-row table showing active 'work' (green) and inactive 'personal' (gray)

Decoding the output:

  • Pool-aggregate bars: sum utilization across HTTP-ok slots over N × 100%. Bar color: green <50%, yellow ≥50%, red ≥90%.
  • Active marker (*): sourced from ~/.claude/.sca-state.json; appears at the start of the row and inherits the row's color.
  • Account column: the OAuth email captured at save time. Shows when the email equals the slot name (deduped filename), the actual email otherwise.
  • Session / Week cells: <pct>% <delta>. The delta is (2h 11m) under 24h with minute precision, (102h) at 24h+ with integer hours, now if the reset is past, or when no data is available.
  • Status column: one of ok, near limit (≥90%), limited 5h / limited 7d (≥100%), error, expired, unauthorized, rate-limited, or no-oauth. Status drives the entire row's color.

Drill into a single slot for absolute reset times in your local timezone:

sca usage work

sca usage work: yellow [Usage] header, dim Account line, green Status: ok, then Session and Week rows with absolute reset times in Europe/Berlin

list, switch, usage, warmup, and monitor (per poll) run a quiet reconcile pass before doing their work: if .credentials.json has changed since the last sync (Claude Code refreshed a token, or you logged into a different account inside Claude Code), the new bytes are captured into the tracked slot, or auto-saved under auto-<UTC-timestamp>(<email>).json if the email differs.

Warning

Unofficial API. sca usage calls api.anthropic.com/api/oauth/usage, the same endpoint Claude Code's /usage uses internally. Undocumented by Anthropic and may break on Claude Code upgrades; when that happens, see the extraction recipe at the top of switch_claude_account.ps1 to re-pin the constants. The endpoint is not a public API and may be changed or withdrawn at Anthropic's discretion; use accordingly.

Note

Token refresh. If a slot's access token has expired (default TTL ~1h), sca usage transparently refreshes it against platform.claude.com/v1/oauth/token and mirrors the new tokens back into both the slot file and .credentials.json via atomic rename so the active session keeps working.

Watch plan usage live

Execute sca usage -Watch to enable the live dashboard:

sca usage -Watch                  # live, self-refreshing view; Ctrl-C to quit
sca usage work -Watch             # follow a single slot
sca usage -Watch -Interval 300    # slower poll cadence (60s floor)
sca usage -Watch -NoColor         # strip ANSI color

The terminal-tab title is updated on every poll so a backgrounded watch is glanceable from the taskbar / Alt-Tab:

22% | 62% | Switch Claude Account

sca usage -Watch: pool-aggregate Session bar at 22% (green) and Week bar at 62% (yellow), then a five-row slot table with the active 'work' row in green, two inactive 'ok' rows, one yellow 'near limit' row, one red 'limited 7d' row, and a [Watch] Last poll footer

Note

The title's numbers come from the active slot (or the slot named in sca usage <name> -Watch); a non-ok row falls back to the bare brand suffix. A [~] prefix appears when a bucket is ≥90%, [!] when ≥100%. Pre-watch title is restored on Ctrl-C.

Warm up cold slots

Anthropic only reports /api/oauth/usage data for slots that have an open server-side 5h session window, which only a real message can open. Warmup automates the manual "switch to a slot, send one message" routine across every saved slot: for each slot it switches in and runs the real Claude Code CLI (claude -p "Hi" in safe-mode on Haiku, ~$0.004/slot), then restores the slot you started on. Because it runs the actual client, it opens the window exactly like you typing a message would.

sca warmup                            # warm every slot once, print the table, exit
sca warmup slot-2                     # warm just one slot
sca monitor -KeepWarm                 # auto-rotate AND keep every slot warm for the whole watch

sca monitor -KeepWarm does more than the one-shot pass: at each poll it re-opens any slot whose 5h window has since closed, so a long session keeps every slot warm instead of letting them all expire ~5h after startup. (A 5h window can only be reopened after it closes, so a just-expired slot is re-warmed within one poll, not before.) A per-slot cooldown keeps a slot whose warm keeps failing from being retried every poll.

Both sca warmup and sca monitor -KeepWarm refuse to operate while Claude Code is running (the per-slot swap writes ~/.claude.json) and require the claude CLI to be installed and logged in. A slot whose token refresh is temporarily rate-limited is reported and skipped, not retried. -KeepWarm is the typical companion to monitor: rotation needs every peer slot reporting real data to make good decisions, which keeping them warm guarantees.

Auto-rotate on usage limit (OpenCode only)

sca monitor is a live watch that auto-rotates to the next eligible slot when the active slot's max(Session, Week) utilization hits the threshold. Rotation is what monitor is for, so it is always on (there is no -Auto flag); for a read-only live view use sca usage -Watch instead.

sca monitor                  # rotate when active slot hits 95% (default)
sca monitor -Threshold 90    # rotate earlier on either bucket
sca monitor -KeepWarm        # also keep every slot warm (billable)

Peer slots are walked in alphabetical wrap order (same direction as sca switch without a name); peers that are themselves at or above the threshold are skipped, as are peers with non-ok HTTP status. When no peer is eligible, the footer surfaces the soonest reset across all slots as a cooldown ETA: [Monitor] No free slot available! Cooling down for 1h 12m.. The mode is indicated on every frame by a right-aligned ▶ switching slot at N% header indicator plus a latched [Monitor] … footer line.

sca monitor: same five-row slot table as the watch view, with a right-aligned '▶ switching slot at 95%' header indicator and a '[Monitor] Rotated from \

Important

OpenCode-scoped feature. Requires opencode-claude-auth >= 1.5.4, which re-reads ~/.claude/.credentials.json on cache miss so a swap propagates to a running OpenCode process without restart. Claude Code itself is NOT supported: its in-memory ~/.claude.json cache would race the swap, so sca monitor refuses to start (and to rotate mid-watch) while claude.exe is running. Close Claude Code before running sca monitor; OpenCode can keep running.

Install / uninstall alias

sca install      # Add aliases to your PowerShell profile
sca uninstall    # Remove aliases from your PowerShell profile
sca help         # Show usage info

Workflow

Saving accounts

  1. Open Claude Code and log in with your first account
  2. Close Claude Code
  3. Run sca save work
  4. Open Claude Code, log out, log in with a different account
  5. Close Claude Code
  6. Run sca save personal

If Claude Code is running when you invoke save or switch, the action exits immediately with a clear message; no partial writes occur.

Switching between accounts

  1. Close Claude Code
  2. Run sca switch work
  3. Open Claude Code: it now uses the work credentials and /status shows the matching email

Why close Claude Code first?

sca save and sca switch read and write ~/.claude.json's oauthAccount block. Claude Code keeps that block in an in-memory cache that may flush back and clobber the update. Closing the app eliminates the race. (Slot-file updates done by sca usage's token refresh use MoveFileEx with retry, so they survive an open Claude Code on .credentials.json itself; but the ~/.claude.json cache race means you still need to close it for the two write actions.)

Windows Notes

Name sanitization

Spaces, Windows-invalid filename characters (\ / : * ? " < > | and control chars), PowerShell wildcard brackets ([ ]), and parentheses (( )) are automatically replaced with _. Trailing dots are stripped. Reserved Windows device names (CON, PRN, AUX, NUL, COM1-COM9, LPT1-LPT9) are rejected.

  • my personalmy_personal
  • foo/barfoo_bar
  • foo[bar]foo_bar_
  • foo(bar)foo_bar_
  • foo.foo
  • CON → error (reserved device name)

Profile encoding

sca install and sca uninstall preserve your PowerShell profile's existing encoding (UTF-8 with or without BOM, UTF-16 LE/BE). ANSI-encoded profiles are treated as UTF-8 no-BOM (indistinguishable without a BOM).

State file

The active-slot tracker lives at %USERPROFILE%\.claude\.sca-state.json; plain JSON, safe to inspect. Schema: { schema, active_slot, last_sync_hash }.

Execution policy

If you get a security warning on first run, press Y or run once as:

Set-ExecutionPolicy -Scope CurrentUser RemoteSigned

Testing

pwsh -NoProfile -File tests/Invoke-Tests.ps1

Pester 5 is auto-installed to CurrentUser scope on first use. PSScriptAnalyzer runs in advisory mode if installed. Each test sandboxes $env:USERPROFILE and $PROFILE.CurrentUserAllHosts to Pester's $TestDrive so your real .claude\ directory and PowerShell profile are never touched. Exit code follows Pester: 0 on pass, non-zero on any failure.

License & Disclaimer

MIT. Copyright (c) 2026 Finn Kumkar.

Unofficial tool. Not affiliated with, endorsed by, or sponsored by Anthropic. "Claude" and "Claude Code" are trademarks of Anthropic PBC, used here descriptively. The script interacts with Anthropic's ~/.claude.json config and the undocumented /api/oauth/usage endpoint as a third-party tool; usage is subject to Anthropic's Consumer Terms of Service and Usage Policy in addition to this repo's MIT terms. Use only with Anthropic accounts you personally own; this tool does not enable sharing one account among multiple people.

Support

If sca saves you a hassle, consider supporting future work:

Support on Ko-fi

About

A zero-dependency PowerShell script to switch between multiple Anthropic Claude accounts.

Topics

Resources

License

Stars

5 stars

Watchers

0 watching

Forks

Sponsor this project

  •  

Packages

 
 
 

Contributors