Skip to content

Commit 4517a23

Browse files
committed
fix: ignore empty SSE events
Allows "priming" events for new SSE streams, which the TS SDK has implemented on the latest protocol version (per SEP-1699).
1 parent abc48b4 commit 4517a23

File tree

1 file changed

+23
-3
lines changed

1 file changed

+23
-3
lines changed

mcp-core/src/main/java/io/modelcontextprotocol/client/transport/HttpClientStreamableHttpTransport.java

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -295,12 +295,23 @@ private Mono<Disposable> reconnect(McpTransportStream<Disposable> stream) {
295295
if (statusCode >= 200 && statusCode < 300) {
296296

297297
if (MESSAGE_EVENT_TYPE.equals(responseEvent.sseEvent().event())) {
298+
String data = responseEvent.sseEvent().data();
299+
// Per 2025-11-25 spec (SEP-1699), servers may
300+
// send SSE events
301+
// with empty data to prime the client for
302+
// reconnection.
303+
// Skip these events as they contain no JSON-RPC
304+
// message.
305+
if (data == null || data.isBlank()) {
306+
logger.debug("Skipping SSE event with empty data (stream primer)");
307+
return Flux.empty();
308+
}
298309
try {
299310
// We don't support batching ATM and probably
300311
// won't since the next version considers
301312
// removing it.
302-
McpSchema.JSONRPCMessage message = McpSchema.deserializeJsonRpcMessage(
303-
this.jsonMapper, responseEvent.sseEvent().data());
313+
McpSchema.JSONRPCMessage message = McpSchema
314+
.deserializeJsonRpcMessage(this.jsonMapper, data);
304315

305316
Tuple2<Optional<String>, Iterable<McpSchema.JSONRPCMessage>> idWithMessages = Tuples
306317
.of(Optional.ofNullable(responseEvent.sseEvent().id()),
@@ -503,13 +514,22 @@ public Mono<Void> sendMessage(McpSchema.JSONRPCMessage sentMessage) {
503514
else if (contentType.contains(TEXT_EVENT_STREAM)) {
504515
return Flux.just(((ResponseSubscribers.SseResponseEvent) responseEvent).sseEvent())
505516
.flatMap(sseEvent -> {
517+
String data = sseEvent.data();
518+
// Per 2025-11-25 spec (SEP-1699), servers may send SSE
519+
// events
520+
// with empty data to prime the client for reconnection.
521+
// Skip these events as they contain no JSON-RPC message.
522+
if (data == null || data.isBlank()) {
523+
logger.debug("Skipping SSE event with empty data (stream primer)");
524+
return Flux.empty();
525+
}
506526
try {
507527
// We don't support batching ATM and probably
508528
// won't
509529
// since the
510530
// next version considers removing it.
511531
McpSchema.JSONRPCMessage message = McpSchema
512-
.deserializeJsonRpcMessage(this.jsonMapper, sseEvent.data());
532+
.deserializeJsonRpcMessage(this.jsonMapper, data);
513533

514534
Tuple2<Optional<String>, Iterable<McpSchema.JSONRPCMessage>> idWithMessages = Tuples
515535
.of(Optional.ofNullable(sseEvent.id()), List.of(message));

0 commit comments

Comments
 (0)