Add WithXx overloads that take target instance (#706)
* Add WithXx overloads that take target instance * Special-case enumerables
This commit is contained in:
parent
aef509fd92
commit
2fa658e439
1 changed files with 290 additions and 4 deletions
|
|
@ -5,6 +5,8 @@ using Microsoft.Extensions.Options;
|
|||
using ModelContextProtocol.Client;
|
||||
using ModelContextProtocol.Protocol;
|
||||
using ModelContextProtocol.Server;
|
||||
using Moq;
|
||||
using System.Collections;
|
||||
using System.Collections.Concurrent;
|
||||
using System.ComponentModel;
|
||||
using System.IO.Pipelines;
|
||||
|
|
@ -403,9 +405,11 @@ public partial class McpServerBuilderExtensionsToolsTests : ClientServerTestBase
|
|||
|
||||
Assert.Throws<ArgumentNullException>("tools", () => builder.WithTools((IEnumerable<McpServerTool>)null!));
|
||||
Assert.Throws<ArgumentNullException>("toolTypes", () => builder.WithTools((IEnumerable<Type>)null!));
|
||||
Assert.Throws<ArgumentNullException>("target", () => builder.WithTools<object>(target: null!));
|
||||
|
||||
IMcpServerBuilder nullBuilder = null!;
|
||||
Assert.Throws<ArgumentNullException>("builder", () => nullBuilder.WithTools<object>());
|
||||
Assert.Throws<ArgumentNullException>("builder", () => nullBuilder.WithTools(new object()));
|
||||
Assert.Throws<ArgumentNullException>("builder", () => nullBuilder.WithTools(Array.Empty<Type>()));
|
||||
Assert.Throws<ArgumentNullException>("builder", () => nullBuilder.WithToolsFromAssembly());
|
||||
}
|
||||
|
|
@ -503,6 +507,44 @@ public partial class McpServerBuilderExtensionsToolsTests : ClientServerTestBase
|
|||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task WithTools_TargetInstance_UsesTarget()
|
||||
{
|
||||
ServiceCollection sc = new();
|
||||
|
||||
var target = new EchoTool(new ObjectWithId());
|
||||
sc.AddMcpServer().WithTools(target, BuilderToolsJsonContext.Default.Options);
|
||||
|
||||
McpServerTool tool = sc.BuildServiceProvider().GetServices<McpServerTool>().First(t => t.ProtocolTool.Name == "get_ctor_parameter");
|
||||
var result = await tool.InvokeAsync(new RequestContext<CallToolRequestParams>(new Mock<IMcpServer>().Object), TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.Equal(target.GetCtorParameter(), (result.Content[0] as TextContentBlock)?.Text);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task WithTools_TargetInstance_UsesEnumerableImplementation()
|
||||
{
|
||||
ServiceCollection sc = new();
|
||||
|
||||
sc.AddMcpServer().WithTools(new MyToolProvider());
|
||||
|
||||
var tools = sc.BuildServiceProvider().GetServices<McpServerTool>().ToArray();
|
||||
Assert.Equal(2, tools.Length);
|
||||
Assert.Contains(tools, t => t.ProtocolTool.Name == "Returns42");
|
||||
Assert.Contains(tools, t => t.ProtocolTool.Name == "Returns43");
|
||||
}
|
||||
|
||||
private sealed class MyToolProvider : IEnumerable<McpServerTool>
|
||||
{
|
||||
public IEnumerator<McpServerTool> GetEnumerator()
|
||||
{
|
||||
yield return McpServerTool.Create(() => "42", new() { Name = "Returns42" });
|
||||
yield return McpServerTool.Create(() => "43", new() { Name = "Returns43" });
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Recognizes_Parameter_Types()
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue