tokenchit
A local, read-only MCP server that lets a model answer questions about your AI coding agent usage by reading log files on this machine — it makes no network requests and never writes state.
get_usage — total tokens, equivalent cost, streak, active days, per-agent mix and per-model breakdown across four windows: all time, current year, last 30 days, last 7 days.
get_daily_usage — tokens per local calendar day for a chosen span (default 30, up to 3650 days back, ending today), with idle days returned as zero; best for questions about a specific stretch of time.
get_recap — year in review for a calendar year (default current): headline tiles, per-agent and per-model breakdowns, busiest hour range, plus activity by weekday and hour.
detect_agents — which agents are installed, where each one's logs live, and whether they hold readable usage; the first call to make when a usage read comes back empty.
All four tools:
Read the same local logs the CLI reads (Claude Code, Codex, OpenCode) and can be scoped to a subset of agents via the optional
agentsparameter.Cannot make a network request — no allowlisted module, so every file must be clean.
Never write the ledger; tool calls are questions, not mutations.
Return each figure with its caveat as a sibling field (e.g. equivalent cost is not money you spent), and report failures with
isErrorso "no logs on this machine" is relayable rather than a transport error.
Supports signing in via GitHub device flow to verify a handle, publishing usage stats to a public leaderboard, and providing a GitHub Action to re-fetch and commit the generated stat card.
This server does not currently have a deployable release on Glama. Follow the repository's setup instructions to install and configure it for your MCP client, including any required credentials and local dependencies.
Turn your local AI coding agent logs into a stat card you commit to your README.
That card is this repository's own, generated by the command below and committed as a file. It is not a screenshot and not a hosted image — which is the whole point.
npx -y @tokenchit/cli@latest generate --no-publishOne command: it finds your agents, shows your stats and writes the card. --no-publish stops
it there, and that path has no networking code in it at all — no account, no sign-in, nothing
sent. Running it often? npm i -g @tokenchit/cli, then tokenchit generate --no-publish.
┃ [1/2] DETECT AGENTS
┃ ● Claude Code ~/.claude*/projects/**/*.jsonl
┃ ○ Codex not installed
┃ ○ OpenCode not installed
┃ ○ Gemini CLI not installed
✓ wrote .tokenchit.json (1 agents)
────────────────────────────────────────────────────────────
┃ [2/2] YOUR STATS, AND THE CARD
┃ ~16.7B $7,392 27d 51
┃ TOKENS EQUIV. COST STREAK ACTIVE DAYS
┃
┃ 30d ▁··▄▆▆▆▅▁▃▅█▃▂▄▂▁▅█▆▂█▇█▅▄█▇▆▃ 3.07B in 7d
✓ wrote tokenchit.svg (10144 bytes)
embed 
commit git add tokenchit.svg && git commit -m "chore: update tokenchit"
────────────────────────────────────────────────────────────
stopped before publishing — drop --no-publish to join the boardThen, if you want to
npx -y @tokenchit/cli@latest publishProves your handle over GitHub's device flow and puts you on the public
board, with a hosted card that refreshes without a commit. It
sends daily totals by agent and model and your handle — never prompts, replies or file paths
— and tokenchit unpublish takes all of it back.
Dropping --no-publish runs the same thing at the end of generate. At a terminal it names
the board and waits for a y first; a piped or scripted run has nobody to ask, so it
publishes — which is why --no-publish is what this page leads with.
Put it in your README
The card is a file, so the path is relative to the Markdown file you paste this into: ./
beside the card, ../ from a README one directory down. A profile README is its own
repository, so the SVG has to be committed to that repo.
Why this one
The card is a file, not a URL. Comparable tools serve cards from a hosted endpoint, so your README depends on someone else's uptime and rate limits. A committed SVG has none of that — GitHub serves it directly, and it keeps working if this site goes away.
Nothing leaves your machine unless you ask.
init,sync,recap,ledgeranddoctordo not import the networking module at all — a test enforces that, rather than a promise.publishholds the only code that uploads;generateends by calling it, asking first at a terminal but not in a script, which is what--no-publishis for.--dry-runprints the exact bytes.Honest about what it cannot see. Logs get rotated, prices change, and some models have no public price. Where a number is incomplete, the tool says so.
npx -y @tokenchit/cli@latest recap # the year in review, a second committable SVGRelated MCP server: claudeusage
What it reads
agent | source |
Claude Code |
|
Codex |
|
OpenCode |
|
Gemini CLI |
|
Gemini records token counts only in recent versions, so an installation whose recordings all predate that is reported as detected-but-uncountable rather than as a confident zero.
Copilot CLI is detected and reported as unsupported: it records only a live context gauge, never a cumulative total.
Your numbers will not match Claude Code's Stats panel. It counts an API call once per
streaming rewrite, so it reads roughly twice as high. sync prints both figures and the gap.
Equivalent cost is not what you paid — it is what these tokens would cost at list API
rates. Most agent usage runs under a subscription. See docs/internals.md.
Commands
tokenchit generate detect agents, write the card, join the board
--no-publish stop after the card
tokenchit init detect agents, write .tokenchit.json
tokenchit sync read your logs, show your stats, write the card
tokenchit publish put your row on the public board
tokenchit recap year in review, as a second committable SVG
tokenchit ledger show the local history bank, export it, or merge one in
tokenchit schedule print a cron or launchd entry; installs nothing
tokenchit login prove your GitHub handle (device flow, no password)
tokenchit logout forget this machine
tokenchit whoami who this machine is signed in asMoving your history between machines
tokenchit ledger --export <file> writes a portable copy — usage only, no credentials, no
transcripts, no paths. --import <file> previews merging one in and writes nothing until you
add --apply.
The merge is by session, not by day, which is the only way to tell two machines' work apart from one machine's work copied twice: the same session seen twice counts once at its fuller reading, and different sessions add. History banked before this version carries no session identity, so it is kept and reported but never added — nothing in an aggregate distinguishes independent work from a duplicate.
Your board row is whatever the last publish sent, so if you use more than one machine, merge
first and publish from the machine holding the merged history. Publishing from two machines
separately means each replaces the other. When a publish drops history the previous one
included, publish says how much and how to merge it.
Upgrading migrates the ledger, and going back a version is not safe. An older tokenchit reads the new format as unrecognised, falls back to an empty bank and rewrites it from whatever logs are still on disk. Upgrading itself is lossless and the CLI says so once when it happens. If you might roll back, run
tokenchit ledger --exportfirst — that file is one no version of this tool will overwrite.
tokenchit help <command> explains one command. NO_COLOR=1 drops colour and animation.
Common flags: --out, --theme auto|light|dark, --layout default|compact, --json,
--dry-run.
Keeping the card fresh
The card is a file, which is the point — and a file does not update itself. Re-running
generate is the honest answer, but nobody remembers to.
There is an action in this repository for the half a runner can actually do:
# .github/workflows/card.yml
name: card
on:
schedule: [{ cron: "0 6 * * *" }]
workflow_dispatch:
jobs:
refresh:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v7
- uses: iyashjayesh/tokenchit@v1
with:
handle: your-handleIt does not read your logs, and it cannot. An Actions runner has no access to
~/.claude or ~/.codex, so nothing on a runner can regenerate a card from source — you
still run publish from the machine that has the logs. What the action does is re-fetch the
card you already published and commit it, so the SVG in your README stops drifting away from
your real numbers while readers keep loading a committed file rather than an endpoint.
It refuses to overwrite a good card with a bad response: a non-SVG body, a non-200, or the
placeholder card the endpoint returns for a handle with nothing on the board. That last one
matters — without it a typo in handle commits an empty card on a schedule, silently,
forever.
Inputs are handle (required), output, layout, theme, agents, hide, commit and
commit-message; layout, theme, agents and hide are the same options the embed
endpoint takes. It outputs changed so you can gate later steps on a real update.
One thing to know: GitHub disables scheduled workflows in a repository after 60 days with no
activity, and a run that finds an unchanged card makes no commit. On a quiet repository the
schedule can switch itself off. workflow_dispatch is there so you can start it again, and
the run summary says which happened.
From an agent, not a terminal
There is an MCP server in packages/mcp, so a model can answer questions about your usage
instead of you reading a table:
{
"mcpServers": {
"tokenchit": { "command": "npx", "args": ["-y", "@tokenchit/mcp@latest"] }
}
}Four tools — get_usage, get_daily_usage, get_recap and detect_agents. All of them
read the same logs the CLI reads, and none of them can make a network request: the
net.isolated test covers packages/mcp/src alongside the CLI, and unlike the CLI this
package has no allowlisted module, so every file under it must be clean. Adding a fetch
anywhere in it fails the suite.
Two things it does that a plain data dump would not. Every figure ships with its caveat as a
sibling field, because a model handed equivCostUsd on its own will report it to you as
money you spent — and it is not. And a tool that fails answers with isError rather than a
transport error, so "no logs on this machine" reaches the model as something it can relay
instead of something it has to guess at.
It reads the ledger and never writes it. sync banks what it saw because you asked it to; a
tool call is a question, and a question that mutates state on disk is a surprise you cannot
see or undo.
Privacy
sync and recap make no network request at all.
publish holds the only code that uploads. It sends daily token totals per agent, model
names, and your handle — never prompts, replies, file paths, branch names, or repository
names. --dry-run prints the exact bytes so you can check rather than take our word.
generate ends by calling publish, so it is the one other command that can upload. At a
terminal it names the board and waits for a y; a piped or scripted run has nobody to ask and
publishes as it always has. generate --no-publish returns before any of that.
Five tests in packages/cli/test/privacy.test.js enforce this on every push, including one
that fails if any file outside net.ts can open a socket — across the CLI, the core engine
and the MCP server.
The board
Opt-in, and only publish puts you there. Verified rows rank above unverified ones: signing
in is the only thing that ties a row to a GitHub account. An unverified row still appears.
Submissions are self-reported, so two bands guard them — rejected for the arithmetically
impossible, and held for review for the possible but far outside anything seen. A held row
is stored and returned to you, and kept off the board until a person looks. Both thresholds
have been raised after real users were refused; the reasoning is in
docs/internals.md.
Development
npm install
npm run build # core, then cli, then site
npm test # core, cli and site suites
npm run dev # the site at http://localhost:3000Node 22 or newer — OpenCode support uses the built-in node:sqlite. The site and the CLI
render through the same buildCardSvg(), so they cannot drift.
The CLI, the card and npm test need no database at all — a contributor who only touches
those never sets one up. npm run dev does: the site reads DATABASE_URL from
apps/site/.env.local and any Postgres will do.
The one worth knowing about is a Neon branch. It is a copy-on-write clone of the board — the same rows, created in about a second, where anything you write stays yours:
neon branches create --name dev # then point .env.local at its pooled URLThat matters more than it sounds. Without it the obvious thing to do is point local
development at the live database, and then every npm run dev, every test publish and every
stray query is running against real people's rows.
docs/internals.md has the rest.
Supported by
Neon supports tokenchit through their Open Source programme, and is the
Postgres this project documents as its default — a choice
docs/research.md §4 reached on its own merits, before the sponsorship
existed. Any Postgres works: the site reads one DATABASE_URL and nothing below it knows or
cares who serves it.
Licence
MIT.
Available Tools
4 toolsdetect_agentsA
Which coding agents are installed on this machine, where each one's logs live, and whether they hold readable usage. Call this first when a usage read comes back empty.
Inputs: no named parameters.
get_daily_usageA
Tokens per local calendar day, most recent last. Use this for questions about a specific stretch of time rather than a lifetime total.
Inputs: days, agents.
get_recapA
Year in review for one calendar year: headline tiles, per-agent and per-model breakdown, the busiest hour range, and activity aggregated by weekday and hour (not by date). The same figures tokenchit recap renders.
Inputs: year, agents.
get_usageA
Total local AI coding agent usage: tokens, equivalent cost, streak, active days, per-agent mix and per-model breakdown. Windows are all time, the current calendar year so far, the last 30 days and the last 7 days. Reads logs on this machine; makes no network request.
Inputs: agents.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
This server cannot be deployed
TDQS
Scored across 4 tools
get_usage (windowed totals), get_daily_usage (per-day series), and get_recap (year-in-review aggregates) have partially overlapping subject matter, but each description clearly states its scope and output shape. detect_agents is cleanly distinct. Minor risk that an agent asks for a time range and picks get_usage over get_daily_usage.
Three tools follow a clean get_<noun> snake_case pattern (get_usage, get_daily_usage, get_recap). detect_agents breaks the prefix convention slightly but is still snake_case and readable, so the set is nearly uniform.
Four focused tools cover the analytics surface without redundancy. It is on the lean side but each tool earns its place; nothing feels padded or missing at the count level.
Covers lifetime/window totals, daily series, yearly recap, and agent discovery/diagnostics, which addresses the core questions of a usage-tracking server. Possible gaps like per-project rollups or cross-agent comparison views are not indicated as supported, but no obvious dead end for the stated purpose.
Maintenance
Related MCP Connectors
Exact Claude API cost calc with real cache economics, plus a tiktoken-misuse scanner.
Anthropic organization usage and cost reporting through an admin API key connected by the user.
Ask Claude about your income and spending, and import bank statements. No bank login.
OpenAI organization usage and cost reporting through an admin API key connected by the user.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceAnalyzes Claude Code session token usage and cost locally — where spend actually lands across cache-read, cache-write and output, and what is consuming the context window. Read-only and offline: it parses your own session files and exposes analyze_claude_cost, get_cost_benchmark and tokenscope_share_summary.54 npm4MIT
- AlicenseAqualityBmaintenanceAnalyzes local Claude Code logs to measure subscription value, waste, and rate-limit usage, including chat share and current limits, without uploading data.4MIT
- AlicenseAqualityBmaintenanceToken usage and estimated cost for Claude Code, Codex, Cursor and 20 more AI coding agents, read locally from their session files. No API key, no telemetry.221AGPL 3.0
- AlicenseNot gradedqualityBmaintenanceEnables AI coding agents such as Claude Code, Cursor, Codex, and OpenCode to query local token usage, costs, quotas, projects, and models through six strictly read-only tools. All data stays on the local machine, drawn from passively parsed session logs rather than uploaded telemetry.MIT