Add MCP Apps to NativeAOT coverage (#1711)
Co-authored-by: Loi Nguyen <loinguyen@local> Co-authored-by: Jeff Handley <jeffhandley@users.noreply.github.com>
This commit is contained in:
parent
9f845f8ca5
commit
dfb2205cac
2 changed files with 31 additions and 13 deletions
|
|
@ -7,18 +7,20 @@
|
||||||
<TargetFrameworks></TargetFrameworks>
|
<TargetFrameworks></TargetFrameworks>
|
||||||
<PublishAot>true</PublishAot>
|
<PublishAot>true</PublishAot>
|
||||||
<TrimmerSingleWarn>false</TrimmerSingleWarn>
|
<TrimmerSingleWarn>false</TrimmerSingleWarn>
|
||||||
<!-- Suppress the experimental tasks warning -->
|
<!-- Suppress warnings for the experimental APIs exercised by this test app. -->
|
||||||
<NoWarn>$(NoWarn);MCPEXP001</NoWarn>
|
<NoWarn>$(NoWarn);MCPEXP001;MCPEXP003</NoWarn>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\..\src\ModelContextProtocol.Core\ModelContextProtocol.Core.csproj" />
|
<ProjectReference Include="..\..\src\ModelContextProtocol.Core\ModelContextProtocol.Core.csproj" />
|
||||||
<ProjectReference Include="..\..\src\ModelContextProtocol\ModelContextProtocol.csproj" />
|
<ProjectReference Include="..\..\src\ModelContextProtocol\ModelContextProtocol.csproj" />
|
||||||
<ProjectReference Include="..\..\src\ModelContextProtocol.AspNetCore\ModelContextProtocol.AspNetCore.csproj" />
|
<ProjectReference Include="..\..\src\ModelContextProtocol.AspNetCore\ModelContextProtocol.AspNetCore.csproj" />
|
||||||
|
<ProjectReference Include="..\..\src\ModelContextProtocol.Extensions.Apps\ModelContextProtocol.Extensions.Apps.csproj" />
|
||||||
|
|
||||||
<TrimmerRootAssembly Include="ModelContextProtocol.Core" />
|
<TrimmerRootAssembly Include="ModelContextProtocol.Core" />
|
||||||
<TrimmerRootAssembly Include="ModelContextProtocol" />
|
<TrimmerRootAssembly Include="ModelContextProtocol" />
|
||||||
<TrimmerRootAssembly Include="ModelContextProtocol.AspNetCore" />
|
<TrimmerRootAssembly Include="ModelContextProtocol.AspNetCore" />
|
||||||
|
<TrimmerRootAssembly Include="ModelContextProtocol.Extensions.Apps" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,20 @@
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using ModelContextProtocol.Client;
|
using ModelContextProtocol.Client;
|
||||||
|
using ModelContextProtocol.Extensions.Apps;
|
||||||
using ModelContextProtocol.Protocol;
|
using ModelContextProtocol.Protocol;
|
||||||
using ModelContextProtocol.Server;
|
using ModelContextProtocol.Server;
|
||||||
using System.IO.Pipelines;
|
using System.IO.Pipelines;
|
||||||
|
|
||||||
Pipe clientToServerPipe = new(), serverToClientPipe = new();
|
Pipe clientToServerPipe = new(), serverToClientPipe = new();
|
||||||
|
|
||||||
// Create a server using a stream-based transport over an in-memory pipe.
|
var services = new ServiceCollection();
|
||||||
await using McpServer server = McpServer.Create(
|
services.AddMcpServer()
|
||||||
new StreamServerTransport(clientToServerPipe.Reader.AsStream(), serverToClientPipe.Writer.AsStream()),
|
.WithStreamServerTransport(clientToServerPipe.Reader.AsStream(), serverToClientPipe.Writer.AsStream())
|
||||||
new McpServerOptions()
|
.WithTools<AotTools>()
|
||||||
{
|
.WithMcpApps();
|
||||||
ToolCollection = [McpServerTool.Create((string arg) => $"Echo: {arg}", new() { Name = "Echo" })]
|
|
||||||
});
|
await using var serviceProvider = services.BuildServiceProvider();
|
||||||
|
var server = serviceProvider.GetRequiredService<McpServer>();
|
||||||
_ = server.RunAsync();
|
_ = server.RunAsync();
|
||||||
|
|
||||||
// Connect a client using a stream-based transport over the same in-memory pipe.
|
// Connect a client using a stream-based transport over the same in-memory pipe.
|
||||||
|
|
@ -20,13 +23,18 @@ await using McpClient client = await McpClient.CreateAsync(
|
||||||
|
|
||||||
// List all tools.
|
// List all tools.
|
||||||
var tools = await client.ListToolsAsync();
|
var tools = await client.ListToolsAsync();
|
||||||
if (tools.Count == 0)
|
var echo = tools.FirstOrDefault(t => t.Name == "Echo");
|
||||||
|
if (echo is null)
|
||||||
{
|
{
|
||||||
throw new Exception("Expected at least one tool.");
|
throw new Exception("Expected the Echo tool.");
|
||||||
|
}
|
||||||
|
|
||||||
|
var ui = echo.ProtocolTool.Meta?["ui"]?.AsObject();
|
||||||
|
if (ui?["resourceUri"]?.GetValue<string>() != "ui://aot/echo")
|
||||||
|
{
|
||||||
|
throw new Exception($"Unexpected app UI metadata: {ui}");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Invoke a tool.
|
|
||||||
var echo = tools.First(t => t.Name == "Echo");
|
|
||||||
var result = await echo.InvokeAsync(new() { ["arg"] = "Hello World" });
|
var result = await echo.InvokeAsync(new() { ["arg"] = "Hello World" });
|
||||||
if (result is null || !result.ToString()!.Contains("Echo: Hello World"))
|
if (result is null || !result.ToString()!.Contains("Echo: Hello World"))
|
||||||
{
|
{
|
||||||
|
|
@ -34,3 +42,11 @@ if (result is null || !result.ToString()!.Contains("Echo: Hello World"))
|
||||||
}
|
}
|
||||||
|
|
||||||
Console.WriteLine("Success!");
|
Console.WriteLine("Success!");
|
||||||
|
|
||||||
|
[McpServerToolType]
|
||||||
|
internal sealed class AotTools
|
||||||
|
{
|
||||||
|
[McpServerTool(Name = "Echo")]
|
||||||
|
[McpAppUi(ResourceUri = "ui://aot/echo")]
|
||||||
|
public static string Echo(string arg) => $"Echo: {arg}";
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue