Make tool names stricter

Follow-up to https://github.com/modelcontextprotocol/ruby-sdk/pull/199#issuecomment-3659688807

Tool names are now validated to comply with the specification.
https://modelcontextprotocol.io/specification/2025-11-25/server/tools#tool-names

Since the tool name is optional, `nil` value is treated as "not specified" and is ignored without validation.
This commit is contained in:
Koichi ITO 2025-12-24 19:05:21 +09:00
commit 84ff1fcba1

View file

@ -4,6 +4,7 @@ module MCP
class Tool
class << self
NOT_SET = Object.new
MAX_LENGTH_OF_NAME = 128
attr_reader :title_value
attr_reader :description_value
@ -42,11 +43,13 @@ module MCP
name_value
else
@name_value = value
validate!
end
end
def name_value
@name_value || StringUtils.handle_from_class_name(name)
@name_value || (name.nil? ? nil : StringUtils.handle_from_class_name(name))
end
def input_schema_value
@ -117,6 +120,22 @@ module MCP
output_schema output_schema
self.annotations(annotations) if annotations
define_singleton_method(:call, &block) if block
end.tap(&:validate!)
end
# It complies with the following tool name specification:
# https://modelcontextprotocol.io/specification/latest/server/tools#tool-names
def validate!
return true unless tool_name
if tool_name.empty? || tool_name.length > MAX_LENGTH_OF_NAME
raise ArgumentError, "Tool names should be between 1 and 128 characters in length (inclusive)."
end
unless tool_name.match?(/\A[A-Za-z\d_\-\.]+\z/)
raise ArgumentError, <<~MESSAGE
Tool names only allowed characters: uppercase and lowercase ASCII letters (A-Z, a-z), digits (0-9), underscore (_), hyphen (-), and dot (.).
MESSAGE
end
end
end