S-4 MCP-Light (Daten-Tuer fuer externe KI-Clients, KEIN Modell-Zugang - Modelle laufen weiter ueber OpenRouter): - McpJsonRpc (pur): JSON-RPC 2.0 fuer initialize/ping/tools/list/tools/call ueber die read-only Tool-Registry; Notifications/Fehlerfaelle spezifikationskonform. - McpLightServer (HostedService): lokaler Streamable-HTTP-Endpoint. OPT-IN via POLYTRADER_MCP_PORT, bindet NUR 127.0.0.1. Claude Code: claude mcp add --transport http polytrader http://127.0.0.1:PORT/mcp - End-to-End-Test ueber echtes HTTP (initialize, tools/call, Notification=202, GET=405). S-3 Profile + Berichte: - SupervisorProfiles: Allgemein/Technik/CopyTrading/ResolutionFarming als System-Prompt- Zusatz + Tool-Subset ueber EINER Agent-Infrastruktur (Technik z.B. ohne Strategie-Tools). Agent filtert Tools je Profil. - sup_reports (SupervisorDbContext, Migration generiert UND angewendet): jede Analyse wird mit Profil/Modell/Frage/Antwort/Tool-Aufrufen/Token gespeichert -> Supervisor auditierbar. UI (Richards Vorgabe: designerfaehig): - SupervisorMainForm auf partial + .Designer.cs umgestellt - alle Controls im Designer (3 Tabs: Analyse mit Profil-Combo+Modellfeld, Dossiers, Berichte mit Split/Grid/Detail). Tests: +16 (MCP-JSON-RPC 6, MCP-HTTP-E2E 1, Profile 2, bestehende erweitert). Build 0 Fehler, 360 Tests gruen, --smoke-ui alle 5 Views gruen. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
70 lines
3.1 KiB
C#
70 lines
3.1 KiB
C#
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
|
|
{
|
|
/// <summary>End-to-End-Test des MCP-Light-HTTP-Hosts (echter HttpListener auf 127.0.0.1).</summary>
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
}
|