From 6f13c1b23f80c7ef76a5c6d6df90faa10d0f3390 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 26 Jul 2026 05:34:35 +0000 Subject: [PATCH 1/3] Initial plan From c982f826fcd2f69f31089bf08da49b542e9220b0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 26 Jul 2026 05:49:36 +0000 Subject: [PATCH 2/3] Add Extensibility diagnostic aliases and update new MCPEXP002 call sites Co-authored-by: jeffhandley <1031940+jeffhandley@users.noreply.github.com> --- src/Common/Experimentals.cs | 15 +++++++++++++++ .../Protocol/JsonRpcMessageContext.cs | 2 +- .../Server/McpServerRequestHandler.cs | 2 +- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/Common/Experimentals.cs b/src/Common/Experimentals.cs index 1af5ce5a3..69bd7520a 100644 --- a/src/Common/Experimentals.cs +++ b/src/Common/Experimentals.cs @@ -85,6 +85,21 @@ internal static class Experimentals /// public const string Subclassing_Url = "https://github.com/modelcontextprotocol/csharp-sdk/blob/main/docs/list-of-diagnostics.md#mcpexp002"; + /// + /// Diagnostic ID for experimental extensibility points in the C# SDK implementation. + /// + public const string Extensibility_DiagnosticId = Subclassing_DiagnosticId; + + /// + /// Message for experimental extensibility points in the C# SDK implementation. + /// + public const string Extensibility_Message = "This C# SDK extensibility API is experimental and subject to change."; + + /// + /// URL for experimental extensibility points in the C# SDK implementation. + /// + public const string Extensibility_Url = Subclassing_Url; + /// /// Diagnostic ID for the experimental RunSessionHandler API. /// diff --git a/src/ModelContextProtocol.Core/Protocol/JsonRpcMessageContext.cs b/src/ModelContextProtocol.Core/Protocol/JsonRpcMessageContext.cs index fae0684d9..def9b89e4 100644 --- a/src/ModelContextProtocol.Core/Protocol/JsonRpcMessageContext.cs +++ b/src/ModelContextProtocol.Core/Protocol/JsonRpcMessageContext.cs @@ -83,7 +83,7 @@ public sealed class JsonRpcMessageContext /// Streamable HTTP transports emit this value in the Mcp-Name header. This enables /// extension methods to identify the named resource targeted by a request. /// - [Experimental(Experimentals.Subclassing_DiagnosticId, UrlFormat = Experimentals.Subclassing_Url)] + [Experimental(Experimentals.Extensibility_DiagnosticId, UrlFormat = Experimentals.Extensibility_Url)] [JsonIgnore] public string? RoutingName { get; set; } diff --git a/src/ModelContextProtocol.Core/Server/McpServerRequestHandler.cs b/src/ModelContextProtocol.Core/Server/McpServerRequestHandler.cs index 2da6d0eb9..bbe9401d0 100644 --- a/src/ModelContextProtocol.Core/Server/McpServerRequestHandler.cs +++ b/src/ModelContextProtocol.Core/Server/McpServerRequestHandler.cs @@ -32,7 +32,7 @@ public sealed class McpServerRequestHandler /// When set, Streamable HTTP servers require the request to include an Mcp-Name /// header whose decoded value matches the string value of this parameter. /// - [Experimental(Experimentals.Subclassing_DiagnosticId, UrlFormat = Experimentals.Subclassing_Url)] + [Experimental(Experimentals.Extensibility_DiagnosticId, UrlFormat = Experimentals.Extensibility_Url)] public string? RoutingNameParameter { get; init; } /// From 2be1a7767b55484d7b8013470ba1b7081590a45e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 26 Jul 2026 06:07:56 +0000 Subject: [PATCH 3/3] Replace Subclassing_DiagnosticId/Url with Extensibility_DiagnosticId/Url throughout Co-authored-by: jeffhandley <1031940+jeffhandley@users.noreply.github.com> --- src/Common/Experimentals.cs | 31 +++++-------------- .../Client/McpClient.cs | 2 +- .../Protocol/ResultOrAlternate.cs | 2 +- .../Server/McpRequestFilters.cs | 2 +- .../Server/McpRequestInvocationFilter.cs | 2 +- .../Server/McpServer.Methods.cs | 2 +- .../Server/McpServer.cs | 2 +- .../Server/McpServerHandlers.cs | 2 +- .../Server/McpServerOptions.cs | 2 +- .../Server/McpServerRequestHandler.cs | 2 +- 10 files changed, 17 insertions(+), 32 deletions(-) diff --git a/src/Common/Experimentals.cs b/src/Common/Experimentals.cs index 69bd7520a..f64701cc4 100644 --- a/src/Common/Experimentals.cs +++ b/src/Common/Experimentals.cs @@ -13,9 +13,9 @@ namespace ModelContextProtocol; /// These APIs may change as the specification evolves. /// /// -/// MCPEXP002 covers experimental SDK APIs that are unrelated to the MCP specification, -/// such as subclassing internal types or SDK-specific extensibility hooks. These APIs may -/// change or be removed based on SDK design feedback. +/// MCPEXP002 covers SDK extensibility APIs that enable features to be implemented +/// in standalone packages without requiring Core to understand those features. These APIs +/// remain experimental until additional extensibility scenarios validate the design. /// /// /// @@ -65,30 +65,15 @@ internal static class Experimentals public const string Apps_Url = "https://github.com/modelcontextprotocol/csharp-sdk/blob/main/docs/list-of-diagnostics.md#mcpexp003"; /// - /// Diagnostic ID for experimental SDK APIs unrelated to the MCP specification, - /// such as subclassing McpClient/McpServer or referencing RunSessionHandler. + /// Diagnostic ID for SDK extensibility APIs that enable independently packaged features, + /// such as Tasks, without requiring Core awareness of those features. /// /// /// This diagnostic ID covers experimental SDK-level extensibility APIs. All constants /// in this group share the same diagnostic ID so users need only one suppression point /// for SDK design preview features. /// - public const string Subclassing_DiagnosticId = "MCPEXP002"; - - /// - /// Message for experimental subclassing of McpClient and McpServer. - /// - public const string Subclassing_Message = "Subclassing McpClient and McpServer is experimental and subject to change."; - - /// - /// URL for experimental subclassing of McpClient and McpServer. - /// - public const string Subclassing_Url = "https://github.com/modelcontextprotocol/csharp-sdk/blob/main/docs/list-of-diagnostics.md#mcpexp002"; - - /// - /// Diagnostic ID for experimental extensibility points in the C# SDK implementation. - /// - public const string Extensibility_DiagnosticId = Subclassing_DiagnosticId; + public const string Extensibility_DiagnosticId = "MCPEXP002"; /// /// Message for experimental extensibility points in the C# SDK implementation. @@ -98,13 +83,13 @@ internal static class Experimentals /// /// URL for experimental extensibility points in the C# SDK implementation. /// - public const string Extensibility_Url = Subclassing_Url; + public const string Extensibility_Url = "https://github.com/modelcontextprotocol/csharp-sdk/blob/main/docs/list-of-diagnostics.md#mcpexp002"; /// /// Diagnostic ID for the experimental RunSessionHandler API. /// /// - /// This uses the same diagnostic ID as because + /// This uses the same diagnostic ID as because /// both are experimental SDK APIs unrelated to the MCP specification. /// public const string RunSessionHandler_DiagnosticId = "MCPEXP002"; diff --git a/src/ModelContextProtocol.Core/Client/McpClient.cs b/src/ModelContextProtocol.Core/Client/McpClient.cs index d683172da..6107201f2 100644 --- a/src/ModelContextProtocol.Core/Client/McpClient.cs +++ b/src/ModelContextProtocol.Core/Client/McpClient.cs @@ -12,7 +12,7 @@ public abstract partial class McpClient : McpSession /// /// Initializes a new instance of the class. /// - [Experimental(Experimentals.Subclassing_DiagnosticId, UrlFormat = Experimentals.Subclassing_Url)] + [Experimental(Experimentals.Extensibility_DiagnosticId, UrlFormat = Experimentals.Extensibility_Url)] protected McpClient() { } diff --git a/src/ModelContextProtocol.Core/Protocol/ResultOrAlternate.cs b/src/ModelContextProtocol.Core/Protocol/ResultOrAlternate.cs index 0944ba135..8303978fe 100644 --- a/src/ModelContextProtocol.Core/Protocol/ResultOrAlternate.cs +++ b/src/ModelContextProtocol.Core/Protocol/ResultOrAlternate.cs @@ -20,7 +20,7 @@ namespace ModelContextProtocol.Protocol; /// for the immediate result or for the alternate. /// /// -[Experimental(Experimentals.Subclassing_DiagnosticId, UrlFormat = Experimentals.Subclassing_Url)] +[Experimental(Experimentals.Extensibility_DiagnosticId, UrlFormat = Experimentals.Extensibility_Url)] public class ResultOrAlternate where TResult : Result { private readonly TResult? _result; diff --git a/src/ModelContextProtocol.Core/Server/McpRequestFilters.cs b/src/ModelContextProtocol.Core/Server/McpRequestFilters.cs index df34d48a7..a1aad7112 100644 --- a/src/ModelContextProtocol.Core/Server/McpRequestFilters.cs +++ b/src/ModelContextProtocol.Core/Server/McpRequestFilters.cs @@ -84,7 +84,7 @@ public IList> CallToolFi /// asynchronously, filters registered after it execute as part of that asynchronous operation. /// /// - [Experimental(Experimentals.Subclassing_DiagnosticId, UrlFormat = Experimentals.Subclassing_Url)] + [Experimental(Experimentals.Extensibility_DiagnosticId, UrlFormat = Experimentals.Extensibility_Url)] public IList>> CallToolWithAlternateFilters { get => field ??= []; diff --git a/src/ModelContextProtocol.Core/Server/McpRequestInvocationFilter.cs b/src/ModelContextProtocol.Core/Server/McpRequestInvocationFilter.cs index f9871fca5..baacf4fcc 100644 --- a/src/ModelContextProtocol.Core/Server/McpRequestInvocationFilter.cs +++ b/src/ModelContextProtocol.Core/Server/McpRequestInvocationFilter.cs @@ -11,7 +11,7 @@ namespace ModelContextProtocol.Server; /// The next request handler in the pipeline for this invocation. /// The cancellation token for the current request. /// The result of the filtered request invocation. -[Experimental(Experimentals.Subclassing_DiagnosticId, UrlFormat = Experimentals.Subclassing_Url)] +[Experimental(Experimentals.Extensibility_DiagnosticId, UrlFormat = Experimentals.Extensibility_Url)] public delegate ValueTask McpRequestInvocationFilter( RequestContext context, McpRequestHandler next, diff --git a/src/ModelContextProtocol.Core/Server/McpServer.Methods.cs b/src/ModelContextProtocol.Core/Server/McpServer.Methods.cs index a4a245043..a9a5dddfb 100644 --- a/src/ModelContextProtocol.Core/Server/McpServer.Methods.cs +++ b/src/ModelContextProtocol.Core/Server/McpServer.Methods.cs @@ -39,7 +39,7 @@ public abstract partial class McpServer : McpSession /// On the returned facade, redirected methods skip their client-capability checks, /// because the alternate channel is responsible for delivering the request to the client. /// - [Experimental(Experimentals.Subclassing_DiagnosticId, UrlFormat = Experimentals.Subclassing_Url)] + [Experimental(Experimentals.Extensibility_DiagnosticId, UrlFormat = Experimentals.Extensibility_Url)] public McpServer WithOutgoingRequestInterceptor(Func> interceptor) { Throw.IfNull(interceptor); diff --git a/src/ModelContextProtocol.Core/Server/McpServer.cs b/src/ModelContextProtocol.Core/Server/McpServer.cs index a51010dc0..4797ce151 100644 --- a/src/ModelContextProtocol.Core/Server/McpServer.cs +++ b/src/ModelContextProtocol.Core/Server/McpServer.cs @@ -11,7 +11,7 @@ public abstract partial class McpServer : McpSession /// /// Initializes a new instance of the class. /// - [Experimental(Experimentals.Subclassing_DiagnosticId, UrlFormat = Experimentals.Subclassing_Url)] + [Experimental(Experimentals.Extensibility_DiagnosticId, UrlFormat = Experimentals.Extensibility_Url)] protected McpServer() { } diff --git a/src/ModelContextProtocol.Core/Server/McpServerHandlers.cs b/src/ModelContextProtocol.Core/Server/McpServerHandlers.cs index d7510a932..e8718626e 100644 --- a/src/ModelContextProtocol.Core/Server/McpServerHandlers.cs +++ b/src/ModelContextProtocol.Core/Server/McpServerHandlers.cs @@ -78,7 +78,7 @@ public McpRequestHandler? CallToolHandler /// /// /// is already set. - [Experimental(Experimentals.Subclassing_DiagnosticId, UrlFormat = Experimentals.Subclassing_Url)] + [Experimental(Experimentals.Extensibility_DiagnosticId, UrlFormat = Experimentals.Extensibility_Url)] public McpRequestHandler>? CallToolWithAlternateHandler { get; diff --git a/src/ModelContextProtocol.Core/Server/McpServerOptions.cs b/src/ModelContextProtocol.Core/Server/McpServerOptions.cs index a84bd600e..f3d9b5f74 100644 --- a/src/ModelContextProtocol.Core/Server/McpServerOptions.cs +++ b/src/ModelContextProtocol.Core/Server/McpServerOptions.cs @@ -217,6 +217,6 @@ public McpServerFilters Filters /// Handlers registered here take precedence over built-in handlers for the same method. /// /// - [Experimental(Experimentals.Subclassing_DiagnosticId, UrlFormat = Experimentals.Subclassing_Url)] + [Experimental(Experimentals.Extensibility_DiagnosticId, UrlFormat = Experimentals.Extensibility_Url)] public IList? RequestHandlers { get; set; } } diff --git a/src/ModelContextProtocol.Core/Server/McpServerRequestHandler.cs b/src/ModelContextProtocol.Core/Server/McpServerRequestHandler.cs index bbe9401d0..af8a94091 100644 --- a/src/ModelContextProtocol.Core/Server/McpServerRequestHandler.cs +++ b/src/ModelContextProtocol.Core/Server/McpServerRequestHandler.cs @@ -16,7 +16,7 @@ namespace ModelContextProtocol.Server; /// response, giving extensions full control over request/response serialization. /// /// -[Experimental(Experimentals.Subclassing_DiagnosticId, UrlFormat = Experimentals.Subclassing_Url)] +[Experimental(Experimentals.Extensibility_DiagnosticId, UrlFormat = Experimentals.Extensibility_Url)] public sealed class McpServerRequestHandler { ///