From 90c853103df98ec8f4e83be03256519f76aff7b4 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Thu, 25 Jun 2026 13:47:14 -0700 Subject: [PATCH] Remove `ExperimentalAttribute` from official Extensions/Tasks/MRTR APIs and align `MCPEXP001` usage (#1642) --- docs/list-of-diagnostics.md | 2 +- src/Common/Experimentals.cs | 40 ++++--------------- .../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 - 16 files changed, 9 insertions(+), 62 deletions(-) diff --git a/docs/list-of-diagnostics.md b/docs/list-of-diagnostics.md index 9bf6c98..8e0e892 100644 --- a/docs/list-of-diagnostics.md +++ b/docs/list-of-diagnostics.md @@ -27,7 +27,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` | 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). | | `MCPEXP003` | Experimental MCP Apps extension APIs. MCP Apps is the first official MCP extension (`io.modelcontextprotocol/ui`), enabling servers to deliver interactive UIs inside AI clients (see [MCP Apps specification](https://github.com/modelcontextprotocol/ext-apps/blob/main/specification/2026-01-26/apps.mdx)). | diff --git a/src/Common/Experimentals.cs b/src/Common/Experimentals.cs index b55eba7..1af5ce5 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 MCP Apps extension APIs. @@ -110,22 +104,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"; } diff --git a/src/ModelContextProtocol.Core/Protocol/ClientCapabilities.cs b/src/ModelContextProtocol.Core/Protocol/ClientCapabilities.cs index fd93dce..22245f3 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; @@ -84,7 +83,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 68d767d..1757fa6 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 4f39b17..89f2e53 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 b02bfa9..e82c3ec 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 d2e51ee..24081c0 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 004f171..67a8f00 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 @@ public abstract class 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 abstract class RequestParams /// 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 0f1c4f5..bfc6318 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; @@ -82,7 +81,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 9740ca3..337cb19 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 00c6984..7625982 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 f541523..14447bd 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 99cd7e8..4f739c2 100644 --- a/src/ModelContextProtocol.Core/Server/McpServer.Methods.cs +++ b/src/ModelContextProtocol.Core/Server/McpServer.Methods.cs @@ -600,7 +600,6 @@ public abstract partial class McpServer : McpSession /// 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 fb6d707..5f8ebf6 100644 --- a/src/ModelContextProtocol.Core/Server/McpServer.cs +++ b/src/ModelContextProtocol.Core/Server/McpServer.cs @@ -81,7 +81,6 @@ public abstract partial class McpServer : McpSession /// 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 b691956..749f365 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 87fa8ef..d275fb3 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,