Fix resource subscription handling (#89)

* Fix resource subscription handling
Add resource subscription tests

* Fix typo

* Typo

* small fixes

* Fix concurrency issue with test

* Align with specification schemas
This commit is contained in:
Peder Holdgaard Pedersen 2025-03-17 17:54:29 +01:00 • committed by GitHub
commit 34a6f1c665
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -45,12 +45,12 @@ public sealed class McpServerHandlers
/// <summary>
/// Gets or sets the handler for subscribe to resources messages.
/// </summary>
public Func<RequestContext<string>, CancellationToken, Task>? SubscribeToResourcesHandler { get; set; }
public Func<RequestContext<SubscribeRequestParams>, CancellationToken, Task<EmptyResult>>? SubscribeToResourcesHandler { get; set; }
/// <summary>
/// Gets or sets the handler for unsubscribe from resources messages.
/// </summary>
public Func<RequestContext<string>, CancellationToken, Task>? UnsubscribeFromResourcesHandler { get; set; }
public Func<RequestContext<UnsubscribeRequestParams>, CancellationToken, Task<EmptyResult>>? UnsubscribeFromResourcesHandler { get; set; }
/// <summary>
/// Overwrite any handlers in McpServerOptions with non-null handlers from this instance.
@ -77,25 +77,29 @@ public sealed class McpServerHandlers
ResourcesCapability? resourcesCapability = options.Capabilities?.Resources;
if (ListResourcesHandler is not null ||
ReadResourceHandler is not null ||
SubscribeToResourcesHandler is not null ||
UnsubscribeFromResourcesHandler is not null)
ReadResourceHandler is not null)
{
resourcesCapability = resourcesCapability is null ?
new()
{
ListResourcesHandler = ListResourcesHandler,
ReadResourceHandler = ReadResourceHandler,
SubscribeToResourcesHandler = SubscribeToResourcesHandler,
UnsubscribeFromResourcesHandler = UnsubscribeFromResourcesHandler,
ReadResourceHandler = ReadResourceHandler
} :
resourcesCapability with
{
ListResourcesHandler = ListResourcesHandler ?? resourcesCapability.ListResourcesHandler,
ReadResourceHandler = ReadResourceHandler ?? resourcesCapability.ReadResourceHandler,
ReadResourceHandler = ReadResourceHandler ?? resourcesCapability.ReadResourceHandler
};
if (SubscribeToResourcesHandler is not null || UnsubscribeFromResourcesHandler is not null)
{
resourcesCapability = resourcesCapability with
{
SubscribeToResourcesHandler = SubscribeToResourcesHandler ?? resourcesCapability.SubscribeToResourcesHandler,
UnsubscribeFromResourcesHandler = UnsubscribeFromResourcesHandler ?? resourcesCapability.UnsubscribeFromResourcesHandler,
Subscribe = true
};
}
}
ToolsCapability? toolsCapability = options.Capabilities?.Tools;