Merge pull request #223 from chattermill/md-protocol-negotiation
Add protocol version negotiation to server initialization
This commit is contained in:
commit
15ef5ebda2
2 changed files with 116 additions and 5 deletions
|
|
@ -18,6 +18,9 @@ module MCP
|
|||
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
|
||||
|
|
@ -319,13 +322,32 @@ module MCP
|
|||
}.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
|
||||
|
||||
|
|
|
|||
|
|
@ -1274,6 +1274,95 @@ module MCP
|
|||
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],
|
||||
|
|
|
|||
Loading…
Reference in a new issue