Build1 publisher3 min readPublished
A 24,000-character CJK tool result reached Claude Code's context as 49,964 tokens
Claude Code screens MCP output for character length before it counts tokens, so a dev.to test measured a result at roughly twice the documented 25,000-token cap sitting in the conversation untouched. The docs describe the same guard in two units.
The Engineer · Build desk

What happened
- A dev.to writeup had a 65-line stdio MCP server return text of any requested size to Claude Code v2.1.273, then read the session transcript to see what the model actually received.
- The test found a separate size check that swaps a result for a file path and a 2KB preview once the output lands somewhere between 45,000 and 52,000 characters.
- Because the 25,000-token check only runs after a result is long in characters, 24,000 characters of CJK text went into context whole, as 49,964 tokens.
Compiled by The EngineerSomething wrong?How this is made
Why it matters
- constraint An MCP server that wants to keep a shared context window intact has to cap its own output, because the first guard in the path counts characters and the documented token cap is evaluated after it.
- cost Whatever beats both guards is billed as input on the next request in the session, so the team running the session pays for text the cap was supposed to divert to disk.
- decision Lowering MAX_MCP_OUTPUT_TOKENS buys nothing for output that stays under the character threshold, so the budget worth setting is a character budget inside the tool itself.
- precedent Reviewing an MCP server now means testing it with the densest text it can emit, since English filler will trip the character guard long before the token guard is reached.
Which check fires first depends on one property of the output: characters per token. For the word-list filler in the test, the inline rows worked out to about 2.6 characters per token, and 45,000 characters cost 17,514 input tokens [21]. The character check fires somewhere between 45,000 and 52,000 characters [3]. At 2.6 characters per token, 52,000 characters is around 20,000 tokens [1], so filler of that density is written to disk while still well under the token cap.
Invert the pair to get the crossover. The bottom of the character band divided by the token cap is 45,000 over 25,000, or 1.8 characters per token [2]. Output denser than that can carry more than 25,000 tokens and still be too short in characters to trip the first check. The CJK body measured about 0.48 characters per token: 24,000 characters for 49,964 tokens [3][5].
The documentation describes this in two units. It says Claude Code "displays a warning when any MCP tool output exceeds 10,000 tokens" [6], and that the maximum is 25,000 tokens by default and can be changed with the `MAX_MCP_OUTPUT_TOKENS` environment variable [7]. Over the limit, Claude Code saves the result under the session's `tool-results` directory and "replaces it in the conversation with a message that names the file path" [8]. The next paragraph of the same section switches to characters, and the docs do not give a number for the character threshold [10].
A server can also raise its own spill threshold. Setting `_meta["anthropic/maxResultSizeChars"]` in a `tools/list` entry moves the "default persist-to-disk threshold" for that one tool, up to a hard ceiling of 500,000 characters [9]. At the density the CJK run measured, 500,000 characters is about 1.04 million tokens [5]. That case was not run, and I would not volunteer a context window to find out.
The measurement itself is careful in the places it needed to be. Totals come from each assistant record in the transcript under `~/.claude/projects/`, summing `input_tokens`, `cache_read_input_tokens` and `cache_creation_input_tokens`, not from the summed `usage` block in the JSON output [16]. Request 1 is the prompt alone, request 2 is the prompt plus the tool call plus whatever Claude Code substituted, so the difference is what the result cost as the model saw it [17]. The built-in tools were stripped with `--tools ""` so a spilled file could not be read back into the conversation [15]. Every configuration ran twice, and the growth between the two requests matched to within 8 tokens [20].
Request 1 totalled 3,462 tokens in the first three runs and 3,295 in every run after, with nothing changed on the test's side, so the comparison stays inside a single run [18]. A small Haiku call of between 954 and 965 input tokens appears in every run and is left out of the figures [19]. For the 49,964-token result to mean anything for your server, your tool's output has to run denser than 1.8 characters per token, and the check order has to hold outside the one account, date and build it was measured on: 2026-09-16, Claude Code 2.1.273, default model `claude-opus-5[1m]` [11].
What to watch
- Whether a Claude Code build after 2.1.273 evaluates the token count before the character length, or publishes the character number.
- Whether setting MAX_MCP_OUTPUT_TOKENS below the 25,000 default changes anything for output that stays under the character threshold.
- Whether a tool annotated with anthropic/maxResultSizeChars near the 500,000-character ceiling is still screened by token count at all.