A self-hosted tool to track, visualize, and exploit your Claude Code subscription usage.
Anthropic's Claude Code subscription enforces two rolling quotas:
- A 5-hour rolling window that begins on first use after a reset.
- A weekly quota that caps total usage across all 5-hour windows.
The official UI shows a current point-in-time view. This project adds:
- History — burn-down charts for both the 5-hour and weekly windows.
- Consumption report — dollar-equivalent value of the tokens you ran through it over a chosen period, plus how much of the session and weekly quotas you consumed in that same period (both can exceed 100% over a multi-window period).
- Slack signal — when you are under-utilizing your allocation, an HTTP endpoint surfaces the unused capacity that would otherwise expire at the window boundary, so a job queue can opportunistically run cheap-but-not-worth-real-money work for free.
The trayapp is the server, the database (SQLite), and the dashboard, all in one Go binary
that lives in your system tray. It tails Claude Code's session JSONL files in
~/.claude/projects/, and also accepts HTTP POSTs from container-side Stop hooks and
from a browser userscript.
+---------------------------- Windows host -----------------------------+
| |
| [Browser] -- userscript (when claude.ai is open) --+ |
| \ |
| v |
| [Tray app: Go .exe] <----- HTTP ----- [Containers: Linux CLI] |
| - HTTP server |
| - SQLite DB |
| - passive ingest: ~/.claude JSONL tail + container Stop hooks |
| - tray UI (status, slack indicator) |
| - dashboard (served from same process at http://localhost:27812) |
| |
+-----------------------------------------------------------------------+
Containers reach the host via host.docker.internal:27812. See docs/architecture.md
for binding details and docs/data-sources.md for the ingest tiers.
The build is pure Go (no CGO, no C toolchain) — all you need is Go 1.26.2 or newer.
go install github.com/vector76/cc_usage_dashboard/cmd/trayapp@latestThe binary lands in %USERPROFILE%\go\bin\trayapp.exe. Run it directly:
& "$env:USERPROFILE\go\bin\trayapp.exe"Useful if you want to read or modify the code. No make required.
git clone https://github.com/vector76/cc_usage_dashboard.git
cd cc_usage_dashboard
# Debug build (larger, keeps symbols; useful while developing)
go build -ldflags="-H=windowsgui" -o trayapp.exe .\cmd\trayapp
# Release build (~30% smaller; strips symbol table and DWARF info)
go build -ldflags="-s -w -H=windowsgui" -trimpath -o trayapp.exe .\cmd\trayapp
.\trayapp.exe-H=windowsgui suppresses the console window so the app runs purely in the
tray. -s -w -trimpath shave the symbol table, DWARF debug info, and
filesystem paths out of the binary.
Once you have a trayapp.exe built, the included PowerShell script registers a per-user
Task Scheduler entry that launches it at logon and bootstraps a default prices.yaml in
%APPDATA%\usage_dashboard\:
powershell -ExecutionPolicy Bypass -File .\install.ps1If trayapp.exe is not next to install.ps1 (e.g. you used go install and it is in
%USERPROFILE%\go\bin\), pass its location:
powershell -ExecutionPolicy Bypass -File .\install.ps1 -ExePath "$env:USERPROFILE\go\bin\trayapp.exe"The dashboard is served from the same process at http://localhost:27812. Open it in a browser to confirm the trayapp is running and to see live usage.
If you run Claude Code inside dev containers that don't bind-mount ~/.claude, install
the CLI in the container so its Stop hook POSTs per-message usage to the host:
go install github.com/vector76/cc_usage_dashboard/cmd/clusage-cli@latest
# Wire it into ~/.claude/settings.json:
# "Stop": [{ "hooks": [{ "type": "command", "command": "clusage-cli log --from-hook || true" }] }]For ad-hoc tests:
clusage-cli log --input-tokens 1234 --output-tokens 567 --cost-usd 0.0123The Makefile is the convenience entry point on Linux:
make build-trayapp # headless server-mode binary (debug)
make build-cli # container CLI (debug)
make release # size-optimized Linux + cross-compiled Windows builds
make test # full Go test suiteThe trayapp's tray UI is Windows-only; on Linux it builds as a headless server. Cross-compiling the Windows .exe from Linux is now toolchain-free (no mingw needed) thanks to the pure-Go SQLite driver.
The userscript posts the dashboard's reported quota numbers to the trayapp so
Tier 1 (passive observation) has an authoritative anchor. It lives at
userscript/claude-usage-snapshot.user.js.
- Install Tampermonkey or Violentmonkey in your browser.
- Open
userscript/claude-usage-snapshot.user.jsand let the manager install it (drag the file in, or open the GitHub raw URL). - Grant
GM.xmlHttpRequestand@connect localhost/@connect 127.0.0.1when prompted. - Make sure the trayapp is running (default port
27812). - Open
https://claude.ai/in any tab — the script posts one snapshot per minute once the quota DOM nodes are detected.
See userscript/README.md for troubleshooting and docs/userscript.md for
the snapshot payload schema and the rationale (mixed content, CORS, Private
Network Access).
Design and architecture docs live in docs/ — start with docs/overview.md
and docs/architecture.md.