""" MCP Server für die Stiftungsverwaltung. Startmodus: python -m mcp_server.server Konfiguration über Umgebungsvariablen: MCP_AUTH_TOKEN – Aktiver Zugriffstoken (vom MCP-Client gesetzt) MCP_TOKEN_READONLY – Token für readonly-Rolle MCP_TOKEN_EDITOR – Token für editor-Rolle MCP_TOKEN_ADMIN – Token für admin-Rolle DJANGO_SETTINGS_MODULE – Django-Settings (Standard: core.settings) DB_HOST, DB_PORT, POSTGRES_DB, POSTGRES_USER, POSTGRES_PASSWORD – DB-Verbindung """ import logging import os import sys # ────────────────────────────────────────────────────────────────────────────── # Django Standalone-Setup (ORM ohne HTTP-Server) # ────────────────────────────────────────────────────────────────────────────── # Pfad zum app/-Verzeichnis in sys.path aufnehmen (damit Imports funktionieren) _app_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) if _app_dir not in sys.path: sys.path.insert(0, _app_dir) os.environ.setdefault("DJANGO_SETTINGS_MODULE", "core.settings") os.environ.setdefault("DJANGO_ALLOW_ASYNC_UNSAFE", "true") import django # noqa: E402 django.setup() # ────────────────────────────────────────────────────────────────────────────── # Logging # ────────────────────────────────────────────────────────────────────────────── logging.basicConfig( level=logging.WARNING, format="%(asctime)s %(levelname)s %(name)s: %(message)s", stream=sys.stderr, ) logger = logging.getLogger("mcp_server") # ────────────────────────────────────────────────────────────────────────────── # Auth-Check vor Server-Start # ────────────────────────────────────────────────────────────────────────────── from mcp_server.auth import get_current_role, require_role # noqa: E402 _current_role = get_current_role() try: require_role(_current_role) except ValueError as exc: logger.error("MCP Auth-Fehler: %s", exc) sys.exit(1) logger.info("MCP Server startet mit Rolle: %s", _current_role) # ────────────────────────────────────────────────────────────────────────────── # MCP Server Initialisierung # ────────────────────────────────────────────────────────────────────────────── from mcp.server.fastmcp import FastMCP # noqa: E402 mcp = FastMCP( "Stiftungsverwaltung", instructions=( "MCP-Server der gemeinnützigen Familienstiftung. " f"Aktive Rolle: {_current_role}. " "Lese-Zugriff auf alle Stiftungsdaten. " + ("Schreib-Zugriff aktiv. " if _current_role in ("editor", "admin") else "") + "PII-Felder werden bei readonly/editor maskiert." ), ) # ────────────────────────────────────────────────────────────────────────────── # Lese-Tools registrieren (alle Rollen) # ────────────────────────────────────────────────────────────────────────────── from mcp_server.tools.lesen import ( # noqa: E402 dashboard, destinataer_details, destinataer_suchen, dokument_details, dokument_suchen, globale_suche, konten_uebersicht, land_details, land_suchen, paechter_suchen, statistiken, termine_anzeigen, transaktionen_suchen, veranstaltung_teilnehmer_anzeigen, veranstaltungen_anzeigen, verwaltungskosten, ) mcp.tool()(destinataer_suchen) mcp.tool()(destinataer_details) mcp.tool()(land_suchen) mcp.tool()(land_details) mcp.tool()(paechter_suchen) mcp.tool()(konten_uebersicht) mcp.tool()(verwaltungskosten) mcp.tool()(transaktionen_suchen) mcp.tool()(dokument_suchen) mcp.tool()(dokument_details) mcp.tool()(termine_anzeigen) mcp.tool()(veranstaltungen_anzeigen) mcp.tool()(veranstaltung_teilnehmer_anzeigen) mcp.tool()(globale_suche) mcp.tool()(dashboard) mcp.tool()(statistiken) # ────────────────────────────────────────────────────────────────────────────── # Schreib-Tools registrieren (nur editor/admin) # ────────────────────────────────────────────────────────────────────────────── from mcp_server.auth import can_write # noqa: E402 if can_write(_current_role): from mcp_server.tools.schreiben import ( # noqa: E402 destinataer_aktualisieren, destinataer_anlegen, dokument_verknuepfen, foerderung_anlegen, land_anlegen, paechter_anlegen, termin_anlegen, unterstuetzung_anlegen, veranstaltung_teilnehmer_anlegen, veranstaltung_teilnehmer_importieren, verpachtung_anlegen, verwaltungskosten_erfassen, ) mcp.tool()(destinataer_anlegen) mcp.tool()(destinataer_aktualisieren) mcp.tool()(foerderung_anlegen) mcp.tool()(unterstuetzung_anlegen) mcp.tool()(land_anlegen) mcp.tool()(verpachtung_anlegen) mcp.tool()(paechter_anlegen) mcp.tool()(verwaltungskosten_erfassen) mcp.tool()(termin_anlegen) mcp.tool()(dokument_verknuepfen) mcp.tool()(veranstaltung_teilnehmer_anlegen) mcp.tool()(veranstaltung_teilnehmer_importieren) # ────────────────────────────────────────────────────────────────────────────── # Server starten # ────────────────────────────────────────────────────────────────────────────── if __name__ == "__main__": mcp.run(transport="stdio")