Decouple Handlers and Collections from protocol types (#765)

* Decouple Handlers and Collections (e.g. ToolsHandler and ToolsCollection) from Capabilities by promoting them to the options types.

Also, group all handlers in container classes, for server, I decided to move McpServerHandlers down to Mcp.Core and move the NotificationHandlers there too.

Also, Fix ListResourceTemplatesHandler issue.

* Add remarks for empty protocol capability types

* Keep JsonIgnore properties and mark them as Obsolete

* Continue supporting Obsolete members

* Update Obsolete messages to indicate the member will be removed

* Add EditorBrowsable Never to the remaining obsolete members
This commit is contained in:
David Cantú 2025-09-24 09:42:03 -05:00 • committed by GitHub
commit 5f992994c3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 1588 additions and 1161 deletions

View file

@ -1,5 +1,7 @@
using ModelContextProtocol.Server;
using System.ComponentModel;
using System.Text.Json.Serialization;
using ModelContextProtocol.Client;
using ModelContextProtocol.Server;
namespace ModelContextProtocol.Protocol;
@ -45,7 +47,7 @@ public sealed class ClientCapabilities
/// </para>
/// <para>
/// The server can use <see cref="McpServer.RequestRootsAsync"/> to request the list of
/// available roots from the client, which will trigger the client's <see cref="RootsCapability.RootsHandler"/>.
/// available roots from the client, which will trigger the client's <see cref="ModelContextProtocol.Client.McpClientHandlers.RootsHandler"/>.
/// </para>
/// </remarks>
[JsonPropertyName("roots")]
@ -83,5 +85,7 @@ public sealed class ClientCapabilities
/// </para>
/// </remarks>
[JsonIgnore]
[Obsolete($"Use {nameof(McpClientOptions.Handlers.NotificationHandlers)} instead. This member will be removed in a subsequent release.")] // See: https://github.com/modelcontextprotocol/csharp-sdk/issues/774
[EditorBrowsable(EditorBrowsableState.Never)]
public IEnumerable<KeyValuePair<string, Func<JsonRpcNotification, CancellationToken, ValueTask>>>? NotificationHandlers { get; set; }
}

View file

@ -1,5 +1,6 @@
using ModelContextProtocol.Server;
using System.ComponentModel;
using System.Text.Json.Serialization;
using ModelContextProtocol.Server;
namespace ModelContextProtocol.Protocol;
@ -19,11 +20,14 @@ namespace ModelContextProtocol.Protocol;
/// <para>
/// See the <see href="https://github.com/modelcontextprotocol/specification/blob/main/schema/">schema</see> for details.
/// </para>
/// <para>
/// This class is intentionally empty as the Model Context Protocol specification does not
/// currently define additional properties for sampling capabilities. Future versions of the
/// specification may extend this capability with additional configuration options.
/// </para>
/// </remarks>
public sealed class CompletionsCapability
{
// Currently empty in the spec, but may be extended in the future.
/// <summary>
/// Gets or sets the handler for completion requests.
/// </summary>
@ -33,5 +37,7 @@ public sealed class CompletionsCapability
/// and should return appropriate completion suggestions.
/// </remarks>
[JsonIgnore]
[Obsolete($"Use {nameof(McpServerOptions.Handlers.CompleteHandler)} instead. This member will be removed in a subsequent release.")] // See: https://github.com/modelcontextprotocol/csharp-sdk/issues/774
[EditorBrowsable(EditorBrowsableState.Never)]
public McpRequestHandler<CompleteRequestParams, CompleteResult>? CompleteHandler { get; set; }
}

View file

@ -1,4 +1,6 @@
using System.ComponentModel;
using System.Text.Json.Serialization;
using ModelContextProtocol.Client;
namespace ModelContextProtocol.Protocol;
@ -11,13 +13,16 @@ namespace ModelContextProtocol.Protocol;
/// </para>
/// <para>
/// When this capability is enabled, an MCP server can request the client to provide additional information
/// during interactions. The client must set a <see cref="ElicitationHandler"/> to process these requests.
/// during interactions. The client must set a <see cref="ModelContextProtocol.Client.McpClientHandlers.ElicitationHandler"/> to process these requests.
/// </para>
/// <para>
/// This class is intentionally empty as the Model Context Protocol specification does not
/// currently define additional properties for sampling capabilities. Future versions of the
/// specification may extend this capability with additional configuration options.
/// </para>
/// </remarks>
public sealed class ElicitationCapability
{
// Currently empty in the spec, but may be extended in the future.
/// <summary>
/// Gets or sets the handler for processing <see cref="RequestMethods.ElicitationCreate"/> requests.
/// </summary>
@ -32,5 +37,7 @@ public sealed class ElicitationCapability
/// </para>
/// </remarks>
[JsonIgnore]
[Obsolete($"Use {nameof(McpClientOptions.Handlers.ElicitationHandler)} instead. This member will be removed in a subsequent release.")] // See: https://github.com/modelcontextprotocol/csharp-sdk/issues/774
[EditorBrowsable(EditorBrowsableState.Never)]
public Func<ElicitRequestParams?, CancellationToken, ValueTask<ElicitResult>>? ElicitationHandler { get; set; }
}

