From 70327468f954eef4418cd043f181a1f1593ad70c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 11 Jun 2026 20:25:29 +0000 Subject: [PATCH 1/3] Initial plan From 645396192f802ac10f755f49aecca68026855bff Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 11 Jun 2026 20:55:49 +0000 Subject: [PATCH 2/3] Remove experimental attributes from official APIs Co-authored-by: PranavSenthilnathan <12225508+PranavSenthilnathan@users.noreply.github.com> --- docs/list-of-diagnostics.md | 2 +- .../Protocol/ClientCapabilities.cs | 2 -- .../Protocol/InputRequest.cs | 2 -- .../Protocol/InputRequiredException.cs | 3 --- .../Protocol/InputRequiredResult.cs | 2 -- .../Protocol/InputResponse.cs | 2 -- .../Protocol/RequestParams.cs | 3 --- .../Protocol/ServerCapabilities.cs | 2 -- .../Server/IMcpTaskStore.cs | 2 -- .../Server/InMemoryMcpTaskStore.cs | 2 -- .../Server/InputResponseReceivedEventArgs.cs | 2 -- .../Server/McpServer.Methods.cs | 1 - .../Server/McpServer.cs | 1 - .../Server/McpTaskExecutionContext.cs | 3 --- .../Server/McpTaskInfo.cs | 2 -- .../ExperimentalInternalPropertyTests.cs | 24 +++++++++++++++++++ 16 files changed, 25 insertions(+), 30 deletions(-) diff --git a/docs/list-of-diagnostics.md b/docs/list-of-diagnostics.md index 26a44bd78..c2891f860 100644 --- a/docs/list-of-diagnostics.md +++ b/docs/list-of-diagnostics.md @@ -23,7 +23,7 @@ If you use experimental APIs, you will get one of the diagnostics shown below. T | Diagnostic ID | Description | | :------------ | :---------- | -| `MCPEXP001` | Experimental APIs for features in the MCP specification itself, including Tasks and Extensions. Tasks provide a mechanism for asynchronous long-running operations that can be polled for status and results (see [SEP-2663](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/seps/2663-tasks-extension.md)). Extensions provide a framework for extending the Model Context Protocol while maintaining interoperability (see [SEP-2133](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2133)). | +| `MCPEXP001` | Reserved diagnostic ID for APIs that were previously experimental and tied to MCP specification features (including Tasks, Extensions, and MRTR). This ID is intentionally kept and not reused for future diagnostics. | | `MCPEXP002` | Experimental SDK APIs unrelated to the MCP specification itself, including subclassing `McpClient`/`McpServer` (see [#1363](https://github.com/modelcontextprotocol/csharp-sdk/pull/1363)) and `RunSessionHandler`, which may be removed or change signatures in a future release (consider using `ConfigureSessionOptions` instead). | ## Obsolete APIs diff --git a/src/ModelContextProtocol.Core/Protocol/ClientCapabilities.cs b/src/ModelContextProtocol.Core/Protocol/ClientCapabilities.cs index f41f50fd8..ea7c53f18 100644 --- a/src/ModelContextProtocol.Core/Protocol/ClientCapabilities.cs +++ b/src/ModelContextProtocol.Core/Protocol/ClientCapabilities.cs @@ -1,5 +1,4 @@ using System.ComponentModel; -using System.Diagnostics.CodeAnalysis; using System.Text.Json.Serialization; using ModelContextProtocol.Client; using ModelContextProtocol.Server; @@ -82,7 +81,6 @@ public sealed class ClientCapabilities /// interoperability. Clients advertise extension support via this field during the initialization handshake. /// /// - [Experimental(Experimentals.Extensions_DiagnosticId, UrlFormat = Experimentals.Extensions_Url)] [JsonIgnore] public IDictionary? Extensions { diff --git a/src/ModelContextProtocol.Core/Protocol/InputRequest.cs b/src/ModelContextProtocol.Core/Protocol/InputRequest.cs index bd9161423..4db35498e 100644 --- a/src/ModelContextProtocol.Core/Protocol/InputRequest.cs +++ b/src/ModelContextProtocol.Core/Protocol/InputRequest.cs @@ -1,4 +1,3 @@ -using System.Diagnostics.CodeAnalysis; using System.Text.Json; using System.Text.Json.Serialization; @@ -20,7 +19,6 @@ namespace ModelContextProtocol.Protocol; /// parameters can be accessed via the typed accessor properties. /// /// -[Experimental(Experimentals.Mrtr_DiagnosticId, UrlFormat = Experimentals.Mrtr_Url)] [JsonConverter(typeof(Converter))] public sealed class InputRequest { diff --git a/src/ModelContextProtocol.Core/Protocol/InputRequiredException.cs b/src/ModelContextProtocol.Core/Protocol/InputRequiredException.cs index 4f39b17a5..89f2e538e 100644 --- a/src/ModelContextProtocol.Core/Protocol/InputRequiredException.cs +++ b/src/ModelContextProtocol.Core/Protocol/InputRequiredException.cs @@ -1,5 +1,3 @@ -using System.Diagnostics.CodeAnalysis; - namespace ModelContextProtocol.Protocol; /// @@ -54,7 +52,6 @@ namespace ModelContextProtocol.Protocol; /// } /// /// -[Experimental(Experimentals.Mrtr_DiagnosticId, UrlFormat = Experimentals.Mrtr_Url)] public class InputRequiredException : Exception { /// diff --git a/src/ModelContextProtocol.Core/Protocol/InputRequiredResult.cs b/src/ModelContextProtocol.Core/Protocol/InputRequiredResult.cs index b02bfa9b2..e82c3ec4d 100644 --- a/src/ModelContextProtocol.Core/Protocol/InputRequiredResult.cs +++ b/src/ModelContextProtocol.Core/Protocol/InputRequiredResult.cs @@ -1,4 +1,3 @@ -using System.Diagnostics.CodeAnalysis; using System.Text.Json.Serialization; namespace ModelContextProtocol.Protocol; @@ -22,7 +21,6 @@ namespace ModelContextProtocol.Protocol; /// This type is part of the Multi Round-Trip Requests (MRTR) mechanism defined in SEP-2322. /// /// -[Experimental(Experimentals.Mrtr_DiagnosticId, UrlFormat = Experimentals.Mrtr_Url)] public sealed class InputRequiredResult : Result { /// diff --git a/src/ModelContextProtocol.Core/Protocol/InputResponse.cs b/src/ModelContextProtocol.Core/Protocol/InputResponse.cs index 465ea3235..b9c6425b9 100644 --- a/src/ModelContextProtocol.Core/Protocol/InputResponse.cs +++ b/src/ModelContextProtocol.Core/Protocol/InputResponse.cs @@ -1,4 +1,3 @@ -using System.Diagnostics.CodeAnalysis; using System.Text.Json; using System.Text.Json.Serialization; using System.Text.Json.Serialization.Metadata; @@ -21,7 +20,6 @@ namespace ModelContextProtocol.Protocol; /// the corresponding key in the map. /// /// -[Experimental(Experimentals.Mrtr_DiagnosticId, UrlFormat = Experimentals.Mrtr_Url)] [JsonConverter(typeof(Converter))] public sealed class InputResponse { diff --git a/src/ModelContextProtocol.Core/Protocol/RequestParams.cs b/src/ModelContextProtocol.Core/Protocol/RequestParams.cs index 004f1711f..67a8f00ba 100644 --- a/src/ModelContextProtocol.Core/Protocol/RequestParams.cs +++ b/src/ModelContextProtocol.Core/Protocol/RequestParams.cs @@ -1,4 +1,3 @@ -using System.Diagnostics.CodeAnalysis; using System.Text.Json.Nodes; using System.Text.Json.Serialization; @@ -36,7 +35,6 @@ private protected RequestParams() /// the value is the client's response to that input request. /// /// - [Experimental(Experimentals.Mrtr_DiagnosticId, UrlFormat = Experimentals.Mrtr_Url)] [JsonIgnore] public IDictionary? InputResponses { @@ -59,7 +57,6 @@ public IDictionary? InputResponses /// exact value without modification. /// /// - [Experimental(Experimentals.Mrtr_DiagnosticId, UrlFormat = Experimentals.Mrtr_Url)] [JsonIgnore] public string? RequestState { diff --git a/src/ModelContextProtocol.Core/Protocol/ServerCapabilities.cs b/src/ModelContextProtocol.Core/Protocol/ServerCapabilities.cs index 92ffff424..a48ea1fcd 100644 --- a/src/ModelContextProtocol.Core/Protocol/ServerCapabilities.cs +++ b/src/ModelContextProtocol.Core/Protocol/ServerCapabilities.cs @@ -1,5 +1,4 @@ using System.ComponentModel; -using System.Diagnostics.CodeAnalysis; using System.Text.Json.Serialization; using ModelContextProtocol.Server; @@ -81,7 +80,6 @@ public sealed class ServerCapabilities /// interoperability. Servers advertise extension support via this field during the initialization handshake. /// /// - [Experimental(Experimentals.Extensions_DiagnosticId, UrlFormat = Experimentals.Extensions_Url)] [JsonIgnore] public IDictionary? Extensions { diff --git a/src/ModelContextProtocol.Core/Server/IMcpTaskStore.cs b/src/ModelContextProtocol.Core/Server/IMcpTaskStore.cs index 9740ca378..337cb1946 100644 --- a/src/ModelContextProtocol.Core/Server/IMcpTaskStore.cs +++ b/src/ModelContextProtocol.Core/Server/IMcpTaskStore.cs @@ -1,5 +1,4 @@ using ModelContextProtocol.Protocol; -using System.Diagnostics.CodeAnalysis; using System.Text.Json; namespace ModelContextProtocol.Server; @@ -31,7 +30,6 @@ namespace ModelContextProtocol.Server; /// specification for details on the tasks extension. /// /// -[Experimental(Experimentals.Extensions_DiagnosticId, UrlFormat = Experimentals.Extensions_Url)] public interface IMcpTaskStore { /// diff --git a/src/ModelContextProtocol.Core/Server/InMemoryMcpTaskStore.cs b/src/ModelContextProtocol.Core/Server/InMemoryMcpTaskStore.cs index a13af13e9..81ee7698f 100644 --- a/src/ModelContextProtocol.Core/Server/InMemoryMcpTaskStore.cs +++ b/src/ModelContextProtocol.Core/Server/InMemoryMcpTaskStore.cs @@ -1,7 +1,6 @@ using ModelContextProtocol.Protocol; using System.Collections.Concurrent; using System.Collections.Immutable; -using System.Diagnostics.CodeAnalysis; using System.Text.Json; namespace ModelContextProtocol.Server; @@ -20,7 +19,6 @@ namespace ModelContextProtocol.Server; /// implement a custom . /// /// -[Experimental(Experimentals.Extensions_DiagnosticId, UrlFormat = Experimentals.Extensions_Url)] public class InMemoryMcpTaskStore : IMcpTaskStore { private readonly ConcurrentDictionary _tasks = new(); diff --git a/src/ModelContextProtocol.Core/Server/InputResponseReceivedEventArgs.cs b/src/ModelContextProtocol.Core/Server/InputResponseReceivedEventArgs.cs index f54152368..14447bd6f 100644 --- a/src/ModelContextProtocol.Core/Server/InputResponseReceivedEventArgs.cs +++ b/src/ModelContextProtocol.Core/Server/InputResponseReceivedEventArgs.cs @@ -1,12 +1,10 @@ using ModelContextProtocol.Protocol; -using System.Diagnostics.CodeAnalysis; namespace ModelContextProtocol.Server; /// /// Provides data for the event. /// -[Experimental(Experimentals.Extensions_DiagnosticId, UrlFormat = Experimentals.Extensions_Url)] public sealed class InputResponseReceivedEventArgs { /// diff --git a/src/ModelContextProtocol.Core/Server/McpServer.Methods.cs b/src/ModelContextProtocol.Core/Server/McpServer.Methods.cs index a0d788a27..a8661a671 100644 --- a/src/ModelContextProtocol.Core/Server/McpServer.Methods.cs +++ b/src/ModelContextProtocol.Core/Server/McpServer.Methods.cs @@ -595,7 +595,6 @@ private void ThrowIfRootsUnsupported() /// The task ID in the store. /// The task store to write input requests to. /// An that restores the previous context when disposed. - [Experimental(Experimentals.Extensions_DiagnosticId, UrlFormat = Experimentals.Extensions_Url)] public IDisposable CreateMcpTaskScope( string taskId, IMcpTaskStore store) diff --git a/src/ModelContextProtocol.Core/Server/McpServer.cs b/src/ModelContextProtocol.Core/Server/McpServer.cs index 444365361..1aa71734e 100644 --- a/src/ModelContextProtocol.Core/Server/McpServer.cs +++ b/src/ModelContextProtocol.Core/Server/McpServer.cs @@ -80,7 +80,6 @@ protected McpServer() /// the required feature) instead of throwing . /// /// - [Experimental(Experimentals.Mrtr_DiagnosticId, UrlFormat = Experimentals.Mrtr_Url)] public virtual bool IsMrtrSupported => false; /// diff --git a/src/ModelContextProtocol.Core/Server/McpTaskExecutionContext.cs b/src/ModelContextProtocol.Core/Server/McpTaskExecutionContext.cs index b691956cf..749f36517 100644 --- a/src/ModelContextProtocol.Core/Server/McpTaskExecutionContext.cs +++ b/src/ModelContextProtocol.Core/Server/McpTaskExecutionContext.cs @@ -1,5 +1,3 @@ -using System.Diagnostics.CodeAnalysis; - namespace ModelContextProtocol.Server; /// @@ -9,7 +7,6 @@ namespace ModelContextProtocol.Server; /// and /// are redirected through the task store as input requests rather than sent directly to the client. /// -[Experimental(Experimentals.Extensions_DiagnosticId, UrlFormat = Experimentals.Extensions_Url)] internal sealed class McpTaskExecutionContext { internal static readonly AsyncLocal Current = new(); diff --git a/src/ModelContextProtocol.Core/Server/McpTaskInfo.cs b/src/ModelContextProtocol.Core/Server/McpTaskInfo.cs index ab71d6505..9120e815b 100644 --- a/src/ModelContextProtocol.Core/Server/McpTaskInfo.cs +++ b/src/ModelContextProtocol.Core/Server/McpTaskInfo.cs @@ -1,5 +1,4 @@ using ModelContextProtocol.Protocol; -using System.Diagnostics.CodeAnalysis; using System.Text.Json; namespace ModelContextProtocol.Server; @@ -14,7 +13,6 @@ namespace ModelContextProtocol.Server; /// types (, ) when communicating with clients. /// /// -[Experimental(Experimentals.Extensions_DiagnosticId, UrlFormat = Experimentals.Extensions_Url)] public sealed record McpTaskInfo( string TaskId, McpTaskStatus Status, diff --git a/tests/ModelContextProtocol.Tests/ExperimentalInternalPropertyTests.cs b/tests/ModelContextProtocol.Tests/ExperimentalInternalPropertyTests.cs index 17e18dc2b..f376a8a36 100644 --- a/tests/ModelContextProtocol.Tests/ExperimentalInternalPropertyTests.cs +++ b/tests/ModelContextProtocol.Tests/ExperimentalInternalPropertyTests.cs @@ -1,5 +1,6 @@ using System.Reflection; using System.Text.Json.Serialization; +using ModelContextProtocol.Server; using ModelContextProtocol.Protocol; namespace ModelContextProtocol.Tests; @@ -15,6 +16,29 @@ namespace ModelContextProtocol.Tests; /// public class ExperimentalInternalPropertyTests { + [Fact] + public void OfficialExtensionsTasksAndMrtrApis_AreNotExperimental() + { + static bool HasExperimentalAttribute(ICustomAttributeProvider provider) => + provider.GetCustomAttributes(inherit: false).Any(a => a.GetType().Name == "ExperimentalAttribute"); + + Assert.False(HasExperimentalAttribute(typeof(InputRequest))); + Assert.False(HasExperimentalAttribute(typeof(InputResponse))); + Assert.False(HasExperimentalAttribute(typeof(InputRequiredResult))); + Assert.False(HasExperimentalAttribute(typeof(InputRequiredException))); + Assert.False(HasExperimentalAttribute(typeof(IMcpTaskStore))); + Assert.False(HasExperimentalAttribute(typeof(InMemoryMcpTaskStore))); + Assert.False(HasExperimentalAttribute(typeof(InputResponseReceivedEventArgs))); + Assert.False(HasExperimentalAttribute(typeof(McpTaskInfo))); + + Assert.False(HasExperimentalAttribute(typeof(ClientCapabilities).GetProperty(nameof(ClientCapabilities.Extensions))!)); + Assert.False(HasExperimentalAttribute(typeof(ServerCapabilities).GetProperty(nameof(ServerCapabilities.Extensions))!)); + Assert.False(HasExperimentalAttribute(typeof(RequestParams).GetProperty(nameof(RequestParams.InputResponses))!)); + Assert.False(HasExperimentalAttribute(typeof(RequestParams).GetProperty(nameof(RequestParams.RequestState))!)); + Assert.False(HasExperimentalAttribute(typeof(McpServer).GetProperty(nameof(McpServer.IsMrtrSupported))!)); + Assert.False(HasExperimentalAttribute(typeof(McpServer).GetMethod(nameof(McpServer.CreateMcpTaskScope))!)); + } + [Fact] public void ExperimentalProperties_MustBeHiddenFromSourceGenerator() { From 45214cc2e2e09985d01c3264d360a491882f58a1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 11 Jun 2026 22:29:36 +0000 Subject: [PATCH 3/3] Clean up MCPEXP001 constants for future spec features Co-authored-by: PranavSenthilnathan <12225508+PranavSenthilnathan@users.noreply.github.com> --- docs/list-of-diagnostics.md | 2 +- src/Common/Experimentals.cs | 40 ++++++++----------------------------- 2 files changed, 9 insertions(+), 33 deletions(-) diff --git a/docs/list-of-diagnostics.md b/docs/list-of-diagnostics.md index c2891f860..3e362beb9 100644 --- a/docs/list-of-diagnostics.md +++ b/docs/list-of-diagnostics.md @@ -23,7 +23,7 @@ If you use experimental APIs, you will get one of the diagnostics shown below. T | Diagnostic ID | Description | | :------------ | :---------- | -| `MCPEXP001` | Reserved diagnostic ID for APIs that were previously experimental and tied to MCP specification features (including Tasks, Extensions, and MRTR). This ID is intentionally kept and not reused for future diagnostics. | +| `MCPEXP001` | Experimental APIs tied to MCP specification features. Reuse this ID for newly introduced experimental spec features, and add feature-specific messages/URLs in `Experimentals`. | | `MCPEXP002` | Experimental SDK APIs unrelated to the MCP specification itself, including subclassing `McpClient`/`McpServer` (see [#1363](https://github.com/modelcontextprotocol/csharp-sdk/pull/1363)) and `RunSessionHandler`, which may be removed or change signatures in a future release (consider using `ConfigureSessionOptions` instead). | ## Obsolete APIs diff --git a/src/Common/Experimentals.cs b/src/Common/Experimentals.cs index 411acd989..e7b5c53e0 100644 --- a/src/Common/Experimentals.cs +++ b/src/Common/Experimentals.cs @@ -9,8 +9,8 @@ namespace ModelContextProtocol; /// Experimental diagnostic IDs are grouped by category: /// /// -/// MCPEXP001 covers APIs related to experimental features in the MCP specification itself, -/// such as Extensions. These APIs may change as the specification evolves. +/// MCPEXP001 covers APIs related to experimental features in the MCP specification itself. +/// These APIs may change as the specification evolves. /// /// /// MCPEXP002 covers experimental SDK APIs that are unrelated to the MCP specification, @@ -36,19 +36,13 @@ namespace ModelContextProtocol; internal static class Experimentals { /// - /// Diagnostic ID for the experimental MCP Extensions feature. + /// Diagnostic ID for experimental MCP specification features. /// - public const string Extensions_DiagnosticId = "MCPEXP001"; - - /// - /// Message for the experimental MCP Extensions feature. - /// - public const string Extensions_Message = "The Extensions feature is part of a future MCP specification version that has not yet been ratified and is subject to change."; - - /// - /// URL for the experimental MCP Extensions feature. - /// - public const string Extensions_Url = "https://github.com/modelcontextprotocol/csharp-sdk/blob/main/docs/list-of-diagnostics.md#mcpexp001"; + /// + /// When introducing a new experimental specification feature, add feature-specific message + /// and URL constants that use this diagnostic ID. + /// + public const string SpecificationFeature_DiagnosticId = "MCPEXP001"; /// /// Diagnostic ID for experimental SDK APIs unrelated to the MCP specification, @@ -90,22 +84,4 @@ internal static class Experimentals /// public const string RunSessionHandler_Url = "https://github.com/modelcontextprotocol/csharp-sdk/blob/main/docs/list-of-diagnostics.md#mcpexp002"; - /// - /// Diagnostic ID for the experimental Multi Round-Trip Requests (MRTR) feature. - /// - /// - /// This uses the same diagnostic ID as because MRTR - /// is an experimental feature in the MCP specification (SEP-2322). - /// - public const string Mrtr_DiagnosticId = "MCPEXP001"; - - /// - /// Message for the experimental MRTR feature. - /// - public const string Mrtr_Message = "The Multi Round-Trip Requests (MRTR) feature is experimental per the MCP specification (SEP-2322) and is subject to change."; - - /// - /// URL for the experimental MRTR feature. - /// - public const string Mrtr_Url = "https://github.com/modelcontextprotocol/csharp-sdk/blob/main/docs/list-of-diagnostics.md#mcpexp001"; }