using Agent.Core.Localization; using Agent.Core.Ollama; using Agent.Core.Runtime; using Agent.Mcp; using ModelContextProtocol.Server; using ModelContextProtocol.Protocol; using System.Reflection; using Microsoft.Extensions.DependencyInjection; using ModelContextProtocol; namespace Agent.Mcp.TestHost; public static class Marker; internal static class Program { public static async Task Main(string[] args) { if (args.Length is not (2 or 4)) throw new ArgumentException("Expected or http ."); bool http = args.Length == 4; int offset = http ? 2 : 0; LocaleCatalog locale = LocaleCatalog.Load(args[offset], "en"); var ollama = new OllamaSettings(new Uri("http://127.0.0.1:1"), "unused", false, "0", new Dictionary()); var store = new McpTaskStoreSettings(args[offset + 1], TimeSpan.FromHours(24), 1000); var runtime = new AgentRuntimeSettings("", "en", [], "sandbox"); McpServerTool[] fixtures = [ McpServerTool.Create((string name) => $"Hello, {name}!", new McpServerToolCreateOptions { Name = "greet" }), McpServerTool.Create(async (int seconds, CancellationToken cancellationToken) => { await Task.Delay(TimeSpan.FromSeconds(seconds), cancellationToken).ConfigureAwait(false); return $"Computed after {seconds} seconds"; }, new McpServerToolCreateOptions { Name = "slow_compute" }), McpServerTool.Create(async () => { await Task.Delay(1000).ConfigureAwait(false); return new CallToolResult { IsError = true, Content = [new TextContentBlock { Text = "intentional tool error" }] }; }, new McpServerToolCreateOptions { Name = "failing_job" }), McpServerTool.Create((Func)(() => throw new InvalidOperationException("intentional protocol error")), new McpServerToolCreateOptions { Name = "protocol_error_job" }), .. typeof(ConformanceTools).GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly) .Where(static method => method.GetCustomAttribute() is not null) .Select(method => McpServerTool.Create(method, new ConformanceTools())) ]; var taskTools = new HashSet(["agent_run", "slow_compute", "confirm_delete", "multi_input", "protocol_error_job"], StringComparer.Ordinal); var requiredTaskTools = new HashSet(["failing_job", "test_tool_with_task"], StringComparer.Ordinal); if (http) await McpHost.RunHttpAsync(locale, ollama, runtime, new VisionLimits(), "127.0.0.1", int.Parse(args[1], System.Globalization.CultureInfo.InvariantCulture), CancellationToken.None, taskStoreSettings: store, additionalTools: fixtures, taskCapableTools: taskTools, requiredTaskTools: requiredTaskTools, configureBuilder: ConfigureConformanceFilters).ConfigureAwait(false); else await McpHost.RunStdioAsync(locale, ollama, runtime, new VisionLimits(), CancellationToken.None, taskStoreSettings: store).ConfigureAwait(false); } private static void ConfigureConformanceFilters(IMcpServerBuilder builder) { builder.WithRequestFilters(filters => filters.AddCallToolFilter(next => async (context, cancellationToken) => { if (context.Params?.Name == "test_missing_capability") { #pragma warning disable MCP9005 // Frozen alpha conformance probes the legacy sampling capability shape. throw new MissingRequiredClientCapabilityException( new ClientCapabilities { Sampling = new SamplingCapability() }, "The conformance diagnostic requires the sampling capability."); #pragma warning restore MCP9005 } if (context.Params?.Name == "protocol_error_job") throw new McpProtocolException("intentional protocol error", McpErrorCode.InternalError); return await next(context, cancellationToken).ConfigureAwait(false); })); } }