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

View file

@ -200,6 +200,21 @@ internal class Program
},
Resources = new()
{
ListResourceTemplatesHandler = (request, cancellationToken) =>
{
return Task.FromResult(new ListResourceTemplatesResult()
{
ResourceTemplates = [
new ResourceTemplate()
{
UriTemplate = "test://dynamic/resource/{id}",
Name = "Dynamic Resource",
}
]
});
},
ListResourcesHandler = (request, cancellationToken) =>
{
int startIndex = 0;
@ -236,7 +251,27 @@ internal class Program
{
throw new McpServerException("Missing required argument 'uri'");
}
if (request.Params.Uri.StartsWith("test://dynamic/resource/"))
{
var id = request.Params.Uri.Split('/').LastOrDefault();
if (string.IsNullOrEmpty(id))
{
throw new McpServerException("Invalid resource URI");
}
return Task.FromResult(new ReadResourceResult()
{
Contents = [
new ResourceContents()
{
Uri = request.Params.Uri,
MimeType = "text/plain",
Text = $"Dynamic resource {id}: This is a plaintext resource"
}
]
});
}
ResourceContents? contents = resourceContents.FirstOrDefault(r => r.Uri == request.Params.Uri) ??
throw new McpServerException("Resource not found");