From ed4f8e7d8acc23627eedf87b233d77c1588988d3 Mon Sep 17 00:00:00 2001 From: JermaineHua Date: Tue, 17 Jun 2025 22:39:20 +0800 Subject: [PATCH 1/2] Standard header name used in mcp Signed-off-by: JermaineHua --- .../transport/WebClientStreamableHttpTransport.java | 11 ++++++----- .../java/io/modelcontextprotocol/spec/McpSchema.java | 12 ++++++++++++ 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/mcp-spring/mcp-spring-webflux/src/main/java/io/modelcontextprotocol/client/transport/WebClientStreamableHttpTransport.java b/mcp-spring/mcp-spring-webflux/src/main/java/io/modelcontextprotocol/client/transport/WebClientStreamableHttpTransport.java index e7b7c8ee9..81df0a9f8 100644 --- a/mcp-spring/mcp-spring-webflux/src/main/java/io/modelcontextprotocol/client/transport/WebClientStreamableHttpTransport.java +++ b/mcp-spring/mcp-spring-webflux/src/main/java/io/modelcontextprotocol/client/transport/WebClientStreamableHttpTransport.java @@ -35,6 +35,8 @@ import java.util.function.Function; import java.util.function.Supplier; +import static io.modelcontextprotocol.spec.McpSchema.Headers.MCP_SESSION_ID; + /** * An implementation of the Streamable HTTP protocol as defined by the * 2025-03-26 version of the MCP specification. @@ -129,7 +131,7 @@ private DefaultMcpTransportSession createTransportSession() { DefaultMcpTransportSession transportSession = this.activeSession.get(); return transportSession.sessionId().isEmpty() ? Mono.empty() : webClient.delete().uri(this.endpoint).headers(httpHeaders -> { - httpHeaders.add("mcp-session-id", transportSession.sessionId().get()); + httpHeaders.add(MCP_SESSION_ID, transportSession.sessionId().get()); }).retrieve().toBodilessEntity().doOnError(e -> logger.info("Got response {}", e)).then(); }; return new DefaultMcpTransportSession(onClose); @@ -185,7 +187,7 @@ private Mono reconnect(McpTransportStream stream) { .uri(this.endpoint) .accept(MediaType.TEXT_EVENT_STREAM) .headers(httpHeaders -> { - transportSession.sessionId().ifPresent(id -> httpHeaders.add("mcp-session-id", id)); + transportSession.sessionId().ifPresent(id -> httpHeaders.add(MCP_SESSION_ID, id)); if (stream != null) { stream.lastId().ifPresent(id -> httpHeaders.add("last-event-id", id)); } @@ -243,12 +245,11 @@ public Mono sendMessage(McpSchema.JSONRPCMessage message) { .uri(this.endpoint) .accept(MediaType.TEXT_EVENT_STREAM, MediaType.APPLICATION_JSON) .headers(httpHeaders -> { - transportSession.sessionId().ifPresent(id -> httpHeaders.add("mcp-session-id", id)); + transportSession.sessionId().ifPresent(id -> httpHeaders.add(MCP_SESSION_ID, id)); }) .bodyValue(message) .exchangeToFlux(response -> { - if (transportSession - .markInitialized(response.headers().asHttpHeaders().getFirst("mcp-session-id"))) { + if (transportSession.markInitialized(response.headers().asHttpHeaders().getFirst(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(); diff --git a/mcp/src/main/java/io/modelcontextprotocol/spec/McpSchema.java b/mcp/src/main/java/io/modelcontextprotocol/spec/McpSchema.java index e21d53c80..dbc4adba9 100644 --- a/mcp/src/main/java/io/modelcontextprotocol/spec/McpSchema.java +++ b/mcp/src/main/java/io/modelcontextprotocol/spec/McpSchema.java @@ -134,6 +134,18 @@ public static final class ErrorCodes { } + // --------------------------- + // JSON-RPC Protocol Headers + // --------------------------- + /** + * Standard header name used in MCP JSON-RPC request and responses. + */ + public static final class Headers { + + public static final String MCP_SESSION_ID = "Mcp-Session-Id"; + + } + public sealed interface Request permits InitializeRequest, CallToolRequest, CreateMessageRequest, ElicitRequest, CompleteRequest, GetPromptRequest { From df10fd42b83aeb321eb12a3bf7542aca508be91d Mon Sep 17 00:00:00 2001 From: JermaineHua Date: Thu, 19 Jun 2025 00:33:22 +0800 Subject: [PATCH 2/2] Standard last-event-id request header name --- .../transport/WebClientStreamableHttpTransport.java | 3 ++- .../java/io/modelcontextprotocol/spec/McpSchema.java | 10 ++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/mcp-spring/mcp-spring-webflux/src/main/java/io/modelcontextprotocol/client/transport/WebClientStreamableHttpTransport.java b/mcp-spring/mcp-spring-webflux/src/main/java/io/modelcontextprotocol/client/transport/WebClientStreamableHttpTransport.java index 9016c5629..3c582813e 100644 --- a/mcp-spring/mcp-spring-webflux/src/main/java/io/modelcontextprotocol/client/transport/WebClientStreamableHttpTransport.java +++ b/mcp-spring/mcp-spring-webflux/src/main/java/io/modelcontextprotocol/client/transport/WebClientStreamableHttpTransport.java @@ -35,6 +35,7 @@ import java.util.function.Function; import java.util.function.Supplier; +import static io.modelcontextprotocol.spec.McpSchema.Headers.LAST_EVENT_ID; import static io.modelcontextprotocol.spec.McpSchema.Headers.MCP_SESSION_ID; /** @@ -190,7 +191,7 @@ private Mono reconnect(McpTransportStream stream) { .headers(httpHeaders -> { transportSession.sessionId().ifPresent(id -> httpHeaders.add(MCP_SESSION_ID, id)); if (stream != null) { - stream.lastId().ifPresent(id -> httpHeaders.add("last-event-id", id)); + stream.lastId().ifPresent(id -> httpHeaders.add(LAST_EVENT_ID, id)); } }) .exchangeToFlux(response -> { diff --git a/mcp/src/main/java/io/modelcontextprotocol/spec/McpSchema.java b/mcp/src/main/java/io/modelcontextprotocol/spec/McpSchema.java index ddf7c82e7..2959cf10e 100644 --- a/mcp/src/main/java/io/modelcontextprotocol/spec/McpSchema.java +++ b/mcp/src/main/java/io/modelcontextprotocol/spec/McpSchema.java @@ -142,8 +142,18 @@ public static final class ErrorCodes { */ public static final class Headers { + /** + * The Model Context Protocol (MCP) session ID header name. + */ public static final String MCP_SESSION_ID = "Mcp-Session-Id"; + /** + * The Last-Event-ID HTTP request header reports an EventSource object's last + * event ID string to the server when the user agent is to reestablish the + * connection. + */ + public static final String LAST_EVENT_ID = "Last-Event-ID"; + } public sealed interface Request permits InitializeRequest, CallToolRequest, CreateMessageRequest, ElicitRequest,