feat: deprecate roots sampling and logging

Warn when Roots, Sampling, or Logging APIs are used with MCP protocol version 2026-07-28 or newer.

Add a shared protocol deprecation helper, YARD deprecation notes, and regression tests covering warnings at and after the deprecation threshold and no warnings for older or never-established protocol versions.

Closes https://github.com/modelcontextprotocol/ruby-sdk/issues/390

Co-authored-by: Qlaw <noreply@qlaw.quick.shopify.io>
This commit is contained in:
Ates Goral 2026-06-14 11:45:38 +02:00
commit 6a43d3d6fb
2 changed files with 508 additions and 3 deletions

View file

@ -11,6 +11,8 @@ require "mcp/client"
module MCP
class Client
class HTTPTest < Minitest::Test
include DeprecationWarningTestHelper
def test_raises_load_error_when_faraday_not_available
client = HTTP.new(url: url)
@ -1705,6 +1707,44 @@ module MCP
assert_requested(notification_stub)
end
def test_connect_warns_for_deprecated_capabilities_when_negotiated_protocol_version_is_2026_07_28
notification_stub = stub_notification
init_stub = stub_request(:post, url)
.with { |req| JSON.parse(req.body)["method"] == "initialize" }
.to_return(
status: 200,
headers: { "Content-Type" => "application/json" },
body: { result: { protocolVersion: "2026-07-28" } }.to_json,
)
assert_deprecation_warning(/MCP Roots .*2026-07-28.*MCP Sampling .*2026-07-28/m) do
client.connect(capabilities: { roots: { listChanged: true }, sampling: {} })
end
assert_requested(init_stub)
assert_requested(notification_stub)
end
def test_connect_does_not_warn_for_deprecated_capabilities_when_negotiated_protocol_version_is_older
notification_stub = stub_notification
init_stub = stub_request(:post, url)
.with { |req| JSON.parse(req.body)["method"] == "initialize" }
.to_return(
status: 200,
headers: { "Content-Type" => "application/json" },
body: { result: { protocolVersion: "2025-11-25" } }.to_json,
)
assert_no_deprecation_warning do
client.connect(capabilities: { roots: { listChanged: true }, sampling: {} })
end
assert_requested(init_stub)
assert_requested(notification_stub)
end
def test_connect_is_idempotent
init_stub = stub_initialize
notification_stub = stub_notification

View file

@ -9,6 +9,8 @@ require "mcp/client/tool"
module MCP
class Client
class StdioTest < Minitest::Test
include DeprecationWarningTestHelper
def test_send_request_raises_when_connect_not_called
Open3.expects(:popen3).never
@ -816,6 +818,38 @@ module MCP
stdout_write.close
end
def test_connect_warns_for_deprecated_capabilities_when_negotiated_protocol_version_is_2026_07_28
stdin_read, stdin_write = IO.pipe
stdout_read, stdout_write = IO.pipe
stderr_read, _ = IO.pipe
Open3.stubs(:popen3).returns([stdin_write, stdout_read, stderr_read, mock_wait_thread])
transport = Stdio.new(command: "ruby", args: ["server.rb"])
server_thread = Thread.new do
init_line = stdin_read.gets
init_request = JSON.parse(init_line)
stdout_write.puts(JSON.generate(
jsonrpc: "2.0",
id: init_request["id"],
result: { protocolVersion: "2026-07-28" },
))
stdout_write.flush
stdin_read.gets
end
assert_deprecation_warning(/MCP Roots .*2026-07-28.*MCP Sampling .*2026-07-28/m) do
transport.connect(capabilities: { roots: { listChanged: true }, sampling: {} })
end
ensure
server_thread.join
stdin_read.close
stdin_write.close
stdout_read.close
stdout_write.close
end
def test_connect_raises_on_jsonrpc_error_response
stdin_read, stdin_write = IO.pipe
stdout_read, stdout_write = IO.pipe