Skip to content

Releases: modelcontextprotocol/csharp-sdk

v2.0.0-preview.2

v2.0.0-preview.2 Pre-release
Pre-release

Choose a tag to compare

@jeffhandley jeffhandley released this 09 Jul 17:53
3e7ca32

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

Full Changelog: v2.0.0-preview.1...v2.0.0-preview.2

v1.4.1

Choose a tag to compare

@jeffhandley jeffhandley released this 09 Jul 00:36
2b7fd35

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

Acknowledgements

Full Changelog: v1.4.0...v1.4.1

v2.0.0-preview.1

v2.0.0-preview.1 Pre-release
Pre-release

Choose a tag to compare

@jeffhandley jeffhandley released this 26 Jun 18:30
d6b1615

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):

  1. Client sends a server/discover request with MCP-Protocol-Version: 2026-07-28
  2. If the server supports the 2026-07-28 protocol version, it responds with capabilities -- no handshake, no session
  3. If the server returns an error (MethodNotFound, InvalidParams, etc.) or times out (5s default via McpClientOptions.DiscoverProbeTimeout), the client automatically falls back to the legacy initialize handshake with 2025-11-25
  4. Three "modern server" error codes (-32022 UnsupportedProtocolVersion, -32021 MissingRequiredClientCapability, -32020 HeaderMismatch) 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 legacy initialize handshake and disable the automatic fallback (a non-null ProtocolVersion now acts as both the requested version and the minimum the client accepts)

Per-request metadata (2026-07-28 protocol version):

  • Every request carries _meta with io.modelcontextprotocol/protocolVersion, io.modelcontextprotocol/clientInfo, and io.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 IDs MCPEXP001, MCPEXP002, MCPEXP003)
  • Deprecated features use [Obsolete] with diagnostic ID MCP9005 and 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/discover as a lightweight capability discovery method replacing initialize
  • Removes Mcp-Session-Id header requirement for stateless servers
  • Client/server metadata (clientInfo, clientCapabilities, protocolVersion) moves into per-request _meta fields via MetaKeys.ProtocolVersion, MetaKeys.ClientInfo, MetaKeys.ClientCapabilities
  • Stateful servers (HttpServerTransportOptions.Stateless = false, diagnostic MCP9006) reject 2026-07-28 protocol 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-28 protocol clients work out of the box
  • Error codes renumbered to match spec PR #2907: HeaderMismatch is now -32020, MissingRequiredClientCapability is now -32021, UnsupportedProtocolVersion is now -32022

