csharp-sdk/docs/concepts/transports/transports.md
Jeff Handley 06563e233d
Clean up markdown-link-check warnings (#1395)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-02-28 12:33:36 -05:00

7.7 KiB

title author description uid
Transports jeffhandley How to configure stdio, Streamable HTTP, and SSE transports for MCP communication. transports

Transports

MCP uses a transport layer to handle the communication between clients and servers. Three transport mechanisms are supported: stdio, Streamable HTTP, and SSE (Server-Sent Events, legacy).

stdio transport

The stdio transport communicates over standard input and output streams. It is best suited for local integrations, as the MCP server runs as a child process of the client.

stdio client

Use xref:ModelContextProtocol.Client.StdioClientTransport to launch a server process and communicate over its stdin/stdout. This example connects to the NuGet MCP Server:

var transport = new StdioClientTransport(new StdioClientTransportOptions
{
    Command = "dnx",
    Arguments = ["NuGet.Mcp.Server"],
    ShutdownTimeout = TimeSpan.FromSeconds(10)
});

await using var client = await McpClient.CreateAsync(transport);

Key xref:ModelContextProtocol.Client.StdioClientTransportOptions properties:

Property Description
Command The executable to launch (required)
Arguments Command-line arguments for the process
WorkingDirectory Working directory for the server process
EnvironmentVariables Environment variables (merged with current; null values remove variables)
ShutdownTimeout Graceful shutdown timeout (default: 5 seconds)
StandardErrorLines Callback for stderr output from the server process
Name Optional transport identifier for logging

stdio server

Use xref:ModelContextProtocol.Server.StdioServerTransport for servers that communicate over stdin/stdout:

var builder = Host.CreateApplicationBuilder(args);

builder.Services.AddMcpServer()
    .WithStdioServerTransport()
    .WithTools<MyTools>();

await builder.Build().RunAsync();

Streamable HTTP transport

The Streamable HTTP transport uses HTTP for bidirectional communication with optional streaming. This is the recommended transport for remote servers.

Streamable HTTP client

Use xref:ModelContextProtocol.Client.HttpClientTransport with xref:ModelContextProtocol.Client.HttpTransportMode.StreamableHttp:

var transport = new HttpClientTransport(new HttpClientTransportOptions
{
    Endpoint = new Uri("https://my-mcp-server.example.com/mcp"),
    TransportMode = HttpTransportMode.StreamableHttp,
    ConnectionTimeout = TimeSpan.FromSeconds(30),
    AdditionalHeaders = new Dictionary<string, string>
    {
        ["X-Custom-Header"] = "value"
    }
});

await using var client = await McpClient.CreateAsync(transport);

The client also supports automatic transport detection with xref:ModelContextProtocol.Client.HttpTransportMode.AutoDetect (the default), which tries Streamable HTTP first and falls back to SSE if the server does not support it:

var transport = new HttpClientTransport(new HttpClientTransportOptions
{
    Endpoint = new Uri("https://my-mcp-server.example.com/mcp"),
    // TransportMode defaults to AutoDetect
});

Resuming sessions

Streamable HTTP supports session resumption. Save the session ID, server capabilities, and server info from the original session, then use xref:ModelContextProtocol.Client.McpClient.ResumeSessionAsync* to reconnect:

var transport = new HttpClientTransport(new HttpClientTransportOptions
{
    Endpoint = new Uri("https://my-mcp-server.example.com/mcp"),
    KnownSessionId = previousSessionId
});

await using var client = await McpClient.ResumeSessionAsync(transport, new ResumeClientSessionOptions
{
    ServerCapabilities = previousServerCapabilities,
    ServerInfo = previousServerInfo
});

Streamable HTTP server (ASP.NET Core)

Use the ModelContextProtocol.AspNetCore package to host an MCP server over HTTP. The xref:Microsoft.AspNetCore.Builder.McpEndpointRouteBuilderExtensions.MapMcp* method maps the Streamable HTTP endpoint at the specified route (root by default). It also maps legacy SSE endpoints at {route}/sse and {route}/message for backward compatibility.

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddMcpServer()
    .WithHttpTransport()
    .WithTools<MyTools>();

var app = builder.Build();
app.MapMcp();
app.Run();

A custom route can be specified. For example, the AspNetCoreMcpPerSessionTools sample uses a route parameter:

app.MapMcp("/mcp");

When using a custom route, Streamable HTTP clients should connect directly to that route (e.g., https://host/mcp), while SSE clients should connect to {route}/sse (e.g., https://host/mcp/sse).

SSE transport (legacy)

The SSE (Server-Sent Events) transport is a legacy mechanism that uses unidirectional server-to-client streaming with a separate HTTP endpoint for client-to-server messages. New implementations should prefer Streamable HTTP.

Note

The SSE transport is considered legacy. The Streamable HTTP transport is the recommended approach for HTTP-based communication and supports bidirectional streaming.

SSE client

Use xref:ModelContextProtocol.Client.HttpClientTransport with xref:ModelContextProtocol.Client.HttpTransportMode.Sse:

var transport = new HttpClientTransport(new HttpClientTransportOptions
{
    Endpoint = new Uri("https://my-mcp-server.example.com/sse"),
    TransportMode = HttpTransportMode.Sse,
    MaxReconnectionAttempts = 5,
    DefaultReconnectionInterval = TimeSpan.FromSeconds(1)
});

await using var client = await McpClient.CreateAsync(transport);

SSE-specific configuration options:

Property Description
MaxReconnectionAttempts Maximum number of reconnection attempts on stream disconnect (default: 5)
DefaultReconnectionInterval Wait time between reconnection attempts (default: 1 second)

SSE server (ASP.NET Core)

The ASP.NET Core integration supports SSE transport alongside Streamable HTTP. The same MapMcp() endpoint handles both protocols — clients connecting with SSE are automatically served using the legacy SSE mechanism:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddMcpServer()
    .WithHttpTransport()
    .WithTools<MyTools>();

var app = builder.Build();

// MapMcp() serves both Streamable HTTP and legacy SSE.
// SSE clients connect to /sse (or {route}/sse for custom routes).
app.MapMcp();
app.Run();

No additional configuration is needed. When a client connects using the SSE protocol, the server responds with an SSE stream for server-to-client messages and accepts client-to-server messages via a separate POST endpoint.

Transport mode comparison

Feature stdio Streamable HTTP SSE (Legacy)
Process model Child process Remote HTTP Remote HTTP
Direction Bidirectional Bidirectional Server→client stream + client→server POST
Session resumption N/A ✓ ✗
Authentication Process-level HTTP auth (OAuth, headers) HTTP auth (OAuth, headers)
Best for Local tools Remote servers Legacy compatibility