MCP_AUTH_TOKEN was stored in plain text in .mcp.json and thus in git history. Now connect.sh reads the token from the environment variable MCP_AUTH_TOKEN — set via export in ~/.bashrc or a secrets manager. ⚠️ Old token is in git history and should be rotated on the server. Rotate: python manage.py create_agent_token <username> Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Stiftung MCP Server
MCP (Model Context Protocol) Server für die Stiftungsverwaltung. Ermöglicht AI-Assistenten den strukturierten Zugriff auf alle Stiftungsdaten.
Funktionsumfang
Lese-Tools (alle Rollen)
| Tool | Beschreibung |
|---|---|
destinataer_suchen |
Suche nach Destinatären (Name, Status, Familienzweig) |
destinataer_details |
Vollständige Details eines Destinatärs |
land_suchen |
Suche nach Ländereien (Gemarkung, Gemeinde) |
land_details |
Details einer Länderei inkl. Verpachtungen |
paechter_suchen |
Suche nach Pächtern |
konten_uebersicht |
Alle Stiftungskonten mit Salden |
verwaltungskosten |
Verwaltungskosten filtern (Jahr, Kategorie, Status) |
transaktionen_suchen |
Banktransaktionen durchsuchen |
dokument_suchen |
Volltextsuche im DMS |
dokument_details |
Metadaten eines Dokuments |
termine_anzeigen |
Kalendereinträge und Termine |
globale_suche |
Suche über alle Entitätstypen |
dashboard |
Kennzahlen-Übersicht |
statistiken |
Detaillierte Auswertungen |
Schreib-Tools (editor/admin)
| Tool | Beschreibung |
|---|---|
destinataer_anlegen |
Neuen Destinatär erfassen |
destinataer_aktualisieren |
Bestehenden Destinatär aktualisieren |
foerderung_anlegen |
Neue Förderung zuweisen |
unterstuetzung_anlegen |
Unterstützungszahlung erfassen |
land_anlegen |
Neue Länderei erfassen |
verpachtung_anlegen |
Pachtvertrag erstellen |
paechter_anlegen |
Neuen Pächter erfassen |
verwaltungskosten_erfassen |
Verwaltungskosten buchen |
termin_anlegen |
Neuen Kalendereintrag erstellen |
dokument_verknuepfen |
Dokument mit Entität verknüpfen |
Voraussetzungen
- Python 3.11+
- Zugriff auf die PostgreSQL-Datenbank der Stiftung
- Django-App Abhängigkeiten installiert (
app/requirements.txt) - MCP SDK:
pip install mcp
Authentifizierung & Rollen
Der Server verwendet Token-basierte Authentifizierung mit drei Rollen:
| Rolle | Lesen | Schreiben | PII-Daten |
|---|---|---|---|
readonly |
Ja | Nein | Maskiert |
editor |
Ja | Ja | Maskiert |
admin |
Ja | Ja | Vollzugriff |
PII-Maskierung (readonly/editor)
- IBAN:
****4567 - E-Mail:
***@example.de - Telefon:
****1234 - Geburtsdatum: nur Jahrgang
- Einkommen/Vermögen: Bereichsangabe
Umgebungsvariablen
# Pflicht: Eines der drei Token setzen
MCP_TOKEN_READONLY=<geheimes-token-readonly>
MCP_TOKEN_EDITOR=<geheimes-token-editor>
MCP_TOKEN_ADMIN=<geheimes-token-admin>
# Pflicht: Das aktive Token für diese Sitzung
MCP_AUTH_TOKEN=<das-token-das-gerade-verwendet-wird>
# Django (automatisch wenn im Docker-Netzwerk)
DJANGO_SETTINGS_MODULE=core.settings
DB_HOST=db
DB_PORT=5432
POSTGRES_DB=stiftung
POSTGRES_USER=stiftung
POSTGRES_PASSWORD=<db-passwort>
Einrichtung
1. Token generieren
Generiere sichere, zufällige Token für jede Rolle:
# Beispiel mit openssl
export MCP_TOKEN_READONLY=$(openssl rand -hex 32)
export MCP_TOKEN_EDITOR=$(openssl rand -hex 32)
export MCP_TOKEN_ADMIN=$(openssl rand -hex 32)
echo "READONLY: $MCP_TOKEN_READONLY"
echo "EDITOR: $MCP_TOKEN_EDITOR"
echo "ADMIN: $MCP_TOKEN_ADMIN"
Speichere die Token sicher (z.B. in .env oder einem Passwort-Manager).
2. Starten
# Aus dem app/-Verzeichnis:
cd /pfad/zum/projekt/app
MCP_AUTH_TOKEN=<dein-token> python -m mcp_server
Oder mit dem Start-Skript:
MCP_AUTH_TOKEN=<dein-token> ./app/mcp_server/start.sh
Client-Konfigurationen
Claude Desktop / Claude Code
Datei: ~/.claude/claude_desktop_config.json (macOS/Linux) oder %APPDATA%\Claude\claude_desktop_config.json (Windows)
{
"mcpServers": {
"stiftung": {
"command": "python",
"args": ["-m", "mcp_server"],
"cwd": "/pfad/zum/projekt/app",
"env": {
"DJANGO_SETTINGS_MODULE": "core.settings",
"MCP_AUTH_TOKEN": "<dein-token>",
"MCP_TOKEN_READONLY": "<readonly-token>",
"MCP_TOKEN_EDITOR": "<editor-token>",
"MCP_TOKEN_ADMIN": "<admin-token>",
"DB_HOST": "localhost",
"DB_PORT": "5432",
"POSTGRES_DB": "stiftung",
"POSTGRES_USER": "stiftung",
"POSTGRES_PASSWORD": "<db-passwort>"
}
}
}
}
Claude Code (Projekt-spezifisch)
Datei: .mcp.json im Projekt-Root:
{
"mcpServers": {
"stiftung": {
"command": "python",
"args": ["-m", "mcp_server"],
"cwd": "./app",
"env": {
"DJANGO_SETTINGS_MODULE": "core.settings",
"MCP_AUTH_TOKEN": "<dein-token>",
"MCP_TOKEN_READONLY": "<readonly-token>",
"MCP_TOKEN_EDITOR": "<editor-token>",
"MCP_TOKEN_ADMIN": "<admin-token>",
"DB_HOST": "localhost",
"DB_PORT": "5432",
"POSTGRES_DB": "stiftung",
"POSTGRES_USER": "stiftung",
"POSTGRES_PASSWORD": "<db-passwort>"
}
}
}
}
Cursor
Datei: .cursor/mcp.json im Projekt-Root:
{
"mcpServers": {
"stiftung": {
"command": "python",
"args": ["-m", "mcp_server"],
"cwd": "/pfad/zum/projekt/app",
"env": {
"DJANGO_SETTINGS_MODULE": "core.settings",
"MCP_AUTH_TOKEN": "<dein-token>",
"MCP_TOKEN_READONLY": "<readonly-token>",
"MCP_TOKEN_EDITOR": "<editor-token>",
"MCP_TOKEN_ADMIN": "<admin-token>",
"DB_HOST": "localhost",
"DB_PORT": "5432",
"POSTGRES_DB": "stiftung",
"POSTGRES_USER": "stiftung",
"POSTGRES_PASSWORD": "<db-passwort>"
}
}
}
}
Windsurf
Datei: ~/.codeium/windsurf/mcp_config.json:
{
"mcpServers": {
"stiftung": {
"command": "python",
"args": ["-m", "mcp_server"],
"cwd": "/pfad/zum/projekt/app",
"env": {
"DJANGO_SETTINGS_MODULE": "core.settings",
"MCP_AUTH_TOKEN": "<dein-token>",
"MCP_TOKEN_READONLY": "<readonly-token>",
"MCP_TOKEN_EDITOR": "<editor-token>",
"MCP_TOKEN_ADMIN": "<admin-token>",
"DB_HOST": "localhost",
"DB_PORT": "5432",
"POSTGRES_DB": "stiftung",
"POSTGRES_USER": "stiftung",
"POSTGRES_PASSWORD": "<db-passwort>"
}
}
}
}
Docker (empfohlen für Produktion)
docker compose exec mcp python -m mcp_server
Oder als MCP-Client-Konfiguration:
{
"mcpServers": {
"stiftung": {
"command": "docker",
"args": ["compose", "-f", "/pfad/zum/projekt/compose.yml", "exec", "-T", "mcp", "python", "-m", "mcp_server"],
"env": {
"MCP_AUTH_TOKEN": "<dein-token>"
}
}
}
}
Generisch (jeder MCP-kompatible Client)
Transport: stdio (Standard)
# Direkt starten
cd /pfad/zum/projekt/app
MCP_AUTH_TOKEN=<token> \
MCP_TOKEN_READONLY=<readonly> \
MCP_TOKEN_EDITOR=<editor> \
MCP_TOKEN_ADMIN=<admin> \
DB_HOST=localhost \
POSTGRES_DB=stiftung \
POSTGRES_USER=stiftung \
POSTGRES_PASSWORD=<pw> \
python -m mcp_server
Datenschutz
- Alle Aktionen werden im AuditLog erfasst (Quelle:
mcp:<rolle>) - PII-Felder werden bei readonly/editor automatisch maskiert
- Kein Bulk-Export möglich (Ergebnis-Limits pro Abfrage)
- Listen-Abfragen liefern reduzierte Felder
- Der Server läuft im Docker-internen Netzwerk ohne externen Port
Dateistruktur
app/mcp_server/
├── __init__.py # Paket-Marker
├── __main__.py # python -m mcp_server Einstiegspunkt
├── server.py # MCP Server Hauptmodul (Tool-Registrierung)
├── auth.py # Token-Authentifizierung, Rollen-System
├── privacy.py # PII-Maskierung
├── audit.py # AuditLog-Integration
├── start.sh # Shell-Startskript
├── requirements.txt # MCP-spezifische Abhängigkeiten
├── README.md # Diese Datei
└── tools/
├── __init__.py
├── helpers.py # Serialisierung, Model→Dict Konvertierung
├── lesen.py # 14 Lese-Tools
└── schreiben.py # 10 Schreib-Tools
Sicherheitshinweise
- Token niemals im Code oder in Git committen
- Für Produktion: Token in
.env-Datei oder Secret-Manager speichern - Empfohlene Token-Rotation: alle 90 Tage
- Bei Verdacht auf Token-Kompromittierung: sofort rotieren
- Der MCP Server sollte nur im lokalen Netzwerk oder via VPN erreichbar sein