Skip to content

Commit 77d378d

Browse files
committed
fix: do not advertise 2024-11-05 from Streamable HTTP providers
McpStreamableServerTransportProvider inherited the default protocolVersions() from McpServerTransportProviderBase, which includes 2024-11-05. Streamable HTTP was introduced in 2025-03-26, so a provider of this transport advertised a version whose transport it cannot serve. Override protocolVersions() on the interface rather than on the servlet implementation so every current and future Streamable HTTP provider is covered, mirroring the existing McpStatelessServerTransport default. Fixes gh-750
1 parent 8ee8ccb commit 77d378d

2 files changed

Lines changed: 95 additions & 0 deletions

File tree

mcp-core/src/main/java/io/modelcontextprotocol/spec/McpStreamableServerTransportProvider.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
package io.modelcontextprotocol.spec;
66

7+
import java.util.List;
8+
79
import reactor.core.publisher.Mono;
810

911
/**
@@ -66,4 +68,16 @@ default void close() {
6668
*/
6769
Mono<Void> closeGracefully();
6870

71+
/**
72+
* Streamable HTTP was introduced in protocol version {@code 2025-03-26}, so providers
73+
* of this transport cannot serve {@code 2024-11-05} clients and must not advertise
74+
* that version.
75+
* @return the protocol versions supported by Streamable HTTP transport providers
76+
*/
77+
@Override
78+
default List<String> protocolVersions() {
79+
return List.of(ProtocolVersions.MCP_2025_03_26, ProtocolVersions.MCP_2025_06_18,
80+
ProtocolVersions.MCP_2025_11_25);
81+
}
82+
6983
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/*
2+
* Copyright 2024-2025 the original author or authors.
3+
*/
4+
5+
package io.modelcontextprotocol.spec;
6+
7+
import java.util.List;
8+
9+
import io.modelcontextprotocol.server.McpStatelessServerHandler;
10+
import org.junit.jupiter.api.Test;
11+
import reactor.core.publisher.Mono;
12+
13+
import static org.assertj.core.api.Assertions.assertThat;
14+
15+
/**
16+
* Verifies that each server transport abstraction advertises only the protocol versions
17+
* it can actually serve.
18+
*/
19+
class ServerTransportProtocolVersionsTests {
20+
21+
private static final List<String> STREAMABLE_HTTP_VERSIONS = List.of(ProtocolVersions.MCP_2025_03_26,
22+
ProtocolVersions.MCP_2025_06_18, ProtocolVersions.MCP_2025_11_25);
23+
24+
private static final McpStreamableServerTransportProvider STREAMABLE_PROVIDER = new McpStreamableServerTransportProvider() {
25+
@Override
26+
public void setSessionFactory(McpStreamableServerSession.Factory sessionFactory) {
27+
}
28+
29+
@Override
30+
public Mono<Void> notifyClients(String method, Object params) {
31+
return Mono.empty();
32+
}
33+
34+
@Override
35+
public Mono<Void> closeGracefully() {
36+
return Mono.empty();
37+
}
38+
};
39+
40+
private static final McpStatelessServerTransport STATELESS_TRANSPORT = new McpStatelessServerTransport() {
41+
@Override
42+
public void setMcpHandler(McpStatelessServerHandler mcpHandler) {
43+
}
44+
45+
@Override
46+
public Mono<Void> closeGracefully() {
47+
return Mono.empty();
48+
}
49+
};
50+
51+
@Test
52+
void streamableProviderDoesNotAdvertiseVersionsPredatingStreamableHttp() {
53+
assertThat(STREAMABLE_PROVIDER.protocolVersions()).doesNotContain(ProtocolVersions.MCP_2024_11_05)
54+
.containsExactlyElementsOf(STREAMABLE_HTTP_VERSIONS);
55+
}
56+
57+
@Test
58+
void statelessTransportDoesNotAdvertiseVersionsPredatingStreamableHttp() {
59+
assertThat(STATELESS_TRANSPORT.protocolVersions()).doesNotContain(ProtocolVersions.MCP_2024_11_05)
60+
.containsExactlyElementsOf(STREAMABLE_HTTP_VERSIONS);
61+
}
62+
63+
@Test
64+
void transportsWithoutStreamableHttpConstraintKeepTheFullRange() {
65+
McpServerTransportProviderBase base = new McpServerTransportProviderBase() {
66+
@Override
67+
public Mono<Void> notifyClients(String method, Object params) {
68+
return Mono.empty();
69+
}
70+
71+
@Override
72+
public Mono<Void> closeGracefully() {
73+
return Mono.empty();
74+
}
75+
};
76+
77+
assertThat(base.protocolVersions()).containsExactly(ProtocolVersions.MCP_2024_11_05,
78+
ProtocolVersions.MCP_2025_03_26, ProtocolVersions.MCP_2025_06_18, ProtocolVersions.MCP_2025_11_25);
79+
}
80+
81+
}

0 commit comments

Comments
 (0)