Skip to content

Commit 3cdaeec

Browse files
committed
Add Can_Create_Multiple_Servers_From_Options_And_List_Registered_Tools
1 parent 26a5a60 commit 3cdaeec

File tree

1 file changed

+70
-6
lines changed

1 file changed

+70
-6
lines changed

tests/ModelContextProtocol.Tests/Configuration/McpServerBuilderExtensionsToolsTests.cs

Lines changed: 70 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,30 +11,37 @@
1111
using Microsoft.Extensions.AI;
1212
using System.Threading.Channels;
1313
using ModelContextProtocol.Protocol.Messages;
14+
using Microsoft.Extensions.Options;
15+
using ModelContextProtocol.Tests.Utils;
16+
using Microsoft.Extensions.Logging;
1417

1518
namespace ModelContextProtocol.Tests.Configuration;
1619

17-
public class McpServerBuilderExtensionsToolsTests : IAsyncDisposable
20+
public class McpServerBuilderExtensionsToolsTests : LoggedTest, IAsyncDisposable
1821
{
19-
private Pipe _clientToServerPipe = new();
20-
private Pipe _serverToClientPipe = new();
22+
private readonly Pipe _clientToServerPipe = new();
23+
private readonly Pipe _serverToClientPipe = new();
24+
private readonly ServiceProvider _serviceProvider;
2125
private readonly IMcpServerBuilder _builder;
2226
private readonly IMcpServer _server;
2327

24-
public McpServerBuilderExtensionsToolsTests()
28+
public McpServerBuilderExtensionsToolsTests(ITestOutputHelper testOutputHelper)
29+
: base(testOutputHelper)
2530
{
2631
ServiceCollection sc = new();
32+
sc.AddSingleton(LoggerFactory);
2733
sc.AddSingleton<IServerTransport>(new StdioServerTransport("TestServer", _clientToServerPipe.Reader.AsStream(), _serverToClientPipe.Writer.AsStream()));
2834
sc.AddSingleton(new ObjectWithId());
2935
_builder = sc.AddMcpServer().WithTools<EchoTool>();
30-
_server = sc.BuildServiceProvider().GetRequiredService<IMcpServer>();
36+
_serviceProvider = sc.BuildServiceProvider();
37+
_server = _serviceProvider.GetRequiredService<IMcpServer>();
3138
}
3239

3340
public ValueTask DisposeAsync()
3441
{
3542
_clientToServerPipe.Writer.Complete();
3643
_serverToClientPipe.Writer.Complete();
37-
return _server.DisposeAsync();
44+
return _serviceProvider.DisposeAsync();
3845
}
3946

4047
private async Task<IMcpClient> CreateMcpClientForServer()
@@ -86,6 +93,63 @@ public async Task Can_List_Registered_Tools()
8693
Assert.Equal("Echoes the input back to the client.", doubleEchoTool.Description);
8794
}
8895

96+
97+
[Fact]
98+
public async Task Can_Create_Multiple_Servers_From_Options_And_List_Registered_Tools()
99+
{
100+
var options = _serviceProvider.GetRequiredService<IOptions<McpServerOptions>>().Value;
101+
var loggerFactory = _serviceProvider.GetRequiredService<ILoggerFactory>();
102+
103+
for (int i = 0; i < 2; i++)
104+
{
105+
var stdinPipe = new Pipe();
106+
var stdoutPipe = new Pipe();
107+
108+
try
109+
{
110+
var transport = new StdioServerTransport($"TestServer_{i}", stdinPipe.Reader.AsStream(), stdoutPipe.Writer.AsStream());
111+
var server = McpServerFactory.Create(transport, options, loggerFactory, _serviceProvider);
112+
113+
await server.StartAsync(TestContext.Current.CancellationToken);
114+
115+
var stdin = new StreamWriter(stdinPipe.Writer.AsStream());
116+
var stdout = new StreamReader(stdoutPipe.Reader.AsStream());
117+
118+
var serverConfig = new McpServerConfig()
119+
{
120+
Id = $"TestServer_{i}",
121+
Name = $"TestServer_{i}",
122+
TransportType = "ignored",
123+
};
124+
125+
var client = await McpClientFactory.CreateAsync(
126+
serverConfig,
127+
createTransportFunc: (_, _) => new StreamClientTransport(stdout, stdin),
128+
cancellationToken: TestContext.Current.CancellationToken);
129+
130+
var tools = await client.ListToolsAsync(TestContext.Current.CancellationToken);
131+
Assert.Equal(11, tools.Count);
132+
133+
McpClientTool echoTool = tools.First(t => t.Name == "Echo");
134+
Assert.Equal("Echo", echoTool.Name);
135+
Assert.Equal("Echoes the input back to the client.", echoTool.Description);
136+
Assert.Equal("object", echoTool.JsonSchema.GetProperty("type").GetString());
137+
Assert.Equal(JsonValueKind.Object, echoTool.JsonSchema.GetProperty("properties").GetProperty("message").ValueKind);
138+
Assert.Equal("the echoes message", echoTool.JsonSchema.GetProperty("properties").GetProperty("message").GetProperty("description").GetString());
139+
Assert.Equal(1, echoTool.JsonSchema.GetProperty("required").GetArrayLength());
140+
141+
McpClientTool doubleEchoTool = tools.First(t => t.Name == "double_echo");
142+
Assert.Equal("double_echo", doubleEchoTool.Name);
143+
Assert.Equal("Echoes the input back to the client.", doubleEchoTool.Description);
144+
}
145+
finally
146+
{
147+
stdinPipe.Writer.Complete();
148+
stdoutPipe.Writer.Complete();
149+
}
150+
}
151+
}
152+
89153
[Fact]
90154
public async Task Can_Be_Notified_Of_Tool_Changes()
91155
{

0 commit comments

Comments
 (0)