v5.5.6 - MCP Clients Receive the Streaming SSE Response
MCP clients now receive the SSE response instead of hanging
A focused fix release for the MCP Streamable HTTP transport. The SSE path
framed its events with custom event names, which every conforming MCP client
discards — so a streaming tools/call produced no progress and never
delivered its result, leaving the client blocked until its own timeout. All
frames now carry the protocol's message event name and are delivered.
Changes
- FIXED: The request-scoped SSE stream emitted
event: progressfor
notifications/progressandevent: responsefor the terminating JSON-RPC
response. MCP Streamable HTTP defines a single SSE event type for JSON-RPC
traffic, and clients match only the defaultmessagetype, so both frame
kinds were silently dropped on arrival. Tool progress reported through
agent.report_progressnever surfaced, and — the failure that made
streaming unusable — the final response never reached the client, which
blocked until it timed out on its own. Both sites now emitevent: message,
as the server-to-client GET notification stream and thelist_changed
notifications already did. - CHANGED: Clients discriminate frames from the JSON-RPC envelope rather
than the SSE event name —methodpresent marks a notification,idplus
result/errormarks the response — which is how the protocol intends the
stream to be read and what conforming clients already do.
Behavior Notes
- This is a wire-format change on
Parse::Agent::MCPRackAppwhen constructed
withstreaming: true. Non-streaming JSON responses, transport-level error
shapes, status codes, and every event payload are byte-identical to 5.5.5;
only the SSEevent:line changed. - Deployments that worked around this with middleware rewriting the event name
on the way out should remove it. With both sides corrected, a rewrite of
responsetomessageis a harmless no-op, but a rewrite in the opposite
direction will reintroduce the hang. - Custom clients that were written against this SDK specifically and match on
event: progressorevent: responseneed to matchmessageand branch on
the envelope instead. - The standalone
Parse::Agent::MCPServeris unaffected. It runs on WEBrick,
which buffers whole response bodies, so it constructs the Rack app with
streaming: falseand never emitted SSE frames.
Wire Format
# 5.5.5 — discarded by clients matching the default `message` type
event: progress
data: {"jsonrpc":"2.0","method":"notifications/progress","params":{...}}
event: response
data: {"jsonrpc":"2.0","id":7,"result":{...}}
# 5.5.6 — delivered; the envelope identifies the frame
event: message
data: {"jsonrpc":"2.0","method":"notifications/progress","params":{...}}
event: message
data: {"jsonrpc":"2.0","id":7,"result":{...}}
Commit: 7c29bb4
Author: Adrian Curtin
Date: July 25, 2026