Skip to main content
Glama

License: MIT npm CI Node GitHub last commit Visitors

Turn your local AI coding agent logs into a stat card you commit to your README.

tokenchit — @iyashjayesh AI coding agent usage

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

One command: it finds your agents, shows your stats, writes the card, and puts you on the board. Running it often? npm i -g @tokenchit/cli, then tokenchit generate.

  ┃ [1/3]  DETECT AGENTS
  ┃   ● claude-code   ~/.claude*/projects/**/*.jsonl
  ┃ ✓ 3 agents, written to .tokenchit.json
  ────────────────────────────────────────────────────────────

  ┃ [2/3]  YOUR STATS
  ┃   ~16.7B   $7,392        27d      51
  ┃   TOKENS   EQUIV. COST   STREAK   ACTIVE DAYS
  ┃
  ┃   30d  ▁··▄▆▆▆▅▁▃▅█▃▂▄▂▁▅█▆▂█▇█▅▄█▇▆▃  3.07B in 7d
  ┃ ✓ wrote tokenchit.svg
  ────────────────────────────────────────────────────────────

  ┃ [3/3]  THE BOARD
  ┃ ✓ published as @iyashjayesh — tier: verified

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. sync and recap make no network request. publish is the only command that uploads, and --dry-run prints 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 SVG

tokenchit recap

Related MCP server: claude-spend

What it reads

agent

source

Claude Code

~/.claude*/projects/**/*.jsonl — every profile directory, not just the default

Codex

~/.codex/sessions/**/rollout-*.jsonl

OpenCode

~/.local/share/opencode/opencode.db

Copilot CLI and Gemini CLI are detected and reported as unsupported: Copilot records only a live context gauge, and Gemini's transcripts carry no token counts.

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, or rebuild it
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 as

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-handle

It 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 is the only command that uploads anything. 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.

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:3000

Node 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.

Licence

MIT.

Available Tools

4 tools
detect_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.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden, and it does disclose the diagnostic nature of the operation plus the three facts returned. It does not state that this is a read-only/local scan, whether it is slow, or what permissions it needs, so some behavioral context is still missing.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight sentences with no filler, and the primary function is front-loaded ahead of the fallback-trigger guidance.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema and no parameters, the description must describe the return payload, and it enumerates all three returned facts. An agent has enough to decide to call it and to interpret the result.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so the baseline is 4; there is nothing for the description to clarify beyond what the empty schema already conveys.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States precisely what the tool reports: installed coding agents, their log locations, and whether readable usage exists. This is specific enough to distinguish it from get_usage/get_daily_usage, which read usage rather than enumerate agent installations.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives an explicit trigger: 'Call this first when a usage read comes back empty.' That is a clear when-to-use condition tied to the sibling read tools. It stops short of naming the siblings outright or stating when not to bother calling it.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
daysNoHow many calendar days back to return, ending today. Idle days are included as zero.
agentsNoRestrict the read to these agents. Omit for all of them.

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It does disclose the return ordering (most recent last) and implies a read-only, non-destructive operation via 'get', but says nothing about pagination, response shape, or whether idle days are zeroed (that detail lives only in the schema). Adequate but not rich.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight sentences with zero filler; the output semantics are front-loaded before the usage rule. Every clause earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple, two-optional-parameter read tool with no output schema, the description covers what is returned and when to pick it. It is nearly complete; only the read-only/cost profile is left implicit, which is a minor gap given the 'get' naming.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so both parameters (days, agents) are already fully documented, including the zero-fill for idle days. The description adds no parameter syntax or behavioral detail beyond implying a bounded lookback window, so it earns the baseline 3.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States the resource precisely ('tokens per local calendar day') and the ordering ('most recent last'), and implicitly separates itself from the sibling get_usage by contrasting a stretch of time with a lifetime total. It could be sharper by naming get_usage outright, but an agent can place it correctly without the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives an explicit selection rule: use this for a specific stretch of time rather than a lifetime total. That is genuinely actionable routing guidance, though it stops short of naming the alternative tool (get_usage) or giving any exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
yearNoCalendar year. Omit for the current one.
agentsNoRestrict the read to these agents. Omit for all of them.

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the burden. It does disclose the aggregation shape (by weekday and hour, not by date) and the returned content, but says nothing about read-only safety, required permissions, or error behavior for a 2-param tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with the core scope ('Year in review for one calendar year'), then a compact enumeration of outputs. The list of contents is long but each item conveys distinct return-value information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, describing the returned tiles, breakdowns, busiest hour, and weekday/hour aggregation is genuinely valuable and makes the return shape predictable. Minor gaps: no statement of read-only nature or expected failure modes.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so both 'year' (omit for current) and 'agents' (omit for all) are already fully documented in the schema. The description only reinforces 'one calendar year' and 'per-agent', adding no syntax or format detail beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource (year-in-review recap for one calendar year) and enumerates the contents, which clearly separates it from get_daily_usage and get_usage. It never names a sibling for contrast, so it stops short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied by the scope ('one calendar year', 'not by date'), which points away from the daily/usage siblings. There is no explicit when-to-use or when-not-to-use statement and no alternative is named.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
agentsNoRestrict the read to these agents. Omit for all of them.

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full disclosure burden and does deliver a meaningful trait: 'Reads logs on this machine; makes no network request', which tells the agent this is a local-only read with privacy implications. It stops short of noting read-only safety, expected scan cost on large logs, or empty-state behavior, so it is good but not exhaustive.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, front-loaded with the returned metrics and followed by the windows and the local-read note. Every sentence contributes; the only minor density is the metric list, which is justified by the breadth of the return.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema and no annotations, the description compensates well by listing the returned dimensions, the four time windows, and the local/no-network behavior. The remaining gap is sibling orientation relative to get_daily_usage and get_recap, which matters for correct tool selection.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and the single 'agents' parameter is already documented in-schema ('Restrict the read to these agents. Omit for all of them.'). The description adds no syntax or filtering detail beyond that, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('total ... usage') and resource, then enumerates the exact metrics returned (tokens, equivalent cost, streak, active days, per-agent mix, per-model breakdown). Very clear about what it does, but it never differentiates itself from siblings like get_daily_usage or get_recap, so an agent must infer the granularity distinction.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The enumerated time windows (all time, current year, last 30 days, last 7 days) implicitly signal when this aggregate view is appropriate. However, there is no explicit when-to-use guidance and no direction to or away from get_daily_usage / get_recap, leaving the alternative-selection question unanswered.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 4 tool updates
    • First observeddetect_agents
    • First observedget_daily_usage
    • First observedget_recap
    • First observedget_usage

TDQS

A3.8/5.0

Scored across 4 tools

Disambiguation4/5

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.

Naming Consistency4/5

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.

Tool Count4/5

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.

Completeness4/5

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

ActivityNo data
ResponsivenessResponsive

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    A
    maintenance
    Local-first dashboard + MCP server that parses Claude Code and Codex JSONL files into a SQLite cost / token tracker. Per-MCP and per-tool breakdown, session drill-down, dedup by request_id; never talks to vendor APIs
    5
    100
    1
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Provides tools for Claude to query local Claude Code token usage and cost data, enabling spend analysis and insights through natural language.
    17
    1
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Analyzes 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.
    27
    4
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables local-first tracking of AI token usage and costs from Claude Code and OpenCode, answering queries about tokens, models, sessions, and cost through MCP tools and a CLI, with no network calls.
    161
    1
    MIT