Menu bar app showing your live Claude Code session and weekly usage as a colored progress bar.
Project description
tokenmaxxing
A menu bar app that shows your live Claude Code session and weekly usage as a colored progress bar — sitting next to the system clock so you always know how close you are to a rate-limit reset.
Session ███░░░░░ 38% · resets at Fri 07:00
Weekly ███████░ 87% · resets at Fri 09:00
The bar is tinted by utilization:
| color | range | meaning |
|---|---|---|
| ⚪ | n/a | no active window / data unavailable |
| 🟢 | <50% | plenty of headroom |
| 🟡 | 50–79% | getting close |
| 🔴 | ≥80% | reaching the limit very soon |
Only the filled █ segment is colored; the empty ░ segment stays in the menu bar's default text color (white on dark, dark on light).
Install
Requires Python 3.9+.
pip install tokenmaxxing
This pulls in rumps (which in turn pulls in PyObjC).
Run
tokenmaxxing
Or as a module:
python -m tokenmaxxing
Detached (so the menu bar app survives the launching shell):
nohup tokenmaxxing >/dev/null 2>&1 </dev/null &!
Autostart
Pick one of the two options below. Don't enable both — you'll get two instances of the app.
Option 1 — Launch at login
Open the menu bar dropdown → Preference → check Launch at login.
This writes a ~/Library/LaunchAgents/com.tokenmaxxing.app.plist and a tiny wrapper script at ~/.tokenmaxxing/tokenmaxxing (so System Settings → Login Items shows the friendly name, not "python3.9"). The system's launchd reads the plist on every login and starts the app. Uncheck the menu item to remove both files.
Heads up — Gatekeeper warning. Your system will show "tokenmaxxing is an item from an unidentified developer" the first time it's added to login items. This is unavoidable for any unsigned tool (code signing requires a paid Apple Developer account). To allow it: System Settings → Privacy & Security → scroll to the bottom → click "Allow Anyway". Subsequent boots skip the prompt. If that friction bothers you, use Option 2 instead — launching from a shell is treated as user-initiated and never triggers Gatekeeper.
Option 2 — Launch on first interactive shell (terminal-driven)
Append this guarded launcher to ~/.zshrc:
# tokenmaxxing — menu bar app showing Claude Code session/weekly usage
if [[ -o interactive ]] && ! pgrep -f "tokenmaxxing" >/dev/null 2>&1; then
nohup tokenmaxxing >/dev/null 2>&1 </dev/null &!
fi
The pgrep guard keeps it singleton across nested shells. The &! (zsh) detaches and disowns. The first interactive shell of the day starts it; subsequent shells skip via the guard.
How it works
It polls Anthropic's OAuth usage endpoint — the same call Claude Code makes internally:
GET https://api.anthropic.com/api/oauth/usage
Authorization: Bearer <token>
anthropic-beta: oauth-2025-04-20
The OAuth access token is read from your system keychain (service Claude Code-credentials) with ~/.claude/.credentials.json as fallback. Polling consumes zero tokens — it returns metadata only:
{
"five_hour": {"utilization": 38, "resets_at": "2026-05-01T11:00:00Z"},
"seven_day": {"utilization": 87, "resets_at": "2026-05-01T13:00:00Z"},
"seven_day_opus": null,
"seven_day_sonnet": {"utilization": 100, "resets_at": "2026-05-01T13:00:00Z"},
"extra_usage": {"is_enabled": false}
}
Refresh runs on a background thread every 5 minutes (the OAuth endpoint has aggressive undocumented rate limits, so polling more frequently triggers 429s). Token refresh is handled by Claude Code itself — when claude runs, it rotates the keychain entry and the next poll picks it up automatically.
Dropdown menu
✓ 🟢 Session (5h) ███░░░░░ 38% resets at Fri 07:00
🔴 Weekly (7d) ███████░ 87% resets at Fri 09:00
🔴 Weekly Sonnet ████████ 100% resets at Fri 09:00
─────────────
Plan: Claude Max · Tier 2
Extra usage: off
─────────────
Preference ▸ ← reset-time vs elapsed-time, opt-in 7-day history
Open Claude dashboard…
─────────────
Updated: 14:32:01
Refresh now
Quit
Click any view row to switch which window the menu-bar bar tracks. The ✓ marker shows the active view.
Preferences
Open the Preference submenu:
- Show "resets at Fri 07:00" / Show "resets in 4h10m" — radio toggle for time format
- Show 7-day history — opt-in checkbox; when on, two extra rows appear in the dropdown:
7d: ▁▂▃▄▅▆▇█ ↑— sparkline of utilization over the last 7 days, plus a trend arrow comparing the last 24h vs the prior 24h (±3pp threshold)7d: min 12% · avg 47% · max 89%— min / avg / max for the same window
- Launch at login — opt-in checkbox; installs/removes a LaunchAgent plist at
~/Library/LaunchAgents/com.tokenmaxxing.app.plist. Takes effect on next login.
The history is recorded continuously to ~/.tokenmaxxing/history.json (one snapshot per successful poll, capped at 2000 rolling entries) regardless of whether you display it — so when you turn it on, data is already there.
When the most recent poll has failed (network blip, transient error) but a previous successful poll's data is still cached, every row shows a (stale) suffix. When the OAuth endpoint is rate-limiting, you see [rate limited] instead.
Configuration (env vars)
CLAUDE_DASHBOARD_URL— URL for the "Open Claude dashboard…" item (defaulthttps://claude.ai/settings/usage)
Implementation notes
- Why not parse
~/.claude/projects/*.jsonl? Tried first, scrapped. Even withos.scandir+ per-file mtime cache, parsing was lossy (no auth signal, no plan-aware caps) and stale (only sees what Claude Code chose to log). The OAuth endpoint is authoritative and free. - Why two threads? AppKit calls (setting menu/title) must happen on the main thread; HTTP calls shouldn't block it. A daemon worker fetches usage every 5 min and stages the result; a 1s
rumps.Timeron the main thread applies whatever's staged so countdowns tick smoothly. - Coloring:
NSMutableAttributedStringwithNSForegroundColorAttributeNameapplied only to the leading█chars.NSColor.system{Green,Yellow,Red}Coloradapt to dark/light mode. The empty░segment is left untouched so it inherits the defaultlabelColor. - Backoff: consecutive 429s back off exponentially up to 30 minutes between polls before retrying.
License
Apache-2.0
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file tokenmaxxing-0.1.0.tar.gz.
File metadata
- Download URL: tokenmaxxing-0.1.0.tar.gz
- Upload date:
- Size: 18.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1a7766eaa229afd178970755ebb8a0eacde5012b53be2dfbb0f595180cd07ea9
|
|
| MD5 |
f6ebed8c7041a14e4e86656f61c39ffa
|
|
| BLAKE2b-256 |
0f154e4aa90d70e869b7cb73a10b54ec48bb31fb81f50312da7e4d4fd2fa80c5
|
File details
Details for the file tokenmaxxing-0.1.0-py3-none-any.whl.
File metadata
- Download URL: tokenmaxxing-0.1.0-py3-none-any.whl
- Upload date:
- Size: 20.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1fcdf84f43114a8226eefadd4482555fdb9791e0ea58cd8282be5d23ad6c1a95
|
|
| MD5 |
a8f5ad6a82242757ca1cde92df033592
|
|
| BLAKE2b-256 |
9069e33154cef8aaaeb39413b0539488b0ffbbf79e2c3e7f09132f280d327f7d
|