diff --git a/lib/mcp/server.rb b/lib/mcp/server.rb index 5e34e0a..75d1155 100644 --- a/lib/mcp/server.rb +++ b/lib/mcp/server.rb @@ -338,13 +338,11 @@ def call_tool(request) end end - begin - call_tool_with_args(tool, arguments) - rescue => e - report_exception(e, { request: request }) + call_tool_with_args(tool, arguments) + rescue => e + report_exception(e, request: request) - error_tool_response("Internal error calling tool #{tool_name}: #{e.message}") - end + error_tool_response("Internal error calling tool #{tool_name}: #{e.message}") end def list_prompts(request) diff --git a/test/mcp/server_test.rb b/test/mcp/server_test.rb index 6859da6..0fcef28 100644 --- a/test/mcp/server_test.rb +++ b/test/mcp/server_test.rb @@ -431,6 +431,36 @@ class Example < Tool assert_instrumentation_data({ method: "tools/call", tool_name: "tool_that_raises" }) end + test "#handle tools/call returns error response with isError true if input_schema raises an error during validation" do + tool = Tool.define( + name: "tool_with_faulty_schema", + title: "Tool with faulty schema", + description: "A tool with a faulty schema", + input_schema: { type: "object", properties: { message: { type: "string" } }, required: ["message"] }, + ) { Tool::Response.new("success") } + + tool.input_schema.expects(:missing_required_arguments?).raises(RuntimeError, "Unexpected schema error") + + server = Server.new(name: "test_server", tools: [tool]) + + request = { + jsonrpc: "2.0", + method: "tools/call", + params: { + name: "tool_with_faulty_schema", + arguments: { message: "test" }, + }, + id: 1, + } + + response = server.handle(request) + + assert_nil response[:error], "Expected no JSON-RPC error" + assert response[:result][:isError] + assert_equal "text", response[:result][:content][0][:type] + assert_match(/Internal error calling tool tool_with_faulty_schema: Unexpected schema error/, response[:result][:content][0][:text]) + end + test "#handle tools/call returns error response with isError true for unknown tool" do request = { jsonrpc: "2.0",