aiquokka
One command to see the usage limits of all your AI coding subscriptions —
Claude, Codex, Kimi, Copilot, Grok, DeepSeek, Kiro, Antigravity, Z.ai, and Muse — reading the credentials each official CLI
already stores (or your existing API key). No tokens to paste, no config.

- All in one place — run
aiquokka bare to see every provider at once.
- Only what you use — providers you aren't logged into are skipped silently.
- Pace marker — each bar shows where even, linear usage would put you right
now, so you can tell at a glance if you're burning too fast.
- Auto token refresh — expired OAuth tokens are refreshed and written back.
- Scriptable —
--json / --yaml for machine-readable output, with a
stable id per window, --no-refresh for polling and an exit code of its own
for "not logged in".
- Live watch —
--watch / -w refreshes the view every 60 seconds.
- Menu bar app —
aiquokka tray keeps your limits in the macOS menu bar or
Linux system tray and alerts you before you hit them.
Install
go install github.com/McKean/aiquokka@latest
Requires Go (macOS: brew install go, Linux: use your package manager or https://go.dev/dl/).
Or build from source:
go build -o aiquokka .
Usage
aiquokka # all configured providers at once
aiquokka claude # 5-hour, weekly, and weekly Fable limits
aiquokka codex # weekly limit + remaining resets
aiquokka kimi # 5-hour and weekly limits
aiquokka grok # weekly usage limit + subscription tier
aiquokka copilot # copilot chat/completions limits
aiquokka deepseek # account balance (remaining money)
aiquokka kiro # Kiro CLI monthly credits and overage status
aiquokka agy # daily antigravity limits
aiquokka zai # Z.ai usage bundles and cash balance
aiquokka muse # Muse 5-hour and weekly limits
aiquokka tray # menu bar (macOS) / system tray (Linux) app
aiquokka --watch # refresh all providers every 60s
aiquokka claude -w # watch a single provider
$ aiquokka claude
Claude (max/default_claude_max_5x)
───────────────────────────────────
5h [██████░░░░░░░░░░░░░░░▒░░] 24.0% resets in 33m (Mon 19:00)
Weekly [███████████░░░▒░░░░░░░░░] 45.0% resets in 2d20h (Thu 14:27)
Weekly Fable [██████████████▓█░░░░░░░░] 67.0% resets in 2d20h (Thu 14:27)
Fable draws from the same weekly pool and may take up to half of it, so it is
often the limit you hit first. The two bars move together: Weekly Fable at
100% puts Weekly at 50% or more.
Run with no subcommand to fetch every provider concurrently. In a terminal, a
fixed-order skeleton appears for the providers you use, then each section fills
in as its response arrives — you keep a stable order without waiting for the
slowest provider before seeing anything. Providers you aren't logged into are
skipped; a provider that is configured but errors is shown inline without
aborting the rest. Calling a provider directly (e.g. aiquokka kimi) always
tells you if it isn't set up.
Watch mode
Pass --watch / -w on the root command or any provider subcommand to refresh
the view every 60 seconds until you hit Ctrl+C (or q). In a terminal a
pulsating status line shows the countdown to the next refresh; press r to
refresh immediately, or q (or Ctrl+C) to close. The previous frame is
cleared before each redraw. With --json / --yaml each tick emits a new
document (no status line).
aiquokka tray (or aiquokka bar) runs aiquokka in the macOS menu bar or in
the Linux system tray. It checks your limits in the background and shows them
in a small menu, with the same data as the terminal view.
- Top bar — a small ring and your highest usage right now (for example
44%).
If you only care about one provider, choose it in Preferences under
Menu bar shows (or use --pin claude). Then the top bar shows that provider's logo
and its highest usage, and the logo gets a small ! when it reaches the
alert level. The menu still shows all providers.
- One table for all providers (macOS) — each provider has its logo, and each window
has a usage bar, the percent and the reset time. All bars start in the same
column, so it is easy to compare them.
- On Linux — text rows with a small ring icon, because tray hosts there do
not show wide images in menus. The usage rows are dimmed so they do not
highlight on hover.
- Usage pages — click a provider's name to open its usage page in your
browser.
- Pace marker — the small vertical line on a bar shows where even usage
would put you now (see The pace marker).
- Alerts — a desktop notification when a window reaches the alert level
(default 80%), again when it reaches 100%, and when a window resets.
- Preferences — on macOS, Preferences… opens a small window with all
options in one place: notifications, alert level, what the top bar shows and
the refresh interval. Changes apply right away. On Linux the same options are
in a submenu. aiquokka saves these choices in
tray.json in your user config
folder and uses them next time. Flags on the command line win over the saved
choices.
aiquokka tray # refresh every 60s, alert at 80%
aiquokka tray --interval 2m # refresh every 2 minutes (1m is the minimum)
aiquokka tray --threshold 90 # alert at 90%
aiquokka tray --notify=false # no desktop notifications
aiquokka tray -p claude # watch only one provider
aiquokka tray --pin claude # watch all, but show only Claude in the top bar
Provider logos come from LobeHub Icons
(MIT). The logos are trademarks of their owners and are only used to show which
provider a row belongs to.
Machine-readable output
Add --json or --yaml (alias --yml) to any command. The aggregate view
keys the object by provider.
$ aiquokka grok --json
{
"provider": "Grok",
"plan": "XPremium",
"account": {
"id": "0b6f…",
"email": "you@example.com"
},
"windows": [
{
"id": "weekly",
"label": "Weekly",
"used_percent": 0,
"resets_at": "2026-07-25T07:05:43.476608Z",
"duration_seconds": 604800
}
],
"extra": [
{
"label": "Grok Code",
"value": "yes"
}
]
}
Per window:
id names the window for a program. It is unique within the provider and
stays the same when the display label is reworded, so match on id, never
on label. Where the provider has its own name for the limit, that is the
id; otherwise it is the window's length.
duration_seconds is the window's length. It is left out when the provider
does not say (a balance, a Z.ai bundle, Kiro's credits).
resets_at is left out when there is no known reset.
| Provider |
Window ids |
claude |
session (5h), weekly_all, weekly_scoped (Weekly Fable): the endpoint's limit kinds |
codex |
the length: 5h, 7d; primary / secondary if the length is not reported |
kimi |
the length for each rolling limit (5h), and weekly |
grok |
the period type: weekly, monthly, daily |
copilot |
premium_interactions, chat, completions |
deepseek |
balance/<currency>, e.g. balance/cny |
kiro |
credits |
agy |
<group>/<bucket> from agy's names, e.g. gemini-3-pro/weekly |
zai |
bundle/<model>, e.g. bundle/glm-5.3, and cash |
muse |
5h (rolling session window) and weekly |
account says whose login the answer is for: id is the provider's own
identifier and email the address, each present only if the stored login holds
it. No token or key is ever printed.
| Provider |
account |
claude |
id, email (from ~/.claude.json, where Claude Code records the account at login) |
codex |
id (the ChatGPT account id), email (from the stored id token) |
grok |
id, email |
copilot |
id (the GitHub login) |
kimi, deepseek, zai |
left out: the stored token or API key names no account |
kiro, agy |
left out: the login stays with that CLI, aiquokka never reads it |
muse |
left out: identity fields in the quota response are discarded |
Asking without touching a login
By default an expired token is renewed and written back, which makes aiquokka a
second writer of a login beside the CLI that owns it. A program that polls
should pass --no-refresh: aiquokka then never renews a token and never writes
a stored login. A provider whose token has expired (or is rejected) is reported
as not known, with the reason:
$ aiquokka claude --json --no-refresh
aiquokka: Claude token has expired or was rejected and --no-refresh is set — run `claude` to renew it
$ echo $?
1
$ aiquokka --json --no-refresh
{
"claude": {
"error": "Claude token has expired or was rejected and --no-refresh is set — run `claude` to renew it"
},
"codex": { … }
}
kiro and agy are answered by their own CLIs, which renew their own logins
as they see fit; --no-refresh does not reach into them. muse only reads
its login and has no refresh step, so --no-refresh is a no-op for it.
Exit codes
| Code |
Meaning |
0 |
The answer is on stdout. |
1 |
Any other failure: the network, the provider's endpoint, an expired token under --no-refresh, a wrong command line. The reason is on stderr. |
3 |
Not logged in to this provider: no stored login, no API key, or its CLI is not installed. Nothing to report, and trying again will not help. |
3 is only for a single provider (aiquokka claude). The aggregate view exits
0 whenever it could print: it leaves out providers without a login and gives a
failing one as {"error": "…"} under its key.
The pace marker
Every bar carries a bright-cyan marker cell at the point where even, linear
usage would put you at the current moment — the elapsed fraction of the
window. If the filled bar falls short of the marker you're under pace (headroom
to spare); if it's past the marker you're consuming faster than the window
refills.
Weekly [███████████▓███████████░] 94.0% ← marker buried inside: way over pace
5h [████░░░░░░░░░░░░░░░░▒░░░] 16.0% ← well behind the marker: plenty left
How it works
aiquokka reuses the credentials each official CLI already stores on your
machine and queries the same usage endpoint that CLI uses.
| Command |
Credentials |
Endpoint |
claude |
~/.claude/.credentials.json, or macOS Keychain (OAuth) |
api.anthropic.com/api/oauth/usage |
codex |
~/.codex/auth.json (ChatGPT OAuth) |
chatgpt.com/backend-api/wham/usage |
kimi |
~/.kimi-code / ~/.kimi OAuth, or $KIMI_API_KEY |
api.kimi.com/coding/v1/usages |
grok |
~/.grok/auth.json (xAI OIDC) |
cli-chat-proxy.grok.com/v1/billing?format=credits |
copilot |
~/.config/github-copilot/{apps,hosts}.json |
api.github.com/copilot_internal/user |
deepseek |
$DEEPSEEK_API_KEY |
api.deepseek.com/user/balance |
kiro |
Kiro CLI credential store (via kiro-cli /usage) |
q.<region>.amazonaws.com/getUsageLimits |
agy |
Antigravity CLI's own login |
agy -p /usage --output-format json (no session needed, spends no quota) |
zai |
$ZAI_API_KEY, or the zai provider in ~/.pi/agent/models.json |
api.z.ai/api/biz/tokenAccounts/list/my, api.z.ai/api/biz/account/query-customer-account-report |
muse |
~/.config/muse/auth.json device login (or $MUSE_AUTH_PATH); on macOS, where the token is not in that file, the Muse CLI itself |
api.meta.ai/muse-code/key (the CLI's own key-mint call), or muse serve (usage/read) |
Every provider that uses a short-lived OAuth access token (all except the
static API-key providers Kimi and DeepSeek, plus Muse, whose device login
offers no refresh) refreshes automatically when
the token has expired and writes the new token back to the credential file.
Pass --no-refresh to forbid both (see
Asking without touching a login).
Claude Code on macOS
Claude Code stores its OAuth credential in ~/.claude/.credentials.json or,
on macOS, the Keychain. Aiquokka prefers the credentials file when it contains
an OAuth access token. Otherwise it reads the Claude Code-credentials
item through the macOS security tool (the same helper Claude Code uses to
write it), which avoids a Keychain permission dialog for the aiquokka binary.
Over SSH, unlock the login Keychain first with security unlock-keychain.
If a permission dialog still cannot be confirmed remotely, aiquokka times
out the Keychain read instead of hanging. When a refresh is required, it
updates that same item while preserving fields it does not own. If several
matching items exist, it prefers the current user's. This storage format is
an implementation detail of Claude Code and may change without notice.
Per-provider notes:
- Codex reports a weekly window plus your remaining reset credits ("amount
of resets").
- Kimi limits are only on the Kimi Code coding subscription; the OAuth token
is auto-detected from the CLI, or set
KIMI_API_KEY to an sk-kimi-… key.
- Grok reports the weekly usage-limit window (the same figure the Grok CLI's
/usage shows), plus subscription tier and Grok Code access. xAI rotates
refresh tokens, so if both grok and aiquokka refresh the most recent one
wins; a "run grok to re-login" message means the stored token was superseded.
- Copilot fetches usage across Chat, Completions, and Premium Interactions based on the IDE or GitHub CLI stored credential.
- DeepSeek reads
DEEPSEEK_API_KEY (sk-…) and reports the account balance. The balance is money, not a usage limit, so the bar is full while any balance remains and empties at zero — the amount is the number that matters. The granted and topped-up portions are shown beneath it.
- Kiro runs the installed CLI’s built-in
/usage command non-interactively, so Kiro retains ownership of credentials and token refresh. It reports monthly credits, plan, reset date, and overage status.
- Antigravity runs
agy -p "/usage" --output-format json, which agy 1.2.x answers non-interactively without opening a session or spending quota. agy stays responsible for its credentials and token refresh.
- Z.ai reports the prepaid usage bundles (resource packages) as used/total token bars plus the pay-as-you-go cash balance. Bundles are model-specific — a bundle for
glm-5.3 stays untouched while requests to glm-5.3-flash burn cash — so check the "Applies to" fact if your cash drains faster than expected. The key is the Zhipu {id}.{secret} form; it is turned into a signed JWT locally. On the China platform, set ZAI_BASE_URL=https://open.bigmodel.cn/api (balance is then shown as CNY).
- Muse reports the subscription's rolling 5-hour and weekly windows. Where the
muse login device token is inline in ~/.config/muse/auth.json (override with MUSE_AUTH_PATH), as on Linux, they come from the CLI's own key-mint call. META_API_KEY and dashboard keys cannot read quota, so they are not used. Meta omits the usage block while the 5-hour window is idle, which shows as "idle" rather than 0%; an inactive subscription or a missing payment method is reported as such. The endpoint is rate-limited, so one read is reused for five minutes. The minted key and every identity field are discarded, and the login is never written. On macOS the CLI keeps the token in its own Keychain item, which aiquokka does not read: it starts muse serve --no-session-log, asks it for usage/read, and ends it, within 5 seconds at most. That needs muse on PATH and raises no Keychain dialog. The CLI answers with the usage it last observed; when it has observed none, aiquokka prints "no usage windows reported". The plan shown this way is the tier's id, not its display name.
Caveats
These are all undocumented endpoints used by the respective official CLIs;
they may change without notice. Please don't poll them aggressively — Claude's
endpoint in particular rate-limits hard. --watch refreshes every 60 seconds,
which is the floor you should use; avoid stacking extra watchers or shorter
custom loops on top of it.
License
MIT