Skip to main content
Version: 1.1.0

Transports

The transport determines how JSON-RPC messages travel between client and server. rust-mcp-sdk supports three transports. Pick the one that matches your deployment.

Decision tableโ€‹

StdioStreamable HTTPSSE
Concurrent clients1โœ… Unlimitedโœ… Unlimited
Remote accessโŒ Local onlyโœ…โœ…
ResumabilityโŒ N/Aโœ… with EventStoreโœ… with EventStore
Health checksโŒ N/Aโœ…โœ…
DNS rebinding protectionโŒ N/Aโœ…โœ…
Process managementSDK spawns childYou manage processYou manage process
Best forDesktop tools, Claude Desktop, CursorServices, agents, productionLegacy clients only
Use in new projects?โœ… For local toolsโœ… RecommendedโŒ Deprecated

Note: SSE and Streamable HTTP are served by the same HTTP server (sse_support: true, the default), so server-level features - health checks, DNS rebinding protection, and resumability via an EventStore - apply to both. Stdio has no HTTP layer or reconnect model, so none of those apply to it.

Stdioโ€‹

Client launches the server as a child process. Messages flow over stdin/stdout.

// Server side
let transport = StdioTransport::new(TransportOptions::default())?;

// Client side - launches the server automatically
let transport = StdioTransport::create_with_server_launch(
"npx",
vec!["-y".into(), "@modelcontextprotocol/server-everything@2026.8.18".into()],
None,
TransportOptions::default(),
)?;

Streamable HTTPโ€‹

The modern transport. Client connects over HTTP to a running server. Supports multiple concurrent clients, streaming responses, resumability, and health checks.

// Server side - use rust-mcp-axum or rust-mcp-actix
let server = rust_mcp_axum::create_axum_server(
server_details,
handler.to_mcp_server_handler(),
AxumServerOptions::default(),
);
server.start().await?;
// โ†’ http://127.0.0.1:8080/mcp

// Client side - pass transport options directly to the runtime
let client = client_runtime::with_transport_options(
client_details,
StreamableTransportOptions {
mcp_url: "http://127.0.0.1:8080/mcp".into(),
request_options: RequestOptions { ..Default::default() },
},
handler,
None,
None,
None,
);
client.clone().start().await?;

SSE (Server-Sent Events)โ€‹

Legacy transport, supported for backward compatibility. The client holds open a persistent SSE event stream (text/event-stream) over which the server can push messages. New projects should use Streamable HTTP.

When you create an HTTP server with sse_support: true (the default), both Streamable HTTP and SSE endpoints are available. SSE-only clients connect to /sse instead of /mcp.

Resumabilityโ€‹

With an EventStore, a disconnected client can reconnect and replay messages it missed while offline - this works over both Streamable HTTP and SSE:

AxumServerOptions {
event_store: Some(Arc::new(InMemoryEventStore::default())),
..Default::default()
}

The client reconnects with the same session ID, and the server replays events it missed while disconnected.

Combining transportsโ€‹

You can run stdio-based tools (launched by clients) AND a Streamable HTTP service (for remote access) from the same handler code. The handler trait is transport-agnostic - only main() changes.

Nextโ€‹