ruby-sdk/lib/mcp/configuration.rb
Koichi ITO cb5e87581b Add validation to MCP::Configuration setters
I noticed through the existing tests that `MCP::Configuration#protocol_version=`
allows setting an arbitrary protocol version.

Since the official MCP Ruby SDK is an implementation of the MCP specification,
it should not support arbitrary protocol versions. This change adds validation
to the setter, consistent with `Configuration#initialize`.

The same validation has also been added to `MCP::Configuration#validate_tool_call_arguments=`.
2025-09-24 19:19:02 +09:00

116 lines
3.3 KiB
Ruby

# frozen_string_literal: true
module MCP
class Configuration
DEFAULT_PROTOCOL_VERSION = "2025-06-18"
SUPPORTED_PROTOCOL_VERSIONS = [DEFAULT_PROTOCOL_VERSION, "2025-03-26", "2024-11-05"]
attr_writer :exception_reporter, :instrumentation_callback
def initialize(exception_reporter: nil, instrumentation_callback: nil, protocol_version: nil,
validate_tool_call_arguments: true)
@exception_reporter = exception_reporter
@instrumentation_callback = instrumentation_callback
@protocol_version = protocol_version
if protocol_version
validate_protocol_version!(protocol_version)
end
validate_value_of_validate_tool_call_arguments!(validate_tool_call_arguments)
@validate_tool_call_arguments = validate_tool_call_arguments
end
def protocol_version=(protocol_version)
validate_protocol_version!(protocol_version)
@protocol_version = protocol_version
end
def validate_tool_call_arguments=(validate_tool_call_arguments)
validate_value_of_validate_tool_call_arguments!(validate_tool_call_arguments)
@validate_tool_call_arguments = validate_tool_call_arguments
end
def protocol_version
@protocol_version || DEFAULT_PROTOCOL_VERSION
end
def protocol_version?
!@protocol_version.nil?
end
def exception_reporter
@exception_reporter || default_exception_reporter
end
def exception_reporter?
!@exception_reporter.nil?
end
def instrumentation_callback
@instrumentation_callback || default_instrumentation_callback
end
def instrumentation_callback?
!@instrumentation_callback.nil?
end
attr_reader :validate_tool_call_arguments
def validate_tool_call_arguments?
!!@validate_tool_call_arguments
end
def merge(other)
return self if other.nil?
exception_reporter = if other.exception_reporter?
other.exception_reporter
else
@exception_reporter
end
instrumentation_callback = if other.instrumentation_callback?
other.instrumentation_callback
else
@instrumentation_callback
end
protocol_version = if other.protocol_version?
other.protocol_version
else
@protocol_version
end
validate_tool_call_arguments = other.validate_tool_call_arguments
Configuration.new(
exception_reporter:,
instrumentation_callback:,
protocol_version:,
validate_tool_call_arguments:,
)
end
private
def validate_protocol_version!(protocol_version)
unless SUPPORTED_PROTOCOL_VERSIONS.include?(protocol_version)
message = "protocol_version must be #{SUPPORTED_PROTOCOL_VERSIONS[0...-1].join(", ")}, or #{SUPPORTED_PROTOCOL_VERSIONS[-1]}"
raise ArgumentError, message
end
end
def validate_value_of_validate_tool_call_arguments!(validate_tool_call_arguments)
unless validate_tool_call_arguments.is_a?(TrueClass) || validate_tool_call_arguments.is_a?(FalseClass)
raise ArgumentError, "validate_tool_call_arguments must be a boolean"
end
end
def default_exception_reporter
@default_exception_reporter ||= ->(exception, server_context) {}
end
def default_instrumentation_callback
@default_instrumentation_callback ||= ->(data) {}
end
end
end