Status: accepted, 2026-09-23 (OPIK-8485)
The caller chooses how much comes back, in layers:
list returns short rows.fields=[…] returns only the named paths, from a list or a read.read returns the whole record.The record you ask for always comes back whole. A composite read (a trace, a thread) inlines its children in a slimmer form, and every child carries the id that fetches it whole:
truncate=true);Every cut is stated in the answer, with a count and the call that gets the rest.
Open: Claude Code caps an MCP result at 25,000 tokens by default and warns
at 10,000, so a whole record can hit the host’s cap. The server can declare a
per-tool limit with _meta["anthropic/maxResultSizeChars"]. Not decided yet.
Seen live: a 250-span trace read is about 38,000 tokens with bodies slimmed,
and the host rejects it, so the caller gets nothing (/dogfood, OPIK-8485).
A silently short answer costs a conclusion: the user blames the MCP, not the truncation. A large answer costs context, which the caller can see and narrow (0001).
tests/read_list/test_read_tool.py: test_a_huge_record_comes_back_whole,
test_a_traces_spans_are_asked_for_slim,
test_the_dropped_bodies_are_counted_and_one_call_away.tests/read_list/test_fields.py: projection names what it keeps.tests/read_list/test_dataset_items.py: every cut is declared.max_tokens) removed. They cut answers the caller could not get back (#187).fields=[…] added as the middle layer (#197).