A local monitor for Claude subscription rate limits: the 5-hour Session Window, the Weekly Window, and the Fable (Opus-class) Window. See CONTEXT.md for the vocabulary used throughout this repo.
It works by periodically calling the same undocumented endpoint Claude Desktop's own usage indicator uses, caching the result locally, and showing that Cache through three Frontends. See docs/adr/0001-undocumented-oauth-usage-endpoint.md for why.
claude_usage.pyis a single Python 3.12, stdlib-only script.bin/claude-usageis a thin executable wrapper so it can live onPATH.- Only the fetch path (
--fetch/--refresh) calls the network. It reads the OAuth access token read-only from the macOS Keychain entryClaude Code-credentials(the same one Claude Code itself uses) and callsGET https://api.anthropic.com/api/oauth/usage. - The response, plus the time it was fetched, is written to
~/.cache/claude-usage/usage.json. A launchd agent refreshes this Cache every 5 minutes. All three Frontends below read only this file — they never touch the network themselves. - Parsing is generic and defensive: every Usage Window found in the response is rendered, whether or not it's one of the three known windows. If Anthropic adds a new window, it just shows up.
- Terminal Command — run
claude-usagefor a full bar chart of every Usage Window, with percentage, color, and Reset Time.claude-usage --refreshforces a fetch first. - Web Page —
dashboard/index.html, a static, self-contained, self-reloading HTML page (regenerated by--fetchor--html). Pin it in a browser tab. It respects light/dark mode and recomputes its own "updated X ago" / staleness label client-side every second. - Statusline — wired into Claude Code's
statusLinesetting, showing a compact one-line summary of the three known windows, plus the session's model:effort and context-window token usage (parsed from the session JSON Claude Code pipes in on stdin), e.g.⚡ 5h 42% · wk 18% · fable 63% · Fable 5:medium · 65k tok (32% ctx). Always cache-only, no network, fast.
Color thresholds (Threshold Bands) are the same everywhere: green below 70%, yellow 70-89%, red 90%+. In the Statusline, any window at 80%+ also shows its Reset Time.
claude-usage # print all Usage Windows from the Cache (no fetch)
claude-usage --refresh # force a fetch, then print
claude-usage --fetch # fetch if Cache is older than 5 min, regenerate
# the dashboard, print nothing (launchd entrypoint)
claude-usage --statusline # one-line Cache-only summary for Claude Code
claude-usage --html # regenerate dashboard/index.html only
- Cache older than ~12 minutes is labeled
staleeverywhere. - On a 401 (expired auth), the last good Cache is kept and shown, with a hint to open Claude Code to re-auth. The token is never refreshed or written by this tool.
- On any other fetch failure (429, network error, etc.), the last good Cache is kept and shown, with a note that the last fetch failed.
Requires macOS with Claude Code installed and logged in (the tool reuses Claude Code's OAuth token, read-only, from the Keychain).
git clone <this repo> && cd claude-usage
./install.shThe installer:
- Symlinks
bin/claude-usageinto~/.local/bin(override withCLAUDE_USAGE_BIN_DIR). - Generates and loads a launchd agent,
~/Library/LaunchAgents/com.claude-usage.plist, which runsclaude_usage.py --fetchevery 300 seconds (and once at load), logging to~/.cache/claude-usage/launchd.log. - Prints the
statusLinesnippet to add to~/.claude/settings.jsonif you want the Statusline (this part is manual).
Approve the macOS Keychain prompt on the first fetch.
launchctl bootout gui/$(id -u) ~/Library/LaunchAgents/com.claude-usage.plist
rm ~/Library/LaunchAgents/com.claude-usage.plist
rm ~/.local/bin/claude-usage
rm -rf ~/.cache/claude-usageThen remove the statusLine key from ~/.claude/settings.json if you no
longer want the Statusline.