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
{
///