English · 中文
A macOS menu-bar app that shows your Claude CLI daily token usage, estimated cost, and per-model / MCP / Skill call breakdown.
Stack: Tauri 2 + React + TypeScript (frontend) / Rust (data layer).
- Shows today's token count next to the menu-bar icon (e.g.
⬡ 14.00M) - Click to open the panel: Day / Week / Month toggle
- Metrics: total tokens (input/output), estimated cost, requests / sessions
- Three breakdowns: by model / by MCP call / by Skill call
- Cost donut (hover for a single model), year-long activity heatmap
- Counts only the MCP servers / Skills you installed yourself — all Claude built-in tools and Anthropic's bundled MCP servers are filtered out
| Purpose | Path |
|---|---|
| Session logs (tokens / model / tool calls) | ~/.claude/projects/**/*.jsonl |
| User MCP whitelist | ~/.claude.json → mcpServers + projects[*].mcpServers |
| User Skill whitelist | ~/.claude/skills/ directory |
| Model prices | Primary: models.dev (bare model names, matching Claude CLI logs) → Fallback: LiteLLM → built-in snapshot. Cached in ~/Library/Caches/tokenscope/, refreshed every 24h, with offline fallback |
- Deduplicated by
message.id(streaming/retries repeat the same usage); when one message spans multiple lines, its tool calls are merged and the token usage is counted once - Token split:
input(uncached) /cache(creation+read) /output; the UI folds cache into "In" by default and shows a separate "cached %" - Price matching: exact id → normalized id (strip vendor prefix +
.↔p, e.g.glm-5.1⇄glm-5p1); models.dev's official bare-name price wins - Cost is priced per the four token types; each model carries a
pricedflag — models not found in either source still count tokens but are labelled "no price" in the UI - Logs contain only the bare model name (no vendor) → third-party models default to the official vendor price (an estimate)
- Tool classification:
mcp__<server>__*where the server is in your config → MCP; a Skill call (theSkilltool'sinput.skill, or a/skillslash command) whose name is in your skills directory → Skill; everything else is ignored
Cost is an estimate based on public prices; subscription users should read it as "equivalent spend value".
Every assistant message's usage reports four mutually exclusive token counts (they never double-count the same token):
| Stage | usage field |
What it is | Price (relative to input) |
|---|---|---|---|
| Input (uncached) | input_tokens |
New prompt tokens sent this turn | 1× |
| Cache write | cache_creation_input_tokens |
Context written into the prompt cache | ~1.25× |
| Cache read (hit) | cache_read_input_tokens |
Context replayed from the cache | ~0.1× (much cheaper) |
| Output | output_tokens |
Tokens the model generated | ~5× |
Tokens (per period, summed over messages):
total = input + cache_creation + cache_read + output
# the UI shows: In = input + cache_creation + cache_read, Out = output, cached % = cache_read / total
Cost (each stage priced at its own per-token rate from the price table):
cost = input × price.input
+ cache_creation × price.cache_creation
+ cache_read × price.cache_read # cache hits billed at the discounted read rate
+ output × price.output
So a cache hit is not billed as normal input — it uses the dedicated (cheaper) cache_read rate, which is why heavily-cached usage shows a huge token count but a modest cost. The UI folds cache into "In" for display only; billing always uses the four separate rates above.
brew install --cask hdusy/tokenscope/tokenscopeThe cask's postflight strips the quarantine attribute (xattr -cr) automatically, so it opens on first launch without the "Apple cannot verify" prompt.
After you open it once it registers as a login item, then launches in the menu bar automatically on every boot.
Upgrade:
rm -rf "$(brew --repository)/Library/Taps/hdusy/homebrew-tokenscope" && brew tap HduSy/tokenscope && brew install --cask tokenscope- Download the latest
Tokenscope_*_universal.dmgfrom Releases (works on both Apple Silicon and Intel) - Drag it into Applications
- Because the build is unsigned / unnotarized, Gatekeeper blocks the first launch — pick one:
- Right-click the app → Open → confirm Open again, or
- Run once in the terminal:
xattr -cr /Applications/Tokenscope.app && open /Applications/Tokenscope.app
Unsigned is a current known limitation. A true "double-click to open" experience requires Apple Developer ID signing + notarization — see
PRD.md§6.4.
- An icon plus today's token count appears in the menu bar (e.g.
⬡ 12.40M) - Left-click the icon to toggle the panel; right-click for the menu (Open / Refresh / Quit)
- Launch-at-login is set up automatically — no manual configuration needed
pnpm install
pnpm tauri dev # launch the desktop app (requires the Rust toolchain)Frontend-only preview (using the real-data snapshot public/dev-dashboard.json):
pnpm dev # http://localhost:1420
# refresh the snapshot:
cd src-tauri && cargo run --example dump > ../public/dev-dashboard.jsonpnpm tauri build # outputs .app / .dmg to src-tauri/target/release/bundle/For distribution see PRD.md §6.3 (Homebrew Cask recommended; direct .dmg downloads benefit from code signing + notarization).
src/ React frontend
data.ts types + Tauri bridge + theme + formatting
charts.tsx chart primitives (bars / donut / sparkline / heatmap / segmented control)
App.tsx main panel
src-tauri/src/
store.rs incremental JSONL ingest (dedup by message.id + multi-line merge)
parser.rs aggregation (Day/Week/Month + heatmap)
pricing.rs models.dev / LiteLLM price loading and costing
config.rs user MCP / Skill whitelist
model.rs data structures returned to the frontend
lib.rs Tauri commands + menu-bar tray
Notable bugs found during development — symptom, root cause, and fix — are collected in docs/BUGFIXES.md.
