The response budget
Five stacked mechanisms so a fleet read fits a client's tool-output limit - and a cap that errors rather than truncates.
An unbounded fleet_show on a large record can exceed an MCP client's tool-output limit, and
the client then drops the response instead of handing it to the model. MCP offers no
mechanism for a client to declare its budget to a server, so the server chooses defaults.
Five mechanisms stack:
Default live horizon. fleet_show and wave_show default to horizon: "live" —
terminal streams (merged, closed-without-merge) are excluded — on a mature record they are most
of the payload. History is one explicit
argument away (horizon: "all" — byte-identical to a pre-narrowing read), and a defaulted
response names the default that fired rather than narrowing silently:
Honest summary. detail: "summary" (the default) carries the stream-identity and state
fields, a four-field last_gate (no justification prose — that lives in stream_detail
and full), and a trimmed liveness block. detail: "full" remains complete; the budget
moves data behind an explicit request, it never removes data. The descriptors enumerate
both levels exhaustively.
Cursor pagination as tool arguments. limit defaults to 25, maximum 100 — a value
above the maximum is rejected with limit must be an integer between 1 and 100, never
silently clamped. A truncated response is a successful bounded response
(isError: false): it carries next_after, which names the exact next call
(after: <cursor>), and total_count still answers how many streams exist unfiltered — a
truncated list can never be mistaken for the complete set. (MCP protocol pagination
deliberately does not cover tools/call; these are ordinary arguments read by the model
from the descriptor, which is why the descriptor discipline above is load-bearing.)
Tabular formats. format: "csv" / "tsv" return rows only, a fixed narrow column set
— noticeably fewer tokens than JSON for this row shape. This changes the read
contract (a table, not the envelope) and is therefore opt-in.
A hard byte cap as an error, never a silence. After all narrowing has run, a response
at or above 200,000 bytes is refused, class result-too-large, with the exact next move:
The reasoning: clients truncate oversized tool results silently, at boundaries the server did not choose, and the model then answers with
full confidence from a fragment. If the server does not cut explicitly, something below
will cut implicitly. Additionally, fleet_show / wave_show declare
_meta["anthropic/maxResultSizeChars"] = 200000 — a transitional client-side allowance
at the cap, never a substitute for the narrowing. The three aggregate tools carry the same
200,000-byte cap and refuse rather than truncate.