diff --git a/Sources/MCP/Client/Client.swift b/Sources/MCP/Client/Client.swift index bf07d092..0474158e 100644 --- a/Sources/MCP/Client/Client.swift +++ b/Sources/MCP/Client/Client.swift @@ -637,6 +637,14 @@ public actor Client { let result = try await send(request).value + // If the client does not support the version in the server's response, + // it should disconnect. + guard Version.supported.contains(result.protocolVersion) else { + await disconnect() + throw MCPError.internalError( + "Server's protocol version is not supported: \(result.protocolVersion)") + } + self.serverCapabilities = result.capabilities self.serverVersion = result.protocolVersion self.instructions = result.instructions diff --git a/Tests/MCPTests/ClientTests.swift b/Tests/MCPTests/ClientTests.swift index 8a2882a4..416b250e 100644 --- a/Tests/MCPTests/ClientTests.swift +++ b/Tests/MCPTests/ClientTests.swift @@ -772,4 +772,41 @@ struct ClientTests { await client.disconnect() } + + @Test("Connect fails when the server answers with an unsupported protocol version") + func testConnectRejectsUnsupportedProtocolVersion() async throws { + let transport = MockTransport() + let client = Client(name: "TestClient", version: "1.0") + + let responder = Task { + while true { + if let first = await transport.sentMessages.first, + let request = try? JSONDecoder().decode( + Request.self, from: Data(first.utf8)) + { + try await transport.queue( + response: Initialize.response( + id: request.id, + result: .init( + protocolVersion: "1999-01-01", + capabilities: .init(), + serverInfo: .init(name: "TestServer", version: "1.0") + ) + )) + return + } + try await Task.sleep(for: .milliseconds(5)) + } + } + + await #expect(throws: MCPError.self) { + try await client.connect(transport: transport) + } + responder.cancel() + + // Only the initialize request went out: no notifications/initialized. + let sent = await transport.sentMessages + #expect(sent.count == 1) + #expect(await transport.isConnected == false) + } }