Merge pull request #402 from koic/resource_not_found_error_data

Standardize Resource Not Found Errors on -32602 with URI Data per SEP-2164
This commit is contained in:
Koichi ITO 2026-06-14 16:51:57 +09:00 • committed by GitHub
commit 783eb6303f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 104 additions and 1 deletions

View file

@ -610,6 +610,27 @@ module MCP
assert_raises(Client::ServerError) { client.read_resource(uri: "file:///missing") }
end
def test_read_resource_surfaces_resource_not_found_code_and_data
# Per SEP-2164, servers report unknown resource URIs with -32602 and
# the URI in the error `data`; the client must expose both unmodified.
transport = mock
mock_response = {
"error" => {
"code" => -32_602,
"message" => "Resource not found: file:///missing.txt",
"data" => { "uri" => "file:///missing.txt" },
},
}
transport.expects(:send_request).returns(mock_response).once
client = Client.new(transport: transport)
error = assert_raises(Client::ServerError) { client.read_resource(uri: "file:///missing.txt") }
assert_equal(-32_602, error.code)
assert_equal({ "uri" => "file:///missing.txt" }, error.data)
end
def test_get_prompt_raises_server_error_on_error_response
transport = mock
mock_response = { "error" => { "code" => -32_602, "message" => "Prompt not found" } }

View file

@ -724,6 +724,25 @@ module MCP
)
end
test "#handle resources/read returns -32602 with the uri in error data when the handler raises ResourceNotFoundError" do
# Per SEP-2164, resource-not-found errors use the standard JSON-RPC Invalid Params code (-32602)
# and carry the requested URI in `data`.
@server.resources_read_handler do |request|
raise Server::ResourceNotFoundError.new(request[:uri], request)
end
response = @server.handle({
jsonrpc: "2.0",
method: "resources/read",
id: 1,
params: { uri: "file:///missing.txt" },
})
assert_equal(-32602, response[:error][:code])
assert_equal("Resource not found: file:///missing.txt", response[:error][:message])
assert_equal({ uri: "file:///missing.txt" }, response[:error][:data])
end
test "#handle resources/templates/list returns a list of resource templates" do
request = {
jsonrpc: "2.0",
@ -2206,6 +2225,30 @@ module MCP
assert_equal(-32_602, response[:error][:code])
end
test "#handle completion/complete resource-not-found error carries the uri in error data" do
server = Server.new(
name: "test_server",
capabilities: { completions: {} },
)
server.handle({ jsonrpc: "2.0", method: "initialize", id: 1 })
server.handle({ jsonrpc: "2.0", method: "notifications/initialized" })
response = server.handle({
jsonrpc: "2.0",
id: 2,
method: "completion/complete",
params: {
ref: { type: "ref/resource", uri: "unknown://template" },
argument: { name: "arg", value: "val" },
},
})
assert_equal(-32602, response[:error][:code])
assert_equal("Resource not found: unknown://template", response[:error][:message])
assert_equal({ uri: "unknown://template" }, response[:error][:data])
end
test "#handle completion/complete returns error for invalid ref type" do
server = Server.new(
name: "test_server",