Collect and visualize usage statistics from Claude Code sessions stored locally on your machine. No API key or network access required.
- Node.js 22.5+ (for the built-in
node:sqlitemodule) - Claude Code installed and used at least once (
~/.claude/projects/must exist)
Tell your AI agent:
Install claude-stats from https://github.com/de-otio/claude-stats
The agent should run:
git clone https://github.com/de-otio/claude-stats
cd claude-stats
npm install
npm run build
npm run package:ext
code --install-extension extension/claude-stats-vscode-*.vsixAfter the VS Code extension activates (reload the window if needed), it automatically:
- Registers the MCP server in
~/.claude.json(Claude Code's user-scope config) - Updates any stale registration on subsequent activations
Restart Claude Code after the extension installs for the MCP server to become available.
Open the dashboard via the activity bar icon or: Command Palette (cmd+shift+p) → Claude Stats: Open Dashboard.
The extension embeds the dashboard inside VS Code with a status bar showing today's token usage. It is fully self-contained — all dependencies are bundled, no separate global install required.
The extension also auto-registers the MCP server in ~/.claude.json. Once installed and Claude Code restarted, your AI agent can query your usage stats without any manual MCP configuration.
git clone https://github.com/de-otio/claude-stats
cd claude-stats
npm install
npm run build
npm run package:ext
code --install-extension extension/claude-stats-vscode-*.vsixOpen the dashboard via the activity bar icon or: Command Palette → Claude Stats: Open Dashboard.
The VS Code extension bundles a local MCP server and registers it automatically in ~/.claude.json (Claude Code's user-scope config) on first activation. The server runs as a child process over stdio — no network access or authentication required, all data is local.
If you need to register it manually (without the extension), run:
# The extension directory carries its version — resolve it rather than hardcoding one:
MCP_JS="$(ls -d "$HOME"/.vscode/extensions/de-otio.claude-stats-vscode-*/dist/mcp.js | sort -V | tail -1)"
claude mcp add -s user claude-stats -- "$(which node)" --experimental-sqlite \
-e "require('$MCP_JS').startMcpServer().catch(e=>{console.error(e);process.exit(1)})"Why not just
node mcp.js?mcp.jsexportsstartMcpServer()but does not invoke it when run as a plain script. The-eflag calls the entry point explicitly.Why
~/.claude.jsonand not~/.claude/settings.json? Claude Code CLI registers MCP servers from~/.claude.json. ThemcpServerskey in~/.claude/settings.jsonis silently ignored for server registration.
18 tools, all read-only except where noted. Enumerated from
packages/cli/src/mcp/index.ts — if this
list and that file ever disagree, the file wins.
| Tool | Description |
|---|---|
get_stats |
Usage summary for a period — tokens, cost, sessions, cache efficiency, streaks |
list_sessions |
Recent sessions with token counts and estimated cost |
get_session_detail |
Messages and token usage for a specific session |
list_projects |
Per-project usage breakdown |
get_status |
Database health, session count, last collection time |
search_history |
Search prompt history by keyword |
summarize_day |
Clustered digest of what you got done on a given day |
get_cost_per_task |
Cost per successful task — outcome-cost overall and per model (read-only) |
get_cost_per_ticket |
Cost attributed to work-item ticket keys (e.g. PROJ-123) from locally observed evidence — git branch, commit subjects, prompt mentions — with a coverage denominator and per-figure confidence tier. No Jira/tracker API is called. |
get_calibration |
Whether this tool's own confidence tiers have ever been checked against your corrections — an agreement rate on the reviewed subset, never "accuracy," and "uncalibrated" below a minimum sample |
get_efficiency_hints |
Self-audit: your own wasted spend from six local patterns (cache churn, retry loops, abandoned spend, context bloat, re-entry burn, tier mismatch) — nothing here ranks developers or leaves the machine |
get_cache_ttl_fit |
Is this workload cheaper on the 5-minute or the 1-hour cache TTL? Idle-gap distribution, cache-write origin, per-model net cost, and one verdict — always shown beside the margin that decided it, and labelled a projection when the window was recorded at the other TTL |
get_context_carry |
How much of the bill is carrying context forward, and where does it concentrate? Context-size bands, tokens carried above a set of caps, reset/compaction cycles and their sawtooth shape, and the session-start "prelude" every fresh session repays — every bound labelled as an estimate, never a bare ratio. Also carries an autoCompactWindow fit — a candidate table and a range-not-a-number recommendation for /autocompact's window size, gated behind the same honesty caveats as the rest of the payload. Omits concentration, preludeByProject, turns, and the fit's raw model-id list, and strips session ids from resets/cycles |
generate_justification_pack |
Write a self-contained HTML + CSV bundle for one month to local disk — the artifact you hand to someone who doesn't run claude-stats. Runs the stricter org-plane redaction (no prompt text, file paths, or session ids) |
get_constraint_impact |
What a declared policy boundary (budget cap, model-tier removal, quota change) measurably cost or saved, per task class, on both sides — never inferred from the data |
get_account_info |
Current login's seat tier, billing type, and known accounts on this machine |
get_plan_mechanics_reference |
Dated snapshot of Team/Enterprise seat ranges, pricing, and usage-intensity benchmarks, with a staleness warning |
size_seats |
Seat-sizing scenario table for a company rollout from headcount + technical fraction (never picks a plan) |
See doc/user-doc/commands.md for the matching CLI
commands (report --ticket, ticket, task-class, constraint-impact,
pack) and what each figure does and does not claim.
skills/license-advisor/SKILL.md is a repo-level Claude Code skill that walks
a stakeholder through picking a Team vs Enterprise plan and seat count using
the tools above — grounded in measured usage where it exists, falling back to
benchmarks otherwise, and surfacing the compliance and spend-limit tradeoffs
as choices rather than resolving them silently. See
doc/user-doc/commands.md for the matching
account and plan-advisor CLI commands.
- "How many tokens have I used this week?"
- "What were my most expensive sessions today?"
- "Which projects am I spending the most on?"
- "How much CO₂ did my Claude usage cause last week?"
- "What's my cost per successful task, broken down by model?"
After building, install the CLI. The claude-stats binary belongs to
the @claude-stats/cli workspace — the repo root is a private package with no
bin, so install or link that workspace rather than the root:
npm link -w @claude-stats/cli # link claude-stats globally, OR
npm install -g ./packages/cli # install the built CLI globallyOr run it without installing: node --experimental-sqlite packages/cli/dist/index.js <command>
(equivalently, npm start -- <command>).
claude-stats collect # scan ~/.claude/projects/ and store session data
claude-stats report # print a usage summary
claude-stats serve --open # open the interactive dashboard in your browser
claude-stats report --html # export a standalone HTML dashboard file| Command | Description |
|---|---|
collect |
Incrementally import session data from ~/.claude/projects/ |
report |
Print usage summary, per-session detail, or trend breakdown |
spending |
Detailed cost breakdown by model, session, tool, and MCP server |
cost-per-task |
Cost per successful task — outcome-cost overall and per model |
task-outcome |
Label a task success/partial/fail to ground the metric |
pack |
Write the justification pack (HTML + CSV) for one month |
constraint-impact |
What a declared policy change cost or saved, per task class |
ticket |
Link, negate, or list manual ticket attributions for a session |
recap |
"What did I get done today?" — clustered day summary, plus corrections |
serve |
Start a local web dashboard (http://localhost:9120) |
status |
Show database size, session count, and last collection time |
export |
Export sessions as JSON or CSV |
search |
Search prompt history by keyword |
dashboard |
Output pre-aggregated dashboard JSON to stdout |
ttl-fit |
Is this workload cheaper on the 5-minute or the 1-hour cache TTL? |
context |
How much of the bill is carrying context forward, and where does it concentrate — over time, not at an instant. Includes a range recommendation for /autocompact's window size |
tag / tags |
Tag sessions and list tags |
task-class |
Classify sessions into task classes and show the distribution |
account |
Show and re-attribute the Claude accounts seen on this machine |
plan-advisor |
Size Team vs Enterprise seats for a company-wide rollout |
config |
View or set cost alert thresholds |
backfill |
Re-parse all session files to populate newly added fields |
repair |
Recompute derived data that collection can't fix retroactively |
diagnose |
Show quarantine counts and schema health |
mcp |
Start a local MCP server over stdio for AI agent access |
setup / link / sync / disconnect |
Optional aggregate-only sync to a team backend |
purge |
Delete local claude-stats data (dry run by default; --yes to apply) |
Every command and option: doc/user-doc/commands.md.
The CLI and dashboard ship in 10 languages — English, German, Spanish, French,
Japanese, Polish, Brazilian Portuguese, Russian, Ukrainian, and Simplified
Chinese. The language is taken from your shell locale (LC_ALL, LC_MESSAGES,
or LANG) and can be overridden per run with the global --locale <lang>
option:
claude-stats report --locale deSee Language and locale for fallback behaviour and the VS Code extension's handling.
git clone https://github.com/de-otio/claude-stats
cd claude-stats
npm install
npm run buildnpm test # run tests
npm run test:watch # watch mode
npm run coverage # with coverage report
npm run typecheck # type-check without emittingThis is an informal side-project maintained for personal use — built for fun, inspiration, and experimentation. There are no promises about long-term maintenance, but it will be kept up as long as it continues to be useful personally. Feel free to fork or copy it for your own purposes.
Claude Code writes a JSONL file for every session under ~/.claude/projects/. This tool reads those files incrementally, stores aggregated token counts and session metadata in a local SQLite database (~/.claude-stats/stats.db), and renders summaries on demand.
- Local by default. All data stays in
~/.claude-stats/and no network requests are made. Optional, opt-in backup and sync can copy an end-to-end-encrypted bundle to a cloud folder you already control — you turn it on explicitly, and your cloud provider only ever sees opaque ciphertext. - Incremental. Only new lines are read on each
collectrun. - Non-destructive. The tool never modifies Claude Code's own files.
- No API scraping. Unlike some alternatives, claude-stats does not call undocumented Anthropic endpoints, scrape session cookies, or inject code into Claude Code's process. It only reads the local JSONL files that Claude Code already writes to disk — fully compliant with Anthropic's Terms of Service.
See doc/user-doc/ for full documentation.
