# MCP C# SDK 2.0 Makes HTTP Stateless by Default and Adds Multi Round-Trip Requests

> Source: <https://www.infoq.com/news/2026/10/MCP-CSharp-SDK-Stateless/?utm_campaign=infoq_content&utm_source=infoq&utm_medium=feed&utm_term=global>
> Published: 2026-10-26 08:00:00+00:00

Microsoft announced the stable release of [version 2.0 of the official MCP C# SDK](https://devblogs.microsoft.com/dotnet/announcing-v20-of-the-official-mcp-csharp-sdk/), implementing the [2026-07-28 revision](https://modelcontextprotocol.io/specification/2026-07-28) of the Model Context Protocol (MCP) specification. The release makes Streamable HTTP servers stateless by default, standardises HTTP headers so infrastructure can route MCP traffic, and introduces Multi Round-Trip Requests (MRTR) for interactive tools. Three minor releases, 2.1 to 2.3, followed between August and October.

MCP is an open protocol that standardises how applications supply context and tools to large language models. The [C# SDK](https://github.com/modelcontextprotocol/csharp-sdk) is maintained in collaboration with Microsoft and builds on ASP.NET Core. The SDK team describes the new specification revision as the largest since the protocol launched, because it rethinks how MCP works over HTTP.

The `initialize` handshake and the `Mcp-Session-Id` header are gone. Protocol version and capabilities now travel with every request, so any server instance can handle any request without sticky routing or shared session stores. `HttpServerTransportOptions.Stateless` now defaults to `true`; servers that need sessions set it to `false`. Clients probe `server/discover` first and fall back to the legacy handshake for older servers. Stateful-only options and the legacy SSE endpoints now raise `MCP9006` and `MCP9004` warnings.

A `tools/call` request now carries `Mcp-Method` and `Mcp-Name` headers, and the [`\[McpHeader\]` attribute](https://csharp.sdk.modelcontextprotocol.io/v2/api/ModelContextProtocol.Server.McpHeaderAttribute.html) promotes a tool parameter to an `Mcp-Param-*` header. Load balancers and gateways can then route on headers without reading the body. The body stays authoritative: a mismatched header makes the server return a `HeaderMismatch` error.

Statelessness removes the channel servers used to ask clients for input mid-call. MRTR replaces it: a tool throws `InputRequiredException` with one or more input requests, built with `InputRequest.ForElicitation`, `ForSampling` or `ForRootsList`, plus an opaque `requestState`. The client collects the answers and re-issues the call with `inputResponses`. `McpClient` does this automatically when handlers are registered. Over stateful sessions with 2025-11-25 or earlier clients, the SDK bridges to the old server-initiated requests; on stateless down-level connections the request surfaces as an `McpException`. Roots, sampling and logging APIs are deprecated under `MCP9005`, following [SEP-2577](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2577).

According to the announcement, stable 1.x APIs keep working. The exception is Tasks, which moved to the opt-in `ModelContextProtocol.Extensions.Tasks` package and is incompatible with the experimental version in 1.3 and 1.4. An experimental `ModelContextProtocol.Extensions.Apps` package covers MCP Apps. The release notes also list stricter OAuth behaviour: RFC 9207 issuer validation, mandatory advertised PKCE `S256` support, and an inferred application type in dynamic client registration. Packages target .NET 8, 9 and 10, plus .NET Standard 2.0.

Version 2.1 added an opt-in `subscriptions/listen` handler for custom server-side notification streams and a fallback to `initialize` when `server/discover` fails at the HTTP layer. Version 2.2 introduced `HttpServerSessionMode`, which lets clients using the 2025-11-25 and 2026-07-28 revisions share one endpoint, and fixed an exception in `McpHeaderEncoder.DecodeValue`.

Version 2.3 made `McpClient.ServerInfo` nullable, a source-breaking change because servers may omit optional identity metadata from `server/discover`; the notes warn against using self-reported identity for security decisions. Modern Streamable HTTP responses now wait for the first protocol message before sending headers, so silent long-running handlers may need progress output or a longer HTTP timeout. Other changes preserve registration order when listing tools, prompts and resources, expose `McpClientOptions.TimeProvider` for deterministic timeout tests, exclude OAuth from `DiscoverProbeTimeout`, and close a stdio server's input before waiting for graceful exit.

One reader of the announcement [asked whether the protocol guards `requestState`](https://devblogs.microsoft.com/dotnet/announcing-v20-of-the-official-mcp-csharp-sdk/?commentid=23060#comment-23060) against tampering or reuse across sessions; no reply appeared in the comments.

The team says its next focus is end-to-end authentication and authorisation. The [SDK is available on NuGet](https://www.nuget.org/profiles/ModelContextProtocol), with documentation on the [project site](https://csharp.sdk.modelcontextprotocol.io/) and release notes for [2.0](https://github.com/modelcontextprotocol/csharp-sdk/releases/tag/v2.0.0), [2.1](https://github.com/modelcontextprotocol/csharp-sdk/releases/tag/v2.1.0), [2.2](https://github.com/modelcontextprotocol/csharp-sdk/releases/tag/v2.2.0) and [2.3](https://github.com/modelcontextprotocol/csharp-sdk/releases/tag/v2.3.0) on GitHub.
