Manage multiple Claude Code accounts with usage tracking, load balancing, and a KDE Plasma widget
C2Switcher is a practical CLI tool for juggling multiple Claude Code accounts. It tracks usage, automatically selects the best account based on availability, and includes a neat Plasma widget for at-a-glance monitoring.
- Multi-account management - Store and switch between multiple Claude Code accounts
- Usage tracking - Monitor 5-hour, 7-day, and Opus usage limits with color-coded indicators
- Smart load balancing - Automatically picks the optimal account based on usage and active sessions
- Session tracking - See which accounts are actively being used and where
- KDE Plasma widget - Monitor all accounts from your panel
- Usage caching - Respects rate limits with 30-second cache
- Wrapper script -
c2claudecommand for seamless account switching
This tool uses undocumented OAuth API endpoints to fetch usage data. While Anthropic allows users to create multiple accounts (confirmed by multiple people who asked Anthropic Staff, including me), this specific implementation relies on reverse-engineered API paths that may change without notice.
If Anthropic would prefer this tool not exist, please reach out and I'll gladly take it down. I'm very compliant like that :)
curl -fsSL https://raw.githubusercontent.com/can1357/c2switcher/master/setup.sh | bashOr download and run interactively:
git clone https://github.com/can1357/c2switcher.git
cd c2switcher
./setup.shThe interactive installer will ask what you want to install:
- CLI tools only
- CLI tools + KDE Plasmoid
- Plasmoid only (if CLI already installed)
# Install the package locally (editable)
pip install -e .
# Or use setup.sh with options (installs via pip under the hood)
./setup.sh --cli # CLI tools only
./setup.sh --plasmoid # Plasmoid only (requires CLI)
./setup.sh --all # Install everythingAdd your current account (from ~/.claude/.credentials.json):
c2switcher addAdd with a memorable nickname:
c2switcher add --nickname workAdd from a specific credentials file:
c2switcher add --creds-file ~/path/to/credentials.json --nickname personal$ c2switcher lsOutput:
Claude Code Accounts
╭───────┬──────────┬────────────────────┬───────────┬──────┬───────────────────╮
│ Index │ Nickname │ Email │ Name │ Type │ Tier │
├───────┼──────────┼────────────────────┼───────────┼──────┼───────────────────┤
│ 0 │ main │ ****@gmail.com │ **** │ Max │ default_claude... │
│ 1 │ work │ ****@gmail.com │ **** │ Max │ default_claude... │
│ 2 │ personal │ ****@gmail.com │ **** │ Max │ default_claude... │
╰───────┴──────────┴────────────────────┴───────────┴──────┴───────────────────╯
$ c2switcher usageOutput:
Usage Across Accounts
╭───────┬──────────┬────────────────────┬─────┬─────┬─────────┬──────────╮
│ Index │ Nickname │ Email │ 5h │ 7d │ 7d Opus │ Sessions │
├───────┼──────────┼────────────────────┼─────┼─────┼─────────┼──────────┤
│ 0 │ main │ ****@gmail.com │ 0% │ 45% │ 87% │ 0 │
│ 1 │ work │ ****@gmail.com │ 5% │ 77% │ 100% │ 0 │
│ 2 │ personal │ ****@gmail.com │ 11% │ 3% │ 6% │ 1 │
╰───────┴──────────┴────────────────────┴─────┴─────┴─────────┴──────────╯
Active Sessions (1):
* ****@gmail.com (/home/user/projects/myproject, 4m ago)
Color indicators:
- 🟢 Green (< 70%) - Plenty of headroom
- 🟡 Yellow (70-90%) - Getting close
- 🔴 Red (> 90%) - Nearly exhausted
Force refresh (ignore 30s cache):
c2switcher usage --forceJSON output for scripting:
c2switcher usage --jsonTwo rich analytics dashboards are built in. Each command prints a detailed terminal summary and saves a PNG visualization (default paths shown).
# Session insights (top projects, daily cadence, heatmaps, recommendations)
c2switcher report-sessions \
--db ~/.c2switcher/store.db \
--output ~/c2switcher_session_report.png \
--days 30 \
--min-duration 60
# Usage risk forecast (limit timing, burn rates, reset timeline)
c2switcher report-usage \
--db ~/.c2switcher/store.db \
--output ~/c2switcher_usage_report.png \
--window-hours 24Add --show if you want the figure displayed after it is written.
Switch by index:
c2switcher switch 0Switch by nickname:
c2switcher switch workSwitch by email:
c2switcher switch user@example.comc2switcher optimalThis shows the best account based on:
- Tier 1: Opus usage < 90% (prioritized)
- Tier 2: Opus exhausted but overall usage < 90%
- Load balancing: Considers active and recent sessions
Switch to the optimal account:
c2switcher optimal --switchRotate to the next account in your list:
c2switcher cycleUseful for quick manual rotation without looking up indices.
The wrapper combines account selection with running Claude Code:
# Use optimal account (default)
c2claude
# Use account 0
c2claude -1
# Use account 1
c2claude -2
# Use account by name/email/index
c2claude -a work
# Cycle to next account
c2claude --cycle
# Pass arguments to claude
c2claude -p "explain this code"
c2claude --model opus -p "complex task"The wrapper handles:
- Session registration and tracking
- Load balancing (even for short commands)
- Account stickiness (reuses the same account for a session)
- Cleanup on exit
Want to hack on the tool?
git clone https://github.com/can1357/c2switcher.git
cd c2switcher
pip install -e .
python -m c2switcher --helpThe CLI entry point is c2switcher, and everything now lives under the c2switcher/ package for easier maintenance.
- Compact panel view: Shows average Opus usage with color-coded badge
- Detailed popup: Combined usage bar + individual account cards
- Quick switching: One-click optimal account selection
- Auto-refresh: Polls every 60 seconds
- No services needed: Directly executes
c2switchercommands
./setup.sh --plasmoidOr manually:
kpackagetool6 --type=Plasma/Applet --install plasmoid- Right-click panel -> "Add Widgets..."
- Search for "Claude Code Usage"
- Drag to panel
| Command | Aliases | Description |
|---|---|---|
add |
Add a new account | |
ls |
list, list-accounts |
List all accounts |
usage |
Show usage across accounts | |
report-sessions |
Generate session analytics report | |
report-usage |
Generate usage risk forecast report | |
optimal |
pick |
Find optimal account |
switch |
use |
Switch to specific account |
cycle |
Rotate to next account | |
sessions |
List active sessions | |
history |
session-history |
Show past sessions with usage deltas |
These are typically called by c2claude, not manually:
| Command | Description |
|---|---|
start-session |
Register a new Claude session |
end-session |
Mark a session as ended |
All commands support:
--json- Output as JSON (where applicable)--help- Show command help
All data is stored in ~/.c2switcher/store.db (SQLite):
- Account credentials and metadata
- Usage history with timestamps
- Session tracking (PID, working directory, duration)
When a token expires, c2switcher automatically refreshes it:
- First tries:
claude -p /status --verbose --output-format=json(no usage) - Falls back to:
claude -p hi --model haikuif needed
This ensures tokens stay valid with minimal to no usage consumption.
Sandboxed Refresh: Token refresh operations run in an isolated temporary HOME directory (~/.c2switcher/tmp/{account_uuid}) to avoid interfering with any running Claude Code instances. User preferences (terminal theme, settings) are inherited from the real HOME to prevent prompts. The sandbox is automatically cleaned up after each refresh.
If refresh fails (e.g., revoked or invalid credentials), you'll see:
Error: Failed to refresh token. The credentials may be revoked or invalid.
Please re-authenticate by logging in to Claude Code with this account.
API calls are cached for 30 seconds to avoid rate limiting. Use --force to bypass.
The optimal account selection uses a scoring system:
score = base_usage + (active_sessions × 15) + (recent_sessions × 5)
Where:
base_usage= Opus usage (tier 1) or overall usage (tier 2)active_sessions= currently running Claude instancesrecent_sessions= sessions started in last 5 minutes
Each c2claude invocation:
- Registers a session (PID, working directory)
- Requests optimal account (with session ID for stickiness)
- Switches to the selected account
- Runs Claude
- Marks session as ended on exit
Dead sessions are automatically cleaned up using multi-factor liveness checks.
| Variable | Description |
|---|---|
DEBUG_SESSIONS=1 |
Enable verbose session tracking logs |
| Path | Purpose |
|---|---|
~/.c2switcher/store.db |
SQLite database (accounts, usage, sessions) |
~/.c2switcher/tmp/{uuid}/ |
Sandboxed temp directories for token refresh |
~/.claude/.credentials.json |
Active Claude Code credentials |
/usr/local/bin/c2switcher |
CLI tool |
/usr/local/bin/c2claude |
Wrapper script |
./setup.sh --uninstallOr manually:
# Automatic uninstall
./setup.sh --uninstall
# Or manually:
# Remove CLI tools
sudo rm /usr/local/bin/c2switcher /usr/local/bin/c2claude
# Remove plasmoid
kpackagetool6 --type=Plasma/Applet --remove org.claudecode.usage.plasma
# Remove all c2switcher data (optional)
rm -rf ~/.c2switcher/# Add your accounts (switch credentials in Claude Code first, then add)
c2switcher add --nickname main
c2switcher add --nickname work
c2switcher add --nickname personal
# Check usage
c2switcher usage
# Use optimal account automatically
c2claude
# Or manually pick one
c2claude -a work
# Check session history
c2switcher history# Get JSON output for parsing
optimal=$(c2switcher optimal --json)
email=$(echo "$optimal" | jq -r '.email')
echo "Best account: $email"
# Check if any account has Opus available
c2switcher usage --json | jq '.[] | select(.usage.seven_day_opus.utilization < 90)'# Try each account until one works
for i in {0..2}; do
c2switcher switch $i
claude -p "test" && break
done- Python 3.7+
- Claude Code CLI installed and configured
- KDE Plasma 6.0+ (for plasmoid only)
click>= 8.1.0rich>= 13.0.0requests>= 2.31.0psutil>= 5.9.0
Installed automatically via requirements.txt.
Ensure /usr/local/bin is in your PATH:
export PATH="/usr/local/bin:$PATH"Add to ~/.bashrc or ~/.zshrc to make permanent.
If you see "Failed to refresh token. The credentials may be revoked or invalid":
- Log in to Claude Code with that account to generate fresh credentials
- Re-add the account to c2switcher:
c2switcher add --nickname <name>
Make sure the claude command works:
claude -p hi --model haikuVerify c2switcher works from terminal:
c2switcher usage --jsonCheck plasmoid logs:
journalctl -f | grep plasmashellRestart plasmashell to reload the widget:
systemctl --user restart plasma-plasmashellOr remove and re-add the widget to your panel.
Dead sessions should auto-cleanup, but you can manually verify:
c2switcher sessionsEnable debug mode:
DEBUG_SESSIONS=1 c2claudeImprovements are welcome:
- Fork it
- Create a feature branch
- Submit a PR
Built for personal use, released in case others find it useful. Not affiliated with Anthropic.
Tip: Bind c2claude to a shell alias or keyboard shortcut for maximum laziness.
