pi-mono/packages
robopipi[bot] 4a8b60bc33
fix(mcp): apply maxMessageBytes to Streamable HTTP JSON responses (#11749)
The Streamable HTTP transport checked `maxMessageBytes` on SSE replies
but not on `application/json` replies. The JSON branch called
`response.json()`, which buffered and parsed the whole body with no size
check. A server could send an oversized message as plain JSON, and the
same content sent as SSE would have been rejected.

A new helper, `readBodyText(response, maxBytes)`, reads a body through a
reader and decodes each chunk as it arrives. Once the body goes over
`maxBytes`, it cancels the rest and returns only the first `maxBytes`
bytes, marked as truncated. Counting during the read also covers chunked
replies that have no `Content-Length`. `TextDecoder` strips a leading
BOM, as `response.json()` does.

Two places use it:
- JSON replies: if the body is truncated, `send()` throws `MCP JSON
response exceeds N bytes` (default 16 MiB). Bodies within the limit are
parsed as before.
- HTTP error bodies (`checkResponse`): before, `response.text()` read
the whole error body and then cut it to 8 KiB. A huge or endless error
body was fully buffered, or never finished. Now only the 8 KiB excerpt
is read and the rest is cancelled. The excerpt is decoded from the kept
bytes only, so it does not keep the whole body alive (#9265).

Testing (`packages/mcp/test/streamable-http.test.ts`):
- `applies maxMessageBytes to JSON responses`: with a 512-byte limit, a
small reply is accepted and a 2 KB reply is rejected. Fails without the
fix.
- `decodes JSON responses split inside a BOM and a multi-byte
character`: the body arrives one byte per chunk.
- `reads only an excerpt of HTTP error bodies and cancels the rest`: an
endless 500 body yields an 8 KiB excerpt and is cancelled. Without the
fix it never finishes.
- All MCP tests pass; `npm run check` passes.

Fixes #11335

Requested by @petrroll

---------

Co-authored-by: triagent <triagent@localhost>
Co-authored-by: Petr Houška <houskape@gmail.com>
2026-11-03 21:44:24 +01:00
..
agent Anthropic message threads (#11545) 2026-11-03 14:07:57 +01:00
ai Anthropic message threads (#11545) 2026-11-03 14:07:57 +01:00
chord feat(chord): messages and languages in the app kit (i18n) 2026-11-03 20:25:53 +00:00
codemode Add [Unreleased] section for next cycle 2026-11-02 11:38:21 +01:00
coding-agent fix(coding-agent): process idle ctx.shutdown() requests in RPC mode (#11746) 2026-11-03 21:27:14 +01:00
durable feat(chord): Chord v2 is the package's root 2026-11-02 22:36:55 +00:00
env fix(env): kill what a process program left running when it exits 2026-11-03 14:17:21 +01:00
evals Release v1.5.0 2026-11-02 11:38:21 +01:00
mcp fix(mcp): apply maxMessageBytes to Streamable HTTP JSON responses (#11749) 2026-11-03 21:44:24 +01:00
schema Add [Unreleased] section for next cycle 2026-11-02 11:38:21 +01:00
telemetry Add [Unreleased] section for next cycle 2026-11-02 11:38:21 +01:00
tui Add [Unreleased] section for next cycle 2026-11-02 11:38:21 +01:00