Fix URI template derivation and lookup (#530)

* Use lowercase host in resource URI template derivation.

* Address feedback

* Add casing testing for non-templated resource lookups.

* Fix uri primitive lookup

* Use a hardcoded mcp hostname in derived resource template URIs and ensure built-in resources work with the VS Code client.

* Address feedback

* Fix equality comparison

* Use dedicated type for resource collections.
This commit is contained in:
Eirik Tsarpalis 2025-06-23 19:49:38 +03:00 • committed by GitHub
commit 0b26b7bf22
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -220,7 +220,7 @@ public partial class McpServerBuilderExtensionsResourcesTests : ClientServerTest
await using IMcpClient client = await CreateMcpClientForServer();
await Assert.ThrowsAsync<McpException>(async () => await client.ReadResourceAsync(
$"resource://{nameof(SimpleResources.ThrowsException)}",
$"resource://mcp/{nameof(SimpleResources.ThrowsException)}",
cancellationToken: TestContext.Current.CancellationToken));
}
@ -230,7 +230,7 @@ public partial class McpServerBuilderExtensionsResourcesTests : ClientServerTest
await using IMcpClient client = await CreateMcpClientForServer();
var e = await Assert.ThrowsAsync<McpException>(async () => await client.ReadResourceAsync(
"test://NotRegisteredResource",
"test:///NotRegisteredResource",
cancellationToken: TestContext.Current.CancellationToken));
Assert.Contains("Resource not found", e.Message);
@ -268,8 +268,8 @@ public partial class McpServerBuilderExtensionsResourcesTests : ClientServerTest
sc.AddMcpServer().WithResourcesFromAssembly();
IServiceProvider services = sc.BuildServiceProvider();
Assert.Contains(services.GetServices<McpServerResource>(), t => t.ProtocolResource?.Uri == $"resource://{nameof(SimpleResources.SomeNeatDirectResource)}");
Assert.Contains(services.GetServices<McpServerResource>(), t => t.ProtocolResourceTemplate?.UriTemplate == $"resource://{nameof(SimpleResources.SomeNeatTemplatedResource)}{{?name}}");
Assert.Contains(services.GetServices<McpServerResource>(), t => t.ProtocolResource?.Uri == $"resource://mcp/{nameof(SimpleResources.SomeNeatDirectResource)}");
Assert.Contains(services.GetServices<McpServerResource>(), t => t.ProtocolResourceTemplate?.UriTemplate == $"resource://mcp/{nameof(SimpleResources.SomeNeatTemplatedResource)}{{?name}}");
}
[Fact]
@ -279,13 +279,13 @@ public partial class McpServerBuilderExtensionsResourcesTests : ClientServerTest
sc.AddMcpServer()
.WithResources<SimpleResources>()
.WithResources<MoreResources>()
.WithResources([McpServerResource.Create(() => "42", new() { UriTemplate = "myResources://Returns42/{something}" })]);
.WithResources([McpServerResource.Create(() => "42", new() { UriTemplate = "myResources:///returns42/{something}" })]);
IServiceProvider services = sc.BuildServiceProvider();
Assert.Contains(services.GetServices<McpServerResource>(), t => t.ProtocolResource?.Uri == $"resource://{nameof(SimpleResources.SomeNeatDirectResource)}");
Assert.Contains(services.GetServices<McpServerResource>(), t => t.ProtocolResourceTemplate?.UriTemplate == $"resource://{nameof(SimpleResources.SomeNeatTemplatedResource)}{{?name}}");
Assert.Contains(services.GetServices<McpServerResource>(), t => t.ProtocolResourceTemplate?.UriTemplate == $"resource://{nameof(MoreResources.AnotherNeatDirectResource)}");
Assert.Contains(services.GetServices<McpServerResource>(), t => t.ProtocolResourceTemplate.UriTemplate == "myResources://Returns42/{something}");
Assert.Contains(services.GetServices<McpServerResource>(), t => t.ProtocolResource?.Uri == $"resource://mcp/{nameof(SimpleResources.SomeNeatDirectResource)}");
Assert.Contains(services.GetServices<McpServerResource>(), t => t.ProtocolResourceTemplate?.UriTemplate == $"resource://mcp/{nameof(SimpleResources.SomeNeatTemplatedResource)}{{?name}}");
Assert.Contains(services.GetServices<McpServerResource>(), t => t.ProtocolResourceTemplate?.UriTemplate == $"resource://mcp/{nameof(MoreResources.AnotherNeatDirectResource)}");
Assert.Contains(services.GetServices<McpServerResource>(), t => t.ProtocolResourceTemplate.UriTemplate == "myResources:///returns42/{something}");
}
[McpServerResourceType]