response_bytes is JSON.stringify(result).length — the size of what your tool handed back.
It is not a performance metric. It is a cost metric: every byte your tool returns lands in the model’s context window and is paid for on the next turn, by whoever is running the client.
Bytes, tokens, dollars
MCPulse converts in one place and one place only:
Both constants live in a single service. The moment a
/ 4 or a * 3 appears in a route handler or a component, two answers to the same question exist and they drift.
Four bytes per token is an approximation, deliberately. The point is the order of magnitude — knowing a tool costs roughly 2k tokens rather than roughly 200 is what changes a decision. Real tokenisers vary by content and by model.
$0.0001 renders as <$0.0001 rather than as zero.
Where it appears
The 10kB line
A tool averaging over 10,000 bytes per call is returning roughly 2,500 tokens every time it runs. At three or four calls a session that is a meaningful slice of a context window, and it is being paid for on every subsequent turn of the conversation, not once. The tool health badge and the insight rule read the same threshold from the same constant, so the table cannot say a tool is healthy while the panel directly beneath it says otherwise.Cutting it
The usual causes, in the order they are usually true:- Returning whole records where the model needs three fields. A row with 40 columns costs 40 columns of context.
- No limit. A search that returns everything matching returns everything matching.
- Pretty-printed JSON. Indentation is bytes.
- Echoing the request back in the response. The model already has it.
Unserialisable results measure as zero
IfJSON.stringify throws on the result, the size is recorded as 0 rather than failing the call. Unserialisable means unmeasurable, and recording must never be the reason a tool call fails.
Related
- Cost per session
- Schema size — the cost a tool imposes even when never called