Claude Desktop deaktivierte den ganzen MCP-Server, sobald der Initialize-Handshake beim Bridge-Start fehlschlug - der Regelfall, wenn LehrerApp.Desktop (z.B. nach Windows-Autostart von Claude Desktop) noch nicht läuft. Die Bridge ist jetzt selbst ein MCP-Server gegenüber Claude Desktop und gleichzeitig ein MCP-Client gegenüber dem echten Server in LehrerApp.Desktop: der Handshake gelingt dadurch immer. Verbunden spiegelt sie die echte Werkzeugliste 1:1; ohne Verbindung bietet sie nur ein lehrerapp_status-Werkzeug an, das den Grund erklärt und erneut verbindet. Ein Hintergrund-Loop versucht unabhängig davon alle 5s zu reconnecten und schaltet per notifications/tools/list_changed automatisch auf die echten Werkzeuge um, sobald LehrerApp erreichbar ist. Bricht die Verbindung während eines laufenden Aufrufs ab, kommt ein normales Tool-Fehlerergebnis statt eines Prozessabsturzes zurück. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
46 lines
2.0 KiB
C#
46 lines
2.0 KiB
C#
using LehrerApp.McpBridge;
|
|
using ModelContextProtocol.Protocol;
|
|
using ModelContextProtocol.Server;
|
|
|
|
// Resilienter Bridge-Prozess (Nutzer-Feedback): meldet sich gegenüber dem KI-Client (z.B. Claude
|
|
// Desktop) IMMER erfolgreich als MCP-Server, unabhängig davon, ob LehrerApp.Desktop beim Start
|
|
// dieses Prozesses bereits läuft - Claude Desktop startet oft per Windows-Autostart, bevor der
|
|
// Nutzer LehrerApp geöffnet hat. Die eigentliche Weiterleitung an den echten Server sowie das
|
|
// Nachladen der echten Werkzeugliste, sobald LehrerApp erreichbar ist, übernimmt
|
|
// RealServerBridge - Details und Begründung siehe dort.
|
|
|
|
var bridge = new RealServerBridge();
|
|
await bridge.TryReconnectAsync(CancellationToken.None);
|
|
bridge.EnsureFallbackTool();
|
|
|
|
using var cts = new CancellationTokenSource();
|
|
var reconnectLoop = bridge.RunBackgroundReconnectLoopAsync(TimeSpan.FromSeconds(5), cts.Token);
|
|
|
|
var serverOptions = new McpServerOptions
|
|
{
|
|
ServerInfo = new Implementation { Name = "LehrerApp", Version = "1.0.0" },
|
|
// ListChanged = true: Voraussetzung dafür, dass Claude Desktop reagiert, wenn RealServerBridge
|
|
// das Status-Werkzeug nachträglich durch die echte Werkzeugliste ersetzt (oder umgekehrt, falls
|
|
// LehrerApp während der Sitzung beendet wird).
|
|
Capabilities = new ServerCapabilities { Tools = new ToolsCapability { ListChanged = true } },
|
|
ToolCollection = bridge.Tools,
|
|
};
|
|
|
|
await using var stdin = Console.OpenStandardInput();
|
|
await using var stdout = Console.OpenStandardOutput();
|
|
await using var transport = new StreamServerTransport(stdin, stdout, "LehrerApp.McpBridge");
|
|
await using var server = McpServer.Create(transport, serverOptions, loggerFactory: null, serviceProvider: null);
|
|
|
|
try
|
|
{
|
|
// Läuft, bis der KI-Client stdin schließt (Sitzungsende) - danach ist nichts mehr zu tun.
|
|
await server.RunAsync(cts.Token);
|
|
}
|
|
finally
|
|
{
|
|
await cts.CancelAsync();
|
|
try { await reconnectLoop; }
|
|
catch { /* Beenden über Cancellation ist der Normalfall hier */ }
|
|
await bridge.DisposeAsync();
|
|
}
|