Files
stiftung-management-system/app/mcp_server/server.py
SysAdmin Agent fdf078fa10
Some checks failed
CI/CD Pipeline / test (push) Has been cancelled
CI/CD Pipeline / deploy (push) Has been cancelled
Code Quality / quality (push) Has been cancelled
Add MCP tools for Veranstaltung participant management
- veranstaltungen_anzeigen: list events with participant counts
- veranstaltung_teilnehmer_anzeigen: list participants by event
- veranstaltung_teilnehmer_anlegen: add single participant
- veranstaltung_teilnehmer_importieren: bulk import via JSON array

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 09:15:35 +00:00

161 lines
7.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
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")