diff --git a/src/ModelContextProtocol.Core/Client/McpClientImpl.cs b/src/ModelContextProtocol.Core/Client/McpClientImpl.cs index 4205c28e1..3f44122ed 100644 --- a/src/ModelContextProtocol.Core/Client/McpClientImpl.cs +++ b/src/ModelContextProtocol.Core/Client/McpClientImpl.cs @@ -486,10 +486,10 @@ private void RegisterTaskHandlers(RequestHandlers requestHandlers, IMcpTaskStore // Advertise task capabilities _options.Capabilities ??= new(); - var tasksCapability = _options.Capabilities.Tasks ??= new McpTasksCapability(); + var tasksCapability = _options.Capabilities.Tasks ??= new ClientMcpTasksCapability(); tasksCapability.List ??= new ListMcpTasksCapability(); tasksCapability.Cancel ??= new CancelMcpTasksCapability(); - var requestsCapability = tasksCapability.Requests ??= new RequestMcpTasksCapability(); + var requestsCapability = tasksCapability.Requests ??= new ClientRequestMcpTasksCapability(); // Only advertise sampling tasks if sampling handler is present if (_options.Handlers.SamplingHandler is not null) diff --git a/src/ModelContextProtocol.Core/CompatibilitySuppressions.xml b/src/ModelContextProtocol.Core/CompatibilitySuppressions.xml index 640351668..cc73ddd01 100644 --- a/src/ModelContextProtocol.Core/CompatibilitySuppressions.xml +++ b/src/ModelContextProtocol.Core/CompatibilitySuppressions.xml @@ -1,6 +1,118 @@  + + CP0001 + T:ModelContextProtocol.Protocol.McpTasksCapability + lib/net10.0/ModelContextProtocol.Core.dll + lib/net10.0/ModelContextProtocol.Core.dll + true + + + CP0001 + T:ModelContextProtocol.Protocol.RequestMcpTasksCapability + lib/net10.0/ModelContextProtocol.Core.dll + lib/net10.0/ModelContextProtocol.Core.dll + true + + + CP0001 + T:ModelContextProtocol.Protocol.McpTasksCapability + lib/net8.0/ModelContextProtocol.Core.dll + lib/net8.0/ModelContextProtocol.Core.dll + true + + + CP0001 + T:ModelContextProtocol.Protocol.RequestMcpTasksCapability + lib/net8.0/ModelContextProtocol.Core.dll + lib/net8.0/ModelContextProtocol.Core.dll + true + + + CP0001 + T:ModelContextProtocol.Protocol.McpTasksCapability + lib/net9.0/ModelContextProtocol.Core.dll + lib/net9.0/ModelContextProtocol.Core.dll + true + + + CP0001 + T:ModelContextProtocol.Protocol.RequestMcpTasksCapability + lib/net9.0/ModelContextProtocol.Core.dll + lib/net9.0/ModelContextProtocol.Core.dll + true + + + CP0001 + T:ModelContextProtocol.Protocol.McpTasksCapability + lib/netstandard2.0/ModelContextProtocol.Core.dll + lib/netstandard2.0/ModelContextProtocol.Core.dll + true + + + CP0001 + T:ModelContextProtocol.Protocol.RequestMcpTasksCapability + lib/netstandard2.0/ModelContextProtocol.Core.dll + lib/netstandard2.0/ModelContextProtocol.Core.dll + true + + + CP0002 + M:ModelContextProtocol.Protocol.ClientCapabilities.get_Tasks + lib/net10.0/ModelContextProtocol.Core.dll + lib/net10.0/ModelContextProtocol.Core.dll + true + + + CP0002 + M:ModelContextProtocol.Protocol.ServerCapabilities.get_Tasks + lib/net10.0/ModelContextProtocol.Core.dll + lib/net10.0/ModelContextProtocol.Core.dll + true + + + CP0002 + M:ModelContextProtocol.Protocol.ClientCapabilities.get_Tasks + lib/net8.0/ModelContextProtocol.Core.dll + lib/net8.0/ModelContextProtocol.Core.dll + true + + + CP0002 + M:ModelContextProtocol.Protocol.ServerCapabilities.get_Tasks + lib/net8.0/ModelContextProtocol.Core.dll + lib/net8.0/ModelContextProtocol.Core.dll + true + + + CP0002 + M:ModelContextProtocol.Protocol.ClientCapabilities.get_Tasks + lib/net9.0/ModelContextProtocol.Core.dll + lib/net9.0/ModelContextProtocol.Core.dll + true + + + CP0002 + M:ModelContextProtocol.Protocol.ServerCapabilities.get_Tasks + lib/net9.0/ModelContextProtocol.Core.dll + lib/net9.0/ModelContextProtocol.Core.dll + true + + + CP0002 + M:ModelContextProtocol.Protocol.ClientCapabilities.get_Tasks + lib/netstandard2.0/ModelContextProtocol.Core.dll + lib/netstandard2.0/ModelContextProtocol.Core.dll + true + + + CP0002 + M:ModelContextProtocol.Protocol.ServerCapabilities.get_Tasks + lib/netstandard2.0/ModelContextProtocol.Core.dll + lib/netstandard2.0/ModelContextProtocol.Core.dll + true + CP0005 M:ModelContextProtocol.Client.McpClient.get_Completion diff --git a/src/ModelContextProtocol.Core/McpJsonUtilities.cs b/src/ModelContextProtocol.Core/McpJsonUtilities.cs index abb6d29df..6860e9ef2 100644 --- a/src/ModelContextProtocol.Core/McpJsonUtilities.cs +++ b/src/ModelContextProtocol.Core/McpJsonUtilities.cs @@ -155,8 +155,10 @@ internal static bool IsValidMcpToolSchema(JsonElement element) [JsonSerializable(typeof(ListTasksResult))] [JsonSerializable(typeof(CancelMcpTaskRequestParams))] [JsonSerializable(typeof(CancelMcpTaskResult))] - [JsonSerializable(typeof(McpTasksCapability))] - [JsonSerializable(typeof(RequestMcpTasksCapability))] + [JsonSerializable(typeof(ServerMcpTasksCapability))] + [JsonSerializable(typeof(ClientMcpTasksCapability))] + [JsonSerializable(typeof(ServerRequestMcpTasksCapability))] + [JsonSerializable(typeof(ClientRequestMcpTasksCapability))] [JsonSerializable(typeof(ToolExecution))] [JsonSerializable(typeof(ToolTaskSupport))] diff --git a/src/ModelContextProtocol.Core/Protocol/CancelMcpTasksCapability.cs b/src/ModelContextProtocol.Core/Protocol/CancelMcpTasksCapability.cs new file mode 100644 index 000000000..b308c9192 --- /dev/null +++ b/src/ModelContextProtocol.Core/Protocol/CancelMcpTasksCapability.cs @@ -0,0 +1,9 @@ +using System.Diagnostics.CodeAnalysis; + +namespace ModelContextProtocol.Protocol; + +/// +/// Represents the capability for cancelling tasks. +/// +[Experimental(Experimentals.Tasks_DiagnosticId, UrlFormat = Experimentals.Tasks_Url)] +public sealed class CancelMcpTasksCapability; diff --git a/src/ModelContextProtocol.Core/Protocol/ClientCapabilities.cs b/src/ModelContextProtocol.Core/Protocol/ClientCapabilities.cs index 77b2bef9f..f406be126 100644 --- a/src/ModelContextProtocol.Core/Protocol/ClientCapabilities.cs +++ b/src/ModelContextProtocol.Core/Protocol/ClientCapabilities.cs @@ -78,12 +78,12 @@ public sealed class ClientCapabilities /// elicitation) execute asynchronously, with the ability to poll for status and retrieve results later. /// /// - /// See for details on configuring which operations support tasks. + /// See for details on configuring which operations support tasks. /// /// [Experimental(Experimentals.Tasks_DiagnosticId, UrlFormat = Experimentals.Tasks_Url)] [JsonIgnore] - public McpTasksCapability? Tasks + public ClientMcpTasksCapability? Tasks { get => TasksCore; set => TasksCore = value; @@ -92,7 +92,7 @@ public McpTasksCapability? Tasks // See ExperimentalInternalPropertyTests.cs before modifying this property. [JsonInclude] [JsonPropertyName("tasks")] - internal McpTasksCapability? TasksCore { get; set; } + internal ClientMcpTasksCapability? TasksCore { get; set; } /// /// Gets or sets optional MCP extensions that the client supports. diff --git a/src/ModelContextProtocol.Core/Protocol/ClientMcpTasksCapability.cs b/src/ModelContextProtocol.Core/Protocol/ClientMcpTasksCapability.cs new file mode 100644 index 000000000..543b1916a --- /dev/null +++ b/src/ModelContextProtocol.Core/Protocol/ClientMcpTasksCapability.cs @@ -0,0 +1,45 @@ +using System.Diagnostics.CodeAnalysis; +using System.Text.Json.Serialization; + +namespace ModelContextProtocol.Protocol; + +/// +/// Represents the tasks capability configuration for clients. +/// +/// +/// +/// The tasks capability enables servers to augment their requests with tasks for long-running +/// operations. Tasks are durable state machines that carry information about the underlying +/// execution state of requests. +/// +/// +/// During initialization, both parties exchange their tasks capabilities to establish which +/// operations support task-based execution. Requestors should only augment requests with a +/// task if the corresponding capability has been declared by the receiver. +/// +/// +[Experimental(Experimentals.Tasks_DiagnosticId, UrlFormat = Experimentals.Tasks_Url)] +public sealed class ClientMcpTasksCapability +{ + /// + /// Gets or sets whether this client supports the tasks/list operation. + /// + [JsonPropertyName("list")] + public ListMcpTasksCapability? List { get; set; } + + /// + /// Gets or sets whether this client supports the tasks/cancel operation. + /// + [JsonPropertyName("cancel")] + public CancelMcpTasksCapability? Cancel { get; set; } + + /// + /// Gets or sets which client request types support task augmentation. + /// + /// + /// For clients, this includes tasks.requests.sampling.createMessage and + /// tasks.requests.elicitation.create. + /// + [JsonPropertyName("requests")] + public ClientRequestMcpTasksCapability? Requests { get; set; } +} diff --git a/src/ModelContextProtocol.Core/Protocol/ClientRequestMcpTasksCapability.cs b/src/ModelContextProtocol.Core/Protocol/ClientRequestMcpTasksCapability.cs new file mode 100644 index 000000000..692c78da2 --- /dev/null +++ b/src/ModelContextProtocol.Core/Protocol/ClientRequestMcpTasksCapability.cs @@ -0,0 +1,65 @@ +using System.Diagnostics.CodeAnalysis; +using System.Text.Json.Serialization; + +namespace ModelContextProtocol.Protocol; + +/// +/// Represents task support for client request types. +/// +/// +/// Clients can only support task augmentation for sampling/createMessage and +/// elicitation/create requests. +/// +[Experimental(Experimentals.Tasks_DiagnosticId, UrlFormat = Experimentals.Tasks_Url)] +public sealed class ClientRequestMcpTasksCapability +{ + /// + /// Gets or sets task support for sampling-related requests. + /// + [JsonPropertyName("sampling")] + public SamplingMcpTasksCapability? Sampling { get; set; } + + /// + /// Gets or sets task support for elicitation-related requests. + /// + [JsonPropertyName("elicitation")] + public ElicitationMcpTasksCapability? Elicitation { get; set; } +} + +/// +/// Represents task support for sampling-related requests. +/// +[Experimental(Experimentals.Tasks_DiagnosticId, UrlFormat = Experimentals.Tasks_Url)] +public sealed class SamplingMcpTasksCapability +{ + /// + /// Gets or sets whether sampling/createMessage requests support task augmentation. + /// + [JsonPropertyName("createMessage")] + public CreateMessageMcpTasksCapability? CreateMessage { get; set; } +} + +/// +/// Represents the capability for task-augmented sampling/createMessage requests. +/// +[Experimental(Experimentals.Tasks_DiagnosticId, UrlFormat = Experimentals.Tasks_Url)] +public sealed class CreateMessageMcpTasksCapability; + +/// +/// Represents task support for elicitation-related requests. +/// +[Experimental(Experimentals.Tasks_DiagnosticId, UrlFormat = Experimentals.Tasks_Url)] +public sealed class ElicitationMcpTasksCapability +{ + /// + /// Gets or sets whether elicitation/create requests support task augmentation. + /// + [JsonPropertyName("create")] + public CreateElicitationMcpTasksCapability? Create { get; set; } +} + +/// +/// Represents the capability for task-augmented elicitation/create requests. +/// +[Experimental(Experimentals.Tasks_DiagnosticId, UrlFormat = Experimentals.Tasks_Url)] +public sealed class CreateElicitationMcpTasksCapability; diff --git a/src/ModelContextProtocol.Core/Protocol/ListMcpTasksCapability.cs b/src/ModelContextProtocol.Core/Protocol/ListMcpTasksCapability.cs new file mode 100644 index 000000000..476098112 --- /dev/null +++ b/src/ModelContextProtocol.Core/Protocol/ListMcpTasksCapability.cs @@ -0,0 +1,9 @@ +using System.Diagnostics.CodeAnalysis; + +namespace ModelContextProtocol.Protocol; + +/// +/// Represents the capability for listing tasks. +/// +[Experimental(Experimentals.Tasks_DiagnosticId, UrlFormat = Experimentals.Tasks_Url)] +public sealed class ListMcpTasksCapability; diff --git a/src/ModelContextProtocol.Core/Protocol/McpTasksCapability.cs b/src/ModelContextProtocol.Core/Protocol/McpTasksCapability.cs deleted file mode 100644 index 1b3ccd9dd..000000000 --- a/src/ModelContextProtocol.Core/Protocol/McpTasksCapability.cs +++ /dev/null @@ -1,160 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using System.Text.Json.Serialization; - -namespace ModelContextProtocol.Protocol; - -/// -/// Represents the tasks capability configuration for servers and clients. -/// -/// -/// -/// The tasks capability enables requestors (clients or servers) to augment their requests with -/// tasks for long-running operations. Tasks are durable state machines that carry information -/// about the underlying execution state of requests. -/// -/// -/// During initialization, both parties exchange their tasks capabilities to establish which -/// operations support task-based execution. Requestors should only augment requests with a -/// task if the corresponding capability has been declared by the receiver. -/// -/// -[Experimental(Experimentals.Tasks_DiagnosticId, UrlFormat = Experimentals.Tasks_Url)] -public sealed class McpTasksCapability -{ - /// - /// Gets or sets whether this party supports the tasks/list operation. - /// - /// - /// When present, indicates support for listing all tasks. - /// - [JsonPropertyName("list")] - public ListMcpTasksCapability? List { get; set; } - - /// - /// Gets or sets whether this party supports the tasks/cancel operation. - /// - /// - /// When present, indicates support for cancelling tasks. - /// - [JsonPropertyName("cancel")] - public CancelMcpTasksCapability? Cancel { get; set; } - - /// - /// Gets or sets which request types support task augmentation. - /// - /// - /// - /// The set of capabilities in this property is exhaustive. If a request type is not present, - /// it does not support task augmentation. - /// - /// - /// For servers, this typically includes tools/call. For clients, this typically includes - /// sampling/createMessage and elicitation/create. - /// - /// - [JsonPropertyName("requests")] - public RequestMcpTasksCapability? Requests { get; set; } -} - -/// -/// Represents task support for tool-specific requests. -/// -[Experimental(Experimentals.Tasks_DiagnosticId, UrlFormat = Experimentals.Tasks_Url)] -public sealed class RequestMcpTasksCapability -{ - /// - /// Gets or sets task support for tool-related requests. - /// - [JsonPropertyName("tools")] - public ToolsMcpTasksCapability? Tools { get; set; } - - /// - /// Gets or sets task support for sampling-related requests. - /// - [JsonPropertyName("sampling")] - public SamplingMcpTasksCapability? Sampling { get; set; } - - /// - /// Gets or sets task support for elicitation-related requests. - /// - [JsonPropertyName("elicitation")] - public ElicitationMcpTasksCapability? Elicitation { get; set; } -} - -/// -/// Represents task support for tool-related requests. -/// -[Experimental(Experimentals.Tasks_DiagnosticId, UrlFormat = Experimentals.Tasks_Url)] -public sealed class ToolsMcpTasksCapability -{ - /// - /// Gets or sets whether tools/call requests support task augmentation. - /// - /// - /// When present, indicates that the server supports task-augmented tools/call requests. - /// - [JsonPropertyName("call")] - public CallToolMcpTasksCapability? Call { get; set; } -} - -/// -/// Represents task support for sampling-related requests. -/// -[Experimental(Experimentals.Tasks_DiagnosticId, UrlFormat = Experimentals.Tasks_Url)] -public sealed class SamplingMcpTasksCapability -{ - /// - /// Gets or sets whether sampling/createMessage requests support task augmentation. - /// - /// - /// When present, indicates that the client supports task-augmented sampling/createMessage requests. - /// - [JsonPropertyName("createMessage")] - public CreateMessageMcpTasksCapability? CreateMessage { get; set; } -} - -/// -/// Represents task support for elicitation-related requests. -/// -[Experimental(Experimentals.Tasks_DiagnosticId, UrlFormat = Experimentals.Tasks_Url)] -public sealed class ElicitationMcpTasksCapability -{ - /// - /// Gets or sets whether elicitation/create requests support task augmentation. - /// - /// - /// When present, indicates that the client supports task-augmented elicitation/create requests. - /// - [JsonPropertyName("create")] - public CreateElicitationMcpTasksCapability? Create { get; set; } -} - -/// -/// Represents the capability for listing tasks. -/// -[Experimental(Experimentals.Tasks_DiagnosticId, UrlFormat = Experimentals.Tasks_Url)] -public sealed class ListMcpTasksCapability; - -/// -/// Represents the capability for cancelling tasks. -/// -[Experimental(Experimentals.Tasks_DiagnosticId, UrlFormat = Experimentals.Tasks_Url)] -public sealed class CancelMcpTasksCapability; - -/// -/// Represents the capability for task-augmented tools/call requests. -/// -[Experimental(Experimentals.Tasks_DiagnosticId, UrlFormat = Experimentals.Tasks_Url)] -public sealed class CallToolMcpTasksCapability; - -/// -/// Represents the capability for task-augmented sampling/createMessage requests. -/// -[Experimental(Experimentals.Tasks_DiagnosticId, UrlFormat = Experimentals.Tasks_Url)] -public sealed class CreateMessageMcpTasksCapability; - -/// -/// Represents the capability for task-augmented elicitation/create requests. -/// -[Experimental(Experimentals.Tasks_DiagnosticId, UrlFormat = Experimentals.Tasks_Url)] -public sealed class CreateElicitationMcpTasksCapability; diff --git a/src/ModelContextProtocol.Core/Protocol/ServerCapabilities.cs b/src/ModelContextProtocol.Core/Protocol/ServerCapabilities.cs index d4e23a66f..da120479a 100644 --- a/src/ModelContextProtocol.Core/Protocol/ServerCapabilities.cs +++ b/src/ModelContextProtocol.Core/Protocol/ServerCapabilities.cs @@ -77,12 +77,12 @@ public sealed class ServerCapabilities /// execute asynchronously, with the ability to poll for status and retrieve results later. /// /// - /// See for details on configuring which operations support tasks. + /// See for details on configuring which operations support tasks. /// /// [Experimental(Experimentals.Tasks_DiagnosticId, UrlFormat = Experimentals.Tasks_Url)] [JsonIgnore] - public McpTasksCapability? Tasks + public ServerMcpTasksCapability? Tasks { get => TasksCore; set => TasksCore = value; @@ -91,7 +91,7 @@ public McpTasksCapability? Tasks // See ExperimentalInternalPropertyTests.cs before modifying this property. [JsonInclude] [JsonPropertyName("tasks")] - internal McpTasksCapability? TasksCore { get; set; } + internal ServerMcpTasksCapability? TasksCore { get; set; } /// /// Gets or sets optional MCP extensions that the server supports. diff --git a/src/ModelContextProtocol.Core/Protocol/ServerMcpTasksCapability.cs b/src/ModelContextProtocol.Core/Protocol/ServerMcpTasksCapability.cs new file mode 100644 index 000000000..95b60dabd --- /dev/null +++ b/src/ModelContextProtocol.Core/Protocol/ServerMcpTasksCapability.cs @@ -0,0 +1,44 @@ +using System.Diagnostics.CodeAnalysis; +using System.Text.Json.Serialization; + +namespace ModelContextProtocol.Protocol; + +/// +/// Represents the tasks capability configuration for servers. +/// +/// +/// +/// The tasks capability enables clients to augment their requests with tasks for long-running +/// operations. Tasks are durable state machines that carry information about the underlying +/// execution state of requests. +/// +/// +/// During initialization, both parties exchange their tasks capabilities to establish which +/// operations support task-based execution. Requestors should only augment requests with a +/// task if the corresponding capability has been declared by the receiver. +/// +/// +[Experimental(Experimentals.Tasks_DiagnosticId, UrlFormat = Experimentals.Tasks_Url)] +public sealed class ServerMcpTasksCapability +{ + /// + /// Gets or sets whether this server supports the tasks/list operation. + /// + [JsonPropertyName("list")] + public ListMcpTasksCapability? List { get; set; } + + /// + /// Gets or sets whether this server supports the tasks/cancel operation. + /// + [JsonPropertyName("cancel")] + public CancelMcpTasksCapability? Cancel { get; set; } + + /// + /// Gets or sets which server request types support task augmentation. + /// + /// + /// For servers, this includes tasks.requests.tools.call. + /// + [JsonPropertyName("requests")] + public ServerRequestMcpTasksCapability? Requests { get; set; } +} diff --git a/src/ModelContextProtocol.Core/Protocol/ServerRequestMcpTasksCapability.cs b/src/ModelContextProtocol.Core/Protocol/ServerRequestMcpTasksCapability.cs new file mode 100644 index 000000000..4558f7aa2 --- /dev/null +++ b/src/ModelContextProtocol.Core/Protocol/ServerRequestMcpTasksCapability.cs @@ -0,0 +1,39 @@ +using System.Diagnostics.CodeAnalysis; +using System.Text.Json.Serialization; + +namespace ModelContextProtocol.Protocol; + +/// +/// Represents task support for server request types. +/// +/// +/// Servers can only support task augmentation for tools/call requests. +/// +[Experimental(Experimentals.Tasks_DiagnosticId, UrlFormat = Experimentals.Tasks_Url)] +public sealed class ServerRequestMcpTasksCapability +{ + /// + /// Gets or sets task support for tool-related requests. + /// + [JsonPropertyName("tools")] + public ToolsMcpTasksCapability? Tools { get; set; } +} + +/// +/// Represents task support for tool-related requests. +/// +[Experimental(Experimentals.Tasks_DiagnosticId, UrlFormat = Experimentals.Tasks_Url)] +public sealed class ToolsMcpTasksCapability +{ + /// + /// Gets or sets whether tools/call requests support task augmentation. + /// + [JsonPropertyName("call")] + public CallToolMcpTasksCapability? Call { get; set; } +} + +/// +/// Represents the capability for task-augmented tools/call requests. +/// +[Experimental(Experimentals.Tasks_DiagnosticId, UrlFormat = Experimentals.Tasks_Url)] +public sealed class CallToolMcpTasksCapability; diff --git a/src/ModelContextProtocol.Core/Server/McpServerImpl.cs b/src/ModelContextProtocol.Core/Server/McpServerImpl.cs index 04d11e016..548e37afd 100644 --- a/src/ModelContextProtocol.Core/Server/McpServerImpl.cs +++ b/src/ModelContextProtocol.Core/Server/McpServerImpl.cs @@ -814,11 +814,11 @@ private void ConfigureTasks(McpServerOptions options) } // Advertise task support in server capabilities - ServerCapabilities.Tasks = new McpTasksCapability + ServerCapabilities.Tasks = new ServerMcpTasksCapability { List = new ListMcpTasksCapability(), Cancel = new CancelMcpTasksCapability(), - Requests = new RequestMcpTasksCapability + Requests = new ServerRequestMcpTasksCapability { Tools = new ToolsMcpTasksCapability { diff --git a/tests/ModelContextProtocol.Tests/ExperimentalPropertySerializationTests.cs b/tests/ModelContextProtocol.Tests/ExperimentalPropertySerializationTests.cs index d68902ef5..9bb9421fa 100644 --- a/tests/ModelContextProtocol.Tests/ExperimentalPropertySerializationTests.cs +++ b/tests/ModelContextProtocol.Tests/ExperimentalPropertySerializationTests.cs @@ -97,7 +97,7 @@ public void ExperimentalProperties_RoundTrip_WithDefaultOptions() { var capabilities = new ServerCapabilities { - Tasks = new McpTasksCapability() + Tasks = new ServerMcpTasksCapability() }; string json = JsonSerializer.Serialize(capabilities, McpJsonUtilities.DefaultOptions); diff --git a/tests/ModelContextProtocol.Tests/Protocol/ClientCapabilitiesTests.cs b/tests/ModelContextProtocol.Tests/Protocol/ClientCapabilitiesTests.cs index cacb7e84e..026141046 100644 --- a/tests/ModelContextProtocol.Tests/Protocol/ClientCapabilitiesTests.cs +++ b/tests/ModelContextProtocol.Tests/Protocol/ClientCapabilitiesTests.cs @@ -21,7 +21,7 @@ public static void ClientCapabilities_SerializationRoundTrip_PreservesAllPropert Form = new FormElicitationCapability(), Url = new UrlElicitationCapability() }, - Tasks = new McpTasksCapability(), + Tasks = new ClientMcpTasksCapability(), Extensions = new Dictionary { ["io.modelcontextprotocol/test"] = new object() diff --git a/tests/ModelContextProtocol.Tests/Protocol/McpTasksCapabilityTests.cs b/tests/ModelContextProtocol.Tests/Protocol/McpTasksCapabilityTests.cs index 4e8caa740..12cab9e8c 100644 --- a/tests/ModelContextProtocol.Tests/Protocol/McpTasksCapabilityTests.cs +++ b/tests/ModelContextProtocol.Tests/Protocol/McpTasksCapabilityTests.cs @@ -6,19 +6,87 @@ namespace ModelContextProtocol.Tests.Protocol; public static class McpTasksCapabilityTests { [Fact] - public static void McpTasksCapability_SerializationRoundTrip_WithAllProperties() + public static void ServerMcpTasksCapability_SerializationRoundTrip_WithAllProperties() { // Arrange - var original = new McpTasksCapability + var original = new ServerMcpTasksCapability { List = new ListMcpTasksCapability(), Cancel = new CancelMcpTasksCapability(), - Requests = new RequestMcpTasksCapability + Requests = new ServerRequestMcpTasksCapability { Tools = new ToolsMcpTasksCapability { Call = new CallToolMcpTasksCapability() - }, + } + } + }; + + // Act + string json = JsonSerializer.Serialize(original, McpJsonUtilities.DefaultOptions); + var deserialized = JsonSerializer.Deserialize(json, McpJsonUtilities.DefaultOptions); + + // Assert + Assert.NotNull(deserialized); + Assert.NotNull(deserialized.List); + Assert.NotNull(deserialized.Cancel); + Assert.NotNull(deserialized.Requests); + Assert.NotNull(deserialized.Requests.Tools); + Assert.NotNull(deserialized.Requests.Tools.Call); + } + + [Fact] + public static void ServerMcpTasksCapability_SerializationRoundTrip_WithMinimalProperties() + { + // Arrange + var original = new ServerMcpTasksCapability(); + + // Act + string json = JsonSerializer.Serialize(original, McpJsonUtilities.DefaultOptions); + var deserialized = JsonSerializer.Deserialize(json, McpJsonUtilities.DefaultOptions); + + // Assert + Assert.NotNull(deserialized); + Assert.Null(deserialized.List); + Assert.Null(deserialized.Cancel); + Assert.Null(deserialized.Requests); + } + + [Fact] + public static void ServerMcpTasksCapability_HasCorrectJsonPropertyNames() + { + var capability = new ServerMcpTasksCapability + { + List = new ListMcpTasksCapability(), + Cancel = new CancelMcpTasksCapability(), + Requests = new ServerRequestMcpTasksCapability + { + Tools = new ToolsMcpTasksCapability + { + Call = new CallToolMcpTasksCapability() + } + } + }; + + string json = JsonSerializer.Serialize(capability, McpJsonUtilities.DefaultOptions); + + Assert.Contains("\"list\":", json); + Assert.Contains("\"cancel\":", json); + Assert.Contains("\"requests\":", json); + Assert.Contains("\"tools\":", json); + Assert.Contains("\"call\":", json); + } + + [Fact] + public static void ClientMcpTasksCapability_SerializationRoundTrip_WithAllProperties() + { + // Arrange + var original = new ClientMcpTasksCapability + { + List = new ListMcpTasksCapability(), + Cancel = new CancelMcpTasksCapability(), + Requests = new ClientRequestMcpTasksCapability + { Sampling = new SamplingMcpTasksCapability { CreateMessage = new CreateMessageMcpTasksCapability() @@ -32,15 +100,13 @@ public static void McpTasksCapability_SerializationRoundTrip_WithAllProperties() // Act string json = JsonSerializer.Serialize(original, McpJsonUtilities.DefaultOptions); - var deserialized = JsonSerializer.Deserialize(json, McpJsonUtilities.DefaultOptions); + var deserialized = JsonSerializer.Deserialize(json, McpJsonUtilities.DefaultOptions); // Assert Assert.NotNull(deserialized); Assert.NotNull(deserialized.List); Assert.NotNull(deserialized.Cancel); Assert.NotNull(deserialized.Requests); - Assert.NotNull(deserialized.Requests.Tools); - Assert.NotNull(deserialized.Requests.Tools.Call); Assert.NotNull(deserialized.Requests.Sampling); Assert.NotNull(deserialized.Requests.Sampling.CreateMessage); Assert.NotNull(deserialized.Requests.Elicitation); @@ -48,14 +114,14 @@ public static void McpTasksCapability_SerializationRoundTrip_WithAllProperties() } [Fact] - public static void McpTasksCapability_SerializationRoundTrip_WithMinimalProperties() + public static void ClientMcpTasksCapability_SerializationRoundTrip_WithMinimalProperties() { // Arrange - var original = new McpTasksCapability(); + var original = new ClientMcpTasksCapability(); // Act string json = JsonSerializer.Serialize(original, McpJsonUtilities.DefaultOptions); - var deserialized = JsonSerializer.Deserialize(json, McpJsonUtilities.DefaultOptions); + var deserialized = JsonSerializer.Deserialize(json, McpJsonUtilities.DefaultOptions); // Assert Assert.NotNull(deserialized); @@ -65,17 +131,21 @@ public static void McpTasksCapability_SerializationRoundTrip_WithMinimalProperti } [Fact] - public static void McpTasksCapability_HasCorrectJsonPropertyNames() + public static void ClientMcpTasksCapability_HasCorrectJsonPropertyNames() { - var capability = new McpTasksCapability + var capability = new ClientMcpTasksCapability { List = new ListMcpTasksCapability(), Cancel = new CancelMcpTasksCapability(), - Requests = new RequestMcpTasksCapability + Requests = new ClientRequestMcpTasksCapability { - Tools = new ToolsMcpTasksCapability + Sampling = new SamplingMcpTasksCapability { - Call = new CallToolMcpTasksCapability() + CreateMessage = new CreateMessageMcpTasksCapability() + }, + Elicitation = new ElicitationMcpTasksCapability + { + Create = new CreateElicitationMcpTasksCapability() } } }; @@ -85,7 +155,9 @@ public static void McpTasksCapability_HasCorrectJsonPropertyNames() Assert.Contains("\"list\":", json); Assert.Contains("\"cancel\":", json); Assert.Contains("\"requests\":", json); - Assert.Contains("\"tools\":", json); - Assert.Contains("\"call\":", json); + Assert.Contains("\"sampling\":", json); + Assert.Contains("\"elicitation\":", json); + Assert.Contains("\"createMessage\":", json); + Assert.Contains("\"create\":", json); } } diff --git a/tests/ModelContextProtocol.Tests/Protocol/RequestMcpTasksCapabilityTests.cs b/tests/ModelContextProtocol.Tests/Protocol/RequestMcpTasksCapabilityTests.cs index 8bfcb3be4..a52ced89d 100644 --- a/tests/ModelContextProtocol.Tests/Protocol/RequestMcpTasksCapabilityTests.cs +++ b/tests/ModelContextProtocol.Tests/Protocol/RequestMcpTasksCapabilityTests.cs @@ -6,10 +6,10 @@ namespace ModelContextProtocol.Tests.Protocol; public static class RequestMcpTasksCapabilityTests { [Fact] - public static void RequestMcpTasksCapability_SerializationRoundTrip_ToolsOnly() + public static void ServerRequestMcpTasksCapability_SerializationRoundTrip_ToolsOnly() { // Arrange - var original = new RequestMcpTasksCapability + var original = new ServerRequestMcpTasksCapability { Tools = new ToolsMcpTasksCapability { @@ -19,21 +19,36 @@ public static void RequestMcpTasksCapability_SerializationRoundTrip_ToolsOnly() // Act string json = JsonSerializer.Serialize(original, McpJsonUtilities.DefaultOptions); - var deserialized = JsonSerializer.Deserialize(json, McpJsonUtilities.DefaultOptions); + var deserialized = JsonSerializer.Deserialize(json, McpJsonUtilities.DefaultOptions); // Assert Assert.NotNull(deserialized); Assert.NotNull(deserialized.Tools); Assert.NotNull(deserialized.Tools.Call); - Assert.Null(deserialized.Sampling); - Assert.Null(deserialized.Elicitation); } [Fact] - public static void RequestMcpTasksCapability_SerializationRoundTrip_SamplingOnly() + public static void ServerRequestMcpTasksCapability_HasCorrectJsonPropertyNames() + { + var capability = new ServerRequestMcpTasksCapability + { + Tools = new ToolsMcpTasksCapability + { + Call = new CallToolMcpTasksCapability() + } + }; + + string json = JsonSerializer.Serialize(capability, McpJsonUtilities.DefaultOptions); + + Assert.Contains("\"tools\":", json); + Assert.Contains("\"call\":", json); + } + + [Fact] + public static void ClientRequestMcpTasksCapability_SerializationRoundTrip_SamplingOnly() { // Arrange - var original = new RequestMcpTasksCapability + var original = new ClientRequestMcpTasksCapability { Sampling = new SamplingMcpTasksCapability { @@ -43,21 +58,20 @@ public static void RequestMcpTasksCapability_SerializationRoundTrip_SamplingOnly // Act string json = JsonSerializer.Serialize(original, McpJsonUtilities.DefaultOptions); - var deserialized = JsonSerializer.Deserialize(json, McpJsonUtilities.DefaultOptions); + var deserialized = JsonSerializer.Deserialize(json, McpJsonUtilities.DefaultOptions); // Assert Assert.NotNull(deserialized); - Assert.Null(deserialized.Tools); Assert.NotNull(deserialized.Sampling); Assert.NotNull(deserialized.Sampling.CreateMessage); Assert.Null(deserialized.Elicitation); } [Fact] - public static void RequestMcpTasksCapability_SerializationRoundTrip_ElicitationOnly() + public static void ClientRequestMcpTasksCapability_SerializationRoundTrip_ElicitationOnly() { // Arrange - var original = new RequestMcpTasksCapability + var original = new ClientRequestMcpTasksCapability { Elicitation = new ElicitationMcpTasksCapability { @@ -67,25 +81,20 @@ public static void RequestMcpTasksCapability_SerializationRoundTrip_ElicitationO // Act string json = JsonSerializer.Serialize(original, McpJsonUtilities.DefaultOptions); - var deserialized = JsonSerializer.Deserialize(json, McpJsonUtilities.DefaultOptions); + var deserialized = JsonSerializer.Deserialize(json, McpJsonUtilities.DefaultOptions); // Assert Assert.NotNull(deserialized); - Assert.Null(deserialized.Tools); Assert.Null(deserialized.Sampling); Assert.NotNull(deserialized.Elicitation); Assert.NotNull(deserialized.Elicitation.Create); } [Fact] - public static void RequestMcpTasksCapability_HasCorrectJsonPropertyNames() + public static void ClientRequestMcpTasksCapability_HasCorrectJsonPropertyNames() { - var capability = new RequestMcpTasksCapability + var capability = new ClientRequestMcpTasksCapability { - Tools = new ToolsMcpTasksCapability - { - Call = new CallToolMcpTasksCapability() - }, Sampling = new SamplingMcpTasksCapability { CreateMessage = new CreateMessageMcpTasksCapability() @@ -98,10 +107,8 @@ public static void RequestMcpTasksCapability_HasCorrectJsonPropertyNames() string json = JsonSerializer.Serialize(capability, McpJsonUtilities.DefaultOptions); - Assert.Contains("\"tools\":", json); Assert.Contains("\"sampling\":", json); Assert.Contains("\"elicitation\":", json); - Assert.Contains("\"call\":", json); Assert.Contains("\"createMessage\":", json); Assert.Contains("\"create\":", json); } diff --git a/tests/ModelContextProtocol.Tests/Protocol/ServerCapabilitiesTests.cs b/tests/ModelContextProtocol.Tests/Protocol/ServerCapabilitiesTests.cs index a6f8265f1..8e01d8284 100644 --- a/tests/ModelContextProtocol.Tests/Protocol/ServerCapabilitiesTests.cs +++ b/tests/ModelContextProtocol.Tests/Protocol/ServerCapabilitiesTests.cs @@ -15,7 +15,7 @@ public static void ServerCapabilities_SerializationRoundTrip_PreservesAllPropert Resources = new ResourcesCapability { Subscribe = true, ListChanged = true }, Tools = new ToolsCapability { ListChanged = false }, Completions = new CompletionsCapability(), - Tasks = new McpTasksCapability(), + Tasks = new ServerMcpTasksCapability(), Extensions = new Dictionary { ["io.modelcontextprotocol/apps"] = new object() diff --git a/tests/ModelContextProtocol.Tests/Server/McpServerTaskMethodsTests.cs b/tests/ModelContextProtocol.Tests/Server/McpServerTaskMethodsTests.cs index d908bbb7f..7825d569d 100644 --- a/tests/ModelContextProtocol.Tests/Server/McpServerTaskMethodsTests.cs +++ b/tests/ModelContextProtocol.Tests/Server/McpServerTaskMethodsTests.cs @@ -98,9 +98,9 @@ public async Task SampleAsTaskAsync_SendsRequest_WhenClientSupportsTaskAugmented await InitializeServerAsync(transport, new ClientCapabilities { Sampling = new SamplingCapability(), - Tasks = new McpTasksCapability + Tasks = new ClientMcpTasksCapability { - Requests = new RequestMcpTasksCapability + Requests = new ClientRequestMcpTasksCapability { Sampling = new SamplingMcpTasksCapability { @@ -201,9 +201,9 @@ public async Task ElicitAsTaskAsync_SendsRequest_WhenClientSupportsTaskAugmented await InitializeServerAsync(transport, new ClientCapabilities { Elicitation = new ElicitationCapability { Form = new() }, - Tasks = new McpTasksCapability + Tasks = new ClientMcpTasksCapability { - Requests = new RequestMcpTasksCapability + Requests = new ClientRequestMcpTasksCapability { Elicitation = new ElicitationMcpTasksCapability { @@ -267,7 +267,7 @@ public async Task GetTaskAsync_SendsRequest_AndReturnsTask() var runTask = server.RunAsync(TestContext.Current.CancellationToken); await InitializeServerAsync(transport, new ClientCapabilities { - Tasks = new McpTasksCapability() + Tasks = new ClientMcpTasksCapability() }, TestContext.Current.CancellationToken); // Act @@ -296,7 +296,7 @@ public async Task GetTaskAsync_ThrowsArgumentException_WhenTaskIdIsEmpty() var runTask = server.RunAsync(TestContext.Current.CancellationToken); await InitializeServerAsync(transport, new ClientCapabilities { - Tasks = new McpTasksCapability() + Tasks = new ClientMcpTasksCapability() }, TestContext.Current.CancellationToken); // Act & Assert @@ -343,7 +343,7 @@ public async Task GetTaskResultAsync_ReturnsDeserializedResult() var runTask = server.RunAsync(TestContext.Current.CancellationToken); await InitializeServerAsync(transport, new ClientCapabilities { - Tasks = new McpTasksCapability() + Tasks = new ClientMcpTasksCapability() }, TestContext.Current.CancellationToken); // Act @@ -391,7 +391,7 @@ public async Task ListTasksAsync_ThrowsException_WhenClientDoesNotSupportTaskLis var runTask = server.RunAsync(TestContext.Current.CancellationToken); await InitializeServerAsync(transport, new ClientCapabilities { - Tasks = new McpTasksCapability + Tasks = new ClientMcpTasksCapability { // Note: No List capability } @@ -440,7 +440,7 @@ public async Task ListTasksAsync_ReturnsTaskList() var runTask = server.RunAsync(TestContext.Current.CancellationToken); await InitializeServerAsync(transport, new ClientCapabilities { - Tasks = new McpTasksCapability + Tasks = new ClientMcpTasksCapability { List = new ListMcpTasksCapability() } @@ -490,7 +490,7 @@ public async Task CancelTaskAsync_ThrowsException_WhenClientDoesNotSupportTaskCa var runTask = server.RunAsync(TestContext.Current.CancellationToken); await InitializeServerAsync(transport, new ClientCapabilities { - Tasks = new McpTasksCapability + Tasks = new ClientMcpTasksCapability { // Note: No Cancel capability } @@ -521,7 +521,7 @@ public async Task CancelTaskAsync_SendsRequest_AndReturnsCancelledTask() var runTask = server.RunAsync(TestContext.Current.CancellationToken); await InitializeServerAsync(transport, new ClientCapabilities { - Tasks = new McpTasksCapability + Tasks = new ClientMcpTasksCapability { Cancel = new CancelMcpTasksCapability() } @@ -565,7 +565,7 @@ public async Task PollTaskUntilCompleteAsync_ReturnsImmediately_WhenTaskIsAlread var runTask = server.RunAsync(TestContext.Current.CancellationToken); await InitializeServerAsync(transport, new ClientCapabilities { - Tasks = new McpTasksCapability() + Tasks = new ClientMcpTasksCapability() }, TestContext.Current.CancellationToken); // Act @@ -598,7 +598,7 @@ public async Task PollTaskUntilCompleteAsync_ReturnsTask_WhenTaskFails() var runTask = server.RunAsync(TestContext.Current.CancellationToken); await InitializeServerAsync(transport, new ClientCapabilities { - Tasks = new McpTasksCapability() + Tasks = new ClientMcpTasksCapability() }, TestContext.Current.CancellationToken); // Act @@ -640,7 +640,7 @@ public async Task WaitForTaskResultAsync_ReturnsTaskAndResult_WhenTaskCompletes( var runTask = server.RunAsync(TestContext.Current.CancellationToken); await InitializeServerAsync(transport, new ClientCapabilities { - Tasks = new McpTasksCapability() + Tasks = new ClientMcpTasksCapability() }, TestContext.Current.CancellationToken); // Act @@ -679,7 +679,7 @@ public async Task WaitForTaskResultAsync_ThrowsException_WhenTaskFails() var runTask = server.RunAsync(TestContext.Current.CancellationToken); await InitializeServerAsync(transport, new ClientCapabilities { - Tasks = new McpTasksCapability() + Tasks = new ClientMcpTasksCapability() }, TestContext.Current.CancellationToken); // Act & Assert @@ -711,7 +711,7 @@ public async Task WaitForTaskResultAsync_ThrowsException_WhenTaskIsCancelled() var runTask = server.RunAsync(TestContext.Current.CancellationToken); await InitializeServerAsync(transport, new ClientCapabilities { - Tasks = new McpTasksCapability() + Tasks = new ClientMcpTasksCapability() }, TestContext.Current.CancellationToken); // Act & Assert diff --git a/tests/ModelContextProtocol.Tests/Server/McpServerTests.cs b/tests/ModelContextProtocol.Tests/Server/McpServerTests.cs index d9febd721..0bae0b1c3 100644 --- a/tests/ModelContextProtocol.Tests/Server/McpServerTests.cs +++ b/tests/ModelContextProtocol.Tests/Server/McpServerTests.cs @@ -343,7 +343,7 @@ public async Task Initialize_CopiesAllCapabilityProperties() Resources = new ResourcesCapability(), Tools = new ToolsCapability(), Completions = new CompletionsCapability(), - Tasks = new McpTasksCapability(), + Tasks = new ServerMcpTasksCapability(), Extensions = new Dictionary { ["io.test"] = new JsonObject() }, };