View file

@ -1,5 +1,6 @@
using ModelContextProtocol.Server;
using System.ComponentModel;
using System.Text.Json.Serialization;
using ModelContextProtocol.Server;
namespace ModelContextProtocol.Protocol;
@ -7,16 +8,23 @@ namespace ModelContextProtocol.Protocol;
/// Represents the logging capability configuration for a Model Context Protocol server.
/// </summary>
/// <remarks>
/// <para>
/// This capability allows clients to set the logging level and receive log messages from the server.
/// See the <see href="https://github.com/modelcontextprotocol/specification/blob/main/schema/">schema</see> for details.
/// </para>
/// <para>
/// This class is intentionally empty as the Model Context Protocol specification does not
/// currently define additional properties for sampling capabilities. Future versions of the
/// specification may extend this capability with additional configuration options.
/// </para>
/// </remarks>
public sealed class LoggingCapability
{
// Currently empty in the spec, but may be extended in the future
/// <summary>
/// Gets or sets the handler for set logging level requests from clients.
/// </summary>
[JsonIgnore]
[Obsolete($"Use {nameof(McpServerOptions.Handlers.SetLoggingLevelHandler)} instead. This member will be removed in a subsequent release.")] // See: https://github.com/modelcontextprotocol/csharp-sdk/issues/774
[EditorBrowsable(EditorBrowsableState.Never)]
public McpRequestHandler<SetLevelRequestParams, EmptyResult>? SetLoggingLevelHandler { get; set; }
}

View file

@ -1,4 +1,5 @@
using ModelContextProtocol.Server;
using System.ComponentModel;
using System.Text.Json.Serialization;
namespace ModelContextProtocol.Protocol;
@ -9,7 +10,7 @@ namespace ModelContextProtocol.Protocol;
/// <remarks>
/// <para>
/// The prompts capability allows a server to expose a collection of predefined prompt templates that clients
/// can discover and use. These prompts can be static (defined in the <see cref="PromptCollection"/>) or
/// can discover and use. These prompts can be static (defined in the <see cref="McpServerOptions.PromptCollection"/>) or
/// dynamically generated through handlers.
/// </para>
/// <para>
@ -40,6 +41,8 @@ public sealed class PromptsCapability
/// along with any prompts defined in <see cref="PromptCollection"/>.
/// </remarks>
[JsonIgnore]
[Obsolete($"Use {nameof(McpServerOptions.Handlers.ListPromptsHandler)} instead. This member will be removed in a subsequent release.")] // See: https://github.com/modelcontextprotocol/csharp-sdk/issues/774
[EditorBrowsable(EditorBrowsableState.Never)]
public McpRequestHandler<ListPromptsRequestParams, ListPromptsResult>? ListPromptsHandler { get; set; }
/// <summary>
@ -57,6 +60,8 @@ public sealed class PromptsCapability
/// </para>
/// </remarks>
[JsonIgnore]
[Obsolete($"Use {nameof(McpServerOptions.Handlers.GetPromptHandler)} instead. This member will be removed in a subsequent release.")] // See: https://github.com/modelcontextprotocol/csharp-sdk/issues/774
[EditorBrowsable(EditorBrowsableState.Never)]
public McpRequestHandler<GetPromptRequestParams, GetPromptResult>? GetPromptHandler { get; set; }
/// <summary>
@ -78,5 +83,7 @@ public sealed class PromptsCapability
/// </para>
/// </remarks>
[JsonIgnore]
[Obsolete($"Use {nameof(McpServerOptions.PromptCollection)} instead. This member will be removed in a subsequent release.")] // See: https://github.com/modelcontextprotocol/csharp-sdk/issues/774
[EditorBrowsable(EditorBrowsableState.Never)]
public McpServerPrimitiveCollection<McpServerPrompt>? PromptCollection { get; set; }
}

View file

