# 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

```bash
# 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:

```bash
# 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

```bash
# Aus dem app/-Verzeichnis:
cd /pfad/zum/projekt/app
MCP_AUTH_TOKEN=<dein-token> python -m mcp_server
```

Oder mit dem Start-Skript:
```bash
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)

```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>"
      }
    }
  }
}
```

### Claude Code (Projekt-spezifisch)

Datei: `.mcp.json` im Projekt-Root:

```json
{
  "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:

```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>"
      }
    }
  }
}
```

### Windsurf

Datei: `~/.codeium/windsurf/mcp_config.json`:

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

```bash
docker compose exec mcp python -m mcp_server
```

Oder als MCP-Client-Konfiguration:

```json
{
  "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)

```bash
# 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
