|
5 | 5 | require_relative "methods" |
6 | 6 |
|
7 | 7 | module MCP |
| 8 | + class ToolNotUnique < StandardError |
| 9 | + def initialize(duplicated_tool_names) |
| 10 | + super(<<~MESSAGE) |
| 11 | + Tool names should be unique. Use `tool_name` to assign unique names to: |
| 12 | + #{duplicated_tool_names.join(", ")} |
| 13 | + MESSAGE |
| 14 | + end |
| 15 | + end |
| 16 | + |
8 | 17 | class Server |
9 | 18 | DEFAULT_VERSION = "0.1.0" |
10 | 19 |
|
@@ -53,6 +62,7 @@ def initialize( |
53 | 62 | @title = title |
54 | 63 | @version = version |
55 | 64 | @instructions = instructions |
| 65 | + @tool_names = tools.map(&:name_value) |
56 | 66 | @tools = tools.to_h { |t| [t.name_value, t] } |
57 | 67 | @prompts = prompts.to_h { |p| [p.name_value, p] } |
58 | 68 | @resources = resources |
@@ -101,7 +111,10 @@ def handle_json(request) |
101 | 111 |
|
102 | 112 | def define_tool(name: nil, title: nil, description: nil, input_schema: nil, annotations: nil, meta: nil, &block) |
103 | 113 | tool = Tool.define(name:, title:, description:, input_schema:, annotations:, meta:, &block) |
104 | | - @tools[tool.name_value] = tool |
| 114 | + tool_name = tool.name_value |
| 115 | + |
| 116 | + @tool_names << tool_name |
| 117 | + @tools[tool_name] = tool |
105 | 118 |
|
106 | 119 | validate! |
107 | 120 | end |
@@ -176,6 +189,8 @@ def prompts_get_handler(&block) |
176 | 189 | private |
177 | 190 |
|
178 | 191 | def validate! |
| 192 | + validate_tool_name! |
| 193 | + |
179 | 194 | # NOTE: The draft protocol version is the next version after 2025-11-25. |
180 | 195 | if @configuration.protocol_version <= "2025-06-18" |
181 | 196 | if server_info.key?(:description) |
@@ -216,6 +231,12 @@ def validate! |
216 | 231 | end |
217 | 232 | end |
218 | 233 |
|
| 234 | + def validate_tool_name! |
| 235 | + duplicated_tool_names = @tool_names.tally.filter_map { |name, count| name if count >= 2 } |
| 236 | + |
| 237 | + raise ToolNotUnique, duplicated_tool_names unless duplicated_tool_names.empty? |
| 238 | + end |
| 239 | + |
219 | 240 | def handle_request(request, method) |
220 | 241 | handler = @handlers[method] |
221 | 242 | unless handler |
|
0 commit comments