A read-only viewer for Claude Code token usage and estimated cost. Scans the
JSONL files Claude Code writes under %USERPROFILE%\.claude\projects\, prices
the tokens against current Anthropic API rates pulled from LiteLLM, and shows
a calendar heatmap plus a reporting panel in your browser. No database, no
daemon, no persistent state of its own beyond a small pricing table and
per-day snapshots.
Nothing about your usage leaves your machine. The only network call this tool
ever makes is a one-time (then 7-day-cached) fetch of Anthropic's public
per-token rates from LiteLLM's GitHub repo. Your project names, sessions, and
token counts are never sent anywhere. Use --offline to skip even that fetch
and rely on whatever pricing is already cached.
See CONTEXT.md for the glossary and docs/adr/0001-jsonl-is-the-database.md
for the core architectural decision.
- Install Python 3.9+ if you don't already have it.
- From https://www.python.org/downloads/. Tick "Add python.exe to PATH" in the installer.
- Or from the Microsoft Store: search for "Python 3.12".
- Get the code, either:
git clone https://github.com/Silver556/llm-cost-tracker-windows.git, or- on the GitHub page, Code → Download ZIP, then unzip it somewhere
(e.g.
C:\Tools\llm-cost-tracker).
- Double-click
install.bat(or run it from acmdwindow). It addsbin\to your userPATH. No admin rights needed. - Close that window, open a new
cmdor PowerShell window, and run:claude-cost
You can also skip the installer and run bin\claude-cost.bat directly from
the project folder.
Requires Python 3.9+ (stdlib only, no pip install).
claude-cost generate a fresh HTML and open it in the browser
claude-cost --serve ephemeral local server with in-page refresh button
claude-cost --help all flags
| Flag | Meaning |
|---|---|
| (none) | Scan, render the dashboard into your temp dir, open in browser, exit. |
--serve |
Start a local HTTP server in the foreground; page gains a ↻ Refresh data button. Ctrl-C to stop. |
--port N |
Pin the served port (default: random). |
--refresh-prices |
Force re-fetch of pricing from LiteLLM, ignoring the 7-day cache. |
--offline |
Never hit the network. Cached pricing only. |
--no-open |
Print the file/URL but don't auto-open the browser. |
The page opens on Reporting; the quick-stat strip and calendar follow below it.
- Reporting: independent panel with its own range (Today / 7d / 30d / 90d / This / Last month / YTD / All time / Custom) and project/model filters. Shows summary stats, by-model and by-project breakdowns, a Project x Model matrix, and a per-day trend bar chart. Check Compare to previous period to add a delta (dollar amount + %) to the summary stats and each by-model/by-project row, against the period of equal length immediately before the one you're viewing. Not available for "All time", which has no prior period to compare against.
- Quick-stat strip: today / yesterday / last 7 days / this month. Reacts to the calendar's project/model filters, same as the calendar itself.
- Calendar (per month): heatmap tiles with cost + tokens + per-model micro-bars. Click a tile for a side panel breakdown (per model, per project, per session, expandable to per-turn detail).
The calendar's project + model filters affect the calendar and the quick-stat strip above it, and nothing else. The Reporting section's filters are independent of both.
Light theme by default. Click the circle button near the top to switch to dark.
A generated HTML file has its data frozen in at the time of claude-cost run.
Reloading a stale browser tab does not pick up new events. Either:
- Re-run
claude-cost(opens a new tab with fresh data), or - Use
claude-cost --serveand click the in-page Refresh button.
%USERPROFILE% is C:\Users\<you>.
%USERPROFILE%\.claude\projects\ source of truth (Claude Code writes this)
%USERPROFILE%\.claude-cost\pricing.json append-only date-versioned price table
%USERPROFILE%\.claude-cost\.pricing-cache.json 7-day TTL cache of LiteLLM's raw JSON
%USERPROFILE%\.claude-cost\snapshots\YYYY-MM.json per-day aggregates (cleanup insurance)
%TEMP%\llm-cost-<timestamp>.html generated dashboards (disposable)
- Cost is estimated: tokens are exact, dollars are computed against public API rates. On a Max / Pro subscription, those dollars are not what you actually pay. They model what the same usage would cost via the API.
- Subagent calls (e.g. Explore using Haiku) are attributed to the parent session's project, not split out separately.
- If Claude Code prunes an old JSONL, that day's per-session detail is gone. The daily total survives via the snapshot file, but the day side panel notes that session detail isn't available for that day.
- Calendar filters hide snapshot-only days (only daily totals are stored, not joint per-project-per-model breakdowns required by both-filter case). The Reporting section iterates live events only, so snapshot-only days are not included there either.
- "Compare to previous period" compares against the immediately preceding N days (N = the length of the range you're viewing), not a calendar-aligned period. Comparing "This month" doesn't mean literally last calendar month; it means the same number of days right before the 1st.
MIT.