Auto-set server.transport in Transport#initialize

## Motivation and Context

Transport subclasses (StreamableHTTPTransport, StdioTransport) already
receive the server in their constructor, but users must manually call
`server.transport = transport` after creating a transport instance.
This is boilerplate that can be eliminated by setting the connection
automatically in `Transport#initialize`.

## How Has This Been Tested?

All existing tests pass. Redundant `server.transport = transport` lines
were removed from tests, examples, README.md, and conformance server.

## Breaking Changes

None. Existing code that manually sets `server.transport = transport`
continues to work (idempotent assignment).
This commit is contained in:
Koichi ITO 2026-04-08 22:25:50 +09:00
commit de38804ed7
7 changed files with 10 additions and 36 deletions

View file

@ -26,7 +26,6 @@ module MCP
setup do
@server = Server.new(name: "test_server")
@transport = MockTransport.new(@server)
@server.transport = @transport
@session = ServerSession.new(server: @server, transport: @transport)
end

View file

@ -61,7 +61,6 @@ module MCP
resources: [],
)
@transport = StdioTransport.new(@server)
@server.transport = @transport
end
teardown do

View file

@ -15,7 +15,6 @@ module MCP
resources: [],
)
@transport = StreamableHTTPTransport.new(@server)
@server.transport = @transport
end
test "server notification methods send SSE notifications through HTTP transport" do

View file

@ -2591,7 +2591,6 @@ module MCP
server = Server.new(name: "test", tools: [], prompts: [], resources: [])
server.logging_message_notification = MCP::LoggingMessageNotification.new(level: "debug")
transport = StreamableHTTPTransport.new(server)
server.transport = transport
server.define_tool(name: "log_tool") do |server_context:|
server_context.notify_log_message(data: "secret", level: "info")
@ -2668,7 +2667,6 @@ module MCP
test "session-scoped progress notification is sent only to the originating session" do
server = Server.new(name: "test", tools: [], prompts: [], resources: [])
transport = StreamableHTTPTransport.new(server)
server.transport = transport
server.define_tool(name: "progress_tool") do |server_context:|
server_context.report_progress(50, total: 100, message: "halfway")
@ -2749,7 +2747,6 @@ module MCP
test "each session stores its own client info independently" do
server = Server.new(name: "test", tools: [], prompts: [], resources: [])
transport = StreamableHTTPTransport.new(server)
server.transport = transport
# Initialize session 1 with client "alpha".
init1 = create_rack_request(
@ -2794,7 +2791,6 @@ module MCP
test "each session stores its own logging level independently" do
server = Server.new(name: "test", tools: [], prompts: [], resources: [])
transport = StreamableHTTPTransport.new(server)
server.transport = transport
# Initialize two sessions.
init1 = create_rack_request(

View file

@ -36,7 +36,6 @@ module MCP
)
@mock_transport = MockTransport.new(@server)
@server.transport = @mock_transport
end
test "#notify_tools_list_changed sends notification through transport" do
@ -122,14 +121,13 @@ module MCP
end
test "notification methods handle transport errors gracefully" do
# Create a transport that raises errors
error_transport = Class.new(MockTransport) do
# Replace server's transport with one that raises on send_notification.
Class.new(MockTransport) do
def send_notification(method, params = nil)
raise StandardError, "Transport error"
end
end.new(@server)
@server.transport = error_transport
@server.logging_message_notification = MCP::LoggingMessageNotification.new(level: "error")
# Mock the exception reporter

View file

@ -89,7 +89,6 @@ module MCP
)
@mock_transport = MockTransport.new(@server)
@server.transport = @mock_transport
@session = ServerSession.new(server: @server, transport: @mock_transport)
end

View file

@ -41,7 +41,6 @@ module MCP
)
@mock_transport = MockTransport.new(@server)
@server.transport = @mock_transport
# Simulate client initialization with sampling capability.
@server.handle({
@ -197,8 +196,8 @@ module MCP
test "init with sampling capability allows create_sampling_message" do
server = Server.new(name: "test", version: "1.0")
mock_transport = MockTransport.new(server)
server.transport = mock_transport
# Assigns server.transport via Transport#initialize, which create_sampling_message requires.
MockTransport.new(server)
server.handle({
jsonrpc: "2.0",
@ -222,8 +221,8 @@ module MCP
test "init without capabilities rejects create_sampling_message" do
server = Server.new(name: "test", version: "1.0")
mock_transport = MockTransport.new(server)
server.transport = mock_transport
# Assigns server.transport via Transport#initialize, which create_sampling_message requires.
MockTransport.new(server)
server.handle({
jsonrpc: "2.0",
@ -247,7 +246,6 @@ module MCP
test "create_sampling_message uses per-session capabilities via ServerSession" do
transport = MCP::Server::Transports::StreamableHTTPTransport.new(@server)
@server.transport = transport
# Session with sampling capability passes validation (fails at send_request due to no stream).
session_with_sampling = ServerSession.new(server: @server, transport: transport, session_id: "s1")
@ -277,7 +275,6 @@ module MCP
test "ServerSession#client_capabilities falls back to server global capabilities" do
transport = MCP::Server::Transports::StreamableHTTPTransport.new(@server)
@server.transport = transport
# Session without capabilities stored falls back to @server.client_capabilities.
session = ServerSession.new(server: @server, transport: transport, session_id: "s3")
@ -295,8 +292,8 @@ module MCP
test "session init does not overwrite server global client_capabilities" do
server = Server.new(name: "test", version: "1.0")
mock_transport = MockTransport.new(server)
server.transport = mock_transport
# Assigns server.transport via Transport#initialize, which create_sampling_message requires.
MockTransport.new(server)
# Non-session init sets global capabilities.
server.handle({
@ -314,7 +311,6 @@ module MCP
# Session-scoped init must NOT overwrite global capabilities.
transport = MCP::Server::Transports::StreamableHTTPTransport.new(server)
server.transport = transport
session = ServerSession.new(server: server, transport: transport, session_id: "s1")
server.handle(
@ -340,7 +336,6 @@ module MCP
test "Server#create_sampling_message does not see session-scoped capabilities from HTTP init" do
server = Server.new(name: "test", version: "1.0")
transport = MCP::Server::Transports::StreamableHTTPTransport.new(server)
server.transport = transport
# HTTP init stores capabilities on the session, not on the server.
session = ServerSession.new(server: server, transport: transport, session_id: "s1")