Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,7 @@ Lint/IncompatibleIoSelectWithFiberScheduler:

Minitest/LiteralAsActualArgument:
Enabled: true

Naming/MethodName:
AllowedPatterns:
- '\Atest_'
2 changes: 1 addition & 1 deletion lib/json_rpc_handler.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class ErrorCode
PARSE_ERROR = -32700
end

DEFAULT_ALLOWED_ID_CHARACTERS = /\A[a-zA-Z0-9_-]+\z/
DEFAULT_ALLOWED_ID_CHARACTERS = /\A[a-zA-Z0-9_-]+\z/.freeze

# Sentinel return value from a handler. When a handler returns this,
# `process_request` emits no JSON-RPC response for the request,
Expand Down
2 changes: 1 addition & 1 deletion lib/mcp/client/oauth/discovery.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ module Discovery
# Matches a single `key=value` pair inside an HTTP auth-scheme challenge.
# `value` is either a quoted string (which can contain commas and spaces)
# or a bare token, per RFC 7235.
WWW_AUTH_PARAM_PATTERN = /\A([A-Za-z0-9_-]+)\s*=\s*(?:"((?:[^"\\]|\\.)*)"|([^\s,]+))/
WWW_AUTH_PARAM_PATTERN = /\A([A-Za-z0-9_-]+)\s*=\s*(?:"((?:[^"\\]|\\.)*)"|([^\s,]+))/.freeze

class << self
# Parses a `WWW-Authenticate` header and returns the parameters of
Expand Down
2 changes: 1 addition & 1 deletion lib/mcp/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ class Configuration
LATEST_STABLE_PROTOCOL_VERSION = "2025-11-25"
SUPPORTED_STABLE_PROTOCOL_VERSIONS = [
LATEST_STABLE_PROTOCOL_VERSION, "2025-06-18", "2025-03-26", "2024-11-05",
]
].freeze
DEFAULT_NEGOTIATED_PROTOCOL_VERSION = "2025-03-26"

attr_writer :exception_reporter, :around_request
Expand Down
2 changes: 1 addition & 1 deletion lib/mcp/icon.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

module MCP
class Icon
SUPPORTED_THEMES = ["light", "dark"]
SUPPORTED_THEMES = ["light", "dark"].freeze

attr_reader :mime_type, :sizes, :src, :theme

Expand Down
2 changes: 0 additions & 2 deletions lib/mcp/instrumentation.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@ def instrument_call(method, server_context: {}, exception_already_reported: nil,
rescue => e
already_reported = begin
!!exception_already_reported&.call(e)
# rubocop:disable Lint/RescueException
rescue Exception
# rubocop:enable Lint/RescueException
# The predicate is expected to be side-effect-free and return a boolean.
# Any exception raised from it (including non-StandardError such as SystemExit)
# must not shadow the original exception.
Expand Down
2 changes: 1 addition & 1 deletion lib/mcp/resource_template.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class << self
# Applied after `Regexp.escape`, which turns `{` and `}` into `\{` and `\}`.
# Variable names are restricted to valid Regexp named-group names,
# so RFC 6570 operator expressions (e.g. `{?query}`) stay literal and never match.
VARIABLE_PATTERN = /\\\{([A-Za-z_]\w*)\\\}/
VARIABLE_PATTERN = /\\\{([A-Za-z_]\w*)\\\}/.freeze

attr_reader :uri_template_value
attr_reader :title_value
Expand Down
4 changes: 1 addition & 3 deletions lib/mcp/server.rb
Original file line number Diff line number Diff line change
Expand Up @@ -963,9 +963,7 @@ def report_exception(exception, server_context = {})
end

def index_resources_by_uri(resources)
resources.each_with_object({}) do |resource, hash|
hash[resource.uri] = resource
end
resources.to_h { |resource| [resource.uri, resource] }
end

def error_tool_response(text)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def gets
nil # Simulate end of input
end

def set_encoding(encoding) # rubocop:disable Naming/AccessorMethodName
def set_encoding(encoding)
# Mock implementation
end

Expand Down
8 changes: 7 additions & 1 deletion test/mcp/server/transports/streamable_http_transport_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1925,7 +1925,10 @@ def string
end

test "missing MCP-Protocol-Version header falls back to default for validation" do
MCP::Configuration::SUPPORTED_STABLE_PROTOCOL_VERSIONS.stubs(:include?).returns(false)
# The constant is frozen, so swap it out instead of stubbing `include?` on it.
original_versions = MCP::Configuration::SUPPORTED_STABLE_PROTOCOL_VERSIONS
MCP::Configuration.send(:remove_const, :SUPPORTED_STABLE_PROTOCOL_VERSIONS)
MCP::Configuration.const_set(:SUPPORTED_STABLE_PROTOCOL_VERSIONS, [].freeze)

request = Rack::Request.new(
"REQUEST_METHOD" => "POST",
Expand All @@ -1938,6 +1941,9 @@ def string

body = JSON.parse(response[2][0])
assert_includes body["error"]["message"], MCP::Configuration::DEFAULT_NEGOTIATED_PROTOCOL_VERSION
ensure
MCP::Configuration.send(:remove_const, :SUPPORTED_STABLE_PROTOCOL_VERSIONS)
MCP::Configuration.const_set(:SUPPORTED_STABLE_PROTOCOL_VERSIONS, original_versions)
end

test "POST request with empty MCP-Protocol-Version header returns 400" do
Expand Down