@ -1,4 +1,5 @@
using ModelContextProtocol.Server;
using System.ComponentModel;
using System.Text.Json.Serialization;
namespace ModelContextProtocol.Protocol;
@ -39,6 +40,8 @@ public sealed class ResourcesCapability
/// allowing clients to discover available resource types and their access patterns.
/// </remarks>
[JsonIgnore]
[Obsolete($"Use {nameof(McpServerOptions.Handlers.ListResourceTemplatesHandler)} instead. This member will be removed in a subsequent release.")] // See: https://github.com/modelcontextprotocol/csharp-sdk/issues/774
[EditorBrowsable(EditorBrowsableState.Never)]
public McpRequestHandler<ListResourceTemplatesRequestParams, ListResourceTemplatesResult>? ListResourceTemplatesHandler { get; set; }
/// <summary>
@ -49,6 +52,8 @@ public sealed class ResourcesCapability
/// The implementation should return a <see cref="ListResourcesResult"/> with the matching resources.
/// </remarks>
[JsonIgnore]
[Obsolete($"Use {nameof(McpServerOptions.Handlers.ListResourcesHandler)} instead. This member will be removed in a subsequent release.")] // See: https://github.com/modelcontextprotocol/csharp-sdk/issues/774
[EditorBrowsable(EditorBrowsableState.Never)]
public McpRequestHandler<ListResourcesRequestParams, ListResourcesResult>? ListResourcesHandler { get; set; }
/// <summary>
@ -61,6 +66,8 @@ public sealed class ResourcesCapability
/// its contents in a ReadResourceResult object.
/// </remarks>
[JsonIgnore]
[Obsolete($"Use {nameof(McpServerOptions.Handlers.ReadResourceHandler)} instead. This member will be removed in a subsequent release.")] // See: https://github.com/modelcontextprotocol/csharp-sdk/issues/774
[EditorBrowsable(EditorBrowsableState.Never)]
public McpRequestHandler<ReadResourceRequestParams, ReadResourceResult>? ReadResourceHandler { get; set; }
/// <summary>
@ -74,6 +81,8 @@ public sealed class ResourcesCapability
/// requiring polling.
/// </remarks>
[JsonIgnore]
[Obsolete($"Use {nameof(McpServerOptions.Handlers.SubscribeToResourcesHandler)} instead. This member will be removed in a subsequent release.")] // See: https://github.com/modelcontextprotocol/csharp-sdk/issues/774
[EditorBrowsable(EditorBrowsableState.Never)]
public McpRequestHandler<SubscribeRequestParams, EmptyResult>? SubscribeToResourcesHandler { get; set; }
/// <summary>
@ -85,6 +94,8 @@ public sealed class ResourcesCapability
/// about the specified resource.
/// </remarks>
[JsonIgnore]
[Obsolete($"Use {nameof(McpServerOptions.Handlers.UnsubscribeFromResourcesHandler)} instead. This member will be removed in a subsequent release.")] // See: https://github.com/modelcontextprotocol/csharp-sdk/issues/774
[EditorBrowsable(EditorBrowsableState.Never)]
public McpRequestHandler<UnsubscribeRequestParams, EmptyResult>? UnsubscribeFromResourcesHandler { get; set; }
/// <summary>
@ -103,5 +114,7 @@ public sealed class ResourcesCapability
/// </para>
/// </remarks>
[JsonIgnore]
[Obsolete($"Use {nameof(McpServerOptions.ResourceCollection)} instead. This member will be removed in a subsequent release.")] // See: https://github.com/modelcontextprotocol/csharp-sdk/issues/774
[EditorBrowsable(EditorBrowsableState.Never)]
public McpServerResourceCollection? ResourceCollection { get; set; }
}

View file

@ -1,4 +1,6 @@
using System.ComponentModel;
using System.Text.Json.Serialization;
using ModelContextProtocol.Client;
namespace ModelContextProtocol.Protocol;
@ -40,5 +42,7 @@ public sealed class RootsCapability
/// The handler receives request parameters and should return a <see cref="ListRootsResult"/> containing the collection of available roots.
/// </remarks>
[JsonIgnore]
[Obsolete($"Use {nameof(McpClientOptions.Handlers.RootsHandler)} instead. This member will be removed in a subsequent release.")] // See: https://github.com/modelcontextprotocol/csharp-sdk/issues/774
[EditorBrowsable(EditorBrowsableState.Never)]
public Func<ListRootsRequestParams?, CancellationToken, ValueTask<ListRootsResult>>? RootsHandler { get; set; }
}

View file

