Skip to content

Fix Streamable HTTP WebClient transport to accept SSE frames without event field - #5783

Closed
ZhangDT-sky wants to merge 2 commits into
spring-projects:mainfrom
ZhangDT-sky:GH-5780
Closed

Fix Streamable HTTP WebClient transport to accept SSE frames without event field#5783
ZhangDT-sky wants to merge 2 commits into
spring-projects:mainfrom
ZhangDT-sky:GH-5780

Conversation

@ZhangDT-sky

Copy link
Copy Markdown
Contributor

Summary

This PR fixes SSE parsing in WebClientStreamableHttpTransport for Streamable HTTP.

Per SSE semantics, when event: is omitted, the event type defaults to message.
Previously, the transport only accepted frames where event == "message" explicitly, so valid data:-only frames could be dropped.

This could cause JSON-RPC responses (including initialize) to be ignored and lead to startup/timeout failures.

Root Cause

WebClientStreamableHttpTransport.parse(...) only parsed SSE frames when:

  • event.event().equals("message")

If event.event() was null (or empty), the frame was ignored.

Changes

  • Updated message-event detection in WebClientStreamableHttpTransport to treat all of the following as message events:
  1. event == null
  2. event == ""
  3. event == "message"
  • Added integration test:
    WebClientStreamableHttpTransportSseParsingIT#shouldParseSseEventWithoutEventFieldAsMessage

The test serves text/event-stream with only data: (no event:) and verifies the JSON-RPC response is parsed and delivered.

Why This Is Safe

  • Scope is limited to SSE event-type filtering in Streamable HTTP WebClient transport.
  • Existing explicit event: message behavior is unchanged.
  • Fix aligns behavior with standard SSE semantics and improves interoperability with spec-compliant servers.

Verification

  • Added dedicated regression test for data:-only SSE frames.
  • Local targeted test passed for the new scenario.

Fixes #5780

Signed-off-by: ZhangDT-sky <485918776@qq.com>
Signed-off-by: ZhangDT-sky <485918776@qq.com>
@Kehrlann

Kehrlann commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

For reference, here's the Java SDK equivalent modelcontextprotocol/java-sdk#913

@Kehrlann Kehrlann added this to the 2.0.1 milestone Aug 3, 2026

@Kehrlann Kehrlann left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for your contribution.

I have one open question before we merge this.

Comment on lines +507 to +510
if (data == null || data.isEmpty()) {
logger.debug("Ignoring SSE message event with empty data: {}", event);
return Tuples.of(Optional.empty(), List.of());
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is untested; what's the use-case?


private static boolean isMessageEvent(@Nullable String eventType) {
// Per SSE semantics, missing/blank event type defaults to "message".
return eventType == null || eventType.isEmpty() || MESSAGE_EVENT_TYPE.equals(eventType);

@Kehrlann Kehrlann Aug 4, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return eventType == null || eventType.isEmpty() || MESSAGE_EVENT_TYPE.equals(eventType);
return !StringUtils.hasLength(eventType) || MESSAGE_EVENT_TYPE.equals(eventType);

@Kehrlann Kehrlann closed this in db7544a Aug 6, 2026
@Kehrlann

Kehrlann commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Merged as part of db7544a. Thank you for your contribution!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working mcp

Projects

None yet

Development

Successfully merging this pull request may close these issues.

WebClientStreamableHttpTransport drops valid SSE frames when event: is omitted (should default to message)

3 participants