diff --git a/Sources/MCP/Base/Messages.swift b/Sources/MCP/Base/Messages.swift index c0d9649a..0c6caf2f 100644 --- a/Sources/MCP/Base/Messages.swift +++ b/Sources/MCP/Base/Messages.swift @@ -161,12 +161,11 @@ final class TypedRequestHandler: RequestHandlerBox, @unchecked Sendab let decoder = JSONDecoder() // Create a concrete request from the type-erased one - let data = try encoder.encode(request.params) - let params = try decoder.decode(M.Parameters.self, from: data) - let typedRequest = Request(id: request.id, method: M.name, params: params) + let data = try encoder.encode(request) + let request = try decoder.decode(Request.self, from: data) // Handle with concrete type - let response = try await _handle(typedRequest) + let response = try await _handle(request) // Convert result to AnyMethod response switch response.result { diff --git a/Tests/MCPTests/ToolTests.swift b/Tests/MCPTests/ToolTests.swift index a9a03fc2..0ab0c503 100644 --- a/Tests/MCPTests/ToolTests.swift +++ b/Tests/MCPTests/ToolTests.swift @@ -111,7 +111,7 @@ struct ToolTests { let emptyParams = ListTools.Parameters() #expect(emptyParams.cursor == nil) } - + @Test("ListTools request decoding with omitted params") func testListToolsRequestDecodingWithOmittedParams() throws { // Test decoding when params field is omitted @@ -126,7 +126,7 @@ struct ToolTests { #expect(decoded.id == "test-id") #expect(decoded.method == ListTools.name) } - + @Test("ListTools request decoding with null params") func testListToolsRequestDecodingWithNullParams() throws { // Test decoding when params field is null @@ -205,4 +205,37 @@ struct ToolTests { func testToolListChangedNotification() throws { #expect(ToolListChangedNotification.name == "notifications/tools/list_changed") } + + @Test("ListTools handler invocation without params") + func testListToolsHandlerWithoutParams() async throws { + let jsonString = """ + {"jsonrpc":"2.0","id":1,"method":"tools/list"} + """ + let jsonData = jsonString.data(using: .utf8)! + + let anyRequest = try JSONDecoder().decode(AnyRequest.self, from: jsonData) + + let handler = TypedRequestHandler { request in + #expect(request.method == ListTools.name) + #expect(request.id == 1) + #expect(request.params.cursor == nil) + + let testTool = Tool(name: "test_tool", description: "Test tool for verification") + return ListTools.response(id: request.id, result: ListTools.Result(tools: [testTool])) + } + + let response = try await handler(anyRequest) + + if case .success(let value) = response.result { + let encoder = JSONEncoder() + let decoder = JSONDecoder() + let data = try encoder.encode(value) + let result = try decoder.decode(ListTools.Result.self, from: data) + + #expect(result.tools.count == 1) + #expect(result.tools[0].name == "test_tool") + } else { + #expect(Bool(false), "Expected success result") + } + } }