Releases: modelcontextprotocol/csharp-sdk
Release list
v2.1.0
This release adds an opt-in subscriptions/listen handler for custom server-side notification streams, improves HTTP transport fallback reliability, and expands guidance and samples for telemetry and binary resources.
What's Changed
- Keep AutoDetect channel open after provisional SSE failure #1768 by @PranavSenthilnathan
- Preserve HTTP status codes across target frameworks #1767 by @PranavSenthilnathan
- Fall back to initialize when server/discover fails at the HTTP layer #1766 by @rbstp
- Add public subscriptions/listen server handler (SEP-2575) #1775 by @tarekgh
Documentation Updates
- Add README for the InMemoryTransport sample #1769 by @AkbarDizaji
- Add Application Insights telemetry example #1778 by @lntutor
- Clarify client handling of embedded binary tool resources #1762 by @luisangelrod
Test Improvements
- Speed up CLI argument escaping tests #1773 by @PranavSenthilnathan
Repository Infrastructure Updates
- Clarify AI disclosure format with a
> [!NOTE]alert example #1771 by @PranavSenthilnathan (co-authored by @Copilot) - Bump the npm_and_yarn group across 1 directory with 6 updates #1787
- Avoid reading Configuration in Directory.Build.props #1776 by @lntutor
- Bump danielpalme/ReportGenerator-GitHub-Action from 5.5.10 to 5.5.11 #1784
Acknowledgements
- @AkbarDizaji made their first contribution in #1769
- @luisangelrod made their first contribution in #1762
- @rbstp submitted issue #1765 (resolved by #1766)
- @TomasHubelbauer submitted issue #1026 (resolved by #1778)
- @Youssef1313 submitted issue #995 (resolved by #1766)
- @eng-marani submitted issue #1261 (resolved by #1762)
- @jeffhandley @tarekgh @halter73 @PranavSenthilnathan reviewed pull requests
Full Changelog: v2.0.0...v2.1.0
v2.0.0
Version 2.0.0 brings the C# SDK into stable alignment with the MCP 2026-07-28 specification.
This major release introduces discovery-first negotiation, multi-round-trip requests, stateless-by-default HTTP, caching hints, standardized headers, stronger OAuth and token-cache safety, and dedicated MCP Apps and Tasks extension packages, with down-level interoperability for peers negotiating 2025-11-25 and earlier. Review the migration guidance below.
Breaking Changes
Refer to the C# SDK Versioning documentation for details on versioning and breaking-change policies.
- Default to stateless HTTP and discovery-first negotiation #1610
HttpServerTransportOptions.Statelessnow defaults totrue. Stateless servers do not create transport sessions, expose the standalone SSEGET/DELETEendpoints, or support unsolicited server-to-client requests.- Set
Stateless = falsewhen an existing server requires legacy stateful behavior. Stateful-only options now produceMCP9006warnings and apply only to down-level initialize-handshake connections. - Clients probe
server/discoverfirst and automatically fall back to the legacyinitializehandshake for down-level servers.
- Deprecate Roots, Sampling, and Logging APIs #1651
- The stable Roots, Sampling, and Logging API surfaces now produce
MCP9005warnings because these features are deprecated by the 2026-07-28 specification. - Existing down-level connections can continue using these APIs. Suppress
MCP9005temporarily if continued use is required while planning migration.
- The stable Roots, Sampling, and Logging API surfaces now produce
- Move Tasks into
ModelContextProtocol.Extensions.Tasks#1693- The v1.4.x Tasks implementation is replaced by a dedicated extension package and has no API or wire compatibility with the earlier experimental implementation.
- Add a reference to
ModelContextProtocol.Extensions.Tasks, import its namespace, register Tasks withWithTasks(...), and replace CoreRequestMethods.Tasks*constants withTasksProtocolmembers.
- Strengthen OAuth callback and issuer validation #1605
AuthorizationRedirectDelegateandClientOAuthOptions.AuthorizationRedirectDelegatenow produceMCP9007warnings. Migrate toClientOAuthOptions.AuthorizationCallbackHandlerso callbacks can return the authorization code, state, and issuer.- OAuth authorization now rejects issuer mismatches required by RFC 9207 and RFC 8414. Correct inconsistent authorization-server metadata rather than bypassing validation.
- Emit non-object structured tool results directly #1568
- Tools with
UseStructuredContent = trueand a non-object return type now emit the raw value and matching schema, such asstructuredContent: 72, instead of wrapping it as{ "result": 72 }. - Update clients to read the value according to the advertised output schema rather than assuming a
resultproperty.
- Tools with
- Require
Tool.inputSchemaduring deserialization #1600- Deserializing a
Toolpayload withoutinputSchemanow throwsJsonExceptioninstead of silently defaulting the schema. - Custom servers, proxies, and test fixtures that produce tool JSON must include
inputSchema; an empty{}is sufficient.
- Deserializing a
- Require explicit PKCE S256 support in OAuth metadata #1700
- OAuth authorization now fails when authorization-server metadata does not advertise
S256incode_challenge_methods_supported. - Update the authorization server metadata to declare PKCE S256 support.
- OAuth authorization now fails when authorization-server metadata does not advertise
- Send
application_typeduring dynamic client registration #1613- Dynamic client registration requests now include an inferred
application_type. - Authorization servers that validate the request shape must accept this standard field; set
DynamicClientRegistrationOptions.ApplicationTypeexplicitly when the inferred value is not appropriate.
- Dynamic client registration requests now include an inferred
- Propagate underlying SSE connection exceptions #1432
- Explicit SSE connections now surface the underlying
HttpRequestException,TimeoutException, or genuine I/O exception instead of always wrapping failures inIOException. - Update connection error handling that depends on the old
IOException("Failed to connect transport.")wrapper. In AutoDetect mode, inspect the outerHttpRequestExceptionand its inner SSE failure.
- Explicit SSE connections now surface the underlying
- Fail OAuth step-up when a challenge makes no progress #1591
- A repeated
insufficient_scopechallenge that introduces no new scopes now throwsMcpExceptioninstead of retrying indefinitely. - Handle the exception as an authorization failure and ensure repeated challenges add scopes when another step-up attempt is expected.
- A repeated
What's Changed
- Add
InheritEnvironmentVariablestoStdioClientTransportOptions#1563 by @halter73 - Stop logging stdio transport environment variables #1538 by @halter73 (co-authored by @Copilot)
- Implement SEP-2243 HTTP header standardization #1553 by @mikekistler (co-authored by @tarekgh @Copilot)
- Append
offline_accessto authorization scope when advertised (SEP-2207) #1479 by @stephentoub (co-authored by @Copilot) - Deprecate
McpErrorCode.ResourceNotFoundper SEP-2164 #1558 by @jayaraman-venkatesan - Add APIs for pre-populating the
McpClienttool cache #1590 by @tarekgh - Add
ScopeSelectorDelegateto OAuth options #1596 by @halllo - Validate the authenticated user on Streamable HTTP session deletion #1604 by @halter73
- Relax resource URI validation to accept a base URL #1517 by @JBallan (co-authored by @tarekgh)
- Rename
MinVersionForStandardHeaderstoDraftProtocolVersion#1603 by @halter73 - Add Enterprise Managed Authorization support (SEP-990) #1305 by @aniket-okta
- Add multi-round-trip requests (MRTR) #1458 by @halter73
- Align
x-mcp-headerbehavior with SEP-2243 clarifications #1619 by @tarekgh - Skip the idle-tracking timer in stateless mode #1531 by @MukundaKatta
- Fix
$refpointer resolution after output-schema wrapping #1435 by @weinong - Add
McpClientOptions.InitializeMeta#1599 by @adityasingh2400 - Remove
charset=utf-8from HTTPapplication/jsoncontent types #1528 by @jayaraman-venkatesan - Require Tool
inputSchemaduring deserialization #1600 by @DragonFSKY - Release the SSE response stream reference when a GET request ends #1519 by @joelmforsyth
- Diagnose messages dropped from the GET SSE stream #1609 by @halter73
- Implement the SEP-2663 Tasks extension #1579 by @PranavSenthilnathan (co-authored by @Copilot)
- Add SEP-2549 caching hints to cacheable results #1623 by @tarekgh
- Accept any JSON Schema 2020-12 document as an output schema (SEP-2106) #1568 by @jayaraman-venkatesan (co-authored by @mikekistler)
- Add MCP Apps extension support #1484 by @mikekistler (co-authored by @Copilot)
- Accumulate client scopes during step-up authorization (SEP-2350) #1591 by @mikekistler (co-authored by @Copilot @tarekgh)
- Obsolete Roots, Sampling, and Logging APIs per SEP-2577 #1651 by @tarekgh
- Enable .NET Framework UI MCP clients #1639 by @KirillOsenkov
- Use
TimeToLiveinstead ofTtlMsin public APIs #1644 by @PranavSenthilnathan (co-authored by @halter73 @Copilot) - Add sessionless and handshake-less draft protocol support #1610 by @halter73
- Stabilize official Extensions, Tasks, and MRTR APIs #1642 by @PranavSenthilnathan (co-authored by @Copilot)
- Finalize 2026-07-28 terminology, error codes, and protocol-version floors #1671 by @halter73
- Document caching behavior and warn on non-conformant cacheable results #1669 by @tarekgh
- Stabilize protocol properties #1686 by @eiriktsarpalis (co-authored by @Copilot)
- Echo the request ID in post-parse Streamable HTTP errors #1687 by @tarekgh
- Add
DeferChangedEvents()for batched primitive-change notifications #1689 by @jeffhandley (co-authored by @Copilot) - Fix request-scoped client capabilities #1685 by @PranavSenthilnathan (co-authored by @Copilot @tarekgh)
- Tighten protocol-negotiation boundaries #1692 by @halter73 (co-authored by @Copilot @tarekgh)
- Add the
completeresult discriminator #1684 by @PranavSenthilnathan (co-authored by @Copilot @tarekgh) - Ignore empty Streamable HTTP JSON responses #1626 by @jstar0
- Extract Tasks into
ModelContextProtocol.Extensions.Tasks#1693 by @jeffhandley (co-authored by @Copilot @tarekgh) - Add an opt-out for the Streamable HTTP standalone GET stream #1699 by @jstar0 (co-authored by @jeffhandley @Copilot)
- Enforce PKCE metadata compliance in the OAuth client #1700 by @PranavSenthilnathan
- Make authorization-provider token caches thread-safe #1708 by @tarekgh
- Add
application_typeto dynamic client registration #1613 by @jayaraman-venkatesan - Preserve the underlying status code in AutoDetect probes #1530 by @MukundaKatta
- Return a JSON-RPC parse error for over-nested stdio requests #1629 by @adityasingh2400 (co-authored by @tarekgh)
- Implement RFC 9207 issuer validation in
ClientOAuthProvider#1605 by @mikekistler - Reject mismatched initialize protocol versions #1724 by @halter73 (co-authored by @Copilot)
- Fix
ClientOAuthProviderclient ID availability on cold start #1705 by @halter73 (co-authored by @Copilot) - Fix HTTP Task filter composition #1722 by @PranavSenthilnathan
- Rename MCPEXP002 extensibility constants #1739 by @arimu1
- Propagate underlying SSE connection exceptions #1432 by @xue-cai (co-authored by @Copilot @jeffhandley)
- Validate OAuth authorization state #1726 by @halter73 (co-authored by @Copilot)
- Gate 2026-07-28 result fields on the negotiated protocol version #1753 by @tarekgh
- Align the 2026-07-28 wire with specification PR #3002 and SEP-2575 HTTP statuses #1752 by @pcarleton (co-authored by @halter73 @Copilot @tarekgh)
- Reauthorize tools changed by call-tool filters #1737 by @PranavSenthilnathan
- Enable additional client conformance scenarios #1763 by @halter73 (co-authored by @Copilot)
Documentation Upd...
v2.0.0-rc.2
This second 2.0 release candidate advances the SDK’s 2026-07-28 protocol support, expands Tasks extension conformance tests, strengthens OAuth and transport behavior, and expands 2.0 guidance ahead of general availability.
Thank you to the community for using the preview and release-candidate builds and for sharing feedback and issue reports that shape this release!
Breaking Changes
Refer to the C# SDK Versioning documentation for details on versioning and breaking-change policies.
- Align the 2026-07-28 wire protocol and SEP-2575 HTTP statuses #1752
- Aligns with protocol adjustment #3002.
DiscoverResult.ServerInfois removed; read and deserializeMeta[MetaKeys.ServerInfo]instead.- On
2026-07-28, replace legacy initialization, ping, logging, and resource-subscription methods withserver/discover,_metalog level, andsubscriptions/listen.
- Validate OAuth authorization state #1726
- Custom authorization callback handlers must propagate the redirect
statethroughAuthorizationResult.State, and should returnCode,State, andIss.
- Custom authorization callback handlers must propagate the redirect
- Fix SSE session transport shutdown behavior #1432
- Handle the underlying transport exception rather than depending on an
IOExceptionwrapper.
- Handle the underlying transport exception rather than depending on an
What's Changed
- Fix SSE session transport shutdown behavior #1432 by @xue-cai (co-authored by @Copilot)
- Validate OAuth authorization state #1726 by @halter73 (co-authored by @Copilot)
- Add configurable Tasks execution modes and complete conformance support #1741 by @PranavSenthilnathan (co-authored by @Copilot)
- Gate 2026-07-28 result fields by negotiated protocol version #1753 by @tarekgh
- Align the 2026-07-28 wire protocol and SEP-2575 HTTP statuses #1752 by @pcarleton (co-authored by @tarekgh @Copilot)
- Reauthorize tools changed by call-tool filters #1737 by @PranavSenthilnathan (co-authored by @Copilot)
Documentation Updates
- Refine 2.0.0 concept documentation #1742 by @jeffhandley (co-authored by @Copilot)
Test Improvements
- Resolve test-server paths deterministically #1735 by @PranavSenthilnathan (co-authored by @Copilot)
- Add MCP Apps NativeAOT coverage #1711 by @lntutor
- Add MCP Apps
_meta.uiserialization round-trip tests #1698 by @yayayouyou
Repository Infrastructure Updates
- Bump actions/setup-node from 6.4.0 to 7.0.0 #1717
- Bump coverlet.collector from 10.0.0 to 10.0.1 #1582
- Bump qs from 6.14.2 to 6.15.2 #1597
- Bump actions/setup-dotnet from 5.2.0 to 6.0.0 #1716
- Bump danielpalme/ReportGenerator-GitHub-Action from 5.5.5 to 5.5.10 #1569
- Bump actions/checkout from 6 to 7 #1665
- Rename MCPEXP002 extensibility constants #1739 by @arimu1
- Bump the testing-frameworks group #1746
- Bump the serilog-testing group #1748
- Bump actions/checkout from 7.0.0 to 7.0.1 #1745
- Bump Anthropic from 12.17.0 to 12.39.0 #1750
- Bump OpenTelemetry and five other dependencies #1747
- Bump JsonSchema.Net and System.Linq.AsyncEnumerable #1749
- Update Microsoft.Extensions.AI dependencies #1755 by @jeffhandley (co-authored by @Copilot)
- Add AI disclosure guidance #1756 by @PranavSenthilnathan (co-authored by @Copilot)
Acknowledgements
- @lntutor, @arimu1, @yayayouyou, and @xue-cai made their first contributions in #1711, #1739, #1698, and #1432.
- @p-ob reported #1721, resolved by #1753.
- @pcarleton initiated #1752 to address the SEP-2575 revision.
- @jeffhandley @PranavSenthilnathan @halter73 @tarekgh @jozkee reviewed pull requests.
Full Changelog: v2.0.0-rc.1...v2.0.0-rc.2
v2.0.0-rc.1
2.0.0-rc.1 advances the v2 SDK toward general availability with stronger OAuth conformance, improved dynamic client registration, and expanded Tasks validation.
We remain on-track to release 2.0.0 stable on or before 2026-07-28.
We want to give a big thanks to @KubaZ2 for reporting the critical, ship-stopping Tasks/HTTP defect in #1720, fixed by #1722!
Breaking Changes
Refer to the C# SDK Versioning documentation for details on versioning and breaking change policies.
-
Remove the preview task-scope helper #1722
McpTasksServerExtensions.CreateMcpTaskScope(...)was removed from the stable surface. This affects only applications built against the v2 preview API; no stable 2.0 release has shipped.- There is no stable direct replacement; update affected task-scope integration code for the current Tasks APIs.
-
Harden OAuth issuer validation #1605
AuthorizationRedirectDelegatenow producesMCP9007, which breaks warning-as-error builds; the manual authorization flow now requires the complete redirect URL.- Migrate to
AuthorizationCallbackHandlerand returnAuthorizationResult.
-
Require advertised PKCE S256 support #1700
- Authorization servers that omit
code_challenge_methods_supported: ["S256"]now cause authentication to fail instead of receiving an inferred default. - Correct the authorization-server metadata or use a compliant discovery document.
- Authorization servers that omit
-
Send Dynamic Client Registration application types #1613
- Unset
ApplicationTypenow sends an inferredapplication_typeinstead of omitting it. - Set
DynamicClientRegistrationOptions.ApplicationTypeexplicitly when the authorization server requires another value.
- Unset
What's Changed
- Require advertised PKCE S256 support #1700 by @PranavSenthilnathan (co-authored by @Copilot)
- Make authorization-provider token caches thread-safe #1708 by @tarekgh
- Send
application_typein Dynamic Client Registration requests #1613 by @jayaraman-venkatesan (co-authored by @Copilot) - Preserve the original AutoDetect probe status code #1530 by @MukundaKatta
- Return JSON-RPC parse errors for over-nested stdio requests #1629 by @adityasingh2400
- Implement RFC 9207 issuer validation in
ClientOAuthProvider#1605 by @mikekistler (co-authored by @halter73 @Copilot) - Reject mismatched initialize protocol versions #1724 by @halter73 (co-authored by @Copilot)
- Fix OAuth client-ID initialization on cold start #1705 by @halter73 (co-authored by @Copilot)
- Fix HTTP task-filter composition #1722 by @PranavSenthilnathan (co-authored by @Copilot)
- Add initial Tasks extension conformance coverage #1734 by @PranavSenthilnathan (co-authored by @Copilot)
Documentation Updates
- Publish a side-by-side, multi-version documentation site with selectable
release/1.x(v1.4.1) andmain(v2 preview) content #1727 by @jeffhandley (co-authored by @Copilot) - Add Docker-based MCP server deployment guidance #1423 by @john-mckillip (co-authored by @Copilot)
- Improve v2 conceptual documentation clarity and consistency #1728 by @gewarren
- Improve v1 documentation clarity and consistency, and versioning updates #1729 by @jeffhandley (co-authored by @Copilot)
Test Improvements
- Expand npm conformance coverage #1725 by @halter73 (co-authored by @Copilot)
- Extend the in-memory server/discover probe timeout to prevent flaky Windows Debug CI hangs #1702 by @PranavSenthilnathan (co-authored by @halter73 @Copilot)
Acknowledgements
- @john-mckillip made their first contribution in #1423
- @buvinghausen submitted issue #147 (resolved by #1423)
- @mllab-nl submitted issue #730 (resolved by #1700)
- @shmed submitted issue #1526 (resolved by #1530)
- @cclabadmin submitted issues #1580 and #1614 (resolved by #1724 and #1629)
- @KirillOsenkov submitted issue #1658 (resolved by #1705)
- @KubaZ2 reported the critical, ship-stopping P0 Tasks/HTTP defect in #1720 (resolved by #1722)
- @gewarren submitted dotnet/docs#54713 (resolved by #1728)
- @halter73 @jeffhandley @tarekgh @PranavSenthilnathan @luisquintanilla @mikekistler reviewed pull requests
Full Changelog: v2.0.0-preview.3...v2.0.0-rc.1
v2.0.0-preview.3
This preview reorganizes the Tasks feature into its own ModelContextProtocol.Extensions.Tasks package, keeping ModelContextProtocol.Core focused on the base protocol while a new generic request-handler and alternate-result surface lets the Tasks package layer on top. It also delivers correctness fixes to the draft 2026-07-28 protocol -- per-request client capabilities, negotiation boundaries, and the resultType discriminator -- plus Streamable HTTP client improvements (an empty-JSON-response fix and a new standalone GET-stream opt-out) and conformance-test consolidation.
Breaking Changes
Refer to the C# SDK Versioning documentation for details on versioning and breaking change policies.
- Tasks extracted into the new
ModelContextProtocol.Extensions.Taskspackage #1693- The Tasks API -- task result/notification types,
McpTaskStatus,IMcpTaskStore/InMemoryMcpTaskStore, thetasks/*request methods, and the clientGetTaskAsync/UpdateTaskAsync/CancelTaskAsync/CallToolRawAsyncmethods -- is removed fromModelContextProtocol.Coreand relocated to the newModelContextProtocol.Extensions.Taskspackage under theModelContextProtocol.Extensions.Tasksnamespace. - Core now exposes a task-agnostic
ResultOrAlternate<T>(replacingResultOrCreatedTask<T>) plus generic extension points --McpServerRequestHandler,McpServerOptions.RequestHandlers,McpServerHandlers.CallToolWithAlternateHandler,McpRequestFilters.CallToolWithAlternateFilters, andMcpServer.InterceptOutgoingRequests-- that the Tasks package builds on. - Migration: add a
PackageReferencetoModelContextProtocol.Extensions.Tasks; changeusing ModelContextProtocol.Protocol;tousing ModelContextProtocol.Extensions.Tasks;for task types; the task client/server APIs are now extension methods (McpTasksClientExtensions/McpTasksServerExtensions), and the task store is registered via the new builder extensions instead ofMcpServerOptions.TaskStore.
- The Tasks API -- task result/notification types,
Experimental APIs
To support extracting Tasks (#1693), ModelContextProtocol.Core gained a generic server-extension surface -- ResultOrAlternate<T>, McpServerRequestHandler, McpServerOptions.RequestHandlers, McpServerHandlers.CallToolWithAlternateHandler, McpRequestFilters.CallToolWithAlternateFilters, and McpServer.InterceptOutgoingRequests -- that lets extension packages such as ModelContextProtocol.Extensions.Tasks layer behavior onto the server pipeline. These APIs are annotated [Experimental] under diagnostic ID MCPEXP002.
This surface is still being designed: #1704 tracks composing these seams with the normal filter and subscription pipeline (typed custom RPCs, filter composition, and extension-defined subscriptions). Expect these low-level extensibility APIs to change and potentially remain [Experimental] through the 2.0.0 stable release.
What's Changed
- Fix request-scoped draft client capabilities #1685 by @PranavSenthilnathan (co-authored by @Copilot)
- Tighten draft protocol negotiation boundaries #1692 by @halter73 (co-authored by @Copilot)
- Fix missing resultType on complete result responses #1684 by @PranavSenthilnathan (co-authored by @Copilot)
- Ignore empty Streamable HTTP JSON responses #1626 by @jstar0
- Extract Tasks into the
ModelContextProtocol.Extensions.Tasksextension package #1693 by @jeffhandley (co-authored by @Copilot) - Add opt-out for Streamable HTTP standalone GET stream #1699 by @jstar0 (co-authored by @Copilot)
Test Improvements
- Re-enable http-custom-headers conformance scenario #1691 by @tarekgh
- Run stateful and stateless conformance endpoints in a single server process #1672 by @halter73 (co-authored by @Copilot)
Acknowledgements
- @jstar0 made their first contribution in #1626
- @cclabadmin submitted #1676 (resolved by #1684)
- @cclabadmin submitted #1680 (resolved by #1692)
- @DmitryLukyanov submitted #1132 (resolved by #1626)
- @KirillOsenkov submitted #1637 (resolved by #1699)
- @halter73 @tarekgh @PranavSenthilnathan @jeffhandley reviewed pull requests
Full Changelog: v2.0.0-preview.2...v2.0.0-preview.3
v2.0.0-preview.2
This second preview of the 2.0.0 series advances the SDK's alignment with the upcoming 2026-07-28 MCP protocol revision: it adds client-side conformance diagnostics for the SEP-2549 caching hints, makes Streamable HTTP error responses echo the request id per the base protocol and SEP-2243, and fully stabilizes now-stable protocol properties so consumer-defined source generators serialize them correctly. Separately -- and unrelated to the protocol revision -- it introduces DeferChangedEvents() on McpServerPrimitiveCollection<T> for batching list_changed notifications when registering primitives in bulk. There are no breaking changes relative to v2.0.0-preview.1.
What's Changed
- Document caching behavior and warn on non-conformant draft cacheable results (SEP-2549 follow-up) #1669 by @tarekgh
- Fully stabilize now-stable protocol properties #1686 by @eiriktsarpalis (co-authored by @Copilot)
- Echo request id in post-parse Streamable HTTP error responses #1687 by @tarekgh
- Add DeferChangedEvents() to McpServerPrimitiveCollection for batched change notifications #1689 by @jeffhandley (co-authored by @Copilot)
Documentation Updates
- Update package READMEs as part of the release process #1683 by @jeffhandley (co-authored by @Copilot)
Acknowledgements
- @cclabadmin submitted issue #1677 (resolved by #1687)
- @lewing submitted issue #1688 (resolved by #1689)
- @PranavSenthilnathan @halter73 @davidortinau @jeffhandley @lewing @tarekgh reviewed pull requests
Full Changelog: v2.0.0-preview.1...v2.0.0-preview.2
v1.4.1
This release backports a memory-leak fix for HTTP/SSE-based MCP servers. StreamableHttpServerTransport now releases its Server-Sent Events response stream reference as soon as a GET request ends, instead of holding it until the session is disposed via explicit DELETE or idle timeout. Long-lived SSE clients that disconnect without sending DELETE no longer pin the underlying Kestrel connection and its associated memory-pool buffers (~20 MiB per session), preventing the sustained memory growth that could accumulate under connect/disconnect churn.
What's Changed
- Release SSE response stream reference when GET request ends #1628 by @halter73 (co-authored by @joelmforsyth @Copilot)
Acknowledgements
- @slomangino123 submitted issue #766 (resolved by #1628)
Full Changelog: v1.4.0...v1.4.1
v2.0.0-preview.1
This is the first preview of the C# MCP SDK 2.0.0, designed for alignment with the 2026-07-28 MCP specification release. The SDK implements the 2026-07-28 protocol version which fundamentally changes how clients and servers interact -- removing the initialize handshake (SEP-2575), eliminating server-side session state (SEP-2567), introducing Multi Round-Trip Requests (SEP-2322), and deprecating legacy capabilities in favor of the new extensions framework (SEP-2133).
The 2.0.0 SDK is fully backward-compatible with servers and clients using the previous 2024-11-05 protocol version. Clients automatically negotiate down to the legacy initialize handshake when connecting to older servers, and servers continue to accept initialize requests from older clients. API breaking changes in 2.0.0 are limited to two categories: (1) APIs for capabilities deprecated by the new specification (Roots, Sampling, and Logging), which are now marked [Obsolete] with guidance toward their replacements, and (2) experimental APIs whose contracts changed as the specifications were finalized. Stable, non-deprecated APIs from 1.x continue to work without modification.
Protocol Version Negotiation and Handshake Behavior
The 2.0.0 SDK introduces a fundamentally new connection lifecycle:
Default behavior (no configuration needed):
- Client sends a
server/discoverrequest withMCP-Protocol-Version: 2026-07-28 - If the server supports the
2026-07-28protocol version, it responds with capabilities -- no handshake, no session - If the server returns an error (MethodNotFound, InvalidParams, etc.) or times out (5s default via
McpClientOptions.DiscoverProbeTimeout), the client automatically falls back to the legacyinitializehandshake with2025-11-25 - Three "modern server" error codes (
-32022UnsupportedProtocolVersion,-32021MissingRequiredClientCapability,-32020HeaderMismatch) are never treated as legacy indicators and are surfaced as errors
Opting out of the 2026-07-28 protocol version:
- Set
McpClientOptions.ProtocolVersion = "2025-11-25"to force the legacyinitializehandshake and disable the automatic fallback (a non-nullProtocolVersionnow acts as both the requested version and the minimum the client accepts)
Per-request metadata (2026-07-28 protocol version):
- Every request carries
_metawithio.modelcontextprotocol/protocolVersion,io.modelcontextprotocol/clientInfo, andio.modelcontextprotocol/clientCapabilities - Servers MUST NOT infer capabilities from previous requests -- each request is self-describing
2026-07-28 Spec Alignment: SEP Implementation Status
The 2026-07-28 specification release includes 22 SEPs. The table below summarizes C# SDK status. Remaining work is tracked in the 2026-07-28 Spec Compliance milestone.
| SEP | Title | Status | Closed | Open |
|---|---|---|---|---|
| SEP-2596 | Feature Lifecycle and Deprecation Policy | ✅ Aligned | -- | -- |
| SEP-2484 | Require Conformance Tests | 🚧 Partial | -- | #1653 |
| SEP-1730 | SDK Tiers Definition | ✅ Aligned | -- | -- |
| SEP-2575 | Make MCP Stateless | 🚧 Partial | #1610, #1671 | #1670 |
| SEP-2567 | Sessionless MCP via Explicit State Handles | ✅ Complete | #1610, #1671 | -- |
| SEP-2577 | Deprecate Roots, Sampling, and Logging | ✅ Complete | #1651 | -- |
| SEP-2133 | Extensions Framework | ✅ Complete | #1642 | -- |
| SEP-2663 | Tasks Extension | ✅ Complete | #1579, #1642 | -- |
| SEP-1865 | MCP Apps Extension | ✅ Complete | #1484 | -- |
| SEP-2322 | Multi Round-Trip Requests (MRTR) | ✅ Complete | #1458, #1642 | -- |
| SEP-2260 | Require Server Requests Associated with Client Request | ✅ Complete | #1458, #1610, #1671 | -- |
| SEP-2549 | TTL for List Results | 🚧 Partial | #1623, #1644 | #1645, #1650 |
| SEP-2243 | HTTP Standardization | 🚧 Partial | #1553, #1603, #1619 | #1655 |
| SEP-2106 | JSON Schema 2020-12 for inputSchema/outputSchema | ✅ Complete | #1568, #1600 | -- |
| SEP-2164 | Standardize Resource Not Found Error Code | ✅ Complete | #1558 | -- |
| SEP-2207 | OIDC-Flavored Refresh Token Guidance | ✅ Complete | #1479 | -- |
| SEP-2350 | Client-Side Scope Accumulation | ✅ Complete | #1591 | -- |
| SEP-2351 | RFC 8414 Well-Known URI Suffix | ✅ Complete | (built-in) | -- |
| SEP-2352 | Authorization Server Binding and Migration | 🚧 Partial | (built-in) | #1474 |
| SEP-2468 | Recommend Issuer (iss) Parameter | 🚧 Partial | -- | #1571, #1605 |
| SEP-837 | Authorization Client Type Requirements | 🚧 Partial | -- | #1545 |
| SEP-414 | OpenTelemetry Trace Context Propagation | ✅ Complete | (built-in) | -- |
Spec Governance and Process SEPs
SEP-2596: Specification Feature Lifecycle and Deprecation Policy
Defines the stages a specification feature moves through: experimental, stable, deprecated, removed.
- The C# SDK uses
[Experimental]attributes on preview APIs (diagnostic IDsMCPEXP001,MCPEXP002,MCPEXP003) - Deprecated features use
[Obsolete]with diagnostic IDMCP9005and migration guidance in the warning message - Aligns with the SDK's versioning documentation
SEP-2484: Require Conformance Tests for Standards Track SEPs
Process requirement: conformance tests must exist before a SEP reaches final status.
- The C# SDK's test suite provides coverage for all SEPs implemented in this release
- Formal conformance test alignment with the spec's test harness is tracked separately
SEP-1730: SDK Tiers Definition
Defines tier requirements (Tier 1, 2, 3) for official MCP SDK implementations.
- The C# SDK targets Tier 1 status
- This release advances Tier 1 coverage through comprehensive 2026-07-28 SEP implementation
Protocol Lifecycle and Transport
SEP-2575: Make MCP Stateless (#1610, #1671)
The most architecturally significant change in the 2026-07-28 spec. Removes the initialize/initialized handshake for servers operating in stateless mode.
- Introduces
server/discoveras a lightweight capability discovery method replacinginitialize - Removes
Mcp-Session-Idheader requirement for stateless servers - Client/server metadata (clientInfo, clientCapabilities, protocolVersion) moves into per-request
_metafields viaMetaKeys.ProtocolVersion,MetaKeys.ClientInfo,MetaKeys.ClientCapabilities - Stateful servers (
HttpServerTransportOptions.Stateless = false, diagnosticMCP9006) reject2026-07-28protocol requests, forcing the client to downgrade to the legacy flow - The SDK client handles this seamlessly -- dual-era servers that support both legacy and
2026-07-28protocol clients work out of the box - Error codes renumbered to match spec PR #2907:
HeaderMismatchis now -32020,MissingRequiredClientCapabilityis now -32021,UnsupportedProtocolVersionis now -32022
SEP-2567: Sessionless MCP via Explicit State Handles (#1610)
Companion to [SEP-2575](https://git...
v1.4.0
v1.4.0 introduces support for the Identity Assertion Authorization Grant (ID-JAG) flow via the new IdentityAssertionGrantProvider, enabling enterprise SSO scenarios where users authenticate once via their enterprise Identity Provider and access MCP servers without per-server authorization prompts. The release also adds a new InheritEnvironmentVariables option on StdioClientTransportOptions for controlling the child server's environment, alongside two security hardening fixes: the stdio client transport no longer enumerates child-process environment variables in Trace logs, and DELETE on a Streamable HTTP session now requires the same authenticated user that initiated the session.
What's Changed
- Stop logging stdio transport environment variables #1538 by @halter73 (co-authored by @Copilot)
- Add
InheritEnvironmentVariablestoStdioClientTransportOptions#1563 by @halter73 (co-authored by @Copilot) - Validate user on Streamable HTTP session DELETE #1604 by @halter73 (co-authored by @Copilot)
HandleDeleteRequestAsyncnow mirrors theHasSameUserIdcheck already enforced on GET and POST. ADELETEwith a validMcp-Session-Idbut a different authenticated user now returns403 Forbiddeninstead of terminating the session — defense-in-depth against a leaked session ID being used to DoS the original owner.
- Add Enterprise Managed Authorization (SEP-990) support #1305 by @aniket-okta (backported in #1625)
- Adds
IdentityAssertionGrantProviderand supporting option/response types inModelContextProtocol.Authenticationimplementing the Identity Assertion Authorization Grant flow: RFC 8693 token exchange at the enterprise IdP (ID Token → JWT Authorization Grant) followed by RFC 7523 JWT bearer grant at the MCP authorization server (JAG → access token). See the new Cross-Application Access section in the transport docs for full usage details.
- Adds
Documentation Updates
Repository Infrastructure Updates
- Update release processes to support release servicing branches #1620 by @jeffhandley (co-authored by @Copilot)
Acknowledgements
- @aniket-okta made their first contribution in #1305
- @felixweinberger submitted issue #949 (resolved by #1305)
- @eiriktsarpalis @ericstj @PranavSenthilnathan reviewed pull requests
Full Changelog: v1.3.0...v1.4.0
v1.3.0
v1.3.0 focuses on improved transport diagnostics and security-focused documentation. The new public ClientTransportClosedException gives stdio and HTTP clients structured access to transport closure details (exit codes, process IDs, stderr tails, HTTP status codes) without parsing exception messages. Two reliability fixes harden the stdio process pipeline (preventing host crashes from user StandardErrorLines callbacks) and correct the stateless HTTP transport's capability advertisement. New conceptual documentation covers role/identity propagation in tool execution, allowed-hosts and CORS guidance for HTTP servers, and aligns the docs information architecture with the MCP specification structure.
What's Changed
- Make
ClientTransportClosedExceptionpublic and unify transport exception handling #1467 by @stephentoub (co-authored by @halter73 @Copilot)- As part of this unification, SSE/HTTP client connection failures from
McpClient.CreateAsync(...)now surface asIOException(the newClientTransportClosedExceptionderives fromIOException) rather thanInvalidOperationException. Caller-triggeredOperationCanceledExceptionis also no longer wrapped, matching standard async cancellation semantics.
- As part of this unification, SSE/HTTP client connection failures from
- Fix process crash when testing Stderr #1449 by @ericstj (co-authored by @Copilot)
- Fix stateless HTTP transport advertising listChanged capability #1509 by @jayaraman-venkatesan
Documentation Updates
- docs: align docs IA with MCP specification structure #1481 by @jeffhandley (co-authored by @mikekistler @Copilot)
- Document recommended pattern for role/identity propagation in MCP tool execution #1497 by @jeffhandley (co-authored by @halter73 @mikekistler @Copilot)
- Document and demonstrate allowed hosts and CORS policy guidance #1554 by @jeffhandley (co-authored by @halter73 @mikekistler @Copilot)
Test Improvements
- Fix flaky OutgoingFilter_MultipleFilters_ExecuteInOrder test #1488 by @ericstj (co-authored by @Copilot)
Repository Infrastructure Updates
- Bump the opentelemetry-testing group with 5 updates #1478
- Bump actions/deploy-pages from 4.0.5 to 5.0.0 #1477
- Bump actions/download-artifact from 8.0.0 to 8.0.1 #1437
- Bump actions/setup-dotnet from 5.1.0 to 5.2.0 #1418
- Bump actions/setup-node from 6.2.0 to 6.3.0 #1419
- Bump the testing-frameworks group with 1 update #1459
- Bump the npm_and_yarn group across 1 directory with 2 updates #1410
- Switch to custom CodeQL workflow #1489 by @jeffhandley
- Block Release Publishing workflow from automatically running on forks #1450 by @jeffhandley (co-authored by @Copilot)
- Bump actions/checkout from 4 to 6 #1504
- Add testing guidelines, update copilot instructions for tests #1507 by @ericstj
- Bump OpenTelemetry and 3 others #1514
- Bump the opentelemetry-testing group with 6 updates #1533
- Bump actions/setup-node from 6.3.0 to 6.4.0 #1522
- Bump actions/upload-pages-artifact from 4.0.0 to 5.0.0 #1511
- Bump the npm_and_yarn group across 1 directory with 5 updates #1500
- Bump Anthropic from 12.9.0 to 12.11.0 #1506
- Bump actions/upload-artifact from 7.0.0 to 7.0.1 #1512
- Bump danielpalme/ReportGenerator-GitHub-Action from 5.5.4 to 5.5.5 #1521
- Bump the testing-frameworks group with 2 updates #1523
- Bump the other-testing group with 2 updates #1534
- Bump Microsoft.Extensions.AI from 10.4.1 to 10.5.0 #1525
- Remove extraneous labels from dependabot.yml #1535 by @mikekistler
- Bump Anthropic from 12.11.0 to 12.17.0 #1544
- Fix dev container configuration to work in codespaces #1555 by @mikekistler
- Bump Microsoft.NET.Test.Sdk from 18.4.0 to 18.5.1 #1543
- Bump the npm_and_yarn group across 1 directory with 3 updates #1565
- Bump Microsoft.Extensions.AI.Abstractions from 10.5.0 to 10.5.2 #1561
Acknowledgements
- @jayaraman-venkatesan made their first contribution in #1509
- @hulumane submitted issue #1455 (resolved by #1467)
- @mikekistler submitted issue #1486 (resolved by #1509)
- @JLLeitschuh submitted issue #1520 (resolved by #1554)
- @mikekistler @stephentoub @jeffhandley @ericstj @halter73 @eiriktsarpalis reviewed pull requests
Full Changelog: v1.2.0...v1.3.0