Follow-up from grid#56 review (nerdalert): grid#56 landed bounds on the tool
catalog we persist to status.discoveredTools (name length + entry count),
but not on the raw HTTP response rmcp/reqwest buffer into memory before
parsing it into a tools/list result.
Problem
operator::resources::mcp_probe::run_probe_session calls into rmcp's
Streamable HTTP client (rmcp::transport::streamable_http_client). Its SSE
path honors a configured max_sse_event_size limit, but the plain-JSON
tools/list response path
(response.json::<ServerJsonRpcMessage>() in
rmcp::transport::common::reqwest::streamable_http_client) reads the entire
response body into memory with no size cap in the rmcp version this
workspace depends on (3.1.2).
A fast MCP endpoint returning an implausibly large JSON body could exhaust
operator memory before parsing ever completes, even though the outer probe
timeout (PROBE_TIMEOUT) still bounds elapsed time.
Options
- Upstream fix: check whether/when
rmcp adds a body-size cap for the
JSON response path (may already be tracked upstream -- worth checking
their issue tracker before doing anything else here).
- Bypass rmcp's session API: bound bytes ourselves via a raw
reqwest
streamed read (bytes_stream() + running total check) before handing off
to JSON parsing. This means not using rmcp::ServiceExt::serve()/
list_tools() for this call, which undermines this module's "reuse
rmcp's transport, don't reimplement MCP protocol detection" design intent
(see the module doc comment).
- Accept the gap for now: this is a controller-initiated discovery probe
against operator-declared endpoints, not a request-time data-plane path,
and the operator process itself has its own resource limits. Revisit if/
when rmcp closes the gap upstream.
Not blocking grid#56
The count/name-length bounds that landed in grid#56 already narrow the
practical blast radius once a response is read; this issue is specifically
about bounding the read itself.
Follow-up from grid#56 review (nerdalert): grid#56 landed bounds on the tool
catalog we persist to
status.discoveredTools(name length + entry count),but not on the raw HTTP response
rmcp/reqwestbuffer into memory beforeparsing it into a
tools/listresult.Problem
operator::resources::mcp_probe::run_probe_sessioncalls intormcp'sStreamable HTTP client (
rmcp::transport::streamable_http_client). Its SSEpath honors a configured
max_sse_event_sizelimit, but the plain-JSONtools/listresponse path(
response.json::<ServerJsonRpcMessage>()inrmcp::transport::common::reqwest::streamable_http_client) reads the entireresponse body into memory with no size cap in the
rmcpversion thisworkspace depends on (3.1.2).
A fast MCP endpoint returning an implausibly large JSON body could exhaust
operator memory before parsing ever completes, even though the outer probe
timeout (
PROBE_TIMEOUT) still bounds elapsed time.Options
rmcpadds a body-size cap for theJSON response path (may already be tracked upstream -- worth checking
their issue tracker before doing anything else here).
reqweststreamed read (
bytes_stream()+ running total check) before handing offto JSON parsing. This means not using
rmcp::ServiceExt::serve()/list_tools()for this call, which undermines this module's "reusermcp's transport, don't reimplement MCP protocol detection" design intent
(see the module doc comment).
against operator-declared endpoints, not a request-time data-plane path,
and the operator process itself has its own resource limits. Revisit if/
when
rmcpcloses the gap upstream.Not blocking grid#56
The count/name-length bounds that landed in grid#56 already narrow the
practical blast radius once a response is read; this issue is specifically
about bounding the read itself.