@ -1,6 +1,7 @@
using System.ComponentModel;
using System.Text.Json.Serialization;
using Microsoft.Extensions.AI;
using ModelContextProtocol.Client;
using System.Text.Json.Serialization;
namespace ModelContextProtocol.Protocol;
@ -13,13 +14,16 @@ namespace ModelContextProtocol.Protocol;
/// </para>
/// <para>
/// When this capability is enabled, an MCP server can request the client to generate content
/// using an AI model. The client must set a <see cref="SamplingHandler"/> to process these requests.
/// using an AI model. The client must set a <see cref="ModelContextProtocol.Client.McpClientHandlers.SamplingHandler"/> to process these requests.
/// </para>
/// <para>
/// This class is intentionally empty as the Model Context Protocol specification does not
/// currently define additional properties for sampling capabilities. Future versions of the
/// specification may extend this capability with additional configuration options.
/// </para>
/// </remarks>
public sealed class SamplingCapability
{
// Currently empty in the spec, but may be extended in the future
/// <summary>
/// Gets or sets the handler for processing <see cref="RequestMethods.SamplingCreateMessage"/> requests.
/// </summary>
@ -39,5 +43,7 @@ public sealed class SamplingCapability
/// </para>
/// </remarks>
[JsonIgnore]
[Obsolete($"Use {nameof(McpClientOptions.Handlers.SamplingHandler)} instead. This member will be removed in a subsequent release.")] // See: https://github.com/modelcontextprotocol/csharp-sdk/issues/774
[EditorBrowsable(EditorBrowsableState.Never)]
public Func<CreateMessageRequestParams?, IProgress<ProgressNotificationValue>, CancellationToken, ValueTask<CreateMessageResult>>? SamplingHandler { get; set; }
}

View file

@ -1,4 +1,6 @@
using System.ComponentModel;
using System.Text.Json.Serialization;
using ModelContextProtocol.Server;
namespace ModelContextProtocol.Protocol;
@ -21,13 +23,13 @@ public sealed class ServerCapabilities
/// </summary>
/// <remarks>
/// <para>
/// The <see cref="Experimental"/> dictionary allows servers to advertise support for features that are not yet
/// standardized in the Model Context Protocol specification. This extension mechanism enables
/// The <see cref="Experimental"/> dictionary allows servers to advertise support for features that are not yet
/// standardized in the Model Context Protocol specification. This extension mechanism enables
/// future protocol enhancements while maintaining backward compatibility.
/// </para>
/// <para>
/// Values in this dictionary are implementation-specific and should be coordinated between client
/// and server implementations. Clients should not assume the presence of any experimental capability
/// Values in this dictionary are implementation-specific and should be coordinated between client
/// and server implementations. Clients should not assume the presence of any experimental capability
/// without checking for it first.
/// </para>
/// </remarks>
@ -82,5 +84,7 @@ public sealed class ServerCapabilities
/// </para>
/// </remarks>
[JsonIgnore]
[Obsolete($"Use {nameof(McpServerOptions.Handlers.NotificationHandlers)} instead. This member will be removed in a subsequent release.")] // See: https://github.com/modelcontextprotocol/csharp-sdk/issues/774
[EditorBrowsable(EditorBrowsableState.Never)]
public IEnumerable<KeyValuePair<string, Func<JsonRpcNotification, CancellationToken, ValueTask>>>? NotificationHandlers { get; set; }
}

View file

@ -1,5 +1,6 @@
using ModelContextProtocol.Server;
using System.ComponentModel;
using System.Text.Json.Serialization;
using ModelContextProtocol.Server;
namespace ModelContextProtocol.Protocol;
@ -33,6 +34,8 @@ public sealed class ToolsCapability
/// and the tools from the collection will be combined to form the complete list of available tools.
/// </remarks>
[JsonIgnore]
[Obsolete($"Use {nameof(McpServerOptions.Handlers.ListToolsHandler)} instead. This member will be removed in a subsequent release.")] // See: https://github.com/modelcontextprotocol/csharp-sdk/issues/774
[EditorBrowsable(EditorBrowsableState.Never)]
public McpRequestHandler<ListToolsRequestParams, ListToolsResult>? ListToolsHandler { get; set; }
/// <summary>
@ -45,6 +48,8 @@ public sealed class ToolsCapability
/// being called and its arguments, and should return a <see cref="CallToolResult"/> with the execution results.
/// </remarks>
[JsonIgnore]
[Obsolete($"Use {nameof(McpServerOptions.Handlers.CallToolHandler)} instead. This member will be removed in a subsequent release.")] // See: https://github.com/modelcontextprotocol/csharp-sdk/issues/774
[EditorBrowsable(EditorBrowsableState.Never)]
public McpRequestHandler<CallToolRequestParams, CallToolResult>? CallToolHandler { get; set; }
/// <summary>
@ -59,5 +64,7 @@ public sealed class ToolsCapability
/// will be invoked as a fallback.
/// </remarks>
[JsonIgnore]
[Obsolete($"Use {nameof(McpServerOptions.ToolCollection)} instead. This member will be removed in a subsequent release.")] // See: https://github.com/modelcontextprotocol/csharp-sdk/issues/774
[EditorBrowsable(EditorBrowsableState.Never)]
public McpServerPrimitiveCollection<McpServerTool>? ToolCollection { get; set; }
}