Token Meter

Token Meter / Guides / MCP token usage

Which MCP server is
eating your tokens?

Claude Code names every MCP tool call mcp__<server>__<tool> and pairs it with a response size. Token Meter already parses that pairing at ingest — no new tracking required. This guide shows the three ways to read it: a one-line table, a ranked audit, and an in-conversation drill-down.

Updated 2026-07-15 · stats and session_tools have shipped since the first release; if token-meter audit isn't recognized, run npm install -g @whdrnr2583/token-meter@latest first.

Problem

A session that used to feel cheap suddenly burns through context fast, or your weekly token-meter stats total climbs and you can't tell whether it's a model choice, a chatty MCP server (Notion, GitHub, an internal search server, whatever you've registered), or your own built-in tools (Read, Bash, WebSearch) reading something large. You want a name — "it's the Notion server's notion_search tool" — not a vague feeling that "MCP feels heavy."

Cause

Every tool_use block in a Claude Code JSONL transcript is paired with its tool_result at ingest time. Token Meter estimates the size of that result (response_tokens_est, from response_chars using a ~3.5 chars/token heuristic — see estimateTokensFromText() in src/parser.ts) and derives the MCP server name straight from the tool's own name: any tool matching mcp__<server>__... is tagged with that server (parseMcpServer(), same file); everything else — built-in tools — gets mcp_server: null. Both are stored per call in the local tool_events table.

Nothing aggregates that for you by default. A server can be fine on any single call and still dominate your week purely on call volume, and nothing in the Claude Code UI itself breaks usage down by MCP server — you have to ask Token Meter to sum tool_events by (tool_name, mcp_server).

Command

Three real surfaces, from fastest to most detailed. All read the local SQLite DB — none of this calls out to Anthropic or any MCP server.

1. One-line aggregate — token-meter stats

Runs byMcp() (src/stats.ts): groups tool_events by (mcp_server, tool_name) and sorts by summed response_tokens_est, descending. It's part of the default stats output, so you already get it for free:

token-meter stats 7

The number is the lookback window in days. Bare token-meter (no subcommand) runs the same thing with a 30-day default.

2. Ranked findings with recommendations — token-meter audit

The oversized_tool_response detector (D2 of 6) flags any (tool_name, mcp_server) pair averaging ≥5,000 response tokens/call over ≥5 calls in the window, ranks it against the audit's other findings, and attaches a concrete recommendation shaped by the tool's apparent role (search/list-shaped tools get "narrow the query" / "lower the result limit" / "paginate"; read/fetch/exec tools get "pre-filter the output" — buildRecommendations() in src/audit/detectors/oversized-tool-response.ts). Real flags, verified against src/cli.ts:

token-meter audit --days 7 --source all --limit 10

# machine-readable, for scripting or dashboards
token-meter audit --days 7 --source all --limit 10 --json

--source accepts all | claude | codex. --project <value> narrows to one project path. --days is clamped to your tier's history cap (7d Free, 30d Pro, unlimited Pro+) — a clamp warning prints to stderr if you asked for more than you're entitled to. --limit defaults to 5 in terminal mode, 20 in --json mode.

3. Drill into one session, from inside your assistant

The MCP server (token-meter mcp) exposes session_tools — a per-session tool breakdown by response-token share, not just an average across everything. Once registered (claude mcp add token-meter -- npx -y @whdrnr2583/token-meter mcp), ask in plain language:

Use token-meter session_tools for session <session_id>

Get the session_id from recent_sessions or from a token-meter audit finding's sessionId field. For a broader "what's heavy across the whole week" view without a session id, ask "Use token-meter usage_summary for this week" — its output includes a Heaviest : line naming the top 3 tools by response tokens.

Synthetic output

Fabricated example numbers below — not real user data — to show the shape of each command's output.

token-meter stats 7

=== MCP & tools (7d, top 12) ===
mcp           tool                                  calls  resp_tok  avg_latency
notion        mcp__notion__notion_search               41    186.0k  3120ms
-             Read                                     512    98.0k  140ms
github        mcp__github__list_pull_requests           9     71.0k  2480ms
-             Bash                                     203     44.0k  1610ms
notion        mcp__notion__notion_get_page              22     33.0k  1890ms
-             WebSearch                                 18     19.0k  2900ms
internal-kb   mcp__internal-kb__search                  67     17.0k   410ms

token-meter audit --days 7 (terminal, one finding shown)

TOKEN METER AUDIT — LAST 7 DAYS

Sources
claude-code: available (1842 records analyzed, 100% of window covered)
codex: unavailable — no data ingested yet

Confirmed usage
Tokens: 612.4k total (in 210.1k, out 84.6k, cache 317.7k)
Estimated cost: $9.8420

Efficiency signals
Findings: 4
Cost associated: $6.1050
Confidence: medium

1. [notion] mcp__notion__notion_search responses averaging 4.5k tokens
Source: claude-code
Project: /home/you/projects/app
Session: -
Tool: mcp__notion__notion_search
Evidence: [notion] mcp__notion__notion_search returns ~4,536 tokens/call on average (41 calls in 7d window; max 12,800). Configure `fields` or `limit` on [notion] mcp__notion__notion_search to reduce response size (est. 5,220 tokens/week saved).
Confidence: medium
Suggested action: Narrow [notion] mcp__notion__notion_search's query/filter scope instead of searching or listing broadly.

[…3 more findings omitted for brevity…]

Warnings
- [codex] No codex data has ever been ingested. Run `token-meter ingest` after using Codex to populate this source.

Use token-meter session_tools for session 1f4f193b-…

Tools used in session 1f4f193b-… (by response tokens; pct = share of session resp tokens):
  mcp__notion__notion_search (mcp:notion) calls=12 resp=148.0k (61.2%) avg=4200ms
  Read (built-in) calls=88 resp=68.0k (28.1%) avg=180ms
  Bash (built-in) calls=45 resp=26.0k (10.7%) avg=2100ms

Interpretation

Actions

  1. Confirm it's not one outlier session first. Run session_tools on the session named in an expensive_session or oversized_tool_response finding before you touch any MCP config — a server that looks heavy in a 7-day aggregate can turn out to be one bad session (e.g. a runaway loop that called it 40 times) rather than a structurally large tool.
  2. For search/list-shaped MCP tools (name matches search|grep|find|query|list): narrow the query/filter scope you pass it, use a limit/max_results/top_k argument if the tool exposes one, or paginate across multiple calls instead of asking for everything at once.
  3. For read/fetch/exec-shaped tools (read|get|fetch|cat|show|view|download|export|bash|exec|run|shell|command): request specific fields instead of the full payload, or pipe through grep/head where the tool supports it.
  4. Either way, ask whether the tool's output is actually used downstream. If it's being read once and then mostly ignored, a summarization/post-processing step before it enters context is worth more than tuning the call itself.
  5. Repeated near-identical calls in one session (repeated_similar_tool_calls, D4) are worth a second look for dedup/caching — see the Limitations section below for exactly how strong that signal is (and isn't).
  6. If the tool is a built-in binary/asset reader (e.g. Read on .png/.pdf files), this is a Claude Code settings problem, not an MCP problem — add an exclude glob pattern rather than trying to configure an MCP server that isn't involved.

Limitations

← Token Meter home · Source on GitHub · Full MCP server docs