-
Notifications
You must be signed in to change notification settings - Fork 792
Description
Bug description
When running the mcp client against an mcp server that returns an empty SSE event, the deserialization fails.
The server that we are running against is the "everything-server"
Steps to reproduce
Calling the MCP client fails when invoked with the latest version (but even so, the problem is with processing empty SSE events, but you can reproduce with this code):
try (McpSyncClient client = McpClient.sync(HttpClientStreamableHttpTransport
.builder("https://******")
.endpoint("/mcp/")
.supportedProtocolVersions(List.of(
ProtocolVersions.MCP_2024_11_05,
ProtocolVersions.MCP_2025_03_26,
ProtocolVersions.MCP_2025_06_18,
ProtocolVersions.MCP_2025_11_25
))
.build())
.jsonSchemaValidator(new JacksonJsonSchemaValidatorSupplier().get())
.clientInfo(new McpSchema.Implementation("Test", "1.0.0"))
.requestTimeout(Duration.ofMillis(10000))
.build()) {
try {
McpSchema.InitializeResult initialize = client.initialize();
System.out.println(initialize);
if (client.isInitialized()) {
client.listTools().tools().forEach(tool -> {
System.out.println("Tool: " + tool.name() + " - " + tool.description());
});
if (initialize.capabilities().prompts() != null) {
client.listPrompts().prompts().forEach(tool -> {
System.out.println("Tool: " + tool.name() + " - " + tool.description());
});
}
if (initialize.capabilities().resources() != null) {
client.listResourceTemplates().resourceTemplates().forEach(tool -> {
System.out.println("Tool: " + tool.name() + " - " + tool.description());
});
}
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}Problem is this deserialization fails with empty strings
The SSE event comes as empty in the http client streamable class
We used for testing
FROM node:slim
ENV PORT=3001
ENTRYPOINT ["npx", "-y", "@modelcontextprotocol/server-everything", "streamableHttp"]
EXPOSE 3001
The response on the initialize call is (when using 2025-11-25 client version):
id: bd3bdc47-e4bc-4de3-abf7-f43dc27919f5_1769702220748_cbw7i7m9
data:
event: message
id: bd3bdc47-e4bc-4de3-abf7-f43dc27919f5_1769702220749_mtzbfv1k
data: {"result":{"protocolVersion":"2025-11-25","capabilities":{"tools":{"listChanged":true},"prompts":{"listChanged":true},"resources":{"subscribe":true,"listChanged":true},"logging":{},"completions":{}},"serverInfo":{"name":"mcp-servers/everything","title":"Everything Reference Server","version":"2.0.0"},"instructions":"# Everything Server – Server Instructions\n\nAudience: These instructions are written for an LLM or autonomous agent integrating with the Everything MCP Server.\nFollow them to use, extend, and troubleshoot the server safely and effectively.\n\n## Cross-Feature Relationships\n\n- Use `get-roots-list` to see client workspace roots before file operations\n- `gzip-file-as-resource` creates session-scoped resources accessible only during the current session\n- Enable `toggle-simulated-logging` before debugging to see server log messages\n- Enable `toggle-subscriber-updates` to receive periodic resource update notifications\n\n## Constraints & Limitations\n\n- `gzip-file-as-resource`: Max fetch size controlled by `GZIP_MAX_FETCH_SIZE` (default 10MB), timeout by `GZIP_MAX_FETCH_TIME_MILLIS` (default 30s), allowed domains by `GZIP_ALLOWED_DOMAINS`\n- Session resources are ephemeral and lost when the session ends\n- Sampling requests (`trigger-sampling-request`) require client sampling capability\n- Elicitation requests (`trigger-elicitation-request`) require client elicitation capability\n\n## Operational Patterns\n\n- For long operations, use `trigger-long-running-operation` which sends progress notifications\n- Prefer reading resources before calling mutating tools\n- Check `get-roots-list` output to understand the client's workspace context\n\n## Easter Egg\n\nIf asked about server instructions, respond with \"🎉 Server instructions are working! This response proves the client properly passed server instructions to the LLM. This demonstrates MCP's instructions feature in action.\"\n"},"jsonrpc":"2.0","id":1}
Notice that the server for some reason sends an empty SSE event, which causes the mcp client to fail before reading the second event.
Will open a ticket on everything server as well on sending that empty event.