TokenTracking 发布 macOS 菜单栏应用,统一监控 Claude、Cursor、Gemini 等 AI 订阅用量
mduppes/TokenTracking
TokenTracking 是一个 macOS 菜单栏应用,把 Claude、Cursor(含 Grok Bot 周限额)、Gemini、Muse(Meta)和 Antigravity 的用量限额集中显示,并给出配速建议。
One place to see how close you are to the usage limits of your AI subscriptions, and how to pace yourself until they reset. It lives in your macOS menu bar.
Supported: Claude, Cursor (including Grok Bot's weekly limit), Gemini (app), Muse (Meta), and Antigravity (per quota pool, while the app is running). See docs/PROVIDERS.md.
It's local-first:
- Refresh: every 15 minutes a headless Chrome (no window, no Dock icon) uses its own logged-in profile to read each service's usage, then quits. Nothing runs in between.
- Storage: a small local service stores the history and works out pacing.
- Antigravity: read from the desktop app's own local server while it's running (no browser; see SECURITY).
- Display: a menu bar app shows the result.
No API keys, no accounts, no cloud, no browser extension.
Screenshots use demo data (npm run screenshots).
Features
- Every limit in one place. Session (5h), daily, weekly and monthly meters per service, with time until reset.
- Pacing. Each meter shows:
- the even pace marker (where you'd be if you spread usage evenly through the window)
- your current burn rate and projected % at reset
- when you'd run out at this rate
- a budget (%/day, or %/hour when less than a day is left)
- When it frees up. Every meter has a countdown pill to its reset, and a "Resets next" list shows what frees up soonest across all services.
- Status at a glance. Shown as a colored dot plus a label: On pace, Ahead of pace, Will run out before reset, Limit reached.
- History. A sparkline per meter, with hover readouts, from every snapshot stored locally in SQLite.
- Menu bar app:
- Title: one icon and % per service, e.g.
✳74 ➚70 ⇧51 ✕86 Ⓜ97. Each number is that service's worst meter,––means at the limit, and hovering shows details. - Click it for a compact dashboard with Refresh now / Open dashboard / Quit.
- Lifecycle: it starts and stops everything it needs.
- Title: one icon and % per service, e.g.
- Also: the full dashboard at http://127.0.0.1:7878 (card and table views, light and dark) and
npm run statusin the terminal. - Stale and login notices with a Log in button. Services whose data is stale (missed about 2 refreshes) or whose login expired are listed at the top with the reason. Log in opens the TokenTracking browser on that service; quit it (⌘Q) when you're done and that service refreshes automatically.
Quick start
Requirements: macOS 13+, Node.js ≥ 22.13 (for the built-in node:sqlite), Google Chrome, and the Xcode command line tools (for swiftc). There are no npm dependencies, so there's nothing to install.
- Get the code:
git clone https://github.com/mduppes/TokenTracking.git && cd TokenTracking
- Log in once in TokenTracking's own Chrome profile. A normal Chrome window opens with tabs for Claude, Cursor, Gemini and Muse. Log in to each, then quit that window with Cmd+Q.
npm run browser-login
- Check it works. It prints
okorloginper service.npm run refresh
- Create a local signing certificate (one time). This gives the app a stable identity, so macOS remembers its menu bar permission across rebuilds. macOS asks for your password once.
sh scripts/create-signing-cert.sh
- Build the menu bar app:
npm run build:menubar
- Open it:
open build/TokenTracking.app
The menu bar app
-
What it shows: one icon per service, each with a digit for that service's worst meter:
- Icons (in order): ✳ Claude, ➚ Cursor, ⇧ Antigravity, ✕ Grok Bot, Ⓜ Muse. Gemini is only on the dashboard (its limits rarely matter); change
MenuBarGlyphs.servicesto pick your own. - The number is the % used (0–99),
––= at the limit,??= no reading yet. - Hover for exact numbers and the most at-risk meter. Click for the compact dashboard.
- Icons (in order): ✳ Claude, ➚ Cursor, ⇧ Antigravity, ✕ Grok Bot, Ⓜ Muse. Gemini is only on the dashboard (its limits rarely matter); change
-
It's the only thing you run. Opening it starts the local service in the background (and restarts it if it dies). Quitting it stops the service, and the service also exits by itself if the app is force-killed. Service logs go to
~/.tokentracking/service.log. -
Start at login (optional): add
build/TokenTracking.appunder System Settings → General → Login Items. That's a one-time step, because rebuilding updates the app in place. -
Moving things: the paths to this project and to
nodeare baked in at build time, so re-runnpm run build:menubarif you move the project or change Node versions. -
Can't see the icon? macOS hides menu bar icons in two cases:
- The app isn't allowed. Turn TokenTracking on under System Settings → Menu Bar → Allow in the Menu Bar. If it's on but the icon still doesn't show, the entry is probably tied to an older build: without the signing certificate (step 3), every rebuild gets a new identity and the setting goes stale.
- The menu bar is full, common on a MacBook with a notch. Turn off other items or Cmd-drag them out.
While the icon is hidden, TokenTracking shows a Dock icon and the same panel in a small window, with a button to that settings page. When the icon appears, it switches back by itself.
Try the UI with demo data
npm run demo
TOKENTRACKING_HOME=.tokentracking-demo TOKENTRACKING_HEADLESS=0 npm start
Commands
| Command | What it does |
|---|---|
npm run build:menubar |
Build the macOS menu bar app into build/TokenTracking.app |
npm run browser-login |
Open the headless profile in a normal window to log in (-- gemini for one service) |
npm run refresh |
Run one headless refresh now and print results (-- claude muse for some) |
npm start |
Run the local service and dashboard on 127.0.0.1:7878 without the app |
npm run status |
Print current usage and pacing (-- --json for JSON) |
npm run demo |
Write fake data to .tokentracking-demo/ |
npm run build:icon |
Re-render assets/icon.svg into menubar/AppIcon.icns and docs/images/icon.png |
npm run screenshots |
Regenerate docs/images/ from demo data (headless Chrome + swift) |
npm test |
Run the test suite (node:test, including real headless Chrome) |
Environment variables:
TOKENTRACKING_HOME: data directory (default~/.tokentracking)TOKENTRACKING_PORT: port (default7878)TOKENTRACKING_HEADLESS=0: turn headless refresh offTOKENTRACKING_INTERVAL_MIN: refresh interval (default 15, minimum 5)TOKENTRACKING_HEADLESS_SKIP: comma-separated services to skip (e.g.muse)TOKENTRACKING_CHROME: Chrome binary path (default/Applications/Google Chrome.app/…)TOKENTRACKING_URL: service URL for the menu bar app (defaulthttp://127.0.0.1:7878)
Documentation
| Doc | Contents |
|---|---|
| docs/ARCHITECTURE.md | Components, data flow, data model, pacing math |
| docs/PROVIDERS.md | Per-service: where usage lives, how it's read, what's verified |
| docs/SECURITY.md | Threat model, what data is touched, privacy guarantees |
| docs/DECISIONS.md | Architecture decision records (why things are the way they are) |
| docs/ROADMAP.md | What's next: cost-per-token, Antigravity, … |
| AGENTS.md | Orientation for AI coding agents / new contributors |
| CHANGELOG.md | Release history |
Caveats
None of the usage pages or endpoints this reads are official APIs, so they can change without notice. When a meter stops updating, run npm run refresh -- <service> and follow the verification loop in docs/PROVIDERS.md.
This is meant for personal use, reading your own usage with your own logged-in session. Keep the refresh interval reasonable (15 minutes by default).
License
Disclaimer
TokenTracking is an independent personal project. It is not affiliated with, endorsed by, or supported by Anthropic, Anysphere (Cursor), xAI, Google, or Meta. Product names are trademarks of their respective owners. It relies on undocumented web pages and endpoints that may change or break at any time, and using it may be subject to each service's terms. Use at your own risk.
来源:GitHub · github.com