diff --git a/samples/EverythingServer/Program.cs b/samples/EverythingServer/Program.cs index 17ee0753e..56b41de53 100644 --- a/samples/EverythingServer/Program.cs +++ b/samples/EverythingServer/Program.cs @@ -115,7 +115,7 @@ await ctx.Server.RequestSamplingAsync([ } return Task.FromResult(new EmptyResult()); }) - .WithGetCompletionHandler((ctx, ct) => + .WithCompleteHandler((ctx, ct) => { var exampleCompletions = new Dictionary> { diff --git a/src/ModelContextProtocol/Client/McpClientExtensions.cs b/src/ModelContextProtocol/Client/McpClientExtensions.cs index 2850bd1d2..2fc4eb5a3 100644 --- a/src/ModelContextProtocol/Client/McpClientExtensions.cs +++ b/src/ModelContextProtocol/Client/McpClientExtensions.cs @@ -386,7 +386,7 @@ public static Task ReadResourceAsync( /// Name of argument. Must be non-null and non-empty. /// Value of argument. Must be non-null. /// The to monitor for cancellation requests. The default is . - public static Task GetCompletionAsync(this IMcpClient client, Reference reference, string argumentName, string argumentValue, CancellationToken cancellationToken = default) + public static Task CompleteAsync(this IMcpClient client, Reference reference, string argumentName, string argumentValue, CancellationToken cancellationToken = default) { Throw.IfNull(client); Throw.IfNull(reference); diff --git a/src/ModelContextProtocol/Configuration/McpServerBuilderExtensions.cs b/src/ModelContextProtocol/Configuration/McpServerBuilderExtensions.cs index b0ba472cb..92ee17a5d 100644 --- a/src/ModelContextProtocol/Configuration/McpServerBuilderExtensions.cs +++ b/src/ModelContextProtocol/Configuration/McpServerBuilderExtensions.cs @@ -288,15 +288,15 @@ public static IMcpServerBuilder WithReadResourceHandler(this IMcpServerBuilder b } /// - /// Sets the handler for get completion requests. + /// Sets the handler for completion complete requests. /// /// The builder instance. /// The handler. - public static IMcpServerBuilder WithGetCompletionHandler(this IMcpServerBuilder builder, Func, CancellationToken, Task> handler) + public static IMcpServerBuilder WithCompleteHandler(this IMcpServerBuilder builder, Func, CancellationToken, Task> handler) { Throw.IfNull(builder); - builder.Services.Configure(s => s.GetCompletionHandler = handler); + builder.Services.Configure(s => s.CompleteHandler = handler); return builder; } diff --git a/src/ModelContextProtocol/Protocol/Types/Capabilities.cs b/src/ModelContextProtocol/Protocol/Types/Capabilities.cs deleted file mode 100644 index 40a0be378..000000000 --- a/src/ModelContextProtocol/Protocol/Types/Capabilities.cs +++ /dev/null @@ -1,207 +0,0 @@ -using ModelContextProtocol.Protocol.Messages; -using ModelContextProtocol.Server; -using System.Text.Json.Serialization; - -namespace ModelContextProtocol.Protocol.Types; - -/// -/// Represents the capabilities that a client may support. -/// See the schema for details -/// -public class ClientCapabilities -{ - /// - /// Experimental, non-standard capabilities that the client supports. - /// - [JsonPropertyName("experimental")] - public Dictionary? Experimental { get; set; } - - /// - /// Present if the client supports listing roots. - /// - [JsonPropertyName("roots")] - public RootsCapability? Roots { get; set; } - - /// - /// Present if the client supports sampling from an LLM. - /// - [JsonPropertyName("sampling")] - public SamplingCapability? Sampling { get; set; } - - /// Gets or sets notification handlers to register with the client. - /// - /// When constructed, the client will enumerate these handlers, which may contain multiple handlers per key. - /// The client will not re-enumerate the sequence. - /// - [JsonIgnore] - public IEnumerable>>? NotificationHandlers { get; set; } -} - -/// -/// Represents the roots capability configuration. -/// See the schema for details -/// -public class RootsCapability -{ - /// - /// Whether the client supports notifications for changes to the roots list. - /// - [JsonPropertyName("listChanged")] - public bool? ListChanged { get; set; } - - /// Gets or sets the handler for sampling requests. - [JsonIgnore] - public Func>? RootsHandler { get; set; } -} - -/// -/// Represents the sampling capability configuration. -/// See the schema for details -/// -public class SamplingCapability -{ - // Currently empty in the spec, but may be extended in the future - - /// Gets or sets the handler for sampling requests. - [JsonIgnore] - public Func, CancellationToken, Task>? SamplingHandler { get; set; } -} - -/// -/// Represents the logging capability configuration. -/// See the schema for details -/// -public class LoggingCapability -{ - // Currently empty in the spec, but may be extended in the future - - - /// - /// Gets or sets the handler for set logging level requests. - /// - [JsonIgnore] - public Func, CancellationToken, Task>? SetLoggingLevelHandler { get; set; } -} - -/// -/// Represents the prompts capability configuration. -/// See the schema for details -/// -public class PromptsCapability -{ - /// - /// Whether this server supports notifications for changes to the prompt list. - /// - [JsonPropertyName("listChanged")] - public bool? ListChanged { get; set; } - - /// - /// Gets or sets the handler for list prompts requests. - /// - [JsonIgnore] - public Func, CancellationToken, Task>? ListPromptsHandler { get; set; } - - /// - /// Gets or sets the handler for get prompt requests. - /// - [JsonIgnore] - public Func, CancellationToken, Task>? GetPromptHandler { get; set; } - - /// Gets or sets a collection of prompts served by the server. - /// - /// Prompts will specified via augment the and - /// , if provided. ListPrompts requests will output information about every prompt - /// in and then also any tools output by , if it's - /// non-. GetPrompt requests will first check for the prompt - /// being requested, and if the tool is not found in the , any specified - /// will be invoked as a fallback. - /// - [JsonIgnore] - public McpServerPrimitiveCollection? PromptCollection { get; set; } -} - -/// -/// Represents the resources capability configuration. -/// See the schema for details -/// -public class ResourcesCapability -{ - /// - /// Whether this server supports subscribing to resource updates. - /// - [JsonPropertyName("subscribe")] - public bool? Subscribe { get; set; } - - /// - /// Whether this server supports notifications for changes to the resource list. - /// - [JsonPropertyName("listChanged")] - public bool? ListChanged { get; set; } - - /// - /// Gets or sets the handler for list resource templates requests. - /// - [JsonIgnore] - public Func, CancellationToken, Task>? ListResourceTemplatesHandler { get; set; } - - /// - /// Gets or sets the handler for list resources requests. - /// - [JsonIgnore] - public Func, CancellationToken, Task>? ListResourcesHandler { get; set; } - - /// - /// Gets or sets the handler for read resources requests. - /// - [JsonIgnore] - public Func, CancellationToken, Task>? ReadResourceHandler { get; set; } - - /// - /// Gets or sets the handler for subscribe to resources messages. - /// - [JsonIgnore] - public Func, CancellationToken, Task>? SubscribeToResourcesHandler { get; set; } - - /// - /// Gets or sets the handler for unsubscribe from resources messages. - /// - [JsonIgnore] - public Func, CancellationToken, Task>? UnsubscribeFromResourcesHandler { get; set; } -} - -/// -/// Represents the tools capability configuration. -/// See the schema for details -/// -public class ToolsCapability -{ - /// - /// Gets or sets whether this server supports notifications for changes to the tool list. - /// - [JsonPropertyName("listChanged")] - public bool? ListChanged { get; set; } - - /// - /// Gets or sets the handler for list tools requests. - /// - [JsonIgnore] - public Func, CancellationToken, Task>? ListToolsHandler { get; set; } - - /// - /// Gets or sets the handler for call tool requests. - /// - [JsonIgnore] - public Func, CancellationToken, Task>? CallToolHandler { get; set; } - - /// Gets or sets a collection of tools served by the server. - /// - /// Tools will specified via augment the and - /// , if provided. ListTools requests will output information about every tool - /// in and then also any tools output by , if it's - /// non-. CallTool requests will first check for the tool - /// being requested, and if the tool is not found in the , any specified - /// will be invoked as a fallback. - /// - [JsonIgnore] - public McpServerPrimitiveCollection? ToolCollection { get; set; } -} \ No newline at end of file diff --git a/src/ModelContextProtocol/Protocol/Types/ClientCapabilities.cs b/src/ModelContextProtocol/Protocol/Types/ClientCapabilities.cs new file mode 100644 index 000000000..cc700e143 --- /dev/null +++ b/src/ModelContextProtocol/Protocol/Types/ClientCapabilities.cs @@ -0,0 +1,38 @@ +using ModelContextProtocol.Protocol.Messages; +using ModelContextProtocol.Server; +using System.Text.Json.Serialization; + +namespace ModelContextProtocol.Protocol.Types; + +/// +/// Represents the capabilities that a client may support. +/// See the schema for details +/// +public class ClientCapabilities +{ + /// + /// Experimental, non-standard capabilities that the client supports. + /// + [JsonPropertyName("experimental")] + public Dictionary? Experimental { get; set; } + + /// + /// Present if the client supports listing roots. + /// + [JsonPropertyName("roots")] + public RootsCapability? Roots { get; set; } + + /// + /// Present if the client supports sampling from an LLM. + /// + [JsonPropertyName("sampling")] + public SamplingCapability? Sampling { get; set; } + + /// Gets or sets notification handlers to register with the client. + /// + /// When constructed, the client will enumerate these handlers, which may contain multiple handlers per key. + /// The client will not re-enumerate the sequence. + /// + [JsonIgnore] + public IEnumerable>>? NotificationHandlers { get; set; } +} \ No newline at end of file diff --git a/src/ModelContextProtocol/Protocol/Types/CompletionsCapability.cs b/src/ModelContextProtocol/Protocol/Types/CompletionsCapability.cs new file mode 100644 index 000000000..c853c85fb --- /dev/null +++ b/src/ModelContextProtocol/Protocol/Types/CompletionsCapability.cs @@ -0,0 +1,19 @@ +using ModelContextProtocol.Server; +using System.Text.Json.Serialization; + +namespace ModelContextProtocol.Protocol.Types; + +/// +/// Represents the completions capability configuration. +/// See the schema for details +/// +public class CompletionsCapability +{ + // Currently empty in the spec, but may be extended in the future. + + /// + /// Gets or sets the handler for get completion requests. + /// + [JsonIgnore] + public Func, CancellationToken, Task>? CompleteHandler { get; set; } +} \ No newline at end of file diff --git a/src/ModelContextProtocol/Protocol/Types/LoggingCapability.cs b/src/ModelContextProtocol/Protocol/Types/LoggingCapability.cs new file mode 100644 index 000000000..425abca7d --- /dev/null +++ b/src/ModelContextProtocol/Protocol/Types/LoggingCapability.cs @@ -0,0 +1,21 @@ +using ModelContextProtocol.Protocol.Messages; +using ModelContextProtocol.Server; +using System.Text.Json.Serialization; + +namespace ModelContextProtocol.Protocol.Types; + +/// +/// Represents the logging capability configuration. +/// See the schema for details +/// +public class LoggingCapability +{ + // Currently empty in the spec, but may be extended in the future + + + /// + /// Gets or sets the handler for set logging level requests. + /// + [JsonIgnore] + public Func, CancellationToken, Task>? SetLoggingLevelHandler { get; set; } +} \ No newline at end of file diff --git a/src/ModelContextProtocol/Protocol/Types/PromptsCapability.cs b/src/ModelContextProtocol/Protocol/Types/PromptsCapability.cs new file mode 100644 index 000000000..0c5ff3f88 --- /dev/null +++ b/src/ModelContextProtocol/Protocol/Types/PromptsCapability.cs @@ -0,0 +1,42 @@ +using ModelContextProtocol.Protocol.Messages; +using ModelContextProtocol.Server; +using System.Text.Json.Serialization; + +namespace ModelContextProtocol.Protocol.Types; + +/// +/// Represents the prompts capability configuration. +/// See the schema for details +/// +public class PromptsCapability +{ + /// + /// Whether this server supports notifications for changes to the prompt list. + /// + [JsonPropertyName("listChanged")] + public bool? ListChanged { get; set; } + + /// + /// Gets or sets the handler for list prompts requests. + /// + [JsonIgnore] + public Func, CancellationToken, Task>? ListPromptsHandler { get; set; } + + /// + /// Gets or sets the handler for get prompt requests. + /// + [JsonIgnore] + public Func, CancellationToken, Task>? GetPromptHandler { get; set; } + + /// Gets or sets a collection of prompts served by the server. + /// + /// Prompts will specified via augment the and + /// , if provided. ListPrompts requests will output information about every prompt + /// in and then also any tools output by , if it's + /// non-. GetPrompt requests will first check for the prompt + /// being requested, and if the tool is not found in the , any specified + /// will be invoked as a fallback. + /// + [JsonIgnore] + public McpServerPrimitiveCollection? PromptCollection { get; set; } +} \ No newline at end of file diff --git a/src/ModelContextProtocol/Protocol/Types/ResourcesCapability.cs b/src/ModelContextProtocol/Protocol/Types/ResourcesCapability.cs new file mode 100644 index 000000000..94e3ec571 --- /dev/null +++ b/src/ModelContextProtocol/Protocol/Types/ResourcesCapability.cs @@ -0,0 +1,54 @@ +using ModelContextProtocol.Protocol.Messages; +using ModelContextProtocol.Server; +using System.Text.Json.Serialization; + +namespace ModelContextProtocol.Protocol.Types; + +/// +/// Represents the resources capability configuration. +/// See the schema for details +/// +public class ResourcesCapability +{ + /// + /// Whether this server supports subscribing to resource updates. + /// + [JsonPropertyName("subscribe")] + public bool? Subscribe { get; set; } + + /// + /// Whether this server supports notifications for changes to the resource list. + /// + [JsonPropertyName("listChanged")] + public bool? ListChanged { get; set; } + + /// + /// Gets or sets the handler for list resource templates requests. + /// + [JsonIgnore] + public Func, CancellationToken, Task>? ListResourceTemplatesHandler { get; set; } + + /// + /// Gets or sets the handler for list resources requests. + /// + [JsonIgnore] + public Func, CancellationToken, Task>? ListResourcesHandler { get; set; } + + /// + /// Gets or sets the handler for read resources requests. + /// + [JsonIgnore] + public Func, CancellationToken, Task>? ReadResourceHandler { get; set; } + + /// + /// Gets or sets the handler for subscribe to resources messages. + /// + [JsonIgnore] + public Func, CancellationToken, Task>? SubscribeToResourcesHandler { get; set; } + + /// + /// Gets or sets the handler for unsubscribe from resources messages. + /// + [JsonIgnore] + public Func, CancellationToken, Task>? UnsubscribeFromResourcesHandler { get; set; } +} \ No newline at end of file diff --git a/src/ModelContextProtocol/Protocol/Types/RootsCapability.cs b/src/ModelContextProtocol/Protocol/Types/RootsCapability.cs new file mode 100644 index 000000000..df9716ca4 --- /dev/null +++ b/src/ModelContextProtocol/Protocol/Types/RootsCapability.cs @@ -0,0 +1,22 @@ +using ModelContextProtocol.Protocol.Messages; +using ModelContextProtocol.Server; +using System.Text.Json.Serialization; + +namespace ModelContextProtocol.Protocol.Types; + +/// +/// Represents the roots capability configuration. +/// See the schema for details +/// +public class RootsCapability +{ + /// + /// Whether the client supports notifications for changes to the roots list. + /// + [JsonPropertyName("listChanged")] + public bool? ListChanged { get; set; } + + /// Gets or sets the handler for sampling requests. + [JsonIgnore] + public Func>? RootsHandler { get; set; } +} \ No newline at end of file diff --git a/src/ModelContextProtocol/Protocol/Types/SamplingCapability.cs b/src/ModelContextProtocol/Protocol/Types/SamplingCapability.cs new file mode 100644 index 000000000..5d9ff94f3 --- /dev/null +++ b/src/ModelContextProtocol/Protocol/Types/SamplingCapability.cs @@ -0,0 +1,18 @@ +using ModelContextProtocol.Protocol.Messages; +using ModelContextProtocol.Server; +using System.Text.Json.Serialization; + +namespace ModelContextProtocol.Protocol.Types; + +/// +/// Represents the sampling capability configuration. +/// See the schema for details +/// +public class SamplingCapability +{ + // Currently empty in the spec, but may be extended in the future + + /// Gets or sets the handler for sampling requests. + [JsonIgnore] + public Func, CancellationToken, Task>? SamplingHandler { get; set; } +} \ No newline at end of file diff --git a/src/ModelContextProtocol/Protocol/Types/ServerCapabilities.cs b/src/ModelContextProtocol/Protocol/Types/ServerCapabilities.cs index 3b328e58b..31d532c5c 100644 --- a/src/ModelContextProtocol/Protocol/Types/ServerCapabilities.cs +++ b/src/ModelContextProtocol/Protocol/Types/ServerCapabilities.cs @@ -39,6 +39,12 @@ public class ServerCapabilities [JsonPropertyName("tools")] public ToolsCapability? Tools { get; set; } + /// + /// Present if the server supports argument autocompletion suggestions. + /// + [JsonPropertyName("completions")] + public CompletionsCapability? Completions { get; set; } + /// Gets or sets notification handlers to register with the server. /// /// When constructed, the server will enumerate these handlers, which may contain multiple handlers per key. diff --git a/src/ModelContextProtocol/Protocol/Types/ToolsCapability.cs b/src/ModelContextProtocol/Protocol/Types/ToolsCapability.cs new file mode 100644 index 000000000..002ade0dc --- /dev/null +++ b/src/ModelContextProtocol/Protocol/Types/ToolsCapability.cs @@ -0,0 +1,42 @@ +using ModelContextProtocol.Protocol.Messages; +using ModelContextProtocol.Server; +using System.Text.Json.Serialization; + +namespace ModelContextProtocol.Protocol.Types; + +/// +/// Represents the tools capability configuration. +/// See the schema for details +/// +public class ToolsCapability +{ + /// + /// Gets or sets whether this server supports notifications for changes to the tool list. + /// + [JsonPropertyName("listChanged")] + public bool? ListChanged { get; set; } + + /// + /// Gets or sets the handler for list tools requests. + /// + [JsonIgnore] + public Func, CancellationToken, Task>? ListToolsHandler { get; set; } + + /// + /// Gets or sets the handler for call tool requests. + /// + [JsonIgnore] + public Func, CancellationToken, Task>? CallToolHandler { get; set; } + + /// Gets or sets a collection of tools served by the server. + /// + /// Tools will specified via augment the and + /// , if provided. ListTools requests will output information about every tool + /// in and then also any tools output by , if it's + /// non-. CallTool requests will first check for the tool + /// being requested, and if the tool is not found in the , any specified + /// will be invoked as a fallback. + /// + [JsonIgnore] + public McpServerPrimitiveCollection? ToolCollection { get; set; } +} \ No newline at end of file diff --git a/src/ModelContextProtocol/Server/McpServer.cs b/src/ModelContextProtocol/Server/McpServer.cs index 47df1c9aa..81214f0b1 100644 --- a/src/ModelContextProtocol/Server/McpServer.cs +++ b/src/ModelContextProtocol/Server/McpServer.cs @@ -175,11 +175,18 @@ private void SetInitializeHandler(McpServerOptions options) private void SetCompletionHandler(McpServerOptions options) { + if (options.Capabilities?.Completions is not { } completionsCapability) + { + return; + } + + var completeHandler = completionsCapability.CompleteHandler ?? + throw new McpException("Completions capability was enabled, but Complete handler was not specified."); + // This capability is not optional, so return an empty result if there is no handler. - RequestHandlers.Set(RequestMethods.CompletionComplete, - options.GetCompletionHandler is { } handler ? - (request, cancellationToken) => handler(new(this, request), cancellationToken) : - (request, cancellationToken) => Task.FromResult(new CompleteResult() { Completion = new() { Values = [], Total = 0, HasMore = false } }), + RequestHandlers.Set( + RequestMethods.CompletionComplete, + (request, cancellationToken) => completeHandler(new(this, request), cancellationToken), McpJsonUtilities.JsonContext.Default.CompleteRequestParams, McpJsonUtilities.JsonContext.Default.CompleteResult); } diff --git a/src/ModelContextProtocol/Server/McpServerHandlers.cs b/src/ModelContextProtocol/Server/McpServerHandlers.cs index b591182d8..07a3c8f07 100644 --- a/src/ModelContextProtocol/Server/McpServerHandlers.cs +++ b/src/ModelContextProtocol/Server/McpServerHandlers.cs @@ -43,9 +43,9 @@ public sealed class McpServerHandlers public Func, CancellationToken, Task>? ReadResourceHandler { get; set; } /// - /// Gets or sets the handler for get completion requests. + /// Gets or sets the handler for completion complete requests. /// - public Func, CancellationToken, Task>? GetCompletionHandler { get; set; } + public Func, CancellationToken, Task>? CompleteHandler { get; set; } /// /// Gets or sets the handler for subscribe to resources messages. @@ -109,12 +109,18 @@ internal void OverwriteWithSetHandlers(McpServerOptions options) loggingCapability.SetLoggingLevelHandler = SetLoggingLevelHandler; } + CompletionsCapability? completionsCapability = options.Capabilities?.Completions; + if (CompleteHandler is not null) + { + completionsCapability ??= new(); + completionsCapability.CompleteHandler = CompleteHandler; + } + options.Capabilities ??= new(); options.Capabilities.Prompts = promptsCapability; options.Capabilities.Resources = resourcesCapability; options.Capabilities.Tools = toolsCapability; options.Capabilities.Logging = loggingCapability; - - options.GetCompletionHandler = GetCompletionHandler ?? options.GetCompletionHandler; + options.Capabilities.Completions = completionsCapability; } } diff --git a/src/ModelContextProtocol/Server/McpServerOptions.cs b/src/ModelContextProtocol/Server/McpServerOptions.cs index 06b0a2600..fd96ca1fb 100644 --- a/src/ModelContextProtocol/Server/McpServerOptions.cs +++ b/src/ModelContextProtocol/Server/McpServerOptions.cs @@ -35,10 +35,4 @@ public class McpServerOptions /// Optional server instructions to send to clients /// public string ServerInstructions { get; set; } = string.Empty; - - /// - /// Gets or sets the handler for get completion requests. - /// - [JsonIgnore] - public Func, CancellationToken, Task>? GetCompletionHandler { get; set; } } diff --git a/tests/ModelContextProtocol.TestServer/Program.cs b/tests/ModelContextProtocol.TestServer/Program.cs index b728e263e..f650e23c7 100644 --- a/tests/ModelContextProtocol.TestServer/Program.cs +++ b/tests/ModelContextProtocol.TestServer/Program.cs @@ -43,11 +43,11 @@ private static async Task Main(string[] args) Tools = ConfigureTools(), Resources = ConfigureResources(), Prompts = ConfigurePrompts(), - Logging = ConfigureLogging() + Logging = ConfigureLogging(), + Completions = ConfigureCompletions(), }, ProtocolVersion = "2024-11-05", ServerInstructions = "This is a test server with only stub functionality", - GetCompletionHandler = ConfigureCompletion(), }; using var loggerFactory = CreateLoggerFactory(); @@ -477,7 +477,7 @@ private static ResourcesCapability ConfigureResources() }; } - private static Func, CancellationToken, Task> ConfigureCompletion() + private static CompletionsCapability ConfigureCompletions() { List sampleResourceIds = ["1", "2", "3", "4", "5"]; Dictionary> exampleCompletions = new() @@ -486,7 +486,7 @@ private static Func, CancellationToken, Ta {"temperature", ["0", "0.5", "0.7", "1.0"]}, }; - return (request, cancellationToken) => + Func, CancellationToken, Task> handler = (request, cancellationToken) => { if (request.Params?.Ref?.Type == "ref/resource") { @@ -512,6 +512,8 @@ private static Func, CancellationToken, Ta throw new McpException($"Unknown reference type: {request.Params?.Ref.Type}"); }; + + return new() { CompleteHandler = handler }; } static CreateMessageRequestParams CreateRequestSamplingParams(string context, string uri, int maxTokens = 100) diff --git a/tests/ModelContextProtocol.Tests/ClientIntegrationTests.cs b/tests/ModelContextProtocol.Tests/ClientIntegrationTests.cs index be148397a..baa7e55b0 100644 --- a/tests/ModelContextProtocol.Tests/ClientIntegrationTests.cs +++ b/tests/ModelContextProtocol.Tests/ClientIntegrationTests.cs @@ -314,13 +314,13 @@ public async Task UnsubscribeResource_Stdio() [Theory] [MemberData(nameof(GetClients))] - public async Task GetCompletion_Stdio_ResourceReference(string clientId) + public async Task Complete_Stdio_ResourceReference(string clientId) { // arrange // act await using var client = await _fixture.CreateClientAsync(clientId); - var result = await client.GetCompletionAsync(new Reference + var result = await client.CompleteAsync(new Reference { Type = "ref/resource", Uri = "test://static/resource/1" @@ -336,13 +336,13 @@ public async Task GetCompletion_Stdio_ResourceReference(string clientId) [Theory] [MemberData(nameof(GetClients))] - public async Task GetCompletion_Stdio_PromptReference(string clientId) + public async Task Complete_Stdio_PromptReference(string clientId) { // arrange // act await using var client = await _fixture.CreateClientAsync(clientId); - var result = await client.GetCompletionAsync(new Reference + var result = await client.CompleteAsync(new Reference { Type = "ref/prompt", Name = "irrelevant" diff --git a/tests/ModelContextProtocol.Tests/Configuration/McpServerBuilderExtensionsHandlerTests.cs b/tests/ModelContextProtocol.Tests/Configuration/McpServerBuilderExtensionsHandlerTests.cs index 22e538170..896765d97 100644 --- a/tests/ModelContextProtocol.Tests/Configuration/McpServerBuilderExtensionsHandlerTests.cs +++ b/tests/ModelContextProtocol.Tests/Configuration/McpServerBuilderExtensionsHandlerTests.cs @@ -110,16 +110,16 @@ public void WithReadResourceHandler_Sets_Handler() } [Fact] - public void WithGetCompletionHandler_Sets_Handler() + public void WithCompleteHandler_Sets_Handler() { Func, CancellationToken, Task> handler = (context, token) => Task.FromResult(new CompleteResult()); - _builder.Object.WithGetCompletionHandler(handler); + _builder.Object.WithCompleteHandler(handler); var serviceProvider = _services.BuildServiceProvider(); var options = serviceProvider.GetRequiredService>().Value; - Assert.Equal(handler, options.GetCompletionHandler); + Assert.Equal(handler, options.CompleteHandler); } [Fact] diff --git a/tests/ModelContextProtocol.Tests/Server/McpServerDelegatesTests.cs b/tests/ModelContextProtocol.Tests/Server/McpServerDelegatesTests.cs index 3f7d5f7c1..e897ff4d6 100644 --- a/tests/ModelContextProtocol.Tests/Server/McpServerDelegatesTests.cs +++ b/tests/ModelContextProtocol.Tests/Server/McpServerDelegatesTests.cs @@ -17,7 +17,7 @@ public void AllPropertiesAreSettable() Assert.Null(handlers.ListResourceTemplatesHandler); Assert.Null(handlers.ListResourcesHandler); Assert.Null(handlers.ReadResourceHandler); - Assert.Null(handlers.GetCompletionHandler); + Assert.Null(handlers.CompleteHandler); Assert.Null(handlers.SubscribeToResourcesHandler); Assert.Null(handlers.UnsubscribeFromResourcesHandler); @@ -28,7 +28,7 @@ public void AllPropertiesAreSettable() handlers.ListResourceTemplatesHandler = (p, c) => Task.FromResult(new ListResourceTemplatesResult()); handlers.ListResourcesHandler = (p, c) => Task.FromResult(new ListResourcesResult()); handlers.ReadResourceHandler = (p, c) => Task.FromResult(new ReadResourceResult()); - handlers.GetCompletionHandler = (p, c) => Task.FromResult(new CompleteResult()); + handlers.CompleteHandler = (p, c) => Task.FromResult(new CompleteResult()); handlers.SubscribeToResourcesHandler = (s, c) => Task.FromResult(new EmptyResult()); handlers.UnsubscribeFromResourcesHandler = (s, c) => Task.FromResult(new EmptyResult()); @@ -39,7 +39,7 @@ public void AllPropertiesAreSettable() Assert.NotNull(handlers.ListResourceTemplatesHandler); Assert.NotNull(handlers.ListResourcesHandler); Assert.NotNull(handlers.ReadResourceHandler); - Assert.NotNull(handlers.GetCompletionHandler); + Assert.NotNull(handlers.CompleteHandler); Assert.NotNull(handlers.SubscribeToResourcesHandler); Assert.NotNull(handlers.UnsubscribeFromResourcesHandler); } diff --git a/tests/ModelContextProtocol.Tests/Server/McpServerTests.cs b/tests/ModelContextProtocol.Tests/Server/McpServerTests.cs index b1ef6c2ce..ef149b774 100644 --- a/tests/ModelContextProtocol.Tests/Server/McpServerTests.cs +++ b/tests/ModelContextProtocol.Tests/Server/McpServerTests.cs @@ -198,44 +198,29 @@ await Can_Handle_Requests( public async Task Can_Handle_Completion_Requests() { await Can_Handle_Requests( - serverCapabilities: null, - method: RequestMethods.CompletionComplete, - configureOptions: null, - assertResult: response => + new() { - var result = JsonSerializer.Deserialize(response); - Assert.NotNull(result?.Completion); - Assert.Empty(result.Completion.Values); - Assert.Equal(0, result.Completion.Total); - Assert.False(result.Completion.HasMore); - }); - } - - [Fact] - public async Task Can_Handle_Completion_Requests_With_Handler() - { - await Can_Handle_Requests( - serverCapabilities: null, - method: RequestMethods.CompletionComplete, - configureOptions: options => - { - options.GetCompletionHandler = (request, ct) => - Task.FromResult(new CompleteResult - { - Completion = new() + Completions = new() + { + CompleteHandler = (request, ct) => + Task.FromResult(new CompleteResult { - Values = ["test"], - Total = 2, - HasMore = true - } - }); + Completion = new() + { + Values = ["test"], + Total = 2, + HasMore = true + } + }) + } }, + method: RequestMethods.CompletionComplete, + configureOptions: null, assertResult: response => { - CompleteResult? result = JsonSerializer.Deserialize(response); + var result = JsonSerializer.Deserialize(response); Assert.NotNull(result?.Completion); - Assert.NotEmpty(result.Completion.Values); - Assert.Equal("test", result.Completion.Values[0]); + Assert.Equal(["test"], result.Completion.Values); Assert.Equal(2, result.Completion.Total); Assert.True(result.Completion.HasMore); });