Skip to content

Commit 69509ed

Browse files
committed
fix: Correctly propose protocol version vs. error
Signed-off-by: John McBride <john@zuplo.com>
1 parent 126e97d commit 69509ed

File tree

2 files changed

+29
-54
lines changed

2 files changed

+29
-54
lines changed

src/server/index.ts

Lines changed: 21 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,6 @@ import type {
4242
} from "../mcp/20251125/types.js";
4343
import {
4444
LATEST_PROTOCOL_VERSION,
45-
PROTOCOL_VERSION_2024_10_07,
46-
PROTOCOL_VERSION_2024_11_05,
47-
PROTOCOL_VERSION_2025_03_26,
48-
PROTOCOL_VERSION_2025_06_18,
4945
SUPPORTED_PROTOCOL_VERSIONS,
5046
} from "../mcp/versions.js";
5147
import type { PromptConfig, RegisteredPrompt } from "../prompts/types.js";
@@ -432,37 +428,27 @@ export class MCPServer {
432428
});
433429
}
434430

435-
const protocolVersion = parseResult.data.params.protocolVersion;
436-
437-
switch (protocolVersion) {
438-
case LATEST_PROTOCOL_VERSION:
439-
case PROTOCOL_VERSION_2025_06_18:
440-
case PROTOCOL_VERSION_2025_03_26:
441-
case PROTOCOL_VERSION_2024_11_05:
442-
case PROTOCOL_VERSION_2024_10_07: {
443-
const initResponse: InitializeResult = {
444-
protocolVersion: protocolVersion,
445-
capabilities: this.getCapabilities(),
446-
serverInfo: {
447-
name: this.name,
448-
version: this.version,
449-
},
450-
...(this.instructions ? { instructions: this.instructions } : {}),
451-
};
452-
453-
return newJSONRPCReponse({ id: request.id, result: initResponse });
454-
}
455-
default: {
456-
return newJSONRPCError({
457-
id: request.id,
458-
code: ErrorCode.InvalidParams,
459-
message: `Unsupported protocol version: ${protocolVersion} - supported versions: ${SUPPORTED_PROTOCOL_VERSIONS}`,
460-
data: {
461-
supportedVersions: SUPPORTED_PROTOCOL_VERSIONS,
462-
},
463-
});
464-
}
465-
}
431+
// The MCP spec defines that a server should attempt to negotiate
432+
// the highest protocol version it supports:
433+
// https://modelcontextprotocol.io/specification/2025-11-25/basic/lifecycle#version-negotiation
434+
const requestedVersion = parseResult.data.params.protocolVersion;
435+
const negotiatedVersion = SUPPORTED_PROTOCOL_VERSIONS.includes(
436+
requestedVersion
437+
)
438+
? requestedVersion
439+
: LATEST_PROTOCOL_VERSION;
440+
441+
const initResponse: InitializeResult = {
442+
protocolVersion: negotiatedVersion,
443+
capabilities: this.getCapabilities(),
444+
serverInfo: {
445+
name: this.name,
446+
version: this.version,
447+
},
448+
...(this.instructions ? { instructions: this.instructions } : {}),
449+
};
450+
451+
return newJSONRPCReponse({ id: request.id, result: initResponse });
466452
}
467453

468454
private async handleToolListRequest(

src/server/initialization.test.ts

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -165,9 +165,7 @@ describe("MCPServer", () => {
165165
}
166166
});
167167

168-
it("handles ill-supported MCP protocolVersion", async () => {
169-
// should get an error JSON RPC 2 message if protocolVersion is something
170-
// totally untenable like "2001-01-01"
168+
it("negotiates unsupported protocolVersion to server's latest", async () => {
171169
const serverName = "example ping server";
172170
const serverVersion = "0.0.0";
173171
const server = new MCPServer({
@@ -179,7 +177,7 @@ describe("MCPServer", () => {
179177
id: 0,
180178
method: "initialize",
181179
params: {
182-
protocolVersion: "2001-01-01",
180+
protocolVersion: "2099-01-01",
183181
capabilities: {
184182
sampling: {},
185183
roots: {
@@ -199,22 +197,13 @@ describe("MCPServer", () => {
199197
expect(response.jsonrpc).toBe("2.0");
200198
expect(response.id).toBe(0);
201199

202-
if ("error" in response) {
203-
expect(response.error.code).toBe(-32602);
204-
expect(response.error.message).toContain(
205-
"Unsupported protocol version"
206-
);
207-
expect(response.error.data).toEqual({
208-
supportedVersions: [
209-
"2025-11-25",
210-
"2025-06-18",
211-
"2025-03-26",
212-
"2024-11-05",
213-
"2024-10-07",
214-
],
215-
});
200+
if ("result" in response) {
201+
const result = response.result as InitializeResult;
202+
expect(result.protocolVersion).toBe(LATEST_PROTOCOL_VERSION);
203+
expect(result.serverInfo.name).toBe(serverName);
204+
expect(result.serverInfo.version).toBe(serverVersion);
216205
} else {
217-
fail("Expected an error response, got a result");
206+
fail("Expected a result response, got an error");
218207
}
219208
});
220209
});

0 commit comments

Comments
 (0)