diff --git a/Sources/MCP/Client/Client.swift b/Sources/MCP/Client/Client.swift index 453a8fdc..be32df76 100644 --- a/Sources/MCP/Client/Client.swift +++ b/Sources/MCP/Client/Client.swift @@ -344,7 +344,7 @@ public actor Client { } public func callTool(name: String, arguments: [String: Value]? = nil) async throws -> ( - content: [Tool.Content], isError: Bool + content: [Tool.Content], isError: Bool? ) { _ = try checkCapability(\.tools, "Tools") let request = CallTool.request(.init(name: name, arguments: arguments)) diff --git a/Sources/MCP/Server/Tools.swift b/Sources/MCP/Server/Tools.swift index aacb282b..aaa07492 100644 --- a/Sources/MCP/Server/Tools.swift +++ b/Sources/MCP/Server/Tools.swift @@ -154,9 +154,9 @@ public enum CallTool: Method { public struct Result: Hashable, Codable, Sendable { public let content: [Tool.Content] - public let isError: Bool + public let isError: Bool? - public init(content: [Tool.Content], isError: Bool) { + public init(content: [Tool.Content], isError: Bool? = nil) { self.content = content self.isError = isError } diff --git a/Tests/MCPTests/RoundtripTests.swift b/Tests/MCPTests/RoundtripTests.swift index ef314de4..014ca85b 100644 --- a/Tests/MCPTests/RoundtripTests.swift +++ b/Tests/MCPTests/RoundtripTests.swift @@ -52,13 +52,13 @@ struct RoundtripTests { } guard let a = request.arguments?["a"]?.intValue, - let b = request.arguments?["b"]?.intValue + let b = request.arguments?["b"]?.intValue else { return CallTool.Result( content: [.text("Did not receive valid arguments")], isError: true) } - return CallTool.Result(content: [.text("\(a + b)")], isError: false) + return CallTool.Result(content: [.text("\(a + b)")]) } let client = Client(name: "TestClient", version: "1.0") @@ -96,7 +96,7 @@ struct RoundtripTests { let callToolTask = Task { let result = try await client.callTool(name: "add", arguments: ["a": 1, "b": 2]) - #expect(result.isError == false) + #expect(result.isError == nil) #expect(result.content == [.text("3")]) } diff --git a/Tests/MCPTests/ToolTests.swift b/Tests/MCPTests/ToolTests.swift index da8bd9ae..a29ae670 100644 --- a/Tests/MCPTests/ToolTests.swift +++ b/Tests/MCPTests/ToolTests.swift @@ -139,16 +139,16 @@ struct ToolTests { #expect(params.arguments?["param2"] == .int(42)) } - @Test("CallTool result validation") + @Test("CallTool success result validation") func testCallToolResult() throws { let content = [ Tool.Content.text("Result 1"), Tool.Content.text("Result 2"), ] - let result = CallTool.Result(content: content, isError: false) + let result = CallTool.Result(content: content) #expect(result.content.count == 2) - #expect(result.isError == false) + #expect(result.isError == nil) if case .text(let text) = result.content[0] { #expect(text == "Result 1") @@ -157,6 +157,20 @@ struct ToolTests { } } + @Test("CallTool error result validation") + func testCallToolErrorResult() throws { + let errorContent = [Tool.Content.text("Error message")] + let errorResult = CallTool.Result(content: errorContent, isError: true) + #expect(errorResult.content.count == 1) + #expect(errorResult.isError == true) + + if case .text(let text) = errorResult.content[0] { + #expect(text == "Error message") + } else { + #expect(Bool(false), "Expected error text content") + } + } + @Test("ToolListChanged notification name validation") func testToolListChangedNotification() throws { #expect(ToolListChangedNotification.name == "notifications/tools/list_changed")