using System; using System.Net.Http; using System.Text; using System.Text.Json; using System.Threading; using System.Threading.Tasks; using PolyTrader.Modules.Supervisor.Agent; using PolyTrader.Modules.Supervisor.Mcp; using PolyTraderSharp.Services; using Xunit; namespace PolyTrader.Tests { /// End-to-End-Test des MCP-Light-HTTP-Hosts (echter HttpListener auf 127.0.0.1). public class McpLightServerTests { [Fact] public async Task Server_answers_initialize_and_tools_call_over_http() { int port = 52000 + new Random().Next(1000, 9000); Environment.SetEnvironmentVariable("POLYTRADER_MCP_PORT", port.ToString()); try { var reg = new SupervisorToolRegistry(); reg.Register(new SupervisorTool("echo", "Echo", """{"type":"object","properties":{"text":{"type":"string"}}}""", args => "ECHO:" + (SupervisorToolRegistry.GetString(args, "text") ?? ""))); var server = new McpLightServer(reg, new TerminalLogger()); await server.StartAsync(CancellationToken.None); await Task.Delay(300); // Listener-Start abwarten using var http = new HttpClient(); string url = $"http://127.0.0.1:{port}/mcp/"; // initialize var initResp = await http.PostAsync(url, new StringContent( """{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}""", Encoding.UTF8, "application/json")); Assert.True(initResp.IsSuccessStatusCode); using (var doc = JsonDocument.Parse(await initResp.Content.ReadAsStringAsync())) Assert.Equal(McpJsonRpc.ServerName, doc.RootElement.GetProperty("result").GetProperty("serverInfo").GetProperty("name").GetString()); // tools/call var callResp = await http.PostAsync(url, new StringContent( """{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"echo","arguments":{"text":"mcp"}}}""", Encoding.UTF8, "application/json")); using (var doc = JsonDocument.Parse(await callResp.Content.ReadAsStringAsync())) Assert.Equal("ECHO:mcp", doc.RootElement.GetProperty("result").GetProperty("content")[0].GetProperty("text").GetString()); // Notification -> 202 var notifyResp = await http.PostAsync(url, new StringContent( """{"jsonrpc":"2.0","method":"notifications/initialized"}""", Encoding.UTF8, "application/json")); Assert.Equal(202, (int)notifyResp.StatusCode); // GET -> 405 (kein SSE-Stream) var getResp = await http.GetAsync(url); Assert.Equal(405, (int)getResp.StatusCode); await server.StopAsync(CancellationToken.None); } finally { Environment.SetEnvironmentVariable("POLYTRADER_MCP_PORT", null); } } } }