feat: lokaler MCP-Server, Phase 1 (Infrastruktur + Read-Tools)

Erlaubt einem lokalen KI-Client (z.B. Claude Desktop) strukturierten
Lesezugriff auf Schüler, Klausuren, Noten, Stundenplan und Zeiterfassung.
Neuer LehrerApp.McpBridge-Prozess reicht stdio-JSON-RPC über eine Named
Pipe an einen In-Process-MCP-Server im Avalonia-Hauptprozess durch
(ModelContextProtocol.Core, StreamServerTransport direkt auf der Pipe).
Standardmäßig deaktiviert, Opt-in über neuen Einstellungen-Tab.
Dokumentationstypen (Gesprächsnotizen/Vorfälle/Förderpläne) sind auf
Code-Ebene nie erreichbar (McpToolScope, analog PlainEventStore.Allowed).

Write-Tools, Bestätigungsdialog-UI, Worksheets/Lesson-Plans-Tools und
macOS-Packaging folgen in späteren Phasen (siehe TODO.md 4.5.25).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-11 19:59:47 +02:00
co-authored by Claude Sonnet 5
parent 455c61c946
commit 98f5573999
24 changed files with 743 additions and 41 deletions
@@ -0,0 +1,48 @@
using System.Text.Json;
namespace LehrerApp.Desktop.Services;
internal class McpSettingsConfig
{
public bool Enabled { get; set; }
}
/// <summary>
/// Opt-in-Schalter für den lokalen MCP-Server (siehe Planungsdokument, Phase 1). Anders als
/// <see cref="AiSettingsService"/> braucht Phase 1 kein Login/Token — die Named Pipe selbst ist die
/// Vertrauensgrenze (lokaler Prozess, gleiche Windows-Session bzw. Unix-Dateirechte), siehe
/// Begründung im Planungsdokument.
/// </summary>
public class McpSettingsService
{
private readonly string _configPath;
private McpSettingsConfig _config;
public bool Enabled => _config.Enabled;
public McpSettingsService(string appDataPath)
{
_configPath = Path.Combine(appDataPath, "mcp-settings.json");
_config = Load();
}
public void SetEnabled(bool enabled)
{
_config.Enabled = enabled;
Save();
}
private void Save() => File.WriteAllText(_configPath, JsonSerializer.Serialize(_config));
private McpSettingsConfig Load()
{
try
{
if (File.Exists(_configPath))
return JsonSerializer.Deserialize<McpSettingsConfig>(File.ReadAllText(_configPath))
?? new McpSettingsConfig();
}
catch { /* beschädigte Konfiguration -> Standardwert */ }
return new McpSettingsConfig();
}
}