Fork notice. This is a personal fork of nateherkai/token-dashboard with several community pull requests integrated because upstream is currently inactive. See FORK_NOTES.md for the full list of integrated changes and what differs from upstream.
A local dashboard that reads the JSONL transcripts Claude Code writes to ~/.claude/projects/ and turns them into per-prompt cost analytics, tool/file heatmaps, subagent attribution, cache analytics, project comparisons, and a rule-based tips engine.
Everything runs locally. No data leaves your machine — no telemetry, no API calls for your data, no login.
- Seeing which of your prompts are expensive (surprise: they usually involve large tool results).
- Comparing token usage across projects you've worked on.
- Spotting wasteful patterns — the same file read twenty times in a session, a tool call returning 80k tokens.
- Understanding what a "cache hit" actually saves you.
- If you're on Pro or Max, confirming you're getting your money's worth in API-equivalent dollars.
- Python 3.8 or newer — already installed on macOS and most Linux. On Windows:
winget install Python.Python.3.12or download from python.org. - Claude Code — installed and with at least one session run. The dashboard reads those sessions. If you just installed Claude Code and haven't used it yet, run at least one prompt first.
- A web browser. Any modern one.
No pip install. No Node.js. No build step.
git clone https://github.com/muckybuzzwoo/token-dashboard.git
cd token-dashboard
python3 cli.py dashboardOn Windows, if
python3isn't on your PATH, substitutepy -3forpython3in every command below.
The command:
- Scans
~/.claude/projects/(first run is fast in this fork — around 5–10 seconds for ~600 files / 60k+ messages thanks to the batched-insert scanner from PR #18). - Starts a local server at http://127.0.0.1:8080.
- Opens your default browser to that URL.
Leave it running; it re-scans every 30 seconds and pushes updates live. Stop with Ctrl+C.
Claude Code writes one JSONL file per session here:
| OS | Path |
|---|---|
| macOS / Linux | ~/.claude/projects/<project-slug>/<session-id>.jsonl |
| Windows | C:\Users\<you>\.claude\projects\<project-slug>\<session-id>.jsonl |
The dashboard never modifies those files — it only reads them and keeps a local SQLite cache at ~/.claude/token-dashboard.db.
To point at a different location:
python3 cli.py dashboard --projects-dir /path/to/projects --db /path/to/cache.dbYou can also change the .claude folder from the Settings tab. Changing the folder controls future scans; it does not automatically partition old cached data in the current SQLite DB. When switching accounts or profiles, either enable Clear cached transcript data in Settings before saving, or launch with a separate --db path if you want to keep each folder's dashboard history isolated.
| Var | Default | Purpose |
|---|---|---|
PORT |
8080 |
Port the local web server listens on |
HOST |
127.0.0.1 |
Bind address. Keep the default. Setting 0.0.0.0 exposes your entire prompt history to anyone on your local network — don't do this on any network you don't fully control (no coffee-shop Wi-Fi, no coworking spaces). |
CLAUDE_PROJECTS_DIR |
~/.claude/projects |
Where to scan for session JSONL files |
TOKEN_DASHBOARD_DB |
~/.claude/token-dashboard.db |
SQLite cache location |
Pricing lives in pricing.json. Edit it directly if model prices change or to add a new plan.
python3 cli.py scan # populate / refresh the local DB, then exit
python3 cli.py today # today's totals (terminal)
python3 cli.py stats # all-time totals (terminal)
python3 cli.py tips # active suggestions (terminal)
python3 cli.py dashboard # scan + serve the UI at http://localhost:8080
# dashboard flags
python3 cli.py dashboard --no-open # don't auto-open the browser
python3 cli.py dashboard --no-scan # skip the initial scan (use cached DB only)Change the port: PORT=9000 python3 cli.py dashboard.
The dashboard is a single page with a hash-router tab bar across the top. Each tab is backed by its own JSON API under /api/:
- Overview — all-time input/output/cache tokens, sessions, turns, estimated cost on your chosen plan, daily work and cache-read charts, tokens-by-project, token share by model, top tools by call count, and recent sessions. This is the landing tab.
- Prompts — your most expensive user prompts ranked by tokens. Click any row to see the assistant response, tool calls made, and the size of each tool result. Has a "Copy MD" / "Download CSV" export for the current sort/filter.
- Sessions — turn-by-turn view of any single session, with per-turn tokens and tool calls.
- Projects — per-project comparison: tokens, session counts, and which files were touched most.
- Workspaces — bipartite ECharts Sankey of agent cwd (left) → file target (right), counting Read/Edit/Write/NotebookEdit only. Same-name pairs are within-workspace work; cross-pairs are CLAUDE.md consolidation candidates. Includes a ranked cross-workspace leaks table with the top files driving each pair.
- Subagents & Orchestration — per-model spend split into main thread vs Task subagent vs auto-compaction (
agent_id LIKE 'acompact-*'), a per-entrypoint chart (cli/claude-vscode/ SDK runs), an external-orchestration table forsdk-py/sdk-ts/sdk-clisessions, and a dispatcher → child agent dispatch tree reconstructed via session_id + timing-join. - Skills & Commands — split between You ran (distinct sessions where you typed a
/slash-command, tracked via Claude Code's nativeattributionSkillfield) and Claude invoked (realSkilltool calls Claude emitted itself, typically fromTask/Agent-dispatched subagents). Also shows per-skill output-token budget (parsed fromSKILL.md) vs. measured p50/p95, total cost, and total including subagent attribution. See limitations. - RTK — optional rtk savings view if the CLI is installed at
~/.local/bin/rtk. Gracefully degrades on Windows or when RTK is absent (shows install instructions). - Tips — rule-based suggestions for reducing token usage. 19 detectors covering cache-hit rate, repeated file reads, repeated Bash commands, Opus turns that would fit on Sonnet, oversized tool results, subagent outliers, skill-listing budget pressure (scope-aware: reports effective per-session footprint and splits global vs project-scoped skills, named after the most-active recent project), oversized
CLAUDE.md, cross-workspace leaks, dead skills (90d unused, excluding project-scoped skills in projects you haven't visited), subagent sprawl (sidechain dominates main thread), Bash bloat (commands without output limiters), context-window pressure, repeated identical Bash errors, heavy web-fetch sessions, Opus-only workspaces, MCP-server sprawl, stackedCLAUDE.mdfiles, and overlong skill descriptions. Each tip is dismissable for 14 days; drill-down links jump to the responsible session, project, or skill. - Settings — pick your plan (API / Pro / Max / Max-20x / Team). This does not change the dollar figures shown elsewhere — they're always the API pay-per-token value of your usage — it just shows your flat monthly fee next to them for comparison, so you can see whether your usage is worth more than you pay. Also lets you switch the
.claudefolder at runtime.
Most data-heavy tabs carry a built-in, collapsible explanation panel (look for the "— click to expand" hint): the Overview's "What do these numbers mean?" glossary, plus column/chart guides on Prompts, Skills & Commands, Subagents and Workspaces. Each defines its metrics in plain English — what they measure, an example, and what you can read out of them — and is collapsed by default to keep the view uncluttered.
"No data" or empty charts. Run python3 cli.py scan once to populate the DB, then reload.
Port 8080 already in use. PORT=9000 python3 cli.py dashboard.
Numbers look wrong / stuck. The DB lives at ~/.claude/token-dashboard.db. Delete it and re-run python3 cli.py scan to rebuild from scratch. If you changed the .claude folder in Settings, use Clear cached transcript data when saving the new folder to avoid combining data from multiple transcript roots.
Running the dashboard twice at the same time. Don't — both processes will fight over the SQLite DB. Stop all instances before starting a new one.
Claude Code writes each assistant response 2–3 times to disk while it streams (the same API message gets snapshotted as output grows). The dashboard dedupes these by message.id so the final tally matches what the API actually billed. If you compare against another tool that sums every JSONL row, expect this dashboard's numbers to be lower — and closer to reality.
Nothing leaves your machine. No telemetry. No remote calls for your data. The browser fetches its JSON from 127.0.0.1, and all JS/CSS/fonts are served from that same local server — ECharts is vendored into web/, and the UI falls back to system fonts rather than pulling from a font CDN. If you want to verify: grep -r "https://" token_dashboard/ web/ — you'll find nothing.
Python 3 (stdlib only) for the CLI, scanner, and HTTP server. SQLite for the local cache. Vanilla JS + ECharts for the UI, no build step. Dark theme, hash-based router, server-sent events for live refresh.
Data flow: cli.py → token_dashboard/scanner.py → SQLite DB; token_dashboard/server.py exposes /api/* JSON routes and serves web/.
CLAUDE.md— conventions and architecture overview (also picked up automatically by Claude Code)CONTRIBUTING.md— how to develop and testdocs/KNOWN_LIMITATIONS.md— rough edgesdocs/inspiration.md— prior art and how this project diverges
See CONTRIBUTING.md. Short version: fork, python3 -m unittest discover tests before opening a PR, keep it stdlib-only.
MIT.

