Raise an error when duplicate tool names are registered
This raises an exception when duplicate tool names are registered, instead of silently overwriting tools. Tool names are required to be unique within a server, so this behavior aligns with the MCP specification. > Tool names SHOULD be unique within a server. https://modelcontextprotocol.io/specification/2025-11-25/server/tools#tool-names Validation for tool names could be made more strictly spec-compliant in a separate effort. Fixes #197
This commit is contained in:
parent
171baa876e
commit
dee80d20ae
1 changed files with 74 additions and 1 deletions
|
|
@ -374,6 +374,44 @@ module MCP
|
|||
assert_instrumentation_data({ method: "tools/call", tool_name: "tool_that_raises" })
|
||||
end
|
||||
|
||||
test "registers tools with the same class name in different namespaces" do
|
||||
module Foo
|
||||
class Example < Tool
|
||||
end
|
||||
end
|
||||
|
||||
module Bar
|
||||
class Example < Tool
|
||||
end
|
||||
end
|
||||
|
||||
error = assert_raises(MCP::ToolNotUnique) { Server.new(tools: [Foo::Example, Bar::Example]) }
|
||||
assert_equal(<<~MESSAGE, error.message)
|
||||
Tool names should be unique. Use `tool_name` to assign unique names to:
|
||||
example
|
||||
MESSAGE
|
||||
end
|
||||
|
||||
test "registers tools with the same tool name" do
|
||||
module Baz
|
||||
class Example < Tool
|
||||
tool_name "foo"
|
||||
end
|
||||
end
|
||||
|
||||
module Qux
|
||||
class Example < Tool
|
||||
tool_name "foo"
|
||||
end
|
||||
end
|
||||
|
||||
error = assert_raises(MCP::ToolNotUnique) { Server.new(tools: [Baz::Example, Qux::Example]) }
|
||||
assert_equal(<<~MESSAGE, error.message)
|
||||
Tool names should be unique. Use `tool_name` to assign unique names to:
|
||||
foo
|
||||
MESSAGE
|
||||
end
|
||||
|
||||
test "#handle_json returns error response with isError true if the tool raises an error" do
|
||||
request = JSON.generate({
|
||||
jsonrpc: "2.0",
|
||||
|
|
@ -950,6 +988,20 @@ module MCP
|
|||
assert_equal({ content: "success", isError: false }, response[:result])
|
||||
end
|
||||
|
||||
test "#define_tool adds a tool with duplicated tool name to the server" do
|
||||
error = assert_raises(MCP::ToolNotUnique) do
|
||||
@server.define_tool(
|
||||
name: "test_tool", # NOTE: Already registered tool name
|
||||
description: "Defined tool",
|
||||
input_schema: { type: "object", properties: { message: { type: "string" } }, required: ["message"] },
|
||||
meta: { foo: "bar" },
|
||||
) do |message:|
|
||||
Tool::Response.new(message)
|
||||
end
|
||||
end
|
||||
assert_match(/\ATool names should be unique. Use `tool_name` to assign unique names to/, error.message)
|
||||
end
|
||||
|
||||
test "#define_tool call definition allows tool arguments and server context" do
|
||||
@server.server_context = { user_id: "123" }
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue