feat: implement MCP protocol version per transport support (#404)
- Add protocolVersion() method to transport and transport provider interfaces and implementations - Replace hardcoded HTTP header strings with HttpHeaders constants - Update protocol versions to be transport-specific rather than global - Deprecate McpSchema.LATEST_PROTOCOL_VERSION in favor of transport-specific versions - Standardize header names: MCP-Protocol-Version, mcp-session-id, last-event-id - Update clients and servers to use transport.protocolVersion() for initialization - Refactor tests to use transport-specific protocol versions - Include MCP-Protocol-Version header in all GET/POST/DELETE requests - Update WebClientStreamableHttpTransport, WebFluxSseClientTransport, HttpClientSseClientTransport, and HttpClientStreamableHttpTransport Related to #398 , #363 , #250 Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com>
This commit is contained in:
parent
67de84b300
commit
9d58621918
27 changed files with 169 additions and 34 deletions
|
|
@ -23,6 +23,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
|||
|
||||
import io.modelcontextprotocol.spec.DefaultMcpTransportSession;
|
||||
import io.modelcontextprotocol.spec.DefaultMcpTransportStream;
|
||||
import io.modelcontextprotocol.spec.HttpHeaders;
|
||||
import io.modelcontextprotocol.spec.McpClientTransport;
|
||||
import io.modelcontextprotocol.spec.McpError;
|
||||
import io.modelcontextprotocol.spec.McpSchema;
|
||||
|
|
@ -66,6 +67,8 @@ public class WebClientStreamableHttpTransport implements McpClientTransport {
|
|||
|
||||
private static final Logger logger = LoggerFactory.getLogger(WebClientStreamableHttpTransport.class);
|
||||
|
||||
private static final String MCP_PROTOCOL_VERSION = "2025-03-26";
|
||||
|
||||
private static final String DEFAULT_ENDPOINT = "/mcp";
|
||||
|
||||
/**
|
||||
|
|
@ -103,6 +106,11 @@ public class WebClientStreamableHttpTransport implements McpClientTransport {
|
|||
this.activeSession.set(createTransportSession());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String protocolVersion() {
|
||||
return MCP_PROTOCOL_VERSION;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a stateful builder for creating {@link WebClientStreamableHttpTransport}
|
||||
* instances.
|
||||
|
|
@ -128,12 +136,20 @@ public class WebClientStreamableHttpTransport implements McpClientTransport {
|
|||
|
||||
private DefaultMcpTransportSession createTransportSession() {
|
||||
Function<String, Publisher<Void>> onClose = sessionId -> sessionId == null ? Mono.empty()
|
||||
: webClient.delete().uri(this.endpoint).headers(httpHeaders -> {
|
||||
httpHeaders.add("mcp-session-id", sessionId);
|
||||
}).retrieve().toBodilessEntity().onErrorComplete(e -> {
|
||||
logger.warn("Got error when closing transport", e);
|
||||
return true;
|
||||
}).then();
|
||||
: webClient.delete()
|
||||
.uri(this.endpoint)
|
||||
.header(HttpHeaders.PROTOCOL_VERSION, MCP_PROTOCOL_VERSION)
|
||||
.headers(httpHeaders -> {
|
||||
httpHeaders.add(HttpHeaders.MCP_SESSION_ID, sessionId);
|
||||
httpHeaders.add(HttpHeaders.PROTOCOL_VERSION, MCP_PROTOCOL_VERSION);
|
||||
})
|
||||
.retrieve()
|
||||
.toBodilessEntity()
|
||||
.onErrorComplete(e -> {
|
||||
logger.warn("Got error when closing transport", e);
|
||||
return true;
|
||||
})
|
||||
.then();
|
||||
return new DefaultMcpTransportSession(onClose);
|
||||
}
|
||||
|
||||
|
|
@ -186,10 +202,11 @@ public class WebClientStreamableHttpTransport implements McpClientTransport {
|
|||
Disposable connection = webClient.get()
|
||||
.uri(this.endpoint)
|
||||
.accept(MediaType.TEXT_EVENT_STREAM)
|
||||
.header(HttpHeaders.PROTOCOL_VERSION, MCP_PROTOCOL_VERSION)
|
||||
.headers(httpHeaders -> {
|
||||
transportSession.sessionId().ifPresent(id -> httpHeaders.add("mcp-session-id", id));
|
||||
transportSession.sessionId().ifPresent(id -> httpHeaders.add(HttpHeaders.MCP_SESSION_ID, id));
|
||||
if (stream != null) {
|
||||
stream.lastId().ifPresent(id -> httpHeaders.add("last-event-id", id));
|
||||
stream.lastId().ifPresent(id -> httpHeaders.add(HttpHeaders.LAST_EVENT_ID, id));
|
||||
}
|
||||
})
|
||||
.exchangeToFlux(response -> {
|
||||
|
|
@ -246,13 +263,14 @@ public class WebClientStreamableHttpTransport implements McpClientTransport {
|
|||
Disposable connection = webClient.post()
|
||||
.uri(this.endpoint)
|
||||
.accept(MediaType.APPLICATION_JSON, MediaType.TEXT_EVENT_STREAM)
|
||||
.header(HttpHeaders.PROTOCOL_VERSION, MCP_PROTOCOL_VERSION)
|
||||
.headers(httpHeaders -> {
|
||||
transportSession.sessionId().ifPresent(id -> httpHeaders.add("mcp-session-id", id));
|
||||
transportSession.sessionId().ifPresent(id -> httpHeaders.add(HttpHeaders.MCP_SESSION_ID, id));
|
||||
})
|
||||
.bodyValue(message)
|
||||
.exchangeToFlux(response -> {
|
||||
if (transportSession
|
||||
.markInitialized(response.headers().asHttpHeaders().getFirst("mcp-session-id"))) {
|
||||
.markInitialized(response.headers().asHttpHeaders().getFirst(HttpHeaders.MCP_SESSION_ID))) {
|
||||
// Once we have a session, we try to open an async stream for
|
||||
// the server to send notifications and requests out-of-band.
|
||||
reconnect(null).contextWrite(sink.contextView()).subscribe();
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ import java.util.function.Function;
|
|||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
import io.modelcontextprotocol.spec.HttpHeaders;
|
||||
import io.modelcontextprotocol.spec.McpClientTransport;
|
||||
import io.modelcontextprotocol.spec.McpError;
|
||||
import io.modelcontextprotocol.spec.McpSchema;
|
||||
|
|
@ -62,6 +64,8 @@ public class WebFluxSseClientTransport implements McpClientTransport {
|
|||
|
||||
private static final Logger logger = LoggerFactory.getLogger(WebFluxSseClientTransport.class);
|
||||
|
||||
private static final String MCP_PROTOCOL_VERSION = "2024-11-05";
|
||||
|
||||
/**
|
||||
* Event type for JSON-RPC messages received through the SSE connection. The server
|
||||
* sends messages with this event type to transmit JSON-RPC protocol data.
|
||||
|
|
@ -166,6 +170,11 @@ public class WebFluxSseClientTransport implements McpClientTransport {
|
|||
this.sseEndpoint = sseEndpoint;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String protocolVersion() {
|
||||
return MCP_PROTOCOL_VERSION;
|
||||
}
|
||||
|
||||
/**
|
||||
* Establishes a connection to the MCP server using Server-Sent Events (SSE). This
|
||||
* method initiates the SSE connection and sets up the message processing pipeline.
|
||||
|
|
@ -250,6 +259,7 @@ public class WebFluxSseClientTransport implements McpClientTransport {
|
|||
return webClient.post()
|
||||
.uri(messageEndpointUri)
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.header(HttpHeaders.PROTOCOL_VERSION, MCP_PROTOCOL_VERSION)
|
||||
.bodyValue(jsonText)
|
||||
.retrieve()
|
||||
.toBodilessEntity()
|
||||
|
|
@ -282,6 +292,7 @@ public class WebFluxSseClientTransport implements McpClientTransport {
|
|||
.get()
|
||||
.uri(this.sseEndpoint)
|
||||
.accept(MediaType.TEXT_EVENT_STREAM)
|
||||
.header(HttpHeaders.PROTOCOL_VERSION, MCP_PROTOCOL_VERSION)
|
||||
.retrieve()
|
||||
.bodyToFlux(SSE_TYPE)
|
||||
.retryWhen(Retry.from(retrySignal -> retrySignal.handle(inboundRetryHandler)));
|
||||
|
|
|
|||
|
|
@ -79,6 +79,8 @@ public class WebFluxSseServerTransportProvider implements McpServerTransportProv
|
|||
*/
|
||||
public static final String ENDPOINT_EVENT_TYPE = "endpoint";
|
||||
|
||||
private static final String MCP_PROTOCOL_VERSION = "2025-06-18";
|
||||
|
||||
/**
|
||||
* Default SSE endpoint path as specified by the MCP transport specification.
|
||||
*/
|
||||
|
|
@ -212,6 +214,11 @@ public class WebFluxSseServerTransportProvider implements McpServerTransportProv
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String protocolVersion() {
|
||||
return "2024-11-05";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSessionFactory(McpServerSession.Factory sessionFactory) {
|
||||
this.sessionFactory = sessionFactory;
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@ import reactor.core.publisher.Mono;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* Implementation of a WebFlux based {@link McpStatelessServerTransport}.
|
||||
|
|
|
|||
|
|
@ -95,6 +95,11 @@ public class WebFluxStreamableServerTransportProvider implements McpStreamableSe
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String protocolVersion() {
|
||||
return "2025-03-26";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSessionFactory(McpStreamableServerSession.Factory sessionFactory) {
|
||||
this.sessionFactory = sessionFactory;
|
||||
|
|
|
|||
|
|
@ -209,6 +209,11 @@ public class WebMvcSseServerTransportProvider implements McpServerTransportProvi
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String protocolVersion() {
|
||||
return "2024-11-05";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSessionFactory(McpServerSession.Factory sessionFactory) {
|
||||
this.sessionFactory = sessionFactory;
|
||||
|
|
|
|||
|
|
@ -147,6 +147,11 @@ public class WebMvcStreamableServerTransportProvider implements McpStreamableSer
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String protocolVersion() {
|
||||
return "2025-03-26";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSessionFactory(McpStreamableServerSession.Factory sessionFactory) {
|
||||
this.sessionFactory = sessionFactory;
|
||||
|
|
|
|||
|
|
@ -91,8 +91,15 @@ class WebMvcSseCustomContextPathTests {
|
|||
@Bean
|
||||
public WebMvcSseServerTransportProvider webMvcSseServerTransportProvider() {
|
||||
|
||||
return new WebMvcSseServerTransportProvider(new ObjectMapper(), CUSTOM_CONTEXT_PATH, MESSAGE_ENDPOINT,
|
||||
WebMvcSseServerTransportProvider.DEFAULT_SSE_ENDPOINT);
|
||||
return WebMvcSseServerTransportProvider.builder()
|
||||
.objectMapper(new ObjectMapper())
|
||||
.baseUrl(CUSTOM_CONTEXT_PATH)
|
||||
.messageEndpoint(MESSAGE_ENDPOINT)
|
||||
.sseEndpoint(WebMvcSseServerTransportProvider.DEFAULT_SSE_ENDPOINT)
|
||||
.build();
|
||||
// return new WebMvcSseServerTransportProvider(new ObjectMapper(),
|
||||
// CUSTOM_CONTEXT_PATH, MESSAGE_ENDPOINT,
|
||||
// WebMvcSseServerTransportProvider.DEFAULT_SSE_ENDPOINT);
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
|
|
|||
|
|
@ -272,9 +272,8 @@ public class McpAsyncClient {
|
|||
asyncProgressNotificationHandler(progressConsumersFinal));
|
||||
|
||||
this.initializer = new LifecycleInitializer(clientCapabilities, clientInfo,
|
||||
List.of(McpSchema.LATEST_PROTOCOL_VERSION), initializationTimeout,
|
||||
ctx -> new McpClientSession(requestTimeout, transport, requestHandlers, notificationHandlers,
|
||||
con -> con.contextWrite(ctx)));
|
||||
List.of(transport.protocolVersion()), initializationTimeout, ctx -> new McpClientSession(requestTimeout,
|
||||
transport, requestHandlers, notificationHandlers, con -> con.contextWrite(ctx)));
|
||||
this.transport.setExceptionHandler(this.initializer::handleException);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -61,6 +61,10 @@ import reactor.core.publisher.Sinks;
|
|||
*/
|
||||
public class HttpClientSseClientTransport implements McpClientTransport {
|
||||
|
||||
private static final String MCP_PROTOCOL_VERSION = "2024-11-05";
|
||||
|
||||
private static final String MCP_PROTOCOL_VERSION_HEADER_NAME = "MCP-Protocol-Version";
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(HttpClientSseClientTransport.class);
|
||||
|
||||
/** SSE event type for JSON-RPC messages */
|
||||
|
|
@ -211,6 +215,11 @@ public class HttpClientSseClientTransport implements McpClientTransport {
|
|||
this.httpRequestCustomizer = httpRequestCustomizer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String protocolVersion() {
|
||||
return MCP_PROTOCOL_VERSION;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new builder for {@link HttpClientSseClientTransport}.
|
||||
* @param baseUri the base URI of the MCP server
|
||||
|
|
@ -391,6 +400,7 @@ public class HttpClientSseClientTransport implements McpClientTransport {
|
|||
.uri(uri)
|
||||
.header("Accept", "text/event-stream")
|
||||
.header("Cache-Control", "no-cache")
|
||||
.header(MCP_PROTOCOL_VERSION_HEADER_NAME, MCP_PROTOCOL_VERSION)
|
||||
.GET();
|
||||
return Mono.from(this.httpRequestCustomizer.customize(builder, "GET", uri, null));
|
||||
}).flatMap(requestBuilder -> Mono.create(sink -> {
|
||||
|
|
@ -516,7 +526,10 @@ public class HttpClientSseClientTransport implements McpClientTransport {
|
|||
private Mono<HttpResponse<String>> sendHttpPost(final String endpoint, final String body) {
|
||||
final URI requestUri = Utils.resolveUri(baseUri, endpoint);
|
||||
return Mono.defer(() -> {
|
||||
var builder = this.requestBuilder.copy().uri(requestUri).POST(HttpRequest.BodyPublishers.ofString(body));
|
||||
var builder = this.requestBuilder.copy()
|
||||
.uri(requestUri)
|
||||
.header(MCP_PROTOCOL_VERSION_HEADER_NAME, MCP_PROTOCOL_VERSION)
|
||||
.POST(HttpRequest.BodyPublishers.ofString(body));
|
||||
return Mono.from(this.httpRequestCustomizer.customize(builder, "POST", requestUri, body));
|
||||
}).flatMap(customizedBuilder -> {
|
||||
var request = customizedBuilder.build();
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
|||
import io.modelcontextprotocol.client.transport.ResponseSubscribers.ResponseEvent;
|
||||
import io.modelcontextprotocol.spec.DefaultMcpTransportSession;
|
||||
import io.modelcontextprotocol.spec.DefaultMcpTransportStream;
|
||||
import io.modelcontextprotocol.spec.HttpHeaders;
|
||||
import io.modelcontextprotocol.spec.McpClientTransport;
|
||||
import io.modelcontextprotocol.spec.McpError;
|
||||
import io.modelcontextprotocol.spec.McpSchema;
|
||||
|
|
@ -72,6 +73,8 @@ public class HttpClientStreamableHttpTransport implements McpClientTransport {
|
|||
|
||||
private static final Logger logger = LoggerFactory.getLogger(HttpClientStreamableHttpTransport.class);
|
||||
|
||||
private static final String MCP_PROTOCOL_VERSION = "2025-03-26";
|
||||
|
||||
private static final String DEFAULT_ENDPOINT = "/mcp";
|
||||
|
||||
/**
|
||||
|
|
@ -131,6 +134,11 @@ public class HttpClientStreamableHttpTransport implements McpClientTransport {
|
|||
this.httpRequestCustomizer = httpRequestCustomizer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String protocolVersion() {
|
||||
return MCP_PROTOCOL_VERSION;
|
||||
}
|
||||
|
||||
public static Builder builder(String baseUri) {
|
||||
return new Builder(baseUri);
|
||||
}
|
||||
|
|
@ -157,12 +165,14 @@ public class HttpClientStreamableHttpTransport implements McpClientTransport {
|
|||
}
|
||||
|
||||
private Publisher<Void> createDelete(String sessionId) {
|
||||
|
||||
var uri = Utils.resolveUri(this.baseUri, this.endpoint);
|
||||
return Mono.defer(() -> {
|
||||
var builder = this.requestBuilder.copy()
|
||||
.uri(uri)
|
||||
.header("Cache-Control", "no-cache")
|
||||
.header("mcp-session-id", sessionId)
|
||||
.header(HttpHeaders.MCP_SESSION_ID, sessionId)
|
||||
.header(HttpHeaders.PROTOCOL_VERSION, MCP_PROTOCOL_VERSION)
|
||||
.DELETE();
|
||||
return Mono.from(this.httpRequestCustomizer.customize(builder, "DELETE", uri, null));
|
||||
}).flatMap(requestBuilder -> {
|
||||
|
|
@ -221,16 +231,18 @@ public class HttpClientStreamableHttpTransport implements McpClientTransport {
|
|||
HttpRequest.Builder requestBuilder = this.requestBuilder.copy();
|
||||
|
||||
if (transportSession != null && transportSession.sessionId().isPresent()) {
|
||||
requestBuilder = requestBuilder.header("mcp-session-id", transportSession.sessionId().get());
|
||||
requestBuilder = requestBuilder.header(HttpHeaders.MCP_SESSION_ID,
|
||||
transportSession.sessionId().get());
|
||||
}
|
||||
|
||||
if (stream != null && stream.lastId().isPresent()) {
|
||||
requestBuilder = requestBuilder.header("last-event-id", stream.lastId().get());
|
||||
requestBuilder = requestBuilder.header(HttpHeaders.LAST_EVENT_ID, stream.lastId().get());
|
||||
}
|
||||
|
||||
var builder = requestBuilder.uri(uri)
|
||||
.header("Accept", TEXT_EVENT_STREAM)
|
||||
.header("Cache-Control", "no-cache")
|
||||
.header(HttpHeaders.PROTOCOL_VERSION, MCP_PROTOCOL_VERSION)
|
||||
.GET();
|
||||
return Mono.from(this.httpRequestCustomizer.customize(builder, "GET", uri, null));
|
||||
})
|
||||
|
|
@ -377,13 +389,15 @@ public class HttpClientStreamableHttpTransport implements McpClientTransport {
|
|||
HttpRequest.Builder requestBuilder = this.requestBuilder.copy();
|
||||
|
||||
if (transportSession != null && transportSession.sessionId().isPresent()) {
|
||||
requestBuilder = requestBuilder.header("mcp-session-id", transportSession.sessionId().get());
|
||||
requestBuilder = requestBuilder.header(HttpHeaders.MCP_SESSION_ID,
|
||||
transportSession.sessionId().get());
|
||||
}
|
||||
|
||||
var builder = requestBuilder.uri(uri)
|
||||
.header("Accept", APPLICATION_JSON + ", " + TEXT_EVENT_STREAM)
|
||||
.header("Content-Type", APPLICATION_JSON)
|
||||
.header("Cache-Control", "no-cache")
|
||||
.header(HttpHeaders.PROTOCOL_VERSION, MCP_PROTOCOL_VERSION)
|
||||
.POST(HttpRequest.BodyPublishers.ofString(jsonBody));
|
||||
return Mono.from(this.httpRequestCustomizer.customize(builder, "GET", uri, jsonBody));
|
||||
}).flatMapMany(requestBuilder -> Flux.<ResponseEvent>create(responseEventSink -> {
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ public class McpAsyncServer {
|
|||
|
||||
private final ConcurrentHashMap<McpSchema.CompleteReference, McpServerFeatures.AsyncCompletionSpecification> completions = new ConcurrentHashMap<>();
|
||||
|
||||
private List<String> protocolVersions = List.of(McpSchema.LATEST_PROTOCOL_VERSION);
|
||||
private List<String> protocolVersions;
|
||||
|
||||
private McpUriTemplateManagerFactory uriTemplateManagerFactory = new DeafaultMcpUriTemplateManagerFactory();
|
||||
|
||||
|
|
@ -145,6 +145,8 @@ public class McpAsyncServer {
|
|||
Map<String, McpRequestHandler<?>> requestHandlers = prepareRequestHandlers();
|
||||
Map<String, McpNotificationHandler> notificationHandlers = prepareNotificationHandlers(features);
|
||||
|
||||
this.protocolVersions = List.of(mcpTransportProvider.protocolVersion());
|
||||
|
||||
mcpTransportProvider.setSessionFactory(transport -> new McpServerSession(UUID.randomUUID().toString(),
|
||||
requestTimeout, transport, this::asyncInitializeRequestHandler, requestHandlers, notificationHandlers));
|
||||
}
|
||||
|
|
@ -168,6 +170,8 @@ public class McpAsyncServer {
|
|||
Map<String, McpRequestHandler<?>> requestHandlers = prepareRequestHandlers();
|
||||
Map<String, McpNotificationHandler> notificationHandlers = prepareNotificationHandlers(features);
|
||||
|
||||
this.protocolVersions = List.of(mcpTransportProvider.protocolVersion());
|
||||
|
||||
mcpTransportProvider.setSessionFactory(new DefaultMcpStreamableServerSessionFactory(requestTimeout,
|
||||
this::asyncInitializeRequestHandler, requestHandlers, notificationHandlers));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ public class McpStatelessAsyncServer {
|
|||
|
||||
private final ConcurrentHashMap<McpSchema.CompleteReference, McpStatelessServerFeatures.AsyncCompletionSpecification> completions = new ConcurrentHashMap<>();
|
||||
|
||||
private List<String> protocolVersions = List.of(McpSchema.LATEST_PROTOCOL_VERSION);
|
||||
private List<String> protocolVersions;
|
||||
|
||||
private McpUriTemplateManagerFactory uriTemplateManagerFactory = new DeafaultMcpUriTemplateManagerFactory();
|
||||
|
||||
|
|
@ -118,6 +118,8 @@ public class McpStatelessAsyncServer {
|
|||
requestHandlers.put(McpSchema.METHOD_COMPLETION_COMPLETE, completionCompleteRequestHandler());
|
||||
}
|
||||
|
||||
this.protocolVersions = List.of(mcpTransport.protocolVersion());
|
||||
|
||||
McpStatelessServerHandler handler = new DefaultMcpStatelessServerHandler(requestHandlers, Map.of());
|
||||
mcpTransport.setMcpHandler(handler);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -178,6 +178,11 @@ public class HttpServletSseServerTransportProvider extends HttpServlet implement
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String protocolVersion() {
|
||||
return "2024-11-05";
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new HttpServletSseServerTransportProvider instance with the default SSE
|
||||
* endpoint.
|
||||
|
|
|
|||
|
|
@ -154,6 +154,11 @@ public class HttpServletStreamableServerTransportProvider extends HttpServlet
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String protocolVersion() {
|
||||
return "2025-03-26";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSessionFactory(McpStreamableServerSession.Factory sessionFactory) {
|
||||
this.sessionFactory = sessionFactory;
|
||||
|
|
|
|||
|
|
@ -88,6 +88,11 @@ public class StdioServerTransportProvider implements McpServerTransportProvider
|
|||
this.outputStream = outputStream;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String protocolVersion() {
|
||||
return "2024-11-05";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSessionFactory(McpServerSession.Factory sessionFactory) {
|
||||
// Create a single session for the stdio connection
|
||||
|
|
|
|||
|
|
@ -17,4 +17,9 @@ public interface HttpHeaders {
|
|||
*/
|
||||
String LAST_EVENT_ID = "last-event-id";
|
||||
|
||||
/**
|
||||
* Identifies the MCP protocol version.
|
||||
*/
|
||||
String PROTOCOL_VERSION = "MCP-Protocol-Version";
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ public final class McpSchema {
|
|||
private McpSchema() {
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static final String LATEST_PROTOCOL_VERSION = "2025-03-26";
|
||||
|
||||
public static final String JSONRPC_VERSION = "2.0";
|
||||
|
|
|
|||
|
|
@ -55,4 +55,12 @@ public interface McpServerTransportProviderBase {
|
|||
*/
|
||||
Mono<Void> closeGracefully();
|
||||
|
||||
/**
|
||||
* Returns the protocol version supported by this transport provider.
|
||||
* @return the protocol version as a string
|
||||
*/
|
||||
default String protocolVersion() {
|
||||
return "2024-11-05";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,4 +22,8 @@ public interface McpStatelessServerTransport {
|
|||
*/
|
||||
Mono<Void> closeGracefully();
|
||||
|
||||
default String protocolVersion() {
|
||||
return "2025-03-26";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue