v4.1.0: DMS email documents, category-specific Nachweis linking, version system
- Save cover email body as DMS document with new 'email' context type - Show email body separately from attachments in email detail view - Add per-category DMS document assignment in quarterly confirmation (Studiennachweis, Einkommenssituation, Vermögenssituation) - Add VERSION file and context processor for automatic version display - Add MCP server, agent system, import/export, and new migrations - Update compose files and production environment template Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
151
app/mcp_server/server.py
Normal file
151
app/mcp_server/server.py
Normal file
@@ -0,0 +1,151 @@
|
||||
"""
|
||||
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")
|
||||
|
||||
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,
|
||||
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()(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,
|
||||
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)
|
||||
|
||||
# ──────────────────────────────────────────────────────────────────────────────
|
||||
# Server starten
|
||||
# ──────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
if __name__ == "__main__":
|
||||
mcp.run(transport="stdio")
|
||||
Reference in New Issue
Block a user