A zero-dependency PowerShell tool for Claude Code on Windows: a live plan-usage dashboard across multiple accounts, plus safe save / switch / rotate. Single self-contained .ps1, no companion files.
- Live plan-usage dashboard:
sca usage -Watchpolls Anthropic's/api/oauth/usageand 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 - 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
listis guaranteed to be who the tokens actually belong to - 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
- Transparent token refresh: expired access tokens are refreshed before usage queries and mirrored back into the active credentials file
- Atomic-safe writes: slot-file updates survive a running Claude Code via
MoveFileExwith retry;save/switchstill refuse to run while it's open (single source of truth on~/.claude.json) - Named slots with rotation: unlimited accounts under any name (Windows-invalid characters auto-sanitized);
sca switchwith no name cycles through them alphabetically - Zero dependencies: pure PowerShell 7.2+, no external packages, no companion assets
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 latest switch_claude_account.ps1 and place it anywhere on disk.
Tip
Check the releases page for older versions.
.\switch_claude_account.ps1 installThis adds sca (short) and switch-claude-account (long) aliases to your PowerShell profile. Close and reopen your terminal to activate them.
.\switch_claude_account.ps1 <action> [name]Log into an account in Claude Code, close Claude Code, then save:
sca save work
sca save personal
sca save test-projectsave 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.
sca listThe 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.
sca switch workswitch 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.
sca switchWithout 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.
sca remove test-projectremove refuses to delete the slot tracked as currently active.
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 —.
sca usage # one-shot table for every slot
sca usage work # verbose single-slot block (opus / sonnet / overage)
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:
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. Accountcolumn: the OAuth email captured at save time. Shows—when the email equals the slot name (deduped filename), the actual email otherwise.Session/Weekcells:<pct>% <delta>. The delta is(2h 11m)under 24h with minute precision,(102h)at 24h+ with integer hours,nowif the reset is past, or—when no data is available.Statuscolumn: one ofok,near limit(≥90%),limited 5h/limited 7d(≥100%),error,expired,unauthorized,rate-limited, orno-oauth. Status drives the entire row's color.
Drill into a single slot for absolute reset times in your local timezone:
sca usage worklist, switch, and usage 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.
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 colorThe terminal-tab title is updated on every poll so a backgrounded watch is glanceable from the taskbar / Alt-Tab:
22% | 62% | Switch Claude Account
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.
sca install # Add aliases to your PowerShell profile
sca uninstall # Remove aliases from your PowerShell profile
sca help # Show usage info- Open Claude Code and log in with your first account
- Close Claude Code
- Run
sca save work - Open Claude Code, log out, log in with a different account
- Close Claude Code
- 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.
- Close Claude Code
- Run
sca switch work - Open Claude Code: it now uses the
workcredentials and/statusshows the matching email
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.)
Spaces, Windows-invalid filename characters (\ / : * ? " < > | and control chars), and PowerShell wildcard brackets ([ ]) are automatically replaced with _. Trailing dots are stripped. Reserved Windows device names (CON, PRN, AUX, NUL, COM1-COM9, LPT1-LPT9) are rejected.
my personal→my_personalfoo/bar→foo_barfoo[bar]→foo_bar_foo.→fooCON→ error (reserved device name)
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).
The active-slot tracker lives at %USERPROFILE%\.claude\.sca-state.json; plain JSON, safe to inspect. Schema: { schema, active_slot, last_sync_hash }.
If you get a security warning on first run, press Y or run once as:
Set-ExecutionPolicy -Scope CurrentUser RemoteSignedpwsh -NoProfile -File tests/Invoke-Tests.ps1Pester 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.
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.jsonconfig and the undocumented/api/oauth/usageendpoint 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.
If sca saves you a hassle, consider supporting future work:
- GitHub Sponsors: recurring or one-time.
- Ko-fi: one-time tip, no signup required.
