Token Dashboard is a local token usage and cost dashboard for AI coding agents. Claude Code, Codex and Gemini. Per-prompt cost, per-session burn rate, cache analytics, subagent attribution, model breakdown and a waste rules engine.
It reads the transcripts already sitting on your machine and turns them into cost, waste and habit analysis. Claude Code and Codex are billed from their own usage records rather than an estimate.
One command. No account, no API key, no build step, and nothing uploaded.
Built and maintained by Navid Moazzez.
$ npx -y @thenavidm/token-dashboard
Token Dashboard http://localhost:8080
Reading your agent transcripts. Nothing leaves this machine.
| Agent | Where it looks | Metered |
|---|---|---|
| Claude Code | ~/.claude/projects/** including subagent transcripts |
Yes, from its own usage records |
| Codex | ~/.codex/sessions/** |
Yes, from its own usage records |
| Gemini, Antigravity | ~/.gemini/antigravity/brain/** |
No. Activity only |
| Gemini CLI | ~/.gemini/tmp/*/chats/** |
No. Activity only |
| Gemini CLI telemetry | ~/.gemini/telemetry.log |
Yes, once you switch telemetry on |
Gemini reports its token usage, but only through OpenTelemetry, and that is off by default. Until you turn it on there is nothing on disk to bill from, so Gemini shows as activity with a cost of zero rather than an estimate.
To meter it, add this to ~/.gemini/settings.json:
{
"telemetry": {
"enabled": true,
"target": "local",
"outfile": "~/.gemini/telemetry.log"
}
}The dashboard reads that file on its next scan. Point it somewhere else with
GEMINI_TELEMETRY_FILE.
| What it does | |
|---|---|
| Cost per prompt | Every turn between one typed prompt and the next, billed to that prompt |
| Cost per session | Turn by turn, with the curve that shows context growing |
| Cost per project | Grouped by transcript directory, not by a working directory that drifts |
| Cost per model | Every model you have used, with its vendor mark, nothing folded away |
| Cost per agent | Claude Code and Codex side by side, from their own metering |
| Subagent spend | Read from each subagent's own transcript, by agent type |
| Burn calendar | A day cell per day, per agent, on one shared scale |
| Cache economics | 5-minute and 1-hour cache writes billed apart, because they cost differently |
| Waste rules | Repeated reads, oversized tool results, low cache hit rate, long sessions |
| Custom ranges | Presets, or two months of calendar with keyboard shortcuts |
| Export | The current view as JSON, every number the page is showing |
| Light and dark | Follows the system, or pin either |
| Section | ||
|---|---|---|
| 1 | What it shows you | The six tabs, and what each answers |
| 2 | Install | Three ways, pick one |
| 3 | Using it | Every control, and what it narrows |
| 4 | Pricing | How cost is worked out, and how to change it |
| 5 | How it reads your data | The scan, the cache, the dedupe |
| 6 | Your data | What leaves the machine, which is nothing |
| 7 | Risks | Stated plainly, including the ones that remain |
| 8 | Notes and gotchas | What the numbers do and do not cover |
| 9 | Troubleshooting | Symptom to cause |
| 10 | Environment variables | Every path you can move |
| 11 | FAQ | Including why your bill looks enormous |
Overview. What you spent, what you spent it on, and when.
Cost by day, split three ways: by what was billed, by model, or by raw token volume. Cache reads are around 98% of token count and roughly a third of the money, which is why the default view is dollars.
A burn calendar underneath: one day-cell grid per agent on a single shared scale, so you can see which agent burned what, on which day, across the range.
Then a full model table. Every model you have used, with its vendor mark, ranked by spend, with nothing folded into an "other" bucket.
Prompts. Every prompt you typed, ranked by what the turns it set off cost. This is the tab that changes behaviour: one careless sentence at the top of a long session can be the most expensive thing you did that week. Click any row to read the prompt back.
Sessions. Turn by turn, with a cost curve. A rising floor across a session is context growing, not the task getting harder, and seeing the shape of it is what makes the case for starting fresh.
Projects. Per directory: sessions, turns, tokens, spend. Plus which Claude Code versions produced them, which matters when a number moves and you want to know what changed.
Tools and files. Which tools you call, how large their results are, and which files get pulled into context most often. Skills you actually reach for. And subagent spend by agent type, read from each subagent's own transcript, so this is what delegating cost rather than how often you did it.
Tips. Rule-based findings, each one naming the file, session or command it found. Repeated reads of the same file. Tool results large enough to move the context window on their own. A low cache hit rate. Sessions long past the point where context dominates the bill.
You need Node.js 22.5 or newer. Check with node -v.
Claude Code does not need to be running, and this never talks to it.
The fastest path. Downloads, runs, and leaves nothing behind.
npx -y @thenavidm/token-dashboardYour browser opens at http://localhost:8080.
The first run parses every transcript on disk. On a large history that takes under a minute. Every run after it reads only the files that changed, which takes about a second.
To pick a different port:
npx -y @thenavidm/token-dashboard --port=9000To stop it opening a browser, add --no-open.
If you want a short command you can run any time:
npm install -g @thenavidm/token-dashboard
token-dashboardUpdate it later with the same install command. Remove it with npm uninstall -g @thenavidm/token-dashboard.
The container needs your transcripts mounted read-only, and a place to keep its cache so it does not re-scan on every start.
docker build -t token-dashboard .
docker run --rm -p 8080:8080 \
-v "$HOME/.claude/projects:/data/projects:ro" \
-v "$HOME/.codex/sessions:/data/codex:ro" \
-v token-dashboard-cache:/cache \
-e CLAUDE_PROJECTS_DIR=/data/projects \
-e CODEX_SESSIONS_DIR=/data/codex \
-e TOKEN_DASHBOARD_DB=/cache/token-dashboard.db \
token-dashboardThen open http://localhost:8080 yourself.
The :ro is deliberate. The container cannot write to your transcripts.
npx ships with Node. If npx is missing, Node is not installed or not on your PATH. Install it from nodejs.org and open a new terminal window, since PATH changes do not reach terminals that are already open.
On macOS, if you installed Node with Homebrew and the shell still cannot find it, run brew link node.
| Control | What it does |
|---|---|
| Range | Today, 7, 30 or 90 days, month to date, year to date, all time. Applies to everything on the page including the tips |
| Calendar | Two months side by side with a preset rail and keyboard shortcuts. Pick two days for a custom range |
| Agent | All agents, or one. Only appears once a second agent has data, so a single-agent install never sees a one-option dropdown |
| Model | Narrows everything measured off a turn: cost, tokens, sessions, projects, charts, tips |
| Plan | Pay as you go, Pro, Max 5x, Max 20x. Changes one comparison line and never a token count |
| Refresh | The page re-reads changed transcripts every 20 seconds anyway. The arrow forces it now |
| Export | Saves the current view as JSON |
| Theme | Light, dark, or follow the system. From the header or the footer |
The model filter deliberately does not narrow the tool and prompt tables. Those carry no model of their own, and filtering them through a join would drop rows rather than answer the question asked.
Cost is worked out from pricing.json at the root of the package, in US dollars per million tokens. It is a plain file, and the dashboard reads it at startup.
Five things are billed at five different rates, which is why they are listed separately:
| What it is | |
|---|---|
input |
Fresh tokens, never seen before |
cacheWrite5m |
Written to the 5-minute cache, billed at 1.25x input |
cacheWrite1h |
Written to the 1-hour cache, billed at 2x input |
cacheRead |
Served from cache, billed at a tenth of input |
output |
Generated text, the dearest of the five |
OpenAI has no separate cache-write charge, so the gpt family sets both write rates to its input rate.
If your prices differ, edit the file. Nothing else needs to change.
Every figure is at list API prices. On a subscription you are not paying these numbers, which is exactly the point of the comparison on the first card.
Claude Code writes a transcript for every session:
~/.claude/projects/<project>/<session-id>.jsonl
~/.claude/projects/<project>/<session-id>/subagents/agent-<id>.jsonl
Both are read. The nested ones are subagents, and they carry real token usage, so a dashboard that skips them undercounts every session that delegated work.
Codex writes rollouts here:
~/.codex/sessions/<year>/<month>/<day>/rollout-<timestamp>-<id>.jsonl
Point either scanner elsewhere with CLAUDE_PROJECTS_DIR and CODEX_SESSIONS_DIR.
Four things make the totals match what was actually billed:
Deduplication. Claude Code writes each assistant message to disk two or three times while it streams, each write carrying a larger output count than the last. Summing every line roughly doubles your output figure. Only the largest write per message id is counted.
The cache write split. The 5-minute and 1-hour caches are billed at different rates. Older transcripts record only a total, and that total is billed at the 5-minute rate rather than dropped.
Codex deltas. Codex reports a running total plus a per-turn figure. The per-turn figure can disagree with the running total, so per-turn numbers are taken as the difference between consecutive running totals. They then sum to the session total exactly, by construction. Its cached input is a subset of input rather than an addition to it, so fresh input is the difference between the two.
Prompt attribution. A prompt is a turn you actually typed. Hook output, tool results and task notifications all arrive in the same stream and are not prompts. Turns are billed to the last real prompt before them, and subagent turns are billed to whichever prompt was open in the parent session when they ran.
Results are cached in ~/.claude/token-dashboard.db, keyed on each file's size and modification time, so only changed transcripts are ever re-read. Delete that file any time; it costs one re-scan.
Your transcripts are opened read-only and never modified.
Nothing leaves your machine.
The server binds to 127.0.0.1, which is not reachable from your network. There is no telemetry, no analytics, no update check, and no outbound request of any kind carrying your data.
Prompt text is stored in the local cache file so the Prompts tab can show it back to you. That file sits next to the transcripts it came from, under your own home directory.
Two outbound requests exist and neither carries your data: Google Fonts for Inter, and cdn.navid.media for the model vendor marks. Delete the two <link> tags in src/app/layout.tsx and the URLs in src/lib/format.ts if you want none at all.
| Risk | Where it stands |
|---|---|
| Your prompts leaving the machine | They cannot. The server binds to 127.0.0.1 and there is no outbound request carrying your data |
| Prompt text sitting in a cache file | It does, so the Prompts tab can show it back. Delete ~/.claude/token-dashboard.db to remove it |
| Anyone else on the machine reading it | They can, if they have your user account. It is a file under your home directory with your own permissions |
| Exposing it on a network | It binds to loopback. If you deliberately reverse-proxy it, it has no authentication and that is your decision |
| Wrong numbers | Prices come from pricing.json and can go stale. Check it against your own contract |
Costs are list API prices. Not what a subscription charges you. The first card compares the two.
Gemini needs telemetry on to be metered. It counts tokens but publishes them only over OpenTelemetry, which ships disabled. Section 1 has the three lines that turn it on.
Cowork and other server-side sessions are invisible. They run on Anthropic's side and write no local transcript. Nothing on this machine can see them.
The agent filter hides itself with one agent. It only appears when two agents have data in the range.
The model filter is a spend filter. It narrows anything measured off a turn. Tool and prompt tables carry no model, so they are left whole rather than silently emptied.
Projects group by transcript directory. Not by the working directory recorded on each turn, which a subagent or a resumed session can change. Grouping on that split one real project into hundreds.
"Could not read your transcripts." The dashboard looks in ~/.claude/projects. If yours lives elsewhere, point it there:
CLAUDE_PROJECTS_DIR=/path/to/projects npx -y @thenavidm/token-dashboardEverything is zero. You have no transcripts yet, or the range is too narrow. Switch to All time first.
The numbers look far too high. They are list API prices, not what a subscription charges you.
A number moved and I do not know why. Check the Claude Code versions table on the Projects tab. Usage accounting has changed between versions before.
It is slow to start. Only the first run is. If it is slow every time, the cache file cannot be written; set TOKEN_DASHBOARD_DB to a path you own.
Port already in use. Something else is on 8080. Use --port=9000.
I rebuilt from a checkout and the page went blank. Restart the server. A running build serves HTML naming its own asset hashes, and rebuilding underneath it leaves those hashes pointing at files that no longer exist.
| Variable | What it changes |
|---|---|
CLAUDE_PROJECTS_DIR |
Where Claude Code transcripts are read from |
CODEX_SESSIONS_DIR |
Where Codex rollouts are read from |
GEMINI_BRAIN_DIR |
Where Antigravity transcripts are read from |
GEMINI_TMP_DIR |
Where Gemini CLI sessions are read from |
GEMINI_TELEMETRY_FILE |
Where the Gemini CLI's OpenTelemetry output is read from |
TOKEN_DASHBOARD_DB |
Where the parsed cache is written |
PORT |
The port to serve on. --port= does the same |
See CHANGELOG.md, and the releases for tagged notes.
What is Token Dashboard?
Token Dashboard is a free, open-source token usage and cost dashboard for AI coding agents. It reads the session transcripts Claude Code, Codex and Gemini already write to your disk, and turns them into per-prompt cost, per-session burn, cache analytics and a list of where you are wasting money.
It runs entirely on your own machine. One command, no account, no API key.
What is a token, and why does it cost money?
A token is roughly three quarters of a word. Models bill per million tokens, at four different rates: fresh input, tokens written to cache, tokens read back from cache, and generated output.
Output is the dearest by a wide margin. Cache reads are the cheapest, at a tenth of fresh input. The same million tokens can therefore cost wildly different amounts depending on which of the four they were, which is the whole reason this tool splits them apart.
Is my data sent anywhere? Who can see it?
Nowhere, and nobody. The server binds to 127.0.0.1, which is not reachable
from your network. There is no telemetry, no analytics and no update check.
Your prompts are read from disk, cached to another file on the same disk, and rendered in your own browser. Nothing crosses the network.
Does it cost anything to run?
No. Token Dashboard reads files. It never calls a model, so running it adds nothing to your bill.
Does it work with Codex and Gemini, or only Claude Code?
All three. Claude Code and Codex are billed from their own usage records. Gemini is read for activity but left unmetered, for the reason below.
Switch between them with the agent filter, or leave it on All agents to see them side by side.
Why is Gemini showing no cost?
Gemini's telemetry is off by default. It does count tokens, and publishes them
as a gemini_cli.token.usage metric, but it writes nothing to disk until you
enable OpenTelemetry.
Switch it on in ~/.gemini/settings.json with telemetry.enabled,
target: "local" and an outfile, and the dashboard bills it on the next scan.
Until then it shows sessions and tool calls with a cost of zero, because
estimating one would mean inventing a number and printing it as a fact.
Why is my cost so enormous?
Every figure is at list API prices, and you are almost certainly on a subscription instead.
The first card shows the multiple: what the same work would have cost on the API, against what your plan costs for the same stretch of calendar. A large number there means your plan is doing very well. It is not a bill.
Why are cache reads most of my tokens?
Every turn re-reads the context you are carrying, and that read is billed. On a long session it dwarfs everything else, typically around 98% of token volume.
It is also the cheap part, at a tenth of fresh input, so it is roughly a third of the money rather than 98% of it. That gap is why the default chart is dollars and not tokens.
What platforms and clients does it work with?
Every Claude Code surface that writes a local transcript. That covers the terminal CLI, the VS Code extension, the desktop app, and sessions started through the SDK. They all write to the same place, so they all show up, and the Projects tab lists which Claude Code version produced each one.
Codex is covered through its own rollouts, which includes the CLI and the desktop app. Gemini is covered through both the CLI and Antigravity.
It runs on macOS, Windows and Linux.
Does it work with Cursor, Windsurf or JetBrains?
Yes, wherever those run Claude Code or Codex. The extensions use the same transcript store as the terminal, so nothing extra is needed.
What it cannot see is anything that runs server-side and writes no local file. Claude Cowork and the chat on claude.ai are both in that category. Nothing on your machine can measure them.
How accurate are the numbers?
Token counts come from the usage records the agents write themselves, not from counting characters, so they are the same numbers you were billed on.
The dollar figures are those counts multiplied by pricing.json. They are exact
if that file matches your contract, and wrong by whatever margin it does not.
Check it before quoting a number to anyone.
Does it show my rate limits or when I will hit my plan cap?
Not yet. Claude Code writes no limit information to its transcripts, so there is nothing local to read.
Codex does record its rate-limit windows, so a Codex-only view of that is possible later. It is not in this release.
How far back does the data go?
As far back as your transcripts. Agents keep them until you delete them, so most people have months.
Anything you have already cleaned out is gone, and no dashboard can recover it.
Does it slow down my agent?
No. It never touches a running session. It reads finished files from disk, read-only, in a separate process.
Can I use it for a team, or across several machines?
It is a single-user, single-machine tool by design. It reads your own home directory and binds to loopback.
For several of your own machines, run it on each. The JSON export gives you something to combine by hand if you want one total.
Do I need an API key or an account?
Neither. Token Dashboard never talks to any API. It reads files your agents already wrote.
Does Claude Code need to be running?
No. It reads transcripts from disk, so it works with everything closed.
A session running in another window shows up on the next refresh, about twenty seconds.
Will it work on Windows or Linux?
Yes. It is Node and a browser, and the transcripts live under your home directory on every platform.
Section 10 lists an environment variable for every path, if yours differ.
Can I change the prices?
Yes. Prices live in pricing.json at the root of the package, in dollars per
million tokens, read at startup. Edit it and restart.
Where is the data stored, and does it modify my transcripts?
Parsed results go to ~/.claude/token-dashboard.db, a SQLite file under your
own home directory.
Your transcripts are opened read-only and never written to. The Docker
instructions mount them :ro so the container cannot write to them either.
How do I remove it?
Stop the process. If you ran it with npx, nothing was installed and it is
already gone.
If you installed it globally, run npm uninstall -g @thenavidm/token-dashboard.
Delete ~/.claude/token-dashboard.db to remove the cache as well.
Run into a problem or have a question? Open an issue and I will help.
Navid Moazzez is a leading AI business strategist, and the host of the AI Creator Summit, watched by 100,000+ creators. He helps creators and founders master AI and build their own AI Operating System (AI OS) to automate their business and life. This Token Dashboard is the piece of that system that tells him what the rest of it costs.
Links
- Personal website: navid.me
- YouTube: @thenavidm and @thenavidai
- X: @thenavidm
- Instagram: @thenavidm
- LinkedIn: thenavidm
If this is useful, star the repo and come say hi on X.
| Library | Licence | What it does |
|---|---|---|
| Next.js | MIT | The local server and the UI framework |
| React | MIT | Rendering |
| Tailwind CSS | MIT | Styling |
SQLite comes from node:sqlite, built into Node 22.5 and newer. Charts are hand-drawn SVG. There is no charting library.
MIT. Free to use, modify, and share.
Not affiliated with, endorsed by, or connected to Anthropic PBC, OpenAI OpCo LLC, or Google LLC. Claude and Claude Code are trademarks of Anthropic PBC. Codex and ChatGPT are trademarks of OpenAI OpCo LLC. Gemini is a trademark of Google LLC.
© 2026 tokendashboard.io is a trademark of NM Media. All rights reserved. Made with ❤️ by Navid Moazzez.