diff --git a/src/ModelContextProtocol/McpServerOptionsSetup.cs b/src/ModelContextProtocol/McpServerOptionsSetup.cs index aa3ab18aa..2dc7e0ed6 100644 --- a/src/ModelContextProtocol/McpServerOptionsSetup.cs +++ b/src/ModelContextProtocol/McpServerOptionsSetup.cs @@ -97,13 +97,14 @@ private static void OverwriteWithSetHandlers(McpServerHandlers handlers, McpServ optionsHandlers.ListResourceTemplatesHandler = handlers.ListResourceTemplatesHandler ?? optionsHandlers.ListResourceTemplatesHandler; optionsHandlers.ListResourcesHandler = handlers.ListResourcesHandler ?? optionsHandlers.ListResourcesHandler; optionsHandlers.ReadResourceHandler = handlers.ReadResourceHandler ?? optionsHandlers.ReadResourceHandler; + } - if (handlers.SubscribeToResourcesHandler is not null || handlers.UnsubscribeFromResourcesHandler is not null) - { - optionsHandlers.SubscribeToResourcesHandler = handlers.SubscribeToResourcesHandler ?? optionsHandlers.SubscribeToResourcesHandler; - optionsHandlers.UnsubscribeFromResourcesHandler = handlers.UnsubscribeFromResourcesHandler ?? optionsHandlers.UnsubscribeFromResourcesHandler; - resourcesCapability.Subscribe = true; - } + if (handlers.SubscribeToResourcesHandler is not null || handlers.UnsubscribeFromResourcesHandler is not null) + { + resourcesCapability ??= new(); + optionsHandlers.SubscribeToResourcesHandler = handlers.SubscribeToResourcesHandler ?? optionsHandlers.SubscribeToResourcesHandler; + optionsHandlers.UnsubscribeFromResourcesHandler = handlers.UnsubscribeFromResourcesHandler ?? optionsHandlers.UnsubscribeFromResourcesHandler; + resourcesCapability.Subscribe = true; } ToolsCapability? toolsCapability = options.Capabilities?.Tools; diff --git a/tests/ModelContextProtocol.AspNetCore.Tests/ServerConformanceTests.cs b/tests/ModelContextProtocol.AspNetCore.Tests/ServerConformanceTests.cs index 75888c2d8..8c0055fe8 100644 --- a/tests/ModelContextProtocol.AspNetCore.Tests/ServerConformanceTests.cs +++ b/tests/ModelContextProtocol.AspNetCore.Tests/ServerConformanceTests.cs @@ -110,21 +110,6 @@ public async Task RunConformanceTests() private void StartConformanceServer() { - // The ConformanceServer binary is in a parallel directory to the test binary - // Test binary is in: artifacts/bin/ModelContextProtocol.ConformanceTests/Debug/{tfm}/ - // ConformanceServer binary is in: artifacts/bin/ModelContextProtocol.ConformanceServer/Debug/{tfm}/ - var testBinaryDir = AppContext.BaseDirectory; // e.g., .../net10.0/ - var configuration = Path.GetFileName(Path.GetDirectoryName(testBinaryDir.TrimEnd(Path.DirectorySeparatorChar))!); - var targetFramework = Path.GetFileName(testBinaryDir.TrimEnd(Path.DirectorySeparatorChar)); - var conformanceServerDir = Path.GetFullPath( - Path.Combine(testBinaryDir, "..", "..", "..", "ModelContextProtocol.ConformanceServer", configuration, targetFramework)); - - if (!Directory.Exists(conformanceServerDir)) - { - throw new DirectoryNotFoundException( - $"ConformanceServer directory not found at: {conformanceServerDir}"); - } - // Start the server in a background task _serverCts = new CancellationTokenSource(); _serverTask = Task.Run(() => ConformanceServer.Program.MainAsync(["--urls", _serverUrl], new XunitLoggerProvider(_output), cancellationToken: _serverCts.Token)); diff --git a/tests/ModelContextProtocol.ConformanceServer/Program.cs b/tests/ModelContextProtocol.ConformanceServer/Program.cs index e9c810fba..10422678d 100644 --- a/tests/ModelContextProtocol.ConformanceServer/Program.cs +++ b/tests/ModelContextProtocol.ConformanceServer/Program.cs @@ -1,12 +1,9 @@ using ConformanceServer.Prompts; using ConformanceServer.Resources; using ConformanceServer.Tools; -using Microsoft.Extensions.AI; using ModelContextProtocol.Protocol; using System.Collections.Concurrent; using System.Text.Json; -using System.Text.Json.Nodes; -using System.Text.Json.Serialization; namespace ModelContextProtocol.ConformanceServer; @@ -41,18 +38,8 @@ public static async Task MainAsync(string[] args, ILoggerProvider? loggerProvide } if (ctx.Params?.Uri is { } uri) { - subscriptions[ctx.Server.SessionId].TryAdd(uri, 0); - - await ctx.Server.SampleAsync([ - new ChatMessage(ChatRole.System, "You are a helpful test server"), - new ChatMessage(ChatRole.User, $"Resource {uri}, context: A new subscription was started"), - ], - chatOptions: new ChatOptions - { - MaxOutputTokens = 100, - Temperature = 0.7f, - }, - cancellationToken: ct); + var sessionSubscriptions = subscriptions.GetOrAdd(ctx.Server.SessionId, _ => new()); + sessionSubscriptions.TryAdd(uri, 0); } return new EmptyResult(); @@ -67,6 +54,7 @@ await ctx.Server.SampleAsync([ { subscriptions[ctx.Server.SessionId].TryRemove(uri, out _); } + return new EmptyResult(); }) .WithCompleteHandler(async (ctx, ct) => diff --git a/tests/ModelContextProtocol.Tests/Configuration/McpServerOptionsSetupTests.cs b/tests/ModelContextProtocol.Tests/Configuration/McpServerOptionsSetupTests.cs index 27a3580ab..6f770bf5d 100644 --- a/tests/ModelContextProtocol.Tests/Configuration/McpServerOptionsSetupTests.cs +++ b/tests/ModelContextProtocol.Tests/Configuration/McpServerOptionsSetupTests.cs @@ -108,7 +108,7 @@ public void Configure_WithUnsubscribeFromResourcesHandler_And_WithOtherResources } [Fact] - public void Configure_WithSubscribeToResourcesHandler_WithoutOtherResourcesHandler_DoesNotCreateResourcesCapability() + public void Configure_WithSubscribeToResourcesHandler_WithoutOtherResourcesHandler_DoesCreateResourcesCapability() { var services = new ServiceCollection(); services.AddMcpServer() @@ -116,12 +116,13 @@ public void Configure_WithSubscribeToResourcesHandler_WithoutOtherResourcesHandl var options = services.BuildServiceProvider().GetRequiredService>().Value; - Assert.Null(options.Handlers.SubscribeToResourcesHandler); - Assert.Null(options.Capabilities?.Resources); + Assert.NotNull(options.Handlers.SubscribeToResourcesHandler); + Assert.NotNull(options.Capabilities?.Resources); + Assert.True(options.Capabilities.Resources.Subscribe); } [Fact] - public void Configure_WithUnsubscribeFromResourcesHandler_WithoutOtherResourcesHandler_DoesNotCreateResourcesCapability() + public void Configure_WithUnsubscribeFromResourcesHandler_WithoutOtherResourcesHandler_DoesCreateResourcesCapability() { var services = new ServiceCollection(); services.AddMcpServer() @@ -129,8 +130,9 @@ public void Configure_WithUnsubscribeFromResourcesHandler_WithoutOtherResourcesH var options = services.BuildServiceProvider().GetRequiredService>().Value; - Assert.Null(options.Handlers.UnsubscribeFromResourcesHandler); - Assert.Null(options.Capabilities?.Resources); + Assert.NotNull(options.Handlers.UnsubscribeFromResourcesHandler); + Assert.NotNull(options.Capabilities?.Resources); + Assert.True(options.Capabilities.Resources.Subscribe); } [Fact]