Is your feature request related to a problem? Please describe.
Applications wrapping mcp.StreamableHTTPHandler can observe HTTP lifecycle data, but cannot safely observe JSON-RPC/MCP envelope metadata that the SDK already parses internally. To log method, request ID, batch size, notification-only status, or the active session, middleware must currently read and restore req.Body and parse the envelope a second time. That duplicates SDK parsing, can disagree with accepted SDK semantics, adds buffering, and risks retaining request arguments.
This blocks protocol-aware transport observability in generated framework integrations such as CaliLuke/loom-mcp#271. I confirmed that v1.6.1 and v1.7.0-pre.2 expose no parsed-envelope hook on StreamableHTTPOptions.
Describe the solution you'd like
Expose a concurrency-safe hook from the streamable HTTP transport after readBatch has parsed an incoming POST, using the already parsed representation. A safe summary type would be preferable to exposing params/results and could include:
- whether the input was a batch and its envelope count;
- method for a single envelope, or sorted unique methods for a batch;
- request ID for a single request, without synthesizing IDs for notifications;
- whether a single envelope is a notification, or every batch envelope is a notification;
- request
Mcp-Session-Id, and the negotiated session ID for successful initialization when available.
The hook should not cause any additional req.Body reads, replacement, or buffering, and should not expose or retain params, authorization data, or response payloads. Parse failures can remain represented by the existing HTTP outcome when no safe summary exists.
An API shape such as an optional StreamableHTTPOptions callback receiving *http.Request plus an immutable request summary would let outer middleware emit start events before parsing and enrich its terminal event after ServeHTTP returns. The exact shape is flexible; the key contract is access to the SDK's accepted parsed envelope without reparsing the body.
Describe alternatives you've considered
- Reading/restoring the body in middleware: rejected because it duplicates parsing and buffering.
- Inferring methods from URLs or handler callbacks: MCP uses one endpoint and this misses notifications, batches, malformed input, and unknown methods.
- Logging inside each typed MCP handler: incomplete because it misses protocol-level failures, notifications without handlers, batches, and initialization/session metadata.
Additional context
The consumer needs metadata only for structured transport diagnostics. Request arguments, headers, cookies, authorization data, and response bodies must remain redacted.
Is your feature request related to a problem? Please describe.
Applications wrapping
mcp.StreamableHTTPHandlercan observe HTTP lifecycle data, but cannot safely observe JSON-RPC/MCP envelope metadata that the SDK already parses internally. To log method, request ID, batch size, notification-only status, or the active session, middleware must currently read and restorereq.Bodyand parse the envelope a second time. That duplicates SDK parsing, can disagree with accepted SDK semantics, adds buffering, and risks retaining request arguments.This blocks protocol-aware transport observability in generated framework integrations such as CaliLuke/loom-mcp#271. I confirmed that v1.6.1 and v1.7.0-pre.2 expose no parsed-envelope hook on
StreamableHTTPOptions.Describe the solution you'd like
Expose a concurrency-safe hook from the streamable HTTP transport after
readBatchhas parsed an incoming POST, using the already parsed representation. A safe summary type would be preferable to exposing params/results and could include:Mcp-Session-Id, and the negotiated session ID for successful initialization when available.The hook should not cause any additional
req.Bodyreads, replacement, or buffering, and should not expose or retain params, authorization data, or response payloads. Parse failures can remain represented by the existing HTTP outcome when no safe summary exists.An API shape such as an optional
StreamableHTTPOptionscallback receiving*http.Requestplus an immutable request summary would let outer middleware emit start events before parsing and enrich its terminal event afterServeHTTPreturns. The exact shape is flexible; the key contract is access to the SDK's accepted parsed envelope without reparsing the body.Describe alternatives you've considered
Additional context
The consumer needs metadata only for structured transport diagnostics. Request arguments, headers, cookies, authorization data, and response bodies must remain redacted.