Resource subscribe should be true if handler provided (#676)
Co-authored-by: Stephen Halter <halter73@gmail.com> Co-authored-by: Mike Kistler <mikekistler@microsoft.com>
This commit is contained in:
parent
31f8d20a1a
commit
9bbae84c9b
4 changed files with 18 additions and 42 deletions
|
|
@ -97,13 +97,14 @@ internal sealed class McpServerOptionsSetup(
|
|||
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;
|
||||
|
|
|
|||
|
|
@ -110,21 +110,6 @@ public class ServerConformanceTests : IAsyncLifetime
|
|||
|
||||
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));
|
||||
|
|
|
|||
|
|
@ -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 class Program
|
|||
}
|
||||
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 @@ public class Program
|
|||
{
|
||||
subscriptions[ctx.Server.SessionId].TryRemove(uri, out _);
|
||||
}
|
||||
|
||||
return new EmptyResult();
|
||||
})
|
||||
.WithCompleteHandler(async (ctx, ct) =>
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ public class McpServerOptionsSetupTests
|
|||
}
|
||||
|
||||
[Fact]
|
||||
public void Configure_WithSubscribeToResourcesHandler_WithoutOtherResourcesHandler_DoesNotCreateResourcesCapability()
|
||||
public void Configure_WithSubscribeToResourcesHandler_WithoutOtherResourcesHandler_DoesCreateResourcesCapability()
|
||||
{
|
||||
var services = new ServiceCollection();
|
||||
services.AddMcpServer()
|
||||
|
|
@ -116,12 +116,13 @@ public class McpServerOptionsSetupTests
|
|||
|
||||
var options = services.BuildServiceProvider().GetRequiredService<IOptions<McpServerOptions>>().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 class McpServerOptionsSetupTests
|
|||
|
||||
var options = services.BuildServiceProvider().GetRequiredService<IOptions<McpServerOptions>>().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]
|
||||
|
|
|
|||
Loading…
Reference in a new issue