agy-multi
v1.1.0
Published
Multi Google account CLI for Antigravity / agy OAuth — login, quota, rotate, switch accounts by number
Maintainers
Readme
agy-multi
Multi Google account CLI for Antigravity / agy OAuth — login, quota tracking, reactive rotation, and one-command account switching.
Pure Python. No runtime dependencies. Works on macOS and Windows.
Install
npm install -g agy-multiThen run from anywhere:
agy-multi accountsOr run directly with Python:
python3 agy-multi.py accountsInteractive Launcher
Just type agy-multi without any subcommand — full interactive menu appears:
agy-multi — ↑↓ navigate · Enter select
────────────────────────────────────────────────────────────
▶ ● [email protected] 99.1% ok
○ [email protected] 100.0% ok
····························································
▶ Auto (best quota + launch)
📋 Detail quota
🔄 Refresh quotas
🔁 Rotate if exhausted
💬 Recent sessions
🩺 Doctor (health check)
⚙ Config
🗑 Remove account
🔑 Login / Exchange
····························································
❌ Quit
────────────────────────────────────────────────────────────- ↑↓ arrows to navigate, Enter to select;
[1-9]quick-pick → press number to launch account directly - Select an account → token applied to keychain,
agylaunches automatically - Quota colors → green ≥50%, yellow 20-50%, red <20%
- Auto → picks account with most remaining quota + launches
agy - Detail → quota breakdown for all accounts with progress bars
- Refresh → update quota data from API, then auto-show detail
- Rotate → switch to best account if current is exhausted
- Recent sessions → scrollable (12 rows, up to 200), type to search, selects
agy --conversation <id> - Doctor → health check
- Config → view/edit config
- Remove → delete an account (arrow-key picker)
- Setup → guided wizard: browser → exchange → apply
- Login → auto-open browser for Google OAuth
- Quit → exit
Shell completion: agy-multi completion bash|zsh → source <(agy-multi completion) — completes subcommands & account emails.
Subcommands still work: agy-multi setup, agy-multi completion bash, agy-multi list, agy-multi use 1, agy-multi run, etc.
Requirements
- Python 3.10+
agybinary installed (for credential bridge)- macOS: built-in
securityCLI (no extra deps) - Windows:
pywin32recommended for AGY apply (pip install pywin32)
Quick Start
# 1. Login Google (auto-opens browser)
agy-multi login
# 2. Exchange the auth code (from browser redirect URL)
agy-multi exchange "4/0A..."
# 3. See your accounts
agy-multi list
# 4. Switch by number or email
agy-multi use 1
# 5. Apply token to agy keychain (auto on use/switch)
agy-multi apply
# 6. Check quota
agy-multi quota --refresh
# 7. Rotate if exhausted
agy-multi rotateOne-command launch (auto-rotate)
agy-multi runThis will:
- Refresh quota for all accounts
- If active account is exhausted → auto-rotate to best account
- Apply token to keychain
- Launch
agydirectly
Options:
agy-multi run -c # continue last conversation
agy-multi run --model "Gemini 3.1 Pro"
agy-multi run -- --dangerously-skip-permissions # pass extra args to agyCommands
| Command | Description |
|---------|-------------|
| login | Print Google OAuth URL + auto-open browser |
| exchange "CODE" | Exchange OAuth code for tokens |
| list | Compact account table with numbers |
| accounts | Detailed account table with flags |
| use <number\|email> | Set active account (by number or email) |
| remove <number\|email> | Remove account (by number or email) |
| quota [--refresh] | Quota details with progress bars |
| status [--refresh] | JSON status (for agents/automation) |
| refresh [email] | Refresh OAuth tokens (all or specific) |
| apply [--email ...] | Push active account tokens to agy keychain |
| switch [--email ...] [--refresh] | Force or auto switch account |
| rotate | Switch only if active account exhausted |
| run [options] | Pre-flight check + auto-rotate + launch agy |
| doctor | Health check: agy, keychain, token, config, sessions |
| setup | Guided wizard: login → exchange → apply |
| completion [bash\|zsh] | Print shell completion script |
| config [--show] [--threshold N] [--apply-to-agy true] | View/update config |
Usage Examples
List accounts (compact)
# Email Name Tier Quota Token
--- ---------------------------------------- ---------------- -------------- ---------- --------
*1 [email protected] user1 pro-like 99.1% ok
2 [email protected] user2 starter-like 100.0% ok
* = active total: 2Switch by number
agy-multi use 2
# Active → [email protected]Quota view
----------------------------------------------------------------------
*1. [email protected] (pro-like)
----------------------------------------------------------------------
Gemini Models
█████████░ 99.1%
Bucket Remaining Window Reset
Weekly Limit 99.1% weekly 2026-08-10T07:52:49Z
Five Hour Limit 100.0% 5h 2026-08-05T01:15:23ZDoctor (health check)
agy-multi health check
──────────────────────────────────────────────────
✓ agy binary: /usr/local/bin/agy
✓ accounts: 2 registered
✓ active account: [email protected]
✓ token: valid
✓ keychain: credential found (service=gemini, account=antigravity)
✓ config: apply_to_agy=true
✓ sessions DB: ~/.gemini/antigravity-cli/conversation_summaries.db
──────────────────────────────────────────────────
Result: 7 ok · 0 warnings · 0 failures → HEALTHYHow It Works
agy-multi agy (Go binary)
│ │
├── login → exchange │
│ (Google OAuth) │
│ │
├── stores tokens in │
│ ~/.antigravity_cli/ │
│ │
├── apply / use / switch │
│ writes to OS keychain │
│ ──────────────────────────>│ reads refresh_token
│ │ refreshes access_token
│ │ (agy has own refresh logic)
│ │
└── quota / rotate │
(reactive, no polling) │Key insight: agy refreshes its own access_token using the refresh_token stored in the keychain. So once agy-multi writes the credential, agy runs independently — no background daemon needed.
Keychain Bridge
| OS | Keychain Service | Account | Format |
|-----|------------------|---------|--------|
| macOS | gemini | antigravity | go-keyring-base64: + base64(JSON) |
| Windows | Credential Manager | gemini:antigravity | JSON blob |
This matches the agy Go binary's go-keyring library format exactly.
Config
agy-multi config --show| Key | Default | Description |
|-----|---------|-------------|
| threshold_percent | 5.0 | Rotate when worst quota ≤ this % |
| watch_groups | Gemini, Claude/GPT, All Models | Quota groups to monitor |
| apply_to_agy | true | Auto-write tokens to keychain on use/switch |
| auth_method | consumer | OAuth auth method |
| oauth_client_id | (built-in) | Override with your own |
| oauth_client_secret | (built-in) | Override with your own |
Environment Variables
| Variable | Description |
|----------|-------------|
| AG_CLI_DIR | Storage dir (default ~/.antigravity_cli) |
| AG_OAUTH_CLIENT_ID | Override OAuth client ID |
| AG_OAUTH_CLIENT_SECRET | Override OAuth client secret |
| AG_CLI_SCRIPT | Absolute path to script (for agent skills) |
Storage
~/.antigravity_cli/
├── accounts.json # Account index
├── accounts/ # Per-account detail + tokens
│ └── <user_id>.json
├── active_account.json # Active account pointer
├── config.json # User config
└── cli.log # Log fileTokens are DPAPI-encrypted on Windows. On macOS stored plaintext (OS permissions restrict to user); keychain write uses security add-generic-password -U. Files written with 0o600 permissions where applicable.
Policy
- Reactive rotate only — no cron, no background polling
- Missing quota = unknown (never fake 100%)
- Prefer
--refreshbefore rotate decisions - Never paste full tokens in chat
Install on a New Device
- Install
agybinary npm install -g agy-multiagy-multi login→agy-multi exchange "CODE"agy-multi use 1- Run
agy— account detected automatically
Each device needs its own login (OAuth tokens are device-local).
Tests
python3 -m pytest tests/test_cli.py -vLicense
MIT
