From c67db88579bacca1cd78ce17f6490190401b0356 Mon Sep 17 00:00:00 2001 From: Rudy Celekli Date: Sat, 17 Oct 2026 21:07:37 -0400 Subject: [PATCH] fix: report an unknown MCP method as "Method not found" The graphicle program's MCP server answered a method a connection does not serve (`resources/list` on a workspace connection, `prompts/list`, `completion/complete`, any typo) with JSON-RPC error -32602, "Invalid params", the code it uses for every refused call. JSON-RPC 2.0 and MCP reserve -32601, "Method not found", for that case, and clients use it to tell an optional method the server lacks from a call it refused. The graph engine's own server already answers -32601. The message is unchanged; only its code is -32601 now. Every other refusal keeps -32602. Co-Authored-By: Claude Opus 5.5 Signed-off-by: Rudy Celekli --- crates/graphicle/src/api.rs | 14 ++++++++++++-- crates/graphicle/tests/it/workspace_scope.rs | 5 +++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/crates/graphicle/src/api.rs b/crates/graphicle/src/api.rs index 7487132..e13fdf5 100644 --- a/crates/graphicle/src/api.rs +++ b/crates/graphicle/src/api.rs @@ -2001,16 +2001,26 @@ fn mcp_in( } }) } - _ => Err(Error::bad("Unsupported MCP method")), + _ => Err(Error::bad(UNSUPPORTED_METHOD)), } })(); Some(match result { Ok(value) => json!({"jsonrpc":"2.0","id":request["id"],"result":value}), Err(error) => { - json!({"jsonrpc":"2.0","id":request["id"],"error":{"code":-32602,"message":error.message}}) + // JSON-RPC's "Method not found" for a method this connection + // does not serve, so that a client can tell it from a refused + // call. + let code = if error.message == UNSUPPORTED_METHOD { + -32601 + } else { + -32602 + }; + json!({"jsonrpc":"2.0","id":request["id"],"error":{"code":code,"message":error.message}}) } }) } +/// The error message of a method a connection does not serve. +const UNSUPPORTED_METHOD: &str = "Unsupported MCP method"; async fn mcp_http( State(app): State, Path((workspace, repository)): Path<(String, String)>, diff --git a/crates/graphicle/tests/it/workspace_scope.rs b/crates/graphicle/tests/it/workspace_scope.rs index 916c057..686023d 100644 --- a/crates/graphicle/tests/it/workspace_scope.rs +++ b/crates/graphicle/tests/it/workspace_scope.rs @@ -1256,6 +1256,11 @@ fn a_workspace_connection_serves_the_graph_tools_of_the_project_repo_names() { "Unsupported MCP method", "{refused}" ); + // JSON-RPC's "Method not found", not "Invalid params". + assert_eq!(refused["error"]["code"], -32601, "{refused}"); + // A refused call of a served method keeps "Invalid params". + let unknown_tool = rpc(&app, "tools/call", json!({"name":"no_such_tool"})); + assert_eq!(unknown_tool["error"]["code"], -32602, "{unknown_tool}"); // A navigation tool names its project, by id or key. let unnamed = call(&app, "get_node", json!({"label":"quantize_cents"})); assert!(