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
-
mcpcolumn /mcp_serverfield — the server name parsed straight out of the tool's own name (mcp__notion__notion_search→notion). A dash (-) orbuilt-inmeans the tool is one of Claude Code's own (Read/Bash/Grep/WebSearch/…), not an MCP server — don't go hunting for an MCP config to trim if that's what's heavy. -
resp_tok/response_tokens_est— the estimated size of what came back from the tool, summed across every call in the window. This is not a billed line item; it's the payload that then becomes part of your next turn's input context. A tool with few calls but a hugeresp_toktotal is a "large payload" problem; a tool with a small average but very highcallsis a "called too often" problem — the two need different fixes. -
avg_latency— round-trip time, not token cost. High latency and high token cost often correlate (a slow tool is frequently also a large one) but not always; a fast tool that returns 12k tokens is still worth trimming even if it never shows up as "slow." -
Audit finding's cost figure — for
oversized_tool_responsespecifically,estimatedCostUsdis a projected weekly savings estimate (costLabel: 'cost_associated') — it assumes ~40% of the average response is reducible, it is not money you already spent. Compare that to anexpensive_sessionfinding, whose cost is real, already-incurred spend (costLabel: 'estimated_cost'). The audit ranks both kinds together by dollar figure, so check each finding'stype/costLabelbefore treating the top-ranked item as "the most money burned" — it might instead be "the most money that could be saved going forward." -
Confidence —
oversized_tool_responseishighconfidence only at ≥20 calls in the window; below that it's capped atmedium, because a couple of unusually large calls can still swing a small-sample average.
Actions
-
Confirm it's not one outlier session first. Run
session_toolson the session named in anexpensive_sessionoroversized_tool_responsefinding 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. -
For search/list-shaped MCP tools (name matches
search|grep|find|query|list): narrow the query/filter scope you pass it, use alimit/max_results/top_kargument if the tool exposes one, or paginate across multiple calls instead of asking for everything at once. -
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 throughgrep/headwhere the tool supports it. - 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.
-
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). -
If the tool is a built-in binary/asset reader (e.g.
Readon.png/.pdffiles), 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
-
Response size is estimated, not billed.
response_tokens_estcomes from a ~3.5 chars/token heuristic over the tool result text, computed locally — it is not the token count Anthropic actually charged for, and it can't be turned into one after the fact. Treat it as a sizing signal for comparison across tools, not an invoice line. -
No call arguments are ever stored.
tool_eventsdeliberately never captures the arguments a tool was called with (seeToolEventinsrc/types.ts) — this is by-design privacy, not a gap to be filled. You can learn "this tool+server pair is heavy," never "it was heavy because of this specific query/path/file." The one exception isfile_ext, which captures only the lowercased extension from afile_path/path/notebook_pathargument (e.g.png), never the path itself. -
"Repeated calls" is an approximation, by design (D4). The
repeated_similar_tool_callsdetector cannot do true argument-level dedup — there's nothing to compare arguments against. Instead it clusters calls in the same session by same tool + timing proximity (within a 5-minute window) + response-size similarity (within 10% of the cluster's running average) as a proxy for "probably did something similar repeatedly." It is explicitly not proof of identical calls, confidence is capped atmediumfor exactly this reason, and every finding says so in its own evidence text. -
Codex tool calls are never attributed to an MCP server.
codex-parser.tshardcodesmcp_server: nullfor every Codex tool event — Codex's transcript format doesn't carry themcp__<server>__<tool>naming convention Claude Code uses, so there is currently no way to tell a Codex-side MCP tool call apart from one of Codex's own built-in function/custom tools in Token Meter's breakdown. Everything in this guide's MCP-server attribution is Claude Code-only; Codex tool calls still show up (by tool name, response size, latency) but always asmcp_server: null. -
The "savings" number is a heuristic, not a measurement.
oversized_tool_response's projected weekly savings assumes 40% of the average response is reducible — a flat assumption, not something derived from the actual tool or your usage of it. -
--source/--projectscoping on this specific detector is best-effort. The underlying(tool_name, mcp_server)aggregate query has no source/project columns of its own, so anoversized_tool_responsefinding's reportedsource/projectechoes what you asked for rather than guaranteeing the aggregate itself is confined to it — a tool called from both Claude Code and Codex, or from two different projects, can be silently mixed into one finding.
Related links
- Find your most expensive Claude Code sessions
- Find the MCP tools slowing your sessions down
- Reduce oversized MCP tool responses
- Track Codex token cost alongside Claude Code
← Token Meter home · Source on GitHub · Full MCP server docs