Skip to content
Open
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: 28 additions & 4 deletions lib/mcp/server.rb
Original file line number Diff line number Diff line change
Expand Up @@ -313,12 +313,36 @@ def server_info
}.compact
end

def init(request)
def init(params)
client_version = params&.dig(:protocolVersion) || params&.dig("protocolVersion")
negotiated_version = if client_version && Configuration::SUPPORTED_STABLE_PROTOCOL_VERSIONS.include?(client_version)
client_version
else
configuration.protocol_version
end

info = server_info.dup
response_instructions = instructions

if negotiated_version <= "2025-06-18"
info.delete(:description)
info.delete(:icons)
end

if negotiated_version <= "2025-03-26"
info.delete(:title)
info.delete(:websiteUrl)
end

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 @@ -1227,6 +1227,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