@@ -22,8 +22,8 @@ final class DiagnosticCLITests: XCTestCase {
2222 let runtime = AgentdMCPRuntimeStub ( )
2323 let server = AgentdMCPServer ( runtime: runtime)
2424
25- let initialize = try await server. handle (
26- jsonData (
25+ let initialize = await server. handle (
26+ try jsonData (
2727 [
2828 " jsonrpc " : " 2.0 " ,
2929 " id " : 1 ,
@@ -41,8 +41,8 @@ final class DiagnosticCLITests: XCTestCase {
4141 let initializeResult = try XCTUnwrap ( initializeRoot [ " result " ] as? [ String : Any ] )
4242 XCTAssertEqual ( initializeResult [ " protocolVersion " ] as? String , " 2025-06-18 " )
4343
44- let tools = try await server. handle (
45- jsonData ( [ " jsonrpc " : " 2.0 " , " id " : " tools " , " method " : " tools/list " ] ) )
44+ let tools = await server. handle (
45+ try jsonData ( [ " jsonrpc " : " 2.0 " , " id " : " tools " , " method " : " tools/list " ] ) )
4646 let toolsRoot = try jsonObject ( tools)
4747 let toolsResult = try XCTUnwrap ( toolsRoot [ " result " ] as? [ String : Any ] )
4848 let toolList = try XCTUnwrap ( toolsResult [ " tools " ] as? [ [ String : Any ] ] )
@@ -85,8 +85,8 @@ final class DiagnosticCLITests: XCTestCase {
8585 )
8686 let server = AgentdMCPServer ( runtime: runtime)
8787
88- let response = try await server. handle (
89- jsonData ( [
88+ let response = await server. handle (
89+ try jsonData ( [
9090 " jsonrpc " : " 2.0 " ,
9191 " id " : " activity " ,
9292 " method " : " tools/call " ,
@@ -123,8 +123,8 @@ final class DiagnosticCLITests: XCTestCase {
123123 )
124124 let server = AgentdMCPServer ( runtime: runtime)
125125
126- let response = try await server. handle (
127- jsonData ( [
126+ let response = await server. handle (
127+ try jsonData ( [
128128 " jsonrpc " : " 2.0 " ,
129129 " id " : " diag " ,
130130 " method " : " tools/call " ,
@@ -173,8 +173,8 @@ final class DiagnosticCLITests: XCTestCase {
173173 )
174174 let server = AgentdMCPServer ( runtime: runtime)
175175
176- let response = try await server. handle (
177- jsonData ( [
176+ let response = await server. handle (
177+ try jsonData ( [
178178 " jsonrpc " : " 2.0 " ,
179179 " id " : " snapshot " ,
180180 " method " : " tools/call " ,
@@ -193,6 +193,65 @@ final class DiagnosticCLITests: XCTestCase {
193193 XCTAssertEqual ( privacy [ " deniedPathPrefixCount " ] as? Int , 2 )
194194 }
195195
196+ func testMcpInvalidRequestsReturnJsonRpcErrorResponses( ) async throws {
197+ let server = AgentdMCPServer ( runtime: AgentdMCPRuntimeStub ( ) )
198+
199+ let missingMethod = await server. handle (
200+ try jsonData ( [ " jsonrpc " : " 2.0 " , " id " : 1 , " params " : [ : ] ] )
201+ )
202+ let invalidRoot = try jsonObject ( missingMethod)
203+ let invalidError = try XCTUnwrap ( invalidRoot [ " error " ] as? [ String : Any ] )
204+ XCTAssertTrue ( invalidRoot [ " id " ] is NSNull )
205+ XCTAssertEqual ( invalidError [ " code " ] as? Int , - 32600 )
206+ XCTAssertEqual ( invalidError [ " message " ] as? String , " invalid MCP JSON-RPC request " )
207+
208+ let malformed = await server. handle ( Data ( " { " . utf8) )
209+ let malformedRoot = try jsonObject ( malformed)
210+ let malformedError = try XCTUnwrap ( malformedRoot [ " error " ] as? [ String : Any ] )
211+ XCTAssertTrue ( malformedRoot [ " id " ] is NSNull )
212+ XCTAssertEqual ( malformedError [ " code " ] as? Int , - 32700 )
213+ XCTAssertEqual ( malformedError [ " message " ] as? String , " parse error " )
214+ }
215+
216+ func testMcpThrownToolErrorsReturnJsonRpcErrorResponses( ) async throws {
217+ let runtime = AgentdMCPRuntimeStub ( )
218+ runtime. deviceSnapshotError = AgentdMCPStubError ( message: " snapshot failed " )
219+ runtime. activityError = DiagnosticCLIError . usage ( " --window requires one of 10m, 6h, or 24h " )
220+ let server = AgentdMCPServer ( runtime: runtime)
221+
222+ let snapshotResponse = await server. handle (
223+ try jsonData ( [
224+ " jsonrpc " : " 2.0 " ,
225+ " id " : " snapshot-error " ,
226+ " method " : " tools/call " ,
227+ " params " : [
228+ " name " : " agentd_device_snapshot " ,
229+ " arguments " : [ : ] ,
230+ ] ,
231+ ] ) )
232+ let snapshotRoot = try jsonObject ( snapshotResponse)
233+ let snapshotError = try XCTUnwrap ( snapshotRoot [ " error " ] as? [ String : Any ] )
234+ XCTAssertEqual ( snapshotRoot [ " id " ] as? String , " snapshot-error " )
235+ XCTAssertEqual ( snapshotError [ " code " ] as? Int , - 32603 )
236+ XCTAssertEqual ( snapshotError [ " message " ] as? String , " snapshot failed " )
237+
238+ let activityResponse = await server. handle (
239+ try jsonData ( [
240+ " jsonrpc " : " 2.0 " ,
241+ " id " : " activity-error " ,
242+ " method " : " tools/call " ,
243+ " params " : [
244+ " name " : " agentd_activity_recent " ,
245+ " arguments " : [ " window " : " 6h " ] ,
246+ ] ,
247+ ] ) )
248+ let activityRoot = try jsonObject ( activityResponse)
249+ let activityError = try XCTUnwrap ( activityRoot [ " error " ] as? [ String : Any ] )
250+ XCTAssertEqual ( activityRoot [ " id " ] as? String , " activity-error " )
251+ XCTAssertEqual ( activityError [ " code " ] as? Int , - 32602 )
252+ XCTAssertEqual ( activityError [ " message " ] as? String , " --window requires one of 10m, 6h, or 24h " )
253+ }
254+
196255 func testCaptureOnceParserAcceptsSafeFlags( ) throws {
197256 let command = try DiagnosticCommand . parse ( [
198257 " capture-once " , " --display-id " , " 42 " , " --no-ocr " , " --out " , " /tmp/agentd.json " ,
0 commit comments