SEP-2567: Sessionless MCP via Explicit State Handles (#1610)

Companion to [SEP-2575](https://git...

Read more

v1.4.0

Choose a tag to compare

@jeffhandley jeffhandley released this 04 Jun 17:52
06e3604

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 InheritEnvironmentVariables to StdioClientTransportOptions #1563 by @halter73 (co-authored by @Copilot)
  • Validate user on Streamable HTTP session DELETE #1604 by @halter73 (co-authored by @Copilot)
    • HandleDeleteRequestAsync now mirrors the HasSameUserId check already enforced on GET and POST. A DELETE with a valid Mcp-Session-Id but a different authenticated user now returns 403 Forbidden instead 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 IdentityAssertionGrantProvider and supporting option/response types in ModelContextProtocol.Authentication implementing 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.

Documentation Updates

Repository Infrastructure Updates

  • Update release processes to support release servicing branches #1620 by @jeffhandley (co-authored by @Copilot)

Acknowledgements

Full Changelog: v1.3.0...v1.4.0

v1.3.0

Choose a tag to compare

@jeffhandley jeffhandley released this 08 May 01:38
2ce15f4

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 ClientTransportClosedException public 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 as IOException (the new ClientTransportClosedException derives from IOException) rather than InvalidOperationException. Caller-triggered OperationCanceledException is also no longer wrapped, matching standard async cancellation semantics.
  • 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

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

Full Changelog: v1.2.0...v1.3.0

v1.2.0

Choose a tag to compare

@jeffhandley jeffhandley released this 27 Mar 23:50
498de08

This release improves stateless HTTP transport defaults and documentation with a breaking behavioral change that we are considering as a server reliability fix and therefore not bumping the major version with this release. Legacy SSE endpoints are now disabled by default with a new HttpServerTransportOptions.EnableLegacySse property available to opt back into responding to the SSE endpoints; the property is marked as an [Obsolete] warning as we expect to remove this property in a future major version.

A warning-level [Obsolete] attribute is also applied to the RequestContext(McpServer, JsonRpcRequest) constructor, and the RequestContext(McpServer, JsonRpcRequest, TParams) overload should be used instead. This change contributes to fixes including DI scope lifetime in task-augmented tools, meta/progress combination failures, and outgoing message filter routing. We plan to remove the obsolete overload in a future major version.

Breaking Changes

Refer to the C# SDK Versioning documentation for details on versioning and breaking change policies.

1. Disable legacy SSE by default #1468

MapMcp() no longer maps /sse and /message endpoints by default. Servers whose clients connect via SSE will find those endpoints removed.

Migrating from legacy SSE

If your clients connect to a /sse endpoint (e.g., https://my-server.example.com/sse), they were using the legacy SSE transport--if not running in Stateless mode. The /sse and /message endpoints are now disabled by default (EnableLegacySse is false and marked [Obsolete] with diagnostic MCP9004). Upgrading the server SDK without updating clients will break SSE connections.

Client-side migration. Change the client Endpoint from the /sse path to the root MCP endpoint — the same URL your server passes to MapMcp(). For example:

// Before (legacy SSE):
Endpoint = new Uri("https://my-server.example.com/sse")

// After (Streamable HTTP):
Endpoint = new Uri("https://my-server.example.com/")

With the default HttpTransportMode.AutoDetect transport mode, the client automatically tries Streamable HTTP first. You can also set TransportMode = HttpTransportMode.StreamableHttp explicitly if you know the server supports it.

Server-side migration. If you previously relied on /sse being mapped automatically, you now need EnableLegacySse = true (suppressing the MCP9004 warning) to keep serving those endpoints. The recommended path is to migrate all clients to Streamable HTTP and then remove EnableLegacySse.

Transition period. If some clients still need SSE while others have already migrated to Streamable HTTP, set EnableLegacySse = true with Stateless = false. Both transports are served simultaneously by MapMcp() — Streamable HTTP on the root endpoint and SSE on /sse and /message. Once all clients have migrated, remove EnableLegacySse and optionally switch to Stateless = true.

SSE (legacy — opt-in only)

Legacy SSE endpoints are now disabled by default and must be explicitly enabled via HttpServerTransportOptions.EnableLegacySse. This is the primary reason they are disabled — the SSE transport has no built-in HTTP-level backpressure.

The legacy SSE transport separates the request and response channels: clients POST JSON-RPC messages to /message and receive responses through a long-lived GET SSE stream on /sse. The POST endpoint returns 202 Accepted immediately after queuing the message — it does not wait for the handler to complete. This means there is no HTTP-level backpressure on handler concurrency, because each POST frees its connection immediately regardless of how long the handler runs.

Internally, handlers are dispatched with a fire-and-forget pattern. A client can send unlimited POST requests to /message while keeping the GET stream open, and each one spawns a concurrent handler with no built-in limit.

The GET stream does provide session lifetime bounds: handler cancellation tokens are linked to the GET request's HttpContext.RequestAborted, so when the client disconnects the SSE stream, all in-flight handlers are cancelled. This is similar to SignalR's connection-bound lifetime model — but unlike SignalR, there is no per-client concurrency limit like MaximumParallelInvocationsPerClient. The GET stream provides cleanup on disconnect, not rate-limiting during the connection.

2. Obsolete 2-arg RequestContext constructor #1462

The RequestContext(McpServer, JsonRpcRequest) constructor is now [Obsolete] with diagnostic MCP9003, producing build warnings. The Params property is also changed from TParams? to TParams.

Migration: Use the new 3-arg constructor: new RequestContext(server, request, parameters).

What's Changed

  • Support specifying OutputSchema independently of return type for tools returning CallToolResult #1425 by @stephentoub (co-authored by @Copilot)
  • Add 3-arg RequestContext constructor and obsolete 2-arg to eliminate null-forgiving operator usage #1462 by @halter73 (co-authored by @Copilot)
  • Fix WithMeta + WithProgress causing tool invocation failure #1464 by @stephentoub (co-authored by @Copilot)
  • Fix: create per-task DI scope in ExecuteToolAsTaskAsync to prevent ObjectDisposedException #1433 by @stephentoub (co-authored by @Copilot)
  • Route SendRequestAsync logic through outgoing message filters #1465 by @halter73
  • Add stateless doc, prefer stateless mode and disable legacy SSE by default #1468 by @halter73

Documentation Updates

  • Update documentation URLs to new vanity domain #1414 by @jeffhandley (co-authored by @Copilot)
  • docs: align roots terminology with MCP spec clarification #1469 by @stephentoub (co-authored by @Copilot)

Repository Infrastructure Updates

  • [release-notes skill] Harvest Co-authored-by trailers from all commits in every PR #1429 by @jeffhandley (co-authored by @Copilot)
  • Update System10Version to 10.0.4 and MicrosoftExtensionsVersion to 10.4.0 #1445 by @stephentoub (co-authored by @Copilot)
  • Bump danielpalme/ReportGenerator-GitHub-Action from 5.5.2 to 5.5.4 #1438 by @dependabot
  • Bump the other-testing group with 2 updates #1440 by @dependabot
  • Update Microsoft.Extensions.AI.OpenAI version reference #1456 by @stephentoub
  • Bump Anthropic from 12.8.0 to 12.9.0 #1460 by @dependabot
  • Bump Microsoft.Extensions.AI from 10.4.0 to 10.4.1 #1461 by @dependabot

Acknowledgements

Full Changelog: v1.1.0...v1.2.0

v1.1.0

Choose a tag to compare

@jeffhandley jeffhandley released this 06 Mar 22:12
ca040d7

Highlights of v1.1.0 include client completion details for understanding when and why a client connection ended, auto-populated completion handlers from AllowedValuesAttribute, and bug fixes for server-initiated ping handling, server capabilities initialization, and in-flight message handler cleanup.

What's Changed

  • Register ping handler in McpSessionHandler to support server-initiated pings #1391 by @stephentoub (co-authored by @Copilot)
  • Fix Extensions not being copied to ServerCapabilities during initialization #1399 by @stephentoub (co-authored by @Copilot)
  • Auto-populate completion handlers from AllowedValuesAttribute on prompt/resource parameters #1380 by @stephentoub (co-authored by @Copilot)
  • Add client completion notification and details #1368 by @stephentoub (co-authored by @Copilot)
  • Wait for in-flight message handlers before ProcessMessagesCoreAsync returns #1403 by @stephentoub (co-authored by @Copilot)

Documentation Updates

Repository Infrastructure Updates

  • Enable EnablePackageValidation for all src packages with 1.0.0 baseline #1330 by @jeffhandley (co-authored by @Copilot @stephentoub)
  • Bump hono from 4.12.0 to 4.12.2 in the npm_and_yarn group across 1 directory #1392
  • Bump docfx from 2.78.4 to 2.78.5 #1408
  • Bump actions/download-artifact from 7.0.0 to 8.0.0 #1406
  • Bump actions/upload-artifact from 6.0.0 to 7.0.0 #1405
  • Bump danielpalme/ReportGenerator-GitHub-Action from 5.5.1 to 5.5.2 #1404
  • Bump the testing-frameworks group with 1 update #1407
  • Add issue-triage Copilot skill #1412 by @jeffhandley (co-authored by @Copilot)
  • Release v1.1.0 #1411 by @jeffhandley (co-authored by @Copilot)

Acknowledgements

Full Changelog: v1.0.0...v1.1.0

v1.0.0

Choose a tag to compare

@jeffhandley jeffhandley released this 25 Feb 01:21
551db0d

This is the first stable release of the ModelContextProtocol C# SDK. Thank you to all of the contributors who helped us achieve this milestone!

Breaking Changes

Refer to the C# SDK Versioning documentation for details on versioning and breaking change policies.

  1. Mark RunSessionHandler experimental (MCPEXP002) #1383
    • HttpServerTransportOptions.RunSessionHandler is now annotated with [Experimental("MCPEXP002")]
    • Code that references RunSessionHandler will produce a compile-time warning (or error with TreatWarningsAsErrors); suppress with #pragma warning disable MCPEXP002
    • Consider using ConfigureSessionOptions as an alternative; RunSessionHandler may be removed or change signatures in a future release

What's Changed

  • Add 2025-03-26 OAuth backward compatibility for client conformance #1374 by @jeffhandley (co-authored by @Copilot)
  • Mark RunSessionHandler experimental (MCPEXP002) #1383 by @halter73 (co-authored by @Copilot @jeffhandley)

Documentation Updates

Repository Infrastructure Updates

Acknowledgements

Full Changelog: v1.0.0-rc.1...v1.0.0

v1.0.0-rc.1

v1.0.0-rc.1 Pre-release
Pre-release

Choose a tag to compare

@jeffhandley jeffhandley released this 24 Feb 08:37
2ec082b

This release candidate completes a full API surface area audit ahead of the 1.0.0 stable release, with more changes to public APIs to ensure consistency and long-term maintainability. Protocol DTO types are updated to match the MCP specification, deprecated filter APIs are removed, and bug fixes improve transport reliability and JSON handling.

Breaking Changes

Refer to the C# SDK Versioning documentation for details on versioning and breaking change policies.

  1. Address asymmetry in McpServerHandlers/McpClientHandlers and make all filter properties settable #1337

    • Seals McpClientHandlers to match the already-sealed McpServerHandlers
    • Makes McpServerOptions.Handlers, McpServerOptions.Filters, and all IList<T> filter properties settable with null validation
  2. Remove server back-references from protocol DTO types #1345

    • Removes Tool.McpServerTool, Prompt.McpServerPrompt, Resource.McpServerResource, and ResourceTemplate.McpServerResource properties
    • Use McpServerPrimitiveCollection.TryGetPrimitive() for name-based lookups instead
  3. Make Tool.Name required to match other protocol types #1351

    • Adds required modifier to Tool.Name, matching Prompt.Name, Resource.Name, and other IBaseMetadata implementations
    • Callers must now specify Name in object initializers
  4. Make LoggingMessageNotificationParams.Data required per MCP spec #1353

    • Changes LoggingMessageNotificationParams.Data from JsonElement? to required JsonElement per the MCP specification
  5. Fix CreateMessageRequestParams.Metadata type to JsonObject #1354

    • Changes CreateMessageRequestParams.Metadata from JsonElement? to JsonObject? to match all other _meta/Meta properties in the SDK
  6. Normalize CallToolResult.StructuredContent to JsonElement? #1357

    • Changes CallToolResult.StructuredContent from JsonNode? to JsonElement? for consistency with the rest of the SDK
    • Use JsonSerializer.SerializeToElement() to produce a JsonElement
  7. Unify service configuration for ISseEventStreamStore, IMcpTaskStore, and ISessionMigrationHandler #1362

    • Consistent options + DI pattern: explicit options property > DI resolution
  8. Add explicit [Experimental] protected constructors to McpClient and McpServer #1363

    • Protected constructors on McpClient and McpServer now require suppressing MCPEXP002 to subclass
  9. Remove MCP9002 obsolete APIs and document obsolete diagnostics #1366

    • Removes the 13 AddXxxFilter extension methods on IMcpServerBuilder (e.g. AddCallToolFilter, AddListToolsFilter) that were deprecated under diagnostic MCP9002
    • Use WithRequestFilters() and WithMessageFilters() instead
  10. Fix McpClientPrompt/Resource types to use RequestOptions like McpClientTool does #1370

    • Replaces JsonSerializerOptions with RequestOptions parameter for consistency across McpClientPrompt, McpClientResource, and McpClientTool

What's Changed

  • Make Tool.Name required to match other protocol types #1351 by @stephentoub (co-authored by @Copilot)
  • Make LoggingMessageNotificationParams.Data required per MCP spec #1353 by @stephentoub (co-authored by @Copilot)
  • Fix off-by-one error in reconnection attempts #1356 by @stephentoub (co-authored by @Copilot)
  • Remove server back-references from protocol DTO types #1345 by @stephentoub (co-authored by @Copilot)
  • Fix base64 deserialization when JSON encoder escapes forward slashes #1342 by @stephentoub (co-authored by @Copilot)
  • Increase MaxReconnectionAttempts default from 2 to 5 #1355 by @stephentoub (co-authored by @Copilot)
  • Prevent cancellation of initialize request per MCP spec #1350 by @stephentoub (co-authored by @Copilot)
  • Address asymmetry in McpServerHandlers/McpClientHandlers and make all filter properties settable #1337 by @stephentoub (co-authored by @Copilot)
  • Normalize CallToolResult.StructuredContent to JsonElement? #1357 by @stephentoub (co-authored by @Copilot)
  • Fix CreateMessageRequestParams.Metadata type to JsonObject #1354 by @stephentoub (co-authored by @Copilot)
  • Remove MCP9002 obsolete APIs and document obsolete diagnostics #1366 by @jeffhandley (co-authored by @Copilot)
  • Add explicit [Experimental] protected constructors to McpClient and McpServer #1363 by @stephentoub (co-authored by @Copilot @jeffhandley)
  • Fix McpClientPrompt/Resource types to use RequestOptions like McpClientTool does #1370 by @stephentoub (co-authored by @Copilot)
  • Unify service configuration for ISseEventStreamStore, IMcpTaskStore, and ISessionMigrationHandler #1362 by @MackinnonBuck

Documentation Updates

  • Fix malformed XML doc on McpServerPrimitiveCollection.Contains #1348 by @stephentoub (co-authored by @Copilot)
  • Clarify null semantics in ToolAnnotations hint property docs #1346 by @stephentoub (co-authored by @Copilot)
  • Fix compilation errors in README code samples #1369 by @jeffhandley
  • Fix XML documentation spelling, grammar, and correctness issues across SDK #1372 by @stephentoub (co-authored by @Copilot)
  • Add Roadmap document and navigation link #1373 by @jeffhandley

Test Improvements

  • Add CloneResourceMetadataClonesAllProperties test using public reflection #1343 by @stephentoub (co-authored by @Copilot)

Repository Infrastructure Updates

  • Bump version to 1.0.0-rc.1 #1376 by @jeffhandley
  • Add README code sample validation step to release-notes skill #1371 by @jeffhandley
  • Bump the other-testing group with 1 update #1358
  • Bump Anthropic from 12.5.0 to 12.8.0 #1359

Acknowledgements

Full Changelog: v0.9.0-preview.2...v1.0.0-rc.1

v0.9.0-preview.2

v0.9.0-preview.2 Pre-release
Pre-release

Choose a tag to compare

@jeffhandley jeffhandley released this 21 Feb 22:22
1a6c0dd

This release focuses on API surface consistency and correctness ahead of 1.0.0. Public collection properties are now typed as IList<T> instead of concrete List<T> or T[], and Root.Meta is aligned with the rest of the protocol DTOs by using JsonObject?. Other improvements include new experimental Extensions support for capabilities, missing ResourceLinkBlock properties, improved mimeType handling, and several documentation and test reliability fixes.

We plan to release the stable 1.0.0 release early in the week of February 23, 2026.

Breaking Changes

Refer to the C# SDK Versioning documentation for details on versioning and breaking change policies.

  1. Replace concrete collection types with interfaces in public API surface #1326

    • List<T> and T[] properties on ProtectedResourceMetadata, ToolResultContentBlock, ListTasksResult, and DynamicClientRegistrationResponse changed to IList<T>. Replace .Length with .Count and cast to List<T> if List<T>-specific members are needed.
  2. Fix Root.Meta to use JsonObject instead of JsonElement #1341

    • Root.Meta changed from JsonElement? to JsonObject?. Replace meta.Value.GetProperty("key").GetString() with (string?)meta["key"].
  3. Make UrlElicitationRequiredErrorData.Elicitations consistent with other Protocol DTOs #1335

    • Elicitations changed from IReadOnlyList<ElicitRequestParams> with init to IList<ElicitRequestParams> with set. Code using List<T> is unaffected since it implements both interfaces.

What's Changed

  • Remove dead code: options ??= new() in McpServerImpl constructor #1322 by @stephentoub (co-authored by @Copilot)
  • Remove unnecessary _connectCts field from McpClientImpl #1323 by @stephentoub (co-authored by @Copilot)
  • Add missing Title and Icons properties to ResourceLinkBlock #1320 by @stephentoub (co-authored by @Copilot)
  • Omit null mimeType from ResourceContents JSON serialization #1325 by @stephentoub (co-authored by @Copilot)
  • Validate mimeType in ImageContentBlock.FromBytes and AudioContentBlock.FromBytes #1321 by @stephentoub (co-authored by @Copilot)
  • Replace concrete collection types with interfaces in public API surface #1326 by @stephentoub (co-authored by @Copilot)
  • Make UrlElicitationRequiredErrorData.Elicitations consistent with other Protocol DTOs #1335 by @stephentoub (co-authored by @Copilot)
  • Fix Metadata delegation in DelegatingMcpServerTool/Prompt/Resource #1338 by @stephentoub (co-authored by @Copilot @jeffhandley)
  • Add Extensions support to ClientCapabilities and ServerCapabilities #1317 by @stephentoub (co-authored by @Copilot)
  • Fix _meta properties to use JsonObject #1341 by @stephentoub (co-authored by @Copilot)

Documentation Updates

  • Fix incorrect XML doc comments in McpClient.Methods.cs #1333 by @stephentoub (co-authored by @Copilot)
  • Add missing exception documentation for public APIs #1339 by @stephentoub (co-authored by @Copilot)

Test Improvements

  • Fix flaky DiagnosticTests on net10.0 by waiting for specific activities #1324 by @stephentoub (co-authored by @Copilot)
  • Fix flaky sse-retry conformance test due to CI timing overhead #1336 by @ericstj (co-authored by @Copilot)

Repository Infrastructure Updates

  • Bump version to 1.0.0-rc.1 #1327 by @jeffhandley (co-authored by @Copilot)
  • Add release-notes, breaking-changes, and bump-version Copilot skills #1328 by @jeffhandley (co-authored by @Copilot)
  • Bump hono from 4.11.7 to 4.12.0 in the npm_and_yarn group across 1 directory #1316
  • Bump version down to 0.9.0-preview.2 since we are still changing APIs #1344 by @jeffhandley (co-authored by @Copilot)

Acknowledgements

Full Changelog: v0.9.0-preview.1...v0.9.0-preview.2