Skip to content

Commit 144413b

Browse files
Added tests
1 parent 4beb291 commit 144413b

File tree

2 files changed

+125
-1
lines changed

2 files changed

+125
-1
lines changed

src/ModelContextProtocol/Server/McpServer.cs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,14 +185,28 @@ private void SetResourcesHandler(McpServerOptions options)
185185

186186
var listResourcesHandler = resourcesCapability.ListResourcesHandler;
187187
var listResourceTemplatesHandler = resourcesCapability.ListResourceTemplatesHandler;
188+
var resourceCollection = resourcesCapability.ResourceCollection;
188189

189190
if ((listResourcesHandler is not { } && listResourceTemplatesHandler is not { }) ||
190191
resourcesCapability.ReadResourceHandler is not { } readResourceHandler)
191192
{
192193
throw new McpException("Resources capability was enabled, but ListResources and/or ReadResource handlers were not specified.");
193194
}
194195

195-
listResourcesHandler ??= (static (_, _) => Task.FromResult(new ListResourcesResult()));
196+
var originalListResourcesHandler = listResourcesHandler;
197+
listResourcesHandler = async (request, cancellationToken) =>
198+
{
199+
ListResourcesResult result = originalListResourcesHandler is not null ?
200+
await originalListResourcesHandler(request, cancellationToken).ConfigureAwait(false) :
201+
new();
202+
203+
if (request.Params?.Cursor is null && resourceCollection is not null)
204+
{
205+
result.Resources.AddRange(resourceCollection.Select(t => t.ProtocolResource));
206+
}
207+
208+
return result;
209+
};
196210

197211
RequestHandlers.Set(
198212
RequestMethods.ResourcesList,
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
using Microsoft.Extensions.DependencyInjection;
2+
using Microsoft.Extensions.FileProviders;
3+
using Microsoft.Extensions.Options;
4+
using ModelContextProtocol.Client;
5+
using ModelContextProtocol.Protocol.Messages;
6+
using ModelContextProtocol.Server;
7+
8+
namespace ModelContextProtocol.Tests.Configuration;
9+
10+
public class McpServerBuilderExtensionsResourcesTests(ITestOutputHelper testOutputHelper)
11+
: ClientServerTestBase(testOutputHelper)
12+
{
13+
protected override void ConfigureServices(ServiceCollection services, IMcpServerBuilder mcpServerBuilder)
14+
{
15+
mcpServerBuilder = mcpServerBuilder.WithResources(
16+
new FakeFileInfo()
17+
{
18+
Name = "test",
19+
PhysicalPath = "test.txt",
20+
Length = 0,
21+
},
22+
new FakeFileInfo()
23+
{
24+
Name = "test2",
25+
PhysicalPath = "test2.txt",
26+
Length = 0,
27+
});
28+
base.ConfigureServices(services, mcpServerBuilder);
29+
}
30+
31+
private class FakeFileInfo : IFileInfo
32+
{
33+
public string Name { get; set; } = "test.txt";
34+
public long Length { get; set; } = 0;
35+
public bool Exists => true;
36+
37+
public string? PhysicalPath { get; set; } = "test.txt";
38+
39+
public DateTimeOffset LastModified { get; set; } = DateTimeOffset.UtcNow;
40+
41+
public bool IsDirectory => false;
42+
43+
public Stream CreateReadStream() => new MemoryStream();
44+
}
45+
46+
[Fact]
47+
public void Adds_Resources_To_Server()
48+
{
49+
var serverOptions = ServiceProvider.GetRequiredService<IOptions<McpServerOptions>>().Value;
50+
var resources = serverOptions?.Capabilities?.Resources?.ResourceCollection;
51+
Assert.NotNull(resources);
52+
Assert.Equal(2, resources.Count);
53+
Assert.Equal("test.txt", resources["test"].Name);
54+
Assert.Equal("test2.txt", resources["test2"].Name);
55+
}
56+
57+
[Fact]
58+
public async Task Can_List_Resources()
59+
{
60+
// Arrange
61+
var token = TestContext.Current.CancellationToken;
62+
var client = await CreateMcpClientForServer();
63+
64+
// Act
65+
var resources = await client.ListResourcesAsync(token);
66+
67+
// Assert
68+
Assert.NotNull(resources);
69+
Assert.Equal(2, resources.Count);
70+
}
71+
72+
[Fact]
73+
public async Task Can_Be_Notified_Of_ResourceList_Changes()
74+
{
75+
// Arrange
76+
var token = TestContext.Current.CancellationToken;
77+
var client = await CreateMcpClientForServer();
78+
var serverOptions = ServiceProvider
79+
.GetRequiredService<IOptions<McpServerOptions>>()
80+
.Value;
81+
TaskCompletionSource<JsonRpcNotification> changeReceived = new();
82+
client.RegisterNotificationHandler(
83+
NotificationMethods.ResourceListChangedNotification,
84+
(notification, token) =>
85+
{
86+
changeReceived.SetResult(notification);
87+
return changeReceived.Task;
88+
});
89+
90+
// Act
91+
var resources = await client.ListResourcesAsync(token);
92+
Assert.NotNull(resources);
93+
Assert.Equal(2, resources.Count);
94+
95+
serverOptions?.Capabilities?.Resources?.ResourceCollection?.Add(new McpServerResource
96+
{
97+
ProtocolResource = new()
98+
{
99+
Name = "new resource",
100+
Uri = "test3.txt",
101+
},
102+
});
103+
104+
// Assert
105+
await changeReceived.Task.WaitAsync(TimeSpan.FromSeconds(3), token);
106+
var updatedResources = await client.ListResourcesAsync(token);
107+
Assert.NotNull(updatedResources);
108+
Assert.Equal(3, updatedResources.Count);
109+
}
110+
}

0 commit comments

Comments
 (0)