diff --git a/docs/concepts/logging/samples/Directory.Build.props b/docs/concepts/logging/samples/Directory.Build.props
new file mode 100644
index 000000000..22f945ad0
--- /dev/null
+++ b/docs/concepts/logging/samples/Directory.Build.props
@@ -0,0 +1,9 @@
+
+
+
+
+
+ $(NoWarn);MCP9005
+
+
diff --git a/docs/list-of-diagnostics.md b/docs/list-of-diagnostics.md
index 26a44bd78..babf54b21 100644
--- a/docs/list-of-diagnostics.md
+++ b/docs/list-of-diagnostics.md
@@ -38,3 +38,4 @@ When APIs are marked as obsolete, a diagnostic is emitted to warn users that the
| `MCP9002` | Removed | The `AddXxxFilter` extension methods on `IMcpServerBuilder` (e.g., `AddListToolsFilter`, `AddCallToolFilter`, `AddIncomingMessageFilter`) were superseded by `WithRequestFilters()` and `WithMessageFilters()`. |
| `MCP9003` | In place | The `RequestContext(McpServer, JsonRpcRequest)` constructor is obsolete. Use the overload that accepts a `parameters` argument: `RequestContext(McpServer, JsonRpcRequest, TParams)`. |
| `MCP9004` | In place | opts into the legacy SSE transport which has no built-in HTTP-level backpressure. Use Streamable HTTP instead. See [Stateless — Legacy SSE transport](xref:stateless#legacy-sse-transport) for details. |
+| `MCP9005` | In place | The Roots, Sampling, and Logging features are deprecated as of specification version 2026-07-28 and may be removed in a future version. See SEP-2577 for more information. |
diff --git a/samples/Directory.Build.props b/samples/Directory.Build.props
new file mode 100644
index 000000000..1aa7321e0
--- /dev/null
+++ b/samples/Directory.Build.props
@@ -0,0 +1,9 @@
+
+
+
+
+
+ $(NoWarn);MCP9005
+
+
diff --git a/src/Common/Obsoletions.cs b/src/Common/Obsoletions.cs
index 46ea782d8..511f828ac 100644
--- a/src/Common/Obsoletions.cs
+++ b/src/Common/Obsoletions.cs
@@ -33,4 +33,13 @@ internal static class Obsoletions
public const string EnableLegacySse_DiagnosticId = "MCP9004";
public const string EnableLegacySse_Message = "Legacy SSE transport has no built-in request backpressure and should only be used with completely trusted clients in isolated processes. Use Streamable HTTP instead.";
public const string EnableLegacySse_Url = "https://github.com/modelcontextprotocol/csharp-sdk/blob/main/docs/list-of-diagnostics.md#obsolete-apis";
+
+ // SEP-2577 deprecates the Roots, Sampling, and Logging features as a single coordinated
+ // deprecation. They share one diagnostic ID (MCP9005) so consumers can opt out with a single
+ // suppression, while the feature-specific messages keep the diagnostics distinguishable.
+ public const string Deprecated_DiagnosticId = "MCP9005";
+ public const string Deprecated_Url = "https://github.com/modelcontextprotocol/csharp-sdk/blob/main/docs/list-of-diagnostics.md#mcp9005";
+ public const string DeprecatedRoots_Message = "The Roots feature is deprecated as of specification version 2026-07-28 and may be removed in a future version. See SEP-2577 for more information.";
+ public const string DeprecatedSampling_Message = "The Sampling feature is deprecated as of specification version 2026-07-28 and may be removed in a future version. See SEP-2577 for more information.";
+ public const string DeprecatedLogging_Message = "The Logging feature is deprecated as of specification version 2026-07-28 and may be removed in a future version. See SEP-2577 for more information.";
}
diff --git a/src/ModelContextProtocol.Core/AIContentExtensions.cs b/src/ModelContextProtocol.Core/AIContentExtensions.cs
index bf5fd05de..affb8b20a 100644
--- a/src/ModelContextProtocol.Core/AIContentExtensions.cs
+++ b/src/ModelContextProtocol.Core/AIContentExtensions.cs
@@ -34,6 +34,7 @@ public static class AIContentExtensions
///
///
/// is .
+ [Obsolete(Obsoletions.DeprecatedSampling_Message, DiagnosticId = Obsoletions.Deprecated_DiagnosticId, UrlFormat = Obsoletions.Deprecated_Url)]
public static Func, CancellationToken, ValueTask> CreateSamplingHandler(
this IChatClient chatClient,
JsonSerializerOptions? serializerOptions = null)
diff --git a/src/ModelContextProtocol.Core/Client/McpClient.Methods.cs b/src/ModelContextProtocol.Core/Client/McpClient.Methods.cs
index f3355e76d..22245a924 100644
--- a/src/ModelContextProtocol.Core/Client/McpClient.Methods.cs
+++ b/src/ModelContextProtocol.Core/Client/McpClient.Methods.cs
@@ -1208,6 +1208,7 @@ public async ValueTask> CallToolRawAsync(
/// The to monitor for cancellation requests. The default is .
/// A task representing the asynchronous operation.
/// The request failed or the server returned an error response.
+ [Obsolete(Obsoletions.DeprecatedLogging_Message, DiagnosticId = Obsoletions.Deprecated_DiagnosticId, UrlFormat = Obsoletions.Deprecated_Url)]
public Task SetLoggingLevelAsync(LogLevel level, RequestOptions? options = null, CancellationToken cancellationToken = default) =>
SetLoggingLevelAsync(McpServerImpl.ToLoggingLevel(level), options, cancellationToken);
@@ -1219,6 +1220,7 @@ public Task SetLoggingLevelAsync(LogLevel level, RequestOptions? options = null,
/// The to monitor for cancellation requests. The default is .
/// A task representing the asynchronous operation.
/// The request failed or the server returned an error response.
+ [Obsolete(Obsoletions.DeprecatedLogging_Message, DiagnosticId = Obsoletions.Deprecated_DiagnosticId, UrlFormat = Obsoletions.Deprecated_Url)]
public Task SetLoggingLevelAsync(LoggingLevel level, RequestOptions? options = null, CancellationToken cancellationToken = default)
{
return SetLoggingLevelAsync(
@@ -1238,6 +1240,7 @@ public Task SetLoggingLevelAsync(LoggingLevel level, RequestOptions? options = n
/// The result of the request.
/// is .
/// The request failed or the server returned an error response.
+ [Obsolete(Obsoletions.DeprecatedLogging_Message, DiagnosticId = Obsoletions.Deprecated_DiagnosticId, UrlFormat = Obsoletions.Deprecated_Url)]
public Task SetLoggingLevelAsync(
SetLevelRequestParams requestParams,
CancellationToken cancellationToken = default)
diff --git a/src/ModelContextProtocol.Core/Client/McpClientHandlers.cs b/src/ModelContextProtocol.Core/Client/McpClientHandlers.cs
index 0866e4aef..396b5876b 100644
--- a/src/ModelContextProtocol.Core/Client/McpClientHandlers.cs
+++ b/src/ModelContextProtocol.Core/Client/McpClientHandlers.cs
@@ -1,4 +1,4 @@
-using Microsoft.Extensions.AI;
+using Microsoft.Extensions.AI;
using ModelContextProtocol.Protocol;
using System.Diagnostics.CodeAnalysis;
@@ -50,6 +50,7 @@ public sealed class McpClientHandlers
/// This handler is invoked when the server sends a request to retrieve available roots.
/// The handler receives request parameters and should return a containing the collection of available roots.
///
+ [Obsolete(Obsoletions.DeprecatedRoots_Message, DiagnosticId = Obsoletions.Deprecated_DiagnosticId, UrlFormat = Obsoletions.Deprecated_Url)]
public Func>? RootsHandler { get; set; }
///
@@ -85,5 +86,6 @@ public sealed class McpClientHandlers
/// method with any implementation of .
///
///
+ [Obsolete(Obsoletions.DeprecatedSampling_Message, DiagnosticId = Obsoletions.Deprecated_DiagnosticId, UrlFormat = Obsoletions.Deprecated_Url)]
public Func, CancellationToken, ValueTask>? SamplingHandler { get; set; }
}
diff --git a/src/ModelContextProtocol.Core/ModelContextProtocol.Core.csproj b/src/ModelContextProtocol.Core/ModelContextProtocol.Core.csproj
index 23045b317..455c36798 100644
--- a/src/ModelContextProtocol.Core/ModelContextProtocol.Core.csproj
+++ b/src/ModelContextProtocol.Core/ModelContextProtocol.Core.csproj
@@ -9,6 +9,11 @@
README.md
$(NoWarn);MCPEXP001
+
+ $(NoWarn);MCP9005
diff --git a/src/ModelContextProtocol.Core/Protocol/ClientCapabilities.cs b/src/ModelContextProtocol.Core/Protocol/ClientCapabilities.cs
index f41f50fd8..fd93dcee7 100644
--- a/src/ModelContextProtocol.Core/Protocol/ClientCapabilities.cs
+++ b/src/ModelContextProtocol.Core/Protocol/ClientCapabilities.cs
@@ -52,6 +52,7 @@ public sealed class ClientCapabilities
///
///
[JsonPropertyName("roots")]
+ [Obsolete(Obsoletions.DeprecatedRoots_Message, DiagnosticId = Obsoletions.Deprecated_DiagnosticId, UrlFormat = Obsoletions.Deprecated_Url)]
public RootsCapability? Roots { get; set; }
///
@@ -59,6 +60,7 @@ public sealed class ClientCapabilities
/// supports issuing requests to an LLM on behalf of the server.
///
[JsonPropertyName("sampling")]
+ [Obsolete(Obsoletions.DeprecatedSampling_Message, DiagnosticId = Obsoletions.Deprecated_DiagnosticId, UrlFormat = Obsoletions.Deprecated_Url)]
public SamplingCapability? Sampling { get; set; }
///
diff --git a/src/ModelContextProtocol.Core/Protocol/ContentBlock.cs b/src/ModelContextProtocol.Core/Protocol/ContentBlock.cs
index 83cc9d16b..d0b1b80ec 100644
--- a/src/ModelContextProtocol.Core/Protocol/ContentBlock.cs
+++ b/src/ModelContextProtocol.Core/Protocol/ContentBlock.cs
@@ -760,6 +760,9 @@ public sealed class ResourceLinkBlock : ContentBlock
/// Represents a request from the assistant to call a tool.
[DebuggerDisplay("Name = {Name}, Id = {Id}")]
+// Sampling support type: this content block only appears inside sampling messages (an assistant tool call),
+// so it is deprecated together with sampling per SEP-2577.
+[Obsolete(Obsoletions.DeprecatedSampling_Message, DiagnosticId = Obsoletions.Deprecated_DiagnosticId, UrlFormat = Obsoletions.Deprecated_Url)]
public sealed class ToolUseContentBlock : ContentBlock
{
///
@@ -789,6 +792,9 @@ public sealed class ToolUseContentBlock : ContentBlock
/// Represents the result of a tool use, provided by the user back to the assistant.
[DebuggerDisplay("{DebuggerDisplay,nq}")]
+// Sampling support type: this content block only appears inside sampling messages (a tool result returned to
+// the assistant), so it is deprecated together with sampling per SEP-2577.
+[Obsolete(Obsoletions.DeprecatedSampling_Message, DiagnosticId = Obsoletions.Deprecated_DiagnosticId, UrlFormat = Obsoletions.Deprecated_Url)]
public sealed class ToolResultContentBlock : ContentBlock
{
///
diff --git a/src/ModelContextProtocol.Core/Protocol/ContextInclusion.cs b/src/ModelContextProtocol.Core/Protocol/ContextInclusion.cs
index fbe6be56f..5979fa868 100644
--- a/src/ModelContextProtocol.Core/Protocol/ContextInclusion.cs
+++ b/src/ModelContextProtocol.Core/Protocol/ContextInclusion.cs
@@ -16,6 +16,9 @@ namespace ModelContextProtocol.Protocol;
///
///
[JsonConverter(typeof(JsonStringEnumConverter))]
+// Sampling support type: only used to select what context to include on sampling (createMessage) requests,
+// so it is deprecated together with sampling per SEP-2577.
+[Obsolete(Obsoletions.DeprecatedSampling_Message, DiagnosticId = Obsoletions.Deprecated_DiagnosticId, UrlFormat = Obsoletions.Deprecated_Url)]
public enum ContextInclusion
{
///
diff --git a/src/ModelContextProtocol.Core/Protocol/CreateMessageRequestParams.cs b/src/ModelContextProtocol.Core/Protocol/CreateMessageRequestParams.cs
index bb27d70fd..7a4f32984 100644
--- a/src/ModelContextProtocol.Core/Protocol/CreateMessageRequestParams.cs
+++ b/src/ModelContextProtocol.Core/Protocol/CreateMessageRequestParams.cs
@@ -11,6 +11,9 @@ namespace ModelContextProtocol.Protocol;
///
/// See the schema for details.
///
+// Sampling support type: "createMessage" is the sampling request, so this is deprecated together with
+// sampling per SEP-2577.
+[Obsolete(Obsoletions.DeprecatedSampling_Message, DiagnosticId = Obsoletions.Deprecated_DiagnosticId, UrlFormat = Obsoletions.Deprecated_Url)]
public sealed class CreateMessageRequestParams : RequestParams
{
///
diff --git a/src/ModelContextProtocol.Core/Protocol/CreateMessageResult.cs b/src/ModelContextProtocol.Core/Protocol/CreateMessageResult.cs
index 94472421b..7568b4552 100644
--- a/src/ModelContextProtocol.Core/Protocol/CreateMessageResult.cs
+++ b/src/ModelContextProtocol.Core/Protocol/CreateMessageResult.cs
@@ -8,6 +8,9 @@ namespace ModelContextProtocol.Protocol;
///
/// See the schema for details.
///
+// Sampling support type: "createMessage" is the sampling request, so this result is deprecated together
+// with sampling per SEP-2577.
+[Obsolete(Obsoletions.DeprecatedSampling_Message, DiagnosticId = Obsoletions.Deprecated_DiagnosticId, UrlFormat = Obsoletions.Deprecated_Url)]
public sealed class CreateMessageResult : Result
{
///
diff --git a/src/ModelContextProtocol.Core/Protocol/InputRequest.cs b/src/ModelContextProtocol.Core/Protocol/InputRequest.cs
index bd9161423..68d767d99 100644
--- a/src/ModelContextProtocol.Core/Protocol/InputRequest.cs
+++ b/src/ModelContextProtocol.Core/Protocol/InputRequest.cs
@@ -54,6 +54,7 @@ public sealed class InputRequest
///
/// The deserialized sampling parameters, or if the method does not match or params are absent.
[JsonIgnore]
+ [Obsolete(Obsoletions.DeprecatedSampling_Message, DiagnosticId = Obsoletions.Deprecated_DiagnosticId, UrlFormat = Obsoletions.Deprecated_Url)]
public CreateMessageRequestParams? SamplingParams =>
string.Equals(Method, RequestMethods.SamplingCreateMessage, StringComparison.Ordinal) && Params is { } p
? JsonSerializer.Deserialize(p, McpJsonUtilities.JsonContext.Default.CreateMessageRequestParams)
@@ -76,6 +77,7 @@ public sealed class InputRequest
///
/// The deserialized roots list parameters, or if the method does not match or params are absent.
[JsonIgnore]
+ [Obsolete(Obsoletions.DeprecatedRoots_Message, DiagnosticId = Obsoletions.Deprecated_DiagnosticId, UrlFormat = Obsoletions.Deprecated_Url)]
public ListRootsRequestParams? RootsParams =>
string.Equals(Method, RequestMethods.RootsList, StringComparison.Ordinal) && Params is { } p
? JsonSerializer.Deserialize(p, McpJsonUtilities.JsonContext.Default.ListRootsRequestParams)
@@ -86,6 +88,7 @@ public sealed class InputRequest
///
/// The sampling request parameters.
/// A new instance.
+ [Obsolete(Obsoletions.DeprecatedSampling_Message, DiagnosticId = Obsoletions.Deprecated_DiagnosticId, UrlFormat = Obsoletions.Deprecated_Url)]
public static InputRequest ForSampling(CreateMessageRequestParams requestParams)
{
Throw.IfNull(requestParams);
@@ -116,6 +119,7 @@ public static InputRequest ForElicitation(ElicitRequestParams requestParams)
///
/// The roots list request parameters.
/// A new instance.
+ [Obsolete(Obsoletions.DeprecatedRoots_Message, DiagnosticId = Obsoletions.Deprecated_DiagnosticId, UrlFormat = Obsoletions.Deprecated_Url)]
public static InputRequest ForRootsList(ListRootsRequestParams requestParams)
{
Throw.IfNull(requestParams);
diff --git a/src/ModelContextProtocol.Core/Protocol/InputResponse.cs b/src/ModelContextProtocol.Core/Protocol/InputResponse.cs
index 465ea3235..d2e51eeb1 100644
--- a/src/ModelContextProtocol.Core/Protocol/InputResponse.cs
+++ b/src/ModelContextProtocol.Core/Protocol/InputResponse.cs
@@ -58,6 +58,7 @@ public sealed class InputResponse
/// when the corresponding is
/// .
///
+ [Obsolete(Obsoletions.DeprecatedSampling_Message, DiagnosticId = Obsoletions.Deprecated_DiagnosticId, UrlFormat = Obsoletions.Deprecated_Url)]
public static JsonTypeInfo CreateMessageResultJsonTypeInfo => McpJsonUtilities.JsonContext.Default.CreateMessageResult;
///
@@ -65,6 +66,7 @@ public sealed class InputResponse
/// when the corresponding is
/// .
///
+ [Obsolete(Obsoletions.DeprecatedRoots_Message, DiagnosticId = Obsoletions.Deprecated_DiagnosticId, UrlFormat = Obsoletions.Deprecated_Url)]
public static JsonTypeInfo ListRootsResultJsonTypeInfo => McpJsonUtilities.JsonContext.Default.ListRootsResult;
///
@@ -72,6 +74,7 @@ public sealed class InputResponse
///
/// The sampling result.
/// A new instance.
+ [Obsolete(Obsoletions.DeprecatedSampling_Message, DiagnosticId = Obsoletions.Deprecated_DiagnosticId, UrlFormat = Obsoletions.Deprecated_Url)]
public static InputResponse FromSamplingResult(CreateMessageResult result)
{
Throw.IfNull(result);
@@ -100,6 +103,7 @@ public static InputResponse FromElicitResult(ElicitResult result)
///
/// The roots list result.
/// A new instance.
+ [Obsolete(Obsoletions.DeprecatedRoots_Message, DiagnosticId = Obsoletions.Deprecated_DiagnosticId, UrlFormat = Obsoletions.Deprecated_Url)]
public static InputResponse FromRootsResult(ListRootsResult result)
{
Throw.IfNull(result);
diff --git a/src/ModelContextProtocol.Core/Protocol/ListRootsRequestParams.cs b/src/ModelContextProtocol.Core/Protocol/ListRootsRequestParams.cs
index 5f3bf5d0f..602ee502b 100644
--- a/src/ModelContextProtocol.Core/Protocol/ListRootsRequestParams.cs
+++ b/src/ModelContextProtocol.Core/Protocol/ListRootsRequestParams.cs
@@ -8,4 +8,5 @@ namespace ModelContextProtocol.Protocol;
/// The client responds with a containing the client's roots.
/// See the schema for details.
///
+[Obsolete(Obsoletions.DeprecatedRoots_Message, DiagnosticId = Obsoletions.Deprecated_DiagnosticId, UrlFormat = Obsoletions.Deprecated_Url)]
public sealed class ListRootsRequestParams : RequestParams;
diff --git a/src/ModelContextProtocol.Core/Protocol/ListRootsResult.cs b/src/ModelContextProtocol.Core/Protocol/ListRootsResult.cs
index 115283e98..66debfef8 100644
--- a/src/ModelContextProtocol.Core/Protocol/ListRootsResult.cs
+++ b/src/ModelContextProtocol.Core/Protocol/ListRootsResult.cs
@@ -16,6 +16,7 @@ namespace ModelContextProtocol.Protocol;
/// See the schema for details.
///
///
+[Obsolete(Obsoletions.DeprecatedRoots_Message, DiagnosticId = Obsoletions.Deprecated_DiagnosticId, UrlFormat = Obsoletions.Deprecated_Url)]
public sealed class ListRootsResult : Result
{
///
diff --git a/src/ModelContextProtocol.Core/Protocol/LoggingCapability.cs b/src/ModelContextProtocol.Core/Protocol/LoggingCapability.cs
index 18d8f0c28..f33072929 100644
--- a/src/ModelContextProtocol.Core/Protocol/LoggingCapability.cs
+++ b/src/ModelContextProtocol.Core/Protocol/LoggingCapability.cs
@@ -18,6 +18,7 @@ namespace ModelContextProtocol.Protocol;
/// specification may extend this capability with additional configuration options.
///
///
+[Obsolete(Obsoletions.DeprecatedLogging_Message, DiagnosticId = Obsoletions.Deprecated_DiagnosticId, UrlFormat = Obsoletions.Deprecated_Url)]
public sealed class LoggingCapability
{
}
\ No newline at end of file
diff --git a/src/ModelContextProtocol.Core/Protocol/LoggingLevel.cs b/src/ModelContextProtocol.Core/Protocol/LoggingLevel.cs
index 5fadf7fbc..c8d39064c 100644
--- a/src/ModelContextProtocol.Core/Protocol/LoggingLevel.cs
+++ b/src/ModelContextProtocol.Core/Protocol/LoggingLevel.cs
@@ -1,4 +1,4 @@
-using System.Text.Json.Serialization;
+using System.Text.Json.Serialization;
namespace ModelContextProtocol.Protocol;
@@ -9,6 +9,7 @@ namespace ModelContextProtocol.Protocol;
/// These values map to syslog message severities, as specified in RFC-5424.
///
[JsonConverter(typeof(JsonStringEnumConverter))]
+[Obsolete(Obsoletions.DeprecatedLogging_Message, DiagnosticId = Obsoletions.Deprecated_DiagnosticId, UrlFormat = Obsoletions.Deprecated_Url)]
public enum LoggingLevel
{
/// Detailed debug information, typically only valuable to developers.
diff --git a/src/ModelContextProtocol.Core/Protocol/LoggingMessageNotificationParams.cs b/src/ModelContextProtocol.Core/Protocol/LoggingMessageNotificationParams.cs
index 600f620a5..0840c9c7c 100644
--- a/src/ModelContextProtocol.Core/Protocol/LoggingMessageNotificationParams.cs
+++ b/src/ModelContextProtocol.Core/Protocol/LoggingMessageNotificationParams.cs
@@ -20,6 +20,7 @@ namespace ModelContextProtocol.Protocol;
/// See the schema for details.
///
///
+[Obsolete(Obsoletions.DeprecatedLogging_Message, DiagnosticId = Obsoletions.Deprecated_DiagnosticId, UrlFormat = Obsoletions.Deprecated_Url)]
public sealed class LoggingMessageNotificationParams : NotificationParams
{
///
diff --git a/src/ModelContextProtocol.Core/Protocol/ModelHint.cs b/src/ModelContextProtocol.Core/Protocol/ModelHint.cs
index 37e1001a3..9be4c755f 100644
--- a/src/ModelContextProtocol.Core/Protocol/ModelHint.cs
+++ b/src/ModelContextProtocol.Core/Protocol/ModelHint.cs
@@ -14,6 +14,9 @@ namespace ModelContextProtocol.Protocol;
/// See the schema for details.
///
///
+// Sampling support type: only used inside ModelPreferences to hint a model for sampling (createMessage)
+// requests, so it is deprecated together with sampling per SEP-2577.
+[Obsolete(Obsoletions.DeprecatedSampling_Message, DiagnosticId = Obsoletions.Deprecated_DiagnosticId, UrlFormat = Obsoletions.Deprecated_Url)]
public sealed class ModelHint
{
///
diff --git a/src/ModelContextProtocol.Core/Protocol/ModelPreferences.cs b/src/ModelContextProtocol.Core/Protocol/ModelPreferences.cs
index 5c7a50acc..f20b33956 100644
--- a/src/ModelContextProtocol.Core/Protocol/ModelPreferences.cs
+++ b/src/ModelContextProtocol.Core/Protocol/ModelPreferences.cs
@@ -22,6 +22,9 @@ namespace ModelContextProtocol.Protocol;
/// See the schema for details.
///
///
+// Sampling support type: only used to express model selection preferences on sampling (createMessage)
+// requests, so it is deprecated together with sampling per SEP-2577.
+[Obsolete(Obsoletions.DeprecatedSampling_Message, DiagnosticId = Obsoletions.Deprecated_DiagnosticId, UrlFormat = Obsoletions.Deprecated_Url)]
public sealed class ModelPreferences
{
///
diff --git a/src/ModelContextProtocol.Core/Protocol/NotificationMethods.cs b/src/ModelContextProtocol.Core/Protocol/NotificationMethods.cs
index cab98a5bc..825abd92b 100644
--- a/src/ModelContextProtocol.Core/Protocol/NotificationMethods.cs
+++ b/src/ModelContextProtocol.Core/Protocol/NotificationMethods.cs
@@ -63,6 +63,7 @@ public static class NotificationMethods
/// method to get the updated list of roots from the client.
///
///
+ [Obsolete(Obsoletions.DeprecatedRoots_Message, DiagnosticId = Obsoletions.Deprecated_DiagnosticId, UrlFormat = Obsoletions.Deprecated_Url)]
public const string RootsListChangedNotification = "notifications/roots/list_changed";
///
@@ -80,6 +81,7 @@ public static class NotificationMethods
/// the server can determine which messages to send based on its own configuration.
///
///
+ [Obsolete(Obsoletions.DeprecatedLogging_Message, DiagnosticId = Obsoletions.Deprecated_DiagnosticId, UrlFormat = Obsoletions.Deprecated_Url)]
public const string LoggingMessageNotification = "notifications/message";
///
diff --git a/src/ModelContextProtocol.Core/Protocol/RequestMethods.cs b/src/ModelContextProtocol.Core/Protocol/RequestMethods.cs
index 6967dd07d..a6f22148e 100644
--- a/src/ModelContextProtocol.Core/Protocol/RequestMethods.cs
+++ b/src/ModelContextProtocol.Core/Protocol/RequestMethods.cs
@@ -55,6 +55,7 @@ public static class RequestMethods
///
/// The name of the request method sent from the server to request a list of the client's roots.
///
+ [Obsolete(Obsoletions.DeprecatedRoots_Message, DiagnosticId = Obsoletions.Deprecated_DiagnosticId, UrlFormat = Obsoletions.Deprecated_Url)]
public const string RootsList = "roots/list";
///
@@ -71,6 +72,7 @@ public static class RequestMethods
/// send log messages with severity at or above the specified level to the client as
/// notifications.
///
+ [Obsolete(Obsoletions.DeprecatedLogging_Message, DiagnosticId = Obsoletions.Deprecated_DiagnosticId, UrlFormat = Obsoletions.Deprecated_Url)]
public const string LoggingSetLevel = "logging/setLevel";
///
@@ -91,6 +93,7 @@ public static class RequestMethods
/// based on provided messages. It is part of the sampling capability in the Model Context Protocol and enables servers to access
/// client-side AI models without needing direct API access to those models.
///
+ [Obsolete(Obsoletions.DeprecatedSampling_Message, DiagnosticId = Obsoletions.Deprecated_DiagnosticId, UrlFormat = Obsoletions.Deprecated_Url)]
public const string SamplingCreateMessage = "sampling/createMessage";
///
diff --git a/src/ModelContextProtocol.Core/Protocol/Root.cs b/src/ModelContextProtocol.Core/Protocol/Root.cs
index 622dbddb9..debeefd57 100644
--- a/src/ModelContextProtocol.Core/Protocol/Root.cs
+++ b/src/ModelContextProtocol.Core/Protocol/Root.cs
@@ -14,6 +14,7 @@ namespace ModelContextProtocol.Protocol;
/// guidance rather than an access-control mechanism. Each root has a URI that uniquely identifies
/// it and optional metadata like a human-readable name.
///
+[Obsolete(Obsoletions.DeprecatedRoots_Message, DiagnosticId = Obsoletions.Deprecated_DiagnosticId, UrlFormat = Obsoletions.Deprecated_Url)]
public sealed class Root
{
///
diff --git a/src/ModelContextProtocol.Core/Protocol/RootsCapability.cs b/src/ModelContextProtocol.Core/Protocol/RootsCapability.cs
index 0b2f9e762..eebcb741d 100644
--- a/src/ModelContextProtocol.Core/Protocol/RootsCapability.cs
+++ b/src/ModelContextProtocol.Core/Protocol/RootsCapability.cs
@@ -21,6 +21,7 @@ namespace ModelContextProtocol.Protocol;
/// See the schema for details.
///
///
+[Obsolete(Obsoletions.DeprecatedRoots_Message, DiagnosticId = Obsoletions.Deprecated_DiagnosticId, UrlFormat = Obsoletions.Deprecated_Url)]
public sealed class RootsCapability
{
///
diff --git a/src/ModelContextProtocol.Core/Protocol/RootsListChangedNotificationParams.cs b/src/ModelContextProtocol.Core/Protocol/RootsListChangedNotificationParams.cs
index 62312ab32..b4fe33b5f 100644
--- a/src/ModelContextProtocol.Core/Protocol/RootsListChangedNotificationParams.cs
+++ b/src/ModelContextProtocol.Core/Protocol/RootsListChangedNotificationParams.cs
@@ -12,4 +12,5 @@ namespace ModelContextProtocol.Protocol;
/// See the schema for details.
///
///
+[Obsolete(Obsoletions.DeprecatedRoots_Message, DiagnosticId = Obsoletions.Deprecated_DiagnosticId, UrlFormat = Obsoletions.Deprecated_Url)]
public sealed class RootsListChangedNotificationParams : NotificationParams;
diff --git a/src/ModelContextProtocol.Core/Protocol/SamplingCapability.cs b/src/ModelContextProtocol.Core/Protocol/SamplingCapability.cs
index cb530e795..7a4d015de 100644
--- a/src/ModelContextProtocol.Core/Protocol/SamplingCapability.cs
+++ b/src/ModelContextProtocol.Core/Protocol/SamplingCapability.cs
@@ -17,6 +17,7 @@ namespace ModelContextProtocol.Protocol;
/// using an AI model. The client must set a to process these requests.
///
///
+[Obsolete(Obsoletions.DeprecatedSampling_Message, DiagnosticId = Obsoletions.Deprecated_DiagnosticId, UrlFormat = Obsoletions.Deprecated_Url)]
public sealed class SamplingCapability
{
///
diff --git a/src/ModelContextProtocol.Core/Protocol/SamplingContextCapability.cs b/src/ModelContextProtocol.Core/Protocol/SamplingContextCapability.cs
index bae960f3a..a26bc5ccc 100644
--- a/src/ModelContextProtocol.Core/Protocol/SamplingContextCapability.cs
+++ b/src/ModelContextProtocol.Core/Protocol/SamplingContextCapability.cs
@@ -3,4 +3,5 @@ namespace ModelContextProtocol.Protocol;
///
/// Represents the sampling context capability.
///
+[Obsolete(Obsoletions.DeprecatedSampling_Message, DiagnosticId = Obsoletions.Deprecated_DiagnosticId, UrlFormat = Obsoletions.Deprecated_Url)]
public sealed class SamplingContextCapability;
\ No newline at end of file
diff --git a/src/ModelContextProtocol.Core/Protocol/SamplingMessage.cs b/src/ModelContextProtocol.Core/Protocol/SamplingMessage.cs
index d929a6877..1e2fa4c10 100644
--- a/src/ModelContextProtocol.Core/Protocol/SamplingMessage.cs
+++ b/src/ModelContextProtocol.Core/Protocol/SamplingMessage.cs
@@ -28,6 +28,7 @@ namespace ModelContextProtocol.Protocol;
///
///
[DebuggerDisplay("{DebuggerDisplay,nq}")]
+[Obsolete(Obsoletions.DeprecatedSampling_Message, DiagnosticId = Obsoletions.Deprecated_DiagnosticId, UrlFormat = Obsoletions.Deprecated_Url)]
public sealed class SamplingMessage
{
///
diff --git a/src/ModelContextProtocol.Core/Protocol/SamplingToolsCapability.cs b/src/ModelContextProtocol.Core/Protocol/SamplingToolsCapability.cs
index f93b79725..276c36089 100644
--- a/src/ModelContextProtocol.Core/Protocol/SamplingToolsCapability.cs
+++ b/src/ModelContextProtocol.Core/Protocol/SamplingToolsCapability.cs
@@ -3,4 +3,5 @@ namespace ModelContextProtocol.Protocol;
///
/// Represents the sampling tools capability.
///
+[Obsolete(Obsoletions.DeprecatedSampling_Message, DiagnosticId = Obsoletions.Deprecated_DiagnosticId, UrlFormat = Obsoletions.Deprecated_Url)]
public sealed class SamplingToolsCapability;
\ No newline at end of file
diff --git a/src/ModelContextProtocol.Core/Protocol/ServerCapabilities.cs b/src/ModelContextProtocol.Core/Protocol/ServerCapabilities.cs
index 92ffff424..0f1c4f540 100644
--- a/src/ModelContextProtocol.Core/Protocol/ServerCapabilities.cs
+++ b/src/ModelContextProtocol.Core/Protocol/ServerCapabilities.cs
@@ -41,6 +41,7 @@ public sealed class ServerCapabilities
/// Gets or sets a server's logging capability for sending log messages to the client.
///
[JsonPropertyName("logging")]
+ [Obsolete(Obsoletions.DeprecatedLogging_Message, DiagnosticId = Obsoletions.Deprecated_DiagnosticId, UrlFormat = Obsoletions.Deprecated_Url)]
public LoggingCapability? Logging { get; set; }
///
diff --git a/src/ModelContextProtocol.Core/Protocol/SetLevelRequestParams.cs b/src/ModelContextProtocol.Core/Protocol/SetLevelRequestParams.cs
index 9441d39ac..2352eb966 100644
--- a/src/ModelContextProtocol.Core/Protocol/SetLevelRequestParams.cs
+++ b/src/ModelContextProtocol.Core/Protocol/SetLevelRequestParams.cs
@@ -10,6 +10,7 @@ namespace ModelContextProtocol.Protocol;
/// This request allows clients to configure the level of logging information they want to receive from the server.
/// The server will send notifications for log events at the specified level and all higher (more severe) levels.
///
+[Obsolete(Obsoletions.DeprecatedLogging_Message, DiagnosticId = Obsoletions.Deprecated_DiagnosticId, UrlFormat = Obsoletions.Deprecated_Url)]
public sealed class SetLevelRequestParams : RequestParams
{
///
diff --git a/src/ModelContextProtocol.Core/Protocol/ToolChoice.cs b/src/ModelContextProtocol.Core/Protocol/ToolChoice.cs
index ebb80552f..903e978c6 100644
--- a/src/ModelContextProtocol.Core/Protocol/ToolChoice.cs
+++ b/src/ModelContextProtocol.Core/Protocol/ToolChoice.cs
@@ -5,6 +5,9 @@ namespace ModelContextProtocol.Protocol;
///
/// Controls tool selection behavior for sampling requests.
///
+// Sampling support type: only used to configure tool selection on sampling (createMessage) requests,
+// so it is deprecated together with sampling per SEP-2577.
+[Obsolete(Obsoletions.DeprecatedSampling_Message, DiagnosticId = Obsoletions.Deprecated_DiagnosticId, UrlFormat = Obsoletions.Deprecated_Url)]
public sealed class ToolChoice
{
///
diff --git a/src/ModelContextProtocol.Core/Server/DestinationBoundMcpServer.cs b/src/ModelContextProtocol.Core/Server/DestinationBoundMcpServer.cs
index bf87980e5..b8f96237a 100644
--- a/src/ModelContextProtocol.Core/Server/DestinationBoundMcpServer.cs
+++ b/src/ModelContextProtocol.Core/Server/DestinationBoundMcpServer.cs
@@ -14,6 +14,7 @@ internal sealed class DestinationBoundMcpServer(McpServerImpl server, ITransport
public override Implementation? ClientInfo => server.ClientInfo;
public override McpServerOptions ServerOptions => server.ServerOptions;
public override IServiceProvider? Services => server.Services;
+ [Obsolete(Obsoletions.DeprecatedLogging_Message, DiagnosticId = Obsoletions.Deprecated_DiagnosticId, UrlFormat = Obsoletions.Deprecated_Url)]
public override LoggingLevel? LoggingLevel => server.LoggingLevel;
///
diff --git a/src/ModelContextProtocol.Core/Server/McpRequestFilters.cs b/src/ModelContextProtocol.Core/Server/McpRequestFilters.cs
index e778d9d1b..9d9774e8b 100644
--- a/src/ModelContextProtocol.Core/Server/McpRequestFilters.cs
+++ b/src/ModelContextProtocol.Core/Server/McpRequestFilters.cs
@@ -264,6 +264,7 @@ public IList> Unsubscrib
/// at or above the specified level to the client as notifications/message notifications.
///
///
+ [Obsolete(Obsoletions.DeprecatedLogging_Message, DiagnosticId = Obsoletions.Deprecated_DiagnosticId, UrlFormat = Obsoletions.Deprecated_Url)]
public IList> SetLoggingLevelFilters
{
get => field ??= [];
diff --git a/src/ModelContextProtocol.Core/Server/McpServer.Methods.cs b/src/ModelContextProtocol.Core/Server/McpServer.Methods.cs
index a0d788a27..99cd7e80d 100644
--- a/src/ModelContextProtocol.Core/Server/McpServer.Methods.cs
+++ b/src/ModelContextProtocol.Core/Server/McpServer.Methods.cs
@@ -67,6 +67,7 @@ public static McpServer Create(
/// then returns to when the response is received.
///
///
+ [Obsolete(Obsoletions.DeprecatedSampling_Message, DiagnosticId = Obsoletions.Deprecated_DiagnosticId, UrlFormat = Obsoletions.Deprecated_Url)]
public ValueTask SampleAsync(
CreateMessageRequestParams requestParams,
CancellationToken cancellationToken = default)
@@ -107,6 +108,7 @@ public ValueTask SampleAsync(
/// is .
/// The client does not support sampling.
/// The request failed or the client returned an error response.
+ [Obsolete(Obsoletions.DeprecatedSampling_Message, DiagnosticId = Obsoletions.Deprecated_DiagnosticId, UrlFormat = Obsoletions.Deprecated_Url)]
public async Task SampleAsync(
IEnumerable messages, ChatOptions? chatOptions = default, JsonSerializerOptions? serializerOptions = null, CancellationToken cancellationToken = default)
{
@@ -243,6 +245,7 @@ public async Task SampleAsync(
/// , which is always open for the duration of
/// the request, rather than relying on the optional standalone GET SSE stream.
///
+ [Obsolete(Obsoletions.DeprecatedSampling_Message, DiagnosticId = Obsoletions.Deprecated_DiagnosticId, UrlFormat = Obsoletions.Deprecated_Url)]
public IChatClient AsSamplingChatClient(JsonSerializerOptions? serializerOptions = null)
{
ThrowIfSamplingUnsupported();
@@ -252,6 +255,7 @@ public IChatClient AsSamplingChatClient(JsonSerializerOptions? serializerOptions
/// Gets an on which logged messages will be sent as notifications to the client.
/// An that can be used to log to the client.
+ [Obsolete(Obsoletions.DeprecatedLogging_Message, DiagnosticId = Obsoletions.Deprecated_DiagnosticId, UrlFormat = Obsoletions.Deprecated_Url)]
public ILoggerProvider AsClientLoggerProvider() =>
new ClientLoggerProvider(this);
@@ -271,6 +275,7 @@ public ILoggerProvider AsClientLoggerProvider() =>
/// , which is always open for the duration of
/// the request, rather than relying on the optional standalone GET SSE stream.
///
+ [Obsolete(Obsoletions.DeprecatedRoots_Message, DiagnosticId = Obsoletions.Deprecated_DiagnosticId, UrlFormat = Obsoletions.Deprecated_Url)]
public ValueTask RequestRootsAsync(
ListRootsRequestParams requestParams,
CancellationToken cancellationToken = default)
diff --git a/src/ModelContextProtocol.Core/Server/McpServer.cs b/src/ModelContextProtocol.Core/Server/McpServer.cs
index 444365361..fb6d7074a 100644
--- a/src/ModelContextProtocol.Core/Server/McpServer.cs
+++ b/src/ModelContextProtocol.Core/Server/McpServer.cs
@@ -62,6 +62,7 @@ protected McpServer()
public abstract IServiceProvider? Services { get; }
/// Gets the last logging level set by the client, or if it's never been set.
+ [Obsolete(Obsoletions.DeprecatedLogging_Message, DiagnosticId = Obsoletions.Deprecated_DiagnosticId, UrlFormat = Obsoletions.Deprecated_Url)]
public abstract LoggingLevel? LoggingLevel { get; }
///
diff --git a/src/ModelContextProtocol.Core/Server/McpServerHandlers.cs b/src/ModelContextProtocol.Core/Server/McpServerHandlers.cs
index f650a0011..4f9509b9d 100644
--- a/src/ModelContextProtocol.Core/Server/McpServerHandlers.cs
+++ b/src/ModelContextProtocol.Core/Server/McpServerHandlers.cs
@@ -199,6 +199,7 @@ public McpRequestHandler
///
+ [Obsolete(Obsoletions.DeprecatedLogging_Message, DiagnosticId = Obsoletions.Deprecated_DiagnosticId, UrlFormat = Obsoletions.Deprecated_Url)]
public McpRequestHandler? SetLoggingLevelHandler { get; set; }
///
diff --git a/src/ModelContextProtocol.Core/Server/McpServerImpl.cs b/src/ModelContextProtocol.Core/Server/McpServerImpl.cs
index d6759ac79..9ef1782ca 100644
--- a/src/ModelContextProtocol.Core/Server/McpServerImpl.cs
+++ b/src/ModelContextProtocol.Core/Server/McpServerImpl.cs
@@ -169,6 +169,7 @@ void Register(McpServerPrimitiveCollection? collection,
public override IServiceProvider? Services { get; }
///
+ [Obsolete(Obsoletions.DeprecatedLogging_Message, DiagnosticId = Obsoletions.Deprecated_DiagnosticId, UrlFormat = Obsoletions.Deprecated_Url)]
public override LoggingLevel? LoggingLevel => _loggingLevel?.Value;
///
diff --git a/src/ModelContextProtocol.Core/Server/McpServerOptions.cs b/src/ModelContextProtocol.Core/Server/McpServerOptions.cs
index 32c13da27..eb99913d5 100644
--- a/src/ModelContextProtocol.Core/Server/McpServerOptions.cs
+++ b/src/ModelContextProtocol.Core/Server/McpServerOptions.cs
@@ -187,6 +187,7 @@ public McpServerFilters Filters
/// This value is used in
/// when is not set in the request options.
///
+ [Obsolete(Obsoletions.DeprecatedSampling_Message, DiagnosticId = Obsoletions.Deprecated_DiagnosticId, UrlFormat = Obsoletions.Deprecated_Url)]
public int MaxSamplingOutputTokens { get; set; } = 1000;
///
diff --git a/src/ModelContextProtocol/McpRequestFilterBuilderExtensions.cs b/src/ModelContextProtocol/McpRequestFilterBuilderExtensions.cs
index 8ee7fb064..2ed06355f 100644
--- a/src/ModelContextProtocol/McpRequestFilterBuilderExtensions.cs
+++ b/src/ModelContextProtocol/McpRequestFilterBuilderExtensions.cs
@@ -165,6 +165,7 @@ public static IMcpRequestFilterBuilder AddUnsubscribeFromResourcesFilter(this IM
/// The request filter builder instance.
/// The filter function that wraps the handler.
/// The builder provided in .
+ [Obsolete(Obsoletions.DeprecatedLogging_Message, DiagnosticId = Obsoletions.Deprecated_DiagnosticId, UrlFormat = Obsoletions.Deprecated_Url)]
public static IMcpRequestFilterBuilder AddSetLoggingLevelFilter(this IMcpRequestFilterBuilder builder, McpRequestFilter filter)
{
Throw.IfNull(builder);
diff --git a/src/ModelContextProtocol/McpServerBuilderExtensions.cs b/src/ModelContextProtocol/McpServerBuilderExtensions.cs
index da63dc31d..7f07be67e 100644
--- a/src/ModelContextProtocol/McpServerBuilderExtensions.cs
+++ b/src/ModelContextProtocol/McpServerBuilderExtensions.cs
@@ -878,6 +878,7 @@ public static IMcpServerBuilder WithUnsubscribeFromResourcesHandler(this IMcpSer
/// most recently set level.
///
///
+ [Obsolete(Obsoletions.DeprecatedLogging_Message, DiagnosticId = Obsoletions.Deprecated_DiagnosticId, UrlFormat = Obsoletions.Deprecated_Url)]
public static IMcpServerBuilder WithSetLoggingLevelHandler(this IMcpServerBuilder builder, McpRequestHandler handler)
{
Throw.IfNull(builder);
diff --git a/src/ModelContextProtocol/ModelContextProtocol.csproj b/src/ModelContextProtocol/ModelContextProtocol.csproj
index 07167c438..0d717ef10 100644
--- a/src/ModelContextProtocol/ModelContextProtocol.csproj
+++ b/src/ModelContextProtocol/ModelContextProtocol.csproj
@@ -16,6 +16,11 @@
true
+
+
+ $(NoWarn);CS0436
+
+
diff --git a/tests/Directory.Build.props b/tests/Directory.Build.props
index bc169333f..b4a79a31e 100644
--- a/tests/Directory.Build.props
+++ b/tests/Directory.Build.props
@@ -7,5 +7,8 @@
$(NoWarn);MCPEXP001
$(NoWarn);MCP9004
+
+ $(NoWarn);MCP9005
diff --git a/tests/ModelContextProtocol.Tests/Server/McpServerTests.cs b/tests/ModelContextProtocol.Tests/Server/McpServerTests.cs
index 7ed3c35e3..87f363f03 100644
--- a/tests/ModelContextProtocol.Tests/Server/McpServerTests.cs
+++ b/tests/ModelContextProtocol.Tests/Server/McpServerTests.cs
@@ -1368,7 +1368,10 @@ public override Task SendRequestAsync(JsonRpcRequest request, C
public override string? NegotiatedProtocolVersion => throw new NotImplementedException();
public override Implementation? ClientInfo => throw new NotImplementedException();
public override IServiceProvider? Services => throw new NotImplementedException();
+ // McpServer.LoggingLevel is obsolete (SEP-2577) but abstract, so this test double must override it.
+#pragma warning disable CS0672 // Member overrides obsolete member
public override LoggingLevel? LoggingLevel => throw new NotImplementedException();
+#pragma warning restore CS0672
public override Task SendMessageAsync(JsonRpcMessage message, CancellationToken cancellationToken = default) =>
throw new NotImplementedException();
public override Task RunAsync(CancellationToken cancellationToken = default) =>