A tiny macOS menu-bar gauge for your Claude Code usage on a Claude Pro/Max plan: the real 5‑hour and weekly rate-limit numbers Anthropic enforces, pulled live from the API's response headers (not estimated), with desktop alerts before you hit a wall. It reads your Claude Code subscription login (OAuth), not an API key.
Mostly vibe-coded, so expect the odd rough edge. Bug reports and PRs are very welcome.
The menu-bar glyph is itself a gauge that fills with your 5‑hour load…
| ◯ | ◔ | ◑ | ◕ | ● |
|---|---|---|---|---|
| 0% | ~25% | ~50% | ~75% | 100% |
…and shifts green → amber → red as it fills. That little disc is all it occupies in your menu bar:
Claude Code shows your usage with /usage, but only when you go looking. claude-meter keeps the two numbers that actually gate you (the 5‑hour and weekly windows) glanceable in the menu bar, and pings you before you hit the cap, so a big run never dies halfway.
- Live 5h + weekly % gauges, color-coded, from Anthropic's rate-limit headers.
- Exact reset times | clock time and countdown (
resets Tue 11:00 PM · in 4d 12h). - 🔔 Threshold alerts | a desktop notification when a window crosses 50% / 80% / 95%, once per crossing per window (runs in the background, even with the menu closed), plus a heads-up when a window resets after you'd been warned.
- ⏳ Projected exhaustion | "on pace to hit the weekly cap ~Mon 2 AM" from your current burn.
- 🚦 Throttle status | a banner if Anthropic is warning / queueing / rejecting your requests, plus a ⛔/⏳ dot in the menu bar so you catch it without opening the menu.
- 🔥 Burn rate + 📈 trend | a current burn-rate line (e.g.
burn ~42%/hr) and a 24-hour sparkline of your 5h window, account-wide (sampled from the headers each refresh). - Active sessions (this machine) | sessions with log activity in the last 30 min, ranked by spend, with live context size and subagent count; click one to reopen it in a terminal (runs
claude --resumefor you). - $ proxy stats | per-day burn chart, today / week / 30d / all-time, and a by-model breakdown.
- 💡 Insight line | one computed tip from your week (e.g. "95% of input is cached context,
/compactmore often"). - 🔗 Quick links | jump to the repo, your
~/.claudelogs, or Anthropic's status page. - Multiple accounts, and optionally OpenAI Codex | one gauge set per Claude login, plus a Codex subscription read from the local
codexCLI. See Customize.
- The two % gauges are account-wide. Anthropic enforces the rate limit server-side per account, so the utilization headers already reflect every machine you're signed into. Run claude-meter on any one of them and the bars are correct for your whole account.
- The $ figures and "active sessions" are local | parsed from this machine's
~/.claude/projectslogs. They tell you where this machine's tokens went, not your global breakdown. The section is labeled "this machine" so it's never misleading.
- On each refresh it sends a 1-token request to the Anthropic API and reads the response's
anthropic-ratelimit-unified-*headers (5h/7dutilization + reset timestamps). Those are the source of truth. - It authenticates with your own Claude Code OAuth token, read from the macOS Keychain (
Claude Code-credentials), the same token Claude Code already uses. Nothing is stored or transmitted anywhere except that one call toapi.anthropic.com. - The dollar figures come from a local cost proxy that parses
~/.claude/projects/**/*.jsonland prices the tokens at Anthropic's published rates. On a Pro/Max plan these are equivalent API costs, not money billed, a usage proxy. If the API is unreachable (token expired, offline), the widget falls back to this proxy for the percentage bars too.
- macOS (the menu-bar host, SwiftBar, is macOS; a Linux port is on the roadmap)
- Homebrew
- Claude Code on a Pro or Max plan, signed in (OAuth): claude-meter reads that subscription token, and the 5h / weekly figures it shows are your subscription's limits. (Claude Code used with an API key doesn't have these unified rate limits, so the gauges won't apply.)
- Python 3 (system / conda / brew; no third-party packages)
- SwiftBar | the installer adds it for you
git clone https://github.com/fabiohuebel/claude-meter.git
cd claude-meter
./install.shThe installer installs SwiftBar via Homebrew if needed, copies claude-meter.5m.py into ~/SwiftBarPlugins/, points SwiftBar at that folder, and launches it.
- Plugin folder. On its first launch SwiftBar asks you to choose a plugin folder. Pick
~/SwiftBarPlugins(the installer just created it). The disc then appears in your menu bar. - Keychain. The first live fetch pops "SwiftBar wants to use the Claude Code-credentials key." Click Always Allow so it can read your token each refresh. Deny it and the widget still runs, it just shows
○ proxyand uses the local estimate.
- Auto-refreshes every 5 minutes (the
.5m.in the filename). The dropdown has a ↻ Refresh now button that force-pings past the cache, and an "updated Xm ago" freshness line. - Polling cost is negligible: one 1-token Haiku request per refresh (~288/day).
-
Refresh interval: rename the file:
claude-meter.2m.py(2 min),.10m.py,.1h.py, … -
Alert thresholds: edit
ALERT_LEVELSnear the top of the plugin (default[50, 80, 95]). -
Active-session window: edit
ACTIVE_MIN(default30min), how recently a session must have logged to count as active. -
Config file (no code edits): create
~/.config/claude-meter/config.jsonwith any of:{"alert_levels": [50, 80, 95], "active_min": 30, "dual_title": false, "title_window": "5h", "terminal": "Terminal"}dual_title: trueshows both windows in the menu bar (◔35 ◑48);title_window: "weekly"makes the single gauge track the weekly window instead of the 5h.terminalpicks where a clicked session reopens:"Terminal"(default) or"iTerm", both reliable via AppleScript;"Warp"also works but drives the app with simulated keystrokes (needs Accessibility permission and can be flaky). On first click macOS asks to let SwiftBar control the terminal → Allow. -
Show / hide sections: add a
showobject to trim the dropdown to exactly what you want, set any tofalse:{"show": {"forecast": true, "burn": true, "trend": true, "sessions": true, "insight": true, "cost": true, "links": true}}e.g.
{"show": {"cost": false, "links": false, "trend": false}}gives a minimal menu. The menu-bar gauge and the 5h + weekly bars always show. -
Multiple accounts (work + personal): rate limits are enforced per account, so a second Claude Code login needs its own gauge. Add an
accountslist (max 4) and each entry gets its own block in the dropdown, its own alerts, and its own sparkline:{"accounts": [{"label": "Work", "config_dir": "~/.claude"}, {"label": "Personal", "config_dir": "~/.claude-personal"}], "multi_title": true, "title_account": "Work"}Each account is one
CLAUDE_CONFIG_DIR. Log the second one in withCLAUDE_CONFIG_DIR=~/.claude-personal claude /login.multi_titleputs one gauge per account in the menu bar (W◔35 P◑58, first letter of each label);title_accountpicks which single account the title tracks whenmulti_titleis off. With noaccountskey the plugin behaves exactly as before.config_diris normally all you need. Claude Code namespaces its macOS Keychain item per config directory: the default~/.claudeusesClaude Code-credentials, and any other directory gets a-<sha256(abspath)[:8]>suffix, so two logins on the same Mac never overwrite each other. claude-meter derives that name the same way. The full per-account lookup order is: an explicit"keychain_service", then<config_dir>/.credentials.json, then the derived Keychain name, then the platform default.As a safety net the plugin fingerprints each token (SHA-256) and reports
duplicate logininstead of drawing identical numbers under two labels. If you see that, two entries are resolving to the same login. An account with no usable login showsnot signed inrather than a fake 0%.A 5h-only seat (e.g. a managed enterprise seat with no weekly cap) omits the weekly bar instead of showing
0%. -
OpenAI Codex usage (experimental): a Codex subscription can sit alongside your Claude accounts. Set
"provider": "codex"on an entry:{"accounts": [{"label": "Claude", "config_dir": "~/.claude"}, {"label": "Codex", "provider": "codex"}], "multi_title": true}The numbers come from the local
codexCLI, not from OpenAI's HTTP API: claude-meter runscodex app-serverand callsaccount/rateLimits/read, which is part of the CLI's own generated protocol. So there's no second token to store, nothing to keep in the Keychain, and no dependency on an undocumented backend route. It just needscodexonPATHand a completedcodex login.Codex reports each window's length itself (
windowDurationMins) and some plans expose only one window, so bars are labeled from what your plan actually returns (5h,week,30d, …) rather than assuming Claude's fixed 5h + weekly pair. Your plan tier (pro,plus,team, …) shows next to the account name. Add"all_limits": trueto that entry to also draw the per-model buckets (e.g. a separateGPT-5.3-Codex-Sparklimit) instead of just the headline one.Gauges, resets, forecasts, alerts and the sparkline all work for Codex. The $ figures and the active-sessions list stay Claude-only, since those are parsed from
<config-dir>/projectslogs that Codex doesn't produce. -
Colors: edit
clr()(default: green <50%, amber <80%, red ≥80%). -
Offline fallback caps (optional): drop
claude_limit.txt(5h) /claude_weekly_limit.txt(weekly) into~/.config/claude-meter/, one number each, used only to scale the proxy bars when the API is down.
./uninstall.shRemoves the plugin and the ~/.config/claude-meter cache. SwiftBar is left in place (brew uninstall --cask swiftbar to remove it too).
- Your OAuth token is read at refresh time (Keychain, or
<CLAUDE_CONFIG_DIR>/.credentials.jsonfor a second account) and used only as the bearer for a single request toapi.anthropic.com. It's passed tocurlvia stdin, so it never appears inps/argv, and it's never written to disk, logged, copied, or sent anywhere else. With multiple accounts, tokens are compared by SHA-256 fingerprint purely to spot a duplicate login; the fingerprint is never stored or displayed. A Codex account involves no token here at all: the localcodexCLI holds your ChatGPT login and answers the usage query over its own stdio protocol, so nothing is read out of~/.codex/auth.json. - No telemetry / phone-home. The only network request claude-meter makes is that one 1-token ping per Claude account; a Codex account adds none of ours, since the
codexCLI performs its own. The GitHub and status links only open if you click them. - The only thing cached locally is numeric rate-limit data + alert state under
~/.config/claude-meter/, no token, no paths, no session content. Your session titles, directories, and cost figures never leave your machine (menu / clipboard / terminal only). - It's one dependency-free Python file. Read it before you run it.
See ROADMAP.md. Next up: a utilization trend sparkline, a config file, and a Linux port (waybar / Argos) for non-Mac workstations.
MIT. See LICENSE.


0 comments
log in to comment.