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
32 changes: 27 additions & 5 deletions lib/mcp/server.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ def initialize(duplicated_tool_names)
class Server
DEFAULT_VERSION = "0.1.0"

UNSUPPORTED_PROPERTIES_UNTIL_2025_06_18 = [:description, :icons].freeze
UNSUPPORTED_PROPERTIES_UNTIL_2025_03_26 = [:title, :websiteUrl].freeze

class RequestHandlerError < StandardError
attr_reader :error_type
attr_reader :original_error
Expand Down Expand Up @@ -319,13 +322,32 @@ def server_info
}.compact
end

def init(request)
@client = request[:clientInfo] if request
def init(params)
@client = params[:clientInfo] if params

protocol_version = params[:protocolVersion] if params
negotiated_version = if Configuration::SUPPORTED_STABLE_PROTOCOL_VERSIONS.include?(protocol_version)
protocol_version
else
configuration.protocol_version
end

info = server_info.reject do |property|
negotiated_version <= "2025-06-18" && UNSUPPORTED_PROPERTIES_UNTIL_2025_06_18.include?(property) ||
negotiated_version <= "2025-03-26" && UNSUPPORTED_PROPERTIES_UNTIL_2025_03_26.include?(property)
end

response_instructions = instructions

if negotiated_version == "2024-11-05"
response_instructions = nil
end

{
protocolVersion: configuration.protocol_version,
protocolVersion: negotiated_version,
capabilities: capabilities,
serverInfo: server_info,
instructions: instructions,
serverInfo: info,
instructions: response_instructions,
}.compact
end

Expand Down
89 changes: 89 additions & 0 deletions test/mcp/server_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1274,6 +1274,95 @@ class Example < Tool
assert_equal custom_version, response[:result][:protocolVersion]
end

test "server negotiates protocol version when client requests a supported version" do
server = Server.new(name: "test_server")

request = {
jsonrpc: "2.0",
method: "initialize",
id: 1,
params: {
protocolVersion: "2025-06-18",
},
}

response = server.handle(request)
assert_equal "2025-06-18", response[:result][:protocolVersion]
end

test "server falls back to default version when client requests unsupported version" do
server = Server.new(name: "test_server")

request = {
jsonrpc: "2.0",
method: "initialize",
id: 1,
params: {
protocolVersion: "1999-01-01",
},
}

response = server.handle(request)
assert_equal Configuration::LATEST_STABLE_PROTOCOL_VERSION, response[:result][:protocolVersion]
end

test "server removes description and icons from server_info when negotiating to 2025-06-18" do
server = Server.new(
name: "test_server",
description: "A test server",
icons: [Icon.new(src: "https://example.com/icon.png")],
)

request = {
jsonrpc: "2.0",
method: "initialize",
id: 1,
params: {
protocolVersion: "2025-06-18",
},
}

response = server.handle(request)
assert_equal "2025-06-18", response[:result][:protocolVersion]
refute response[:result][:serverInfo].key?(:description)
refute response[:result][:serverInfo].key?(:icons)
end

test "server removes title and websiteUrl when negotiating to 2025-03-26" do
server = Server.new(name: "test_server", title: "Test Server", website_url: "https://example.com")

request = {
jsonrpc: "2.0",
method: "initialize",
id: 1,
params: {
protocolVersion: "2025-03-26",
},
}

response = server.handle(request)
assert_equal "2025-03-26", response[:result][:protocolVersion]
refute response[:result][:serverInfo].key?(:title)
refute response[:result][:serverInfo].key?(:websiteUrl)
end

test "server removes instructions when negotiating to 2024-11-05" do
server = Server.new(name: "test_server", instructions: "Some instructions")

request = {
jsonrpc: "2.0",
method: "initialize",
id: 1,
params: {
protocolVersion: "2024-11-05",
},
}

response = server.handle(request)
assert_equal "2024-11-05", response[:result][:protocolVersion]
refute response[:result].key?(:instructions)
end

test "tools/call handles missing arguments field" do
server = Server.new(
tools: [TestTool],
Expand Down