Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions Sources/MCP/Client/Client.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
37 changes: 37 additions & 0 deletions Tests/MCPTests/ClientTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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<Initialize>.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)
}
}