diff --git a/tests/ModelContextProtocol.AotCompatibility.TestApp/ModelContextProtocol.AotCompatibility.TestApp.csproj b/tests/ModelContextProtocol.AotCompatibility.TestApp/ModelContextProtocol.AotCompatibility.TestApp.csproj
index 2b505f9ed..dd3decb72 100644
--- a/tests/ModelContextProtocol.AotCompatibility.TestApp/ModelContextProtocol.AotCompatibility.TestApp.csproj
+++ b/tests/ModelContextProtocol.AotCompatibility.TestApp/ModelContextProtocol.AotCompatibility.TestApp.csproj
@@ -7,18 +7,20 @@
true
false
-
- $(NoWarn);MCPEXP001
+
+ $(NoWarn);MCPEXP001;MCPEXP003
+
+
diff --git a/tests/ModelContextProtocol.AotCompatibility.TestApp/Program.cs b/tests/ModelContextProtocol.AotCompatibility.TestApp/Program.cs
index 687d78e4e..708cd9361 100644
--- a/tests/ModelContextProtocol.AotCompatibility.TestApp/Program.cs
+++ b/tests/ModelContextProtocol.AotCompatibility.TestApp/Program.cs
@@ -1,17 +1,20 @@
+using Microsoft.Extensions.DependencyInjection;
using ModelContextProtocol.Client;
+using ModelContextProtocol.Extensions.Apps;
using ModelContextProtocol.Protocol;
using ModelContextProtocol.Server;
using System.IO.Pipelines;
Pipe clientToServerPipe = new(), serverToClientPipe = new();
-// Create a server using a stream-based transport over an in-memory pipe.
-await using McpServer server = McpServer.Create(
- new StreamServerTransport(clientToServerPipe.Reader.AsStream(), serverToClientPipe.Writer.AsStream()),
- new McpServerOptions()
- {
- ToolCollection = [McpServerTool.Create((string arg) => $"Echo: {arg}", new() { Name = "Echo" })]
- });
+var services = new ServiceCollection();
+services.AddMcpServer()
+ .WithStreamServerTransport(clientToServerPipe.Reader.AsStream(), serverToClientPipe.Writer.AsStream())
+ .WithTools()
+ .WithMcpApps();
+
+await using var serviceProvider = services.BuildServiceProvider();
+var server = serviceProvider.GetRequiredService();
_ = server.RunAsync();
// Connect a client using a stream-based transport over the same in-memory pipe.
@@ -20,13 +23,18 @@
// List all tools.
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 the Echo tool.");
+}
+
+var ui = echo.ProtocolTool.Meta?["ui"]?.AsObject();
+if (ui?["resourceUri"]?.GetValue() != "ui://aot/echo")
{
- throw new Exception("Expected at least one tool.");
+ 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" });
if (result is null || !result.ToString()!.Contains("Echo: Hello World"))
{
@@ -34,3 +42,11 @@
}
Console.WriteLine("Success!");
+
+[McpServerToolType]
+internal sealed class AotTools
+{
+ [McpServerTool(Name = "Echo")]
+ [McpAppUi(ResourceUri = "ui://aot/echo")]
+ public static string Echo(string arg) => $"Echo: {arg}";
+}