diff --git a/src/server/streamableHttp.test.ts b/src/server/streamableHttp.test.ts index 51cc4c47..f00721e2 100644 --- a/src/server/streamableHttp.test.ts +++ b/src/server/streamableHttp.test.ts @@ -788,7 +788,7 @@ describe("StreamableHTTPServerTransport", () => { expect(response.status).toBe(400); const errorData = await response.json(); - expectErrorResponse(errorData, -32000, /Bad Request: Unsupported protocol version/); + expectErrorResponse(errorData, -32000, /Bad Request: Unsupported protocol version \(supported versions: .+\)/); }); it("should accept but warn when protocol version differs from negotiated version", async () => { @@ -835,7 +835,7 @@ describe("StreamableHTTPServerTransport", () => { expect(response.status).toBe(400); const errorData = await response.json(); - expectErrorResponse(errorData, -32000, /Bad Request: Unsupported protocol version/); + expectErrorResponse(errorData, -32000, /Bad Request: Unsupported protocol version \(supported versions: .+\)/); }); it("should handle protocol version validation for DELETE requests", async () => { @@ -852,7 +852,7 @@ describe("StreamableHTTPServerTransport", () => { expect(response.status).toBe(400); const errorData = await response.json(); - expectErrorResponse(errorData, -32000, /Bad Request: Unsupported protocol version/); + expectErrorResponse(errorData, -32000, /Bad Request: Unsupported protocol version \(supported versions: .+\)/); }); }); }); diff --git a/src/server/streamableHttp.ts b/src/server/streamableHttp.ts index b387f2ff..c6010fd3 100644 --- a/src/server/streamableHttp.ts +++ b/src/server/streamableHttp.ts @@ -1,6 +1,6 @@ import { IncomingMessage, ServerResponse } from "node:http"; import { Transport } from "../shared/transport.js"; -import { isInitializeRequest, isJSONRPCError, isJSONRPCRequest, isJSONRPCResponse, JSONRPCMessage, JSONRPCMessageSchema, RequestId, SUPPORTED_PROTOCOL_VERSIONS } from "../types.js"; +import { isInitializeRequest, isJSONRPCError, isJSONRPCRequest, isJSONRPCResponse, JSONRPCMessage, JSONRPCMessageSchema, RequestId, SUPPORTED_PROTOCOL_VERSIONS, DEFAULT_NEGOTIATED_PROTOCOL_VERSION } from "../types.js"; import getRawBody from "raw-body"; import contentType from "content-type"; import { randomUUID } from "node:crypto"; @@ -538,17 +538,12 @@ export class StreamableHTTPServerTransport implements Transport { } private validateProtocolVersion(req: IncomingMessage, res: ServerResponse): boolean { - let protocolVersion = req.headers["mcp-protocol-version"]; + let protocolVersion = req.headers["mcp-protocol-version"] ?? DEFAULT_NEGOTIATED_PROTOCOL_VERSION; if (Array.isArray(protocolVersion)) { protocolVersion = protocolVersion[protocolVersion.length - 1]; } - - if (protocolVersion == null || protocolVersion === undefined) { - // If the protocol version is not set, we assume the client supports the implicit protocol version - return true; - } - - protocolVersion = String(protocolVersion).trim(); + + if (this.protocolVersion !== undefined && this.protocolVersion !== protocolVersion) { console.warn(`Request has header with protocol version ${protocolVersion}, but version previously negotiated is ${this.protocolVersion}.`); } @@ -557,7 +552,7 @@ export class StreamableHTTPServerTransport implements Transport { jsonrpc: "2.0", error: { code: -32000, - message: 'Bad Request: Unsupported protocol version' + message: `Bad Request: Unsupported protocol version (supported versions: ${SUPPORTED_PROTOCOL_VERSIONS.join(", ")})` }, id: null })); diff --git a/src/types.ts b/src/types.ts index ae25848e..4bf87ef6 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,6 +1,7 @@ import { z, ZodTypeAny } from "zod"; export const LATEST_PROTOCOL_VERSION = "2025-03-26"; +export const DEFAULT_NEGOTIATED_PROTOCOL_VERSION = "2025-03-26"; export const SUPPORTED_PROTOCOL_VERSIONS = [ LATEST_PROTOCOL_VERSION, "2024-11-05",