Skip to content

mcp: expose parsed streamable HTTP request summary hook #1076

Description

@CaliLuke

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Fields

    No fields configured for Enhancement.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions