Skip to content
Merged
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
2 changes: 1 addition & 1 deletion Sources/MCP/Client/Client.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
4 changes: 2 additions & 2 deletions Sources/MCP/Server/Tools.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down
6 changes: 3 additions & 3 deletions Tests/MCPTests/RoundtripTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down Expand Up @@ -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")])
}

Expand Down
20 changes: 17 additions & 3 deletions Tests/MCPTests/ToolTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand All @@ -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")
Expand Down