Add initial support for Resource Templates (#18)

* Add initial support for Resource Templates

* Make ListResourceTemplatesHandler not required

The server was throwing if this handler wasn't specified, and it should probably be optional anyway.

* Remove extra line

Co-authored-by: Stephen Toub <stoub@microsoft.com>

* Fix spaces

Co-authored-by: Stephen Toub <stoub@microsoft.com>

* Fix spaces

Co-authored-by: Stephen Toub <stoub@microsoft.com>

* Add and use a default ListResourceTemplatesHandler

If no ListResourceTemplatesHandler is specified, use a default one that returns an empty result.

* Fix spaces

* Spaces

* Add Client extensions for ListResourceTemplates

* Integration Test for Client ListResourceTemplates

* Fix comment

Co-authored-by: Stephen Toub <stoub@microsoft.com>

* Make Defaults internal

Co-authored-by: Stephen Toub <stoub@microsoft.com>

* Simplify test call

Co-authored-by: Stephen Toub <stoub@microsoft.com>

* Make delegate static

Co-authored-by: Stephen Toub <stoub@microsoft.com>

* Fix test comment

* Spaces

* Fix xml doc

Co-authored-by: Stephen Toub <stoub@microsoft.com>

* Make default handler inline

* Spaces

Co-authored-by: Stephen Halter <halter73@gmail.com>

---------

Co-authored-by: Stephen Toub <stoub@microsoft.com>
Co-authored-by: Stephen Halter <halter73@gmail.com>
This commit is contained in:
Jonathan Dick 2025-03-21 14:09:45 -04:00 • committed by GitHub
commit fe6b401014
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 287 additions and 3 deletions

View file

@ -155,6 +155,12 @@ internal sealed class McpServer : McpJsonRpcEndpoint, IMcpServer
SetRequestHandler<ListResourcesRequestParams, ListResourcesResult>("resources/list", (request, ct) => listResourcesHandler(new(this, request), ct));
SetRequestHandler<ReadResourceRequestParams, ReadResourceResult>("resources/read", (request, ct) => readResourceHandler(new(this, request), ct));
// Set the list resource templates handler, or use the default if not specified
var listResourceTemplatesHandler = resourcesCapability.ListResourceTemplatesHandler
?? (static (_, _) => Task.FromResult(new ListResourceTemplatesResult()));
SetRequestHandler<ListResourceTemplatesRequestParams, ListResourceTemplatesResult>("resources/templates/list", (request, ct) => listResourceTemplatesHandler(new(this, request), ct));
if (resourcesCapability.Subscribe is not true)
{
return;

View file

@ -27,6 +27,11 @@ public sealed class McpServerHandlers
/// </summary>
public Func<RequestContext<GetPromptRequestParams>, CancellationToken, Task<GetPromptResult>>? GetPromptHandler { get; set; }
/// <summary>
/// Gets or sets the handler for list resource templates requests.
/// </summary>
public Func<RequestContext<ListResourceTemplatesRequestParams>, CancellationToken, Task<ListResourceTemplatesResult>>? ListResourceTemplatesHandler { get; set; }
/// <summary>
/// Gets or sets the handler for list resources requests.
/// </summary>
@ -82,11 +87,13 @@ public sealed class McpServerHandlers
resourcesCapability = resourcesCapability is null ?
new()
{
ListResourceTemplatesHandler = ListResourceTemplatesHandler,
ListResourcesHandler = ListResourcesHandler,
ReadResourceHandler = ReadResourceHandler
} :
resourcesCapability with
{
ListResourceTemplatesHandler = ListResourceTemplatesHandler ?? resourcesCapability.ListResourceTemplatesHandler,
ListResourcesHandler = ListResourcesHandler ?? resourcesCapability.ListResourcesHandler,
ReadResourceHandler = ReadResourceHandler ?? resourcesCapability.ReadResourceHandler
};