Bound MCP Payloads
Serialize once, paginate at the source, and keep transport metadata small.
Workflow
- Identify the harness result cardinality before shaping the MCP response.
- Reuse harness cursor pagination; never paginate only after serialization.
- Set Zod defaults and maxima for counts, string lengths, array lengths, and patterns.
- Add serialized-byte validation for nested unknown objects.
- Derive bounded audit metadata before serialization.
- Serialize response content once and measure UTF-8 bytes.
- Return a smaller-page hint or artifact reference when the response exceeds budget.
- Test boundary values and existing client behavior.
Required invariants
- Never JSON.parse response text for logging.
- Never truncate JSON at an arbitrary byte position.
- Never pretty-print large machine payloads.
- Never expose an unlimited list action.
- Never put content, prompts, messages, or secrets in audit metadata.
- Keep MCP adaptation thin; pagination belongs to harness.
- Preserve content text for clients that ignore _meta.
Response choices
Use, in order:
- a normal bounded page;
- a smaller suggested page after pageTooLarge;
- an artifact/export reference for intentionally large output;
- a typed rejection for oversized input.
Do not increase the payload budget to accommodate an unbounded API.
Dotcontext routing
- Keep reusable data limits in harness.
- Keep schema and response shaping in src/mcp/gateway or src/mcp/server.
- Update MCP docs and package smoke tests for public contract changes.
- Follow F-06.
Review gate
Require evidence that normal responses serialize once, list defaults are bounded, limit+1 is rejected, audit metadata stays content-free, and no successful response silently exceeds budget.