Skip to content

Commit a2a0044

Browse files
authored
Remove nonstandard read and list capabilities for resources (#15)
* Remove nonstandard read and list capabilities for server * Update README
1 parent dccaa3a commit a2a0044

File tree

4 files changed

+74
-14
lines changed

4 files changed

+74
-14
lines changed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,11 @@ let server = Server(
5151
name: "MyServer",
5252
version: "1.0.0",
5353
capabilities: .init(
54+
prompts: .init(),
5455
resources: .init(
55-
list: true,
56-
read: true,
5756
subscribe: true
58-
)
57+
),
58+
tools: .init()
5959
)
6060
)
6161

Sources/MCP/Client/Client.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,7 @@ public actor Client {
313313
// MARK: - Resources
314314

315315
public func readResource(uri: String) async throws -> [Resource.Content] {
316-
_ = try checkCapability(\.resources?.read, "Resource reading")
316+
_ = try checkCapability(\.resources, "Resources")
317317
let request = ReadResource.request(.init(uri: uri))
318318
let result = try await send(request)
319319
return result.contents
@@ -322,7 +322,7 @@ public actor Client {
322322
public func listResources(cursor: String? = nil) async throws -> (
323323
resources: [Resource], nextCursor: String?
324324
) {
325-
_ = try checkCapability(\.resources?.list, "Resource listing")
325+
_ = try checkCapability(\.resources, "Resources")
326326
let request = ListResources.request(.init(cursor: cursor))
327327
let result = try await send(request)
328328
return (resources: result.resources, nextCursor: result.nextCursor)

Sources/MCP/Server/Server.swift

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,23 +44,15 @@ public actor Server {
4444
public struct Capabilities: Hashable, Codable, Sendable {
4545
/// Resources capabilities
4646
public struct Resources: Hashable, Codable, Sendable {
47-
/// Whether the list of resources has changed
48-
public var list: Bool?
49-
/// Whether the resource can be read
50-
public var read: Bool?
5147
/// Whether the resource can be subscribed to
5248
public var subscribe: Bool?
5349
/// Whether the list of resources has changed
5450
public var listChanged: Bool?
5551

5652
public init(
57-
list: Bool? = nil,
58-
read: Bool? = nil,
5953
subscribe: Bool? = nil,
6054
listChanged: Bool? = nil
6155
) {
62-
self.list = list
63-
self.read = read
6456
self.subscribe = subscribe
6557
self.listChanged = listChanged
6658
}

Tests/MCPTests/RoundtripTests.swift

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,11 @@ struct RoundtripTests {
3333
let server = Server(
3434
name: "TestServer",
3535
version: "1.0.0",
36-
capabilities: .init(prompts: .init(), tools: .init())
36+
capabilities: .init(
37+
prompts: .init(),
38+
resources: .init(),
39+
tools: .init()
40+
)
3741
)
3842
await server.withMethodHandler(ListTools.self) { _ in
3943
return ListTools.Result(tools: [
@@ -61,6 +65,32 @@ struct RoundtripTests {
6165
return CallTool.Result(content: [.text("\(a + b)")])
6266
}
6367

68+
// Add resource handlers to server
69+
await server.withMethodHandler(ListResources.self) { _ in
70+
return ListResources.Result(resources: [
71+
Resource(
72+
name: "Example Text",
73+
uri: "test://example.txt",
74+
description: "A test resource",
75+
mimeType: "text/plain"
76+
),
77+
Resource(
78+
name: "Test Data",
79+
uri: "test://data.json",
80+
description: "JSON test data",
81+
mimeType: "application/json"
82+
),
83+
])
84+
}
85+
86+
await server.withMethodHandler(ReadResource.self) { request in
87+
guard request.uri == "test://example.txt" else {
88+
return ReadResource.Result(contents: [.text("Resource not found", uri: request.uri)]
89+
)
90+
}
91+
return ReadResource.Result(contents: [.text("Hello, World!", uri: request.uri)])
92+
}
93+
6494
let client = Client(name: "TestClient", version: "1.0")
6595

6696
try await server.start(transport: serverTransport)
@@ -104,15 +134,53 @@ struct RoundtripTests {
104134
group.addTask {
105135
try await Task.sleep(for: .seconds(1))
106136
listToolsTask.cancel()
137+
callToolTask.cancel()
107138
throw CancellationError()
108139
}
140+
group.addTask {
141+
try await listToolsTask.value
142+
}
109143
group.addTask {
110144
try await callToolTask.value
111145
}
112146
try await group.next()
113147
group.cancelAll()
114148
}
115149

150+
// Test listing resources
151+
let listResourcesTask = Task {
152+
let result = try await client.listResources()
153+
#expect(result.resources.count == 2)
154+
#expect(result.resources[0].uri == "test://example.txt")
155+
#expect(result.resources[0].name == "Example Text")
156+
#expect(result.resources[1].uri == "test://data.json")
157+
#expect(result.resources[1].name == "Test Data")
158+
}
159+
160+
// Test reading a resource
161+
let readResourceTask = Task {
162+
let result = try await client.readResource(uri: "test://example.txt")
163+
#expect(result.count == 1)
164+
#expect(result[0] == .text("Hello, World!", uri: "test://example.txt"))
165+
}
166+
167+
try await withThrowingTaskGroup(of: Void.self) { group in
168+
group.addTask {
169+
try await Task.sleep(for: .seconds(1))
170+
listResourcesTask.cancel()
171+
readResourceTask.cancel()
172+
throw CancellationError()
173+
}
174+
group.addTask {
175+
try await listResourcesTask.value
176+
}
177+
group.addTask {
178+
try await readResourceTask.value
179+
}
180+
try await group.next()
181+
group.cancelAll()
182+
}
183+
116184
await server.stop()
117185
await client.disconnect()
118186
try? clientToServerRead.close()

0 commit comments

Comments
 (0)