# mcp-familywall ## Kontext Dieses Projekt entwickelt `mcp-familywall` – einen MCP-Server für den Lesezugriff auf Family Wall (familywall.com). Der MCP-Server läuft lokal und wird in Claude Desktop eingebunden. ## Infrastruktur | | | |---|---| | **Family Wall API** | `https://api.familywall.com/api` | | **Gitea** | `https://gitea.gecheckt.de/marcus/mcp-familywall` | | **Lokaler Code** | `D:\Dev\Projects\mcp-familywall` | | **Sprache** | Python 3.12+, `uv`, MCP SDK, `httpx`, `keyring`, `click`, `rich` | ## Deploy-Workflow (nach jeder Code-Änderung) 1. Claude Code committet und pusht (bei Berechtigungsfehler: bis zu 2 Retries, je 1s warten) ## Aktueller Stand ### Implementierte Tools (v0.4.14) | Kategorie | Tools | |---|---| | Kreise | `get_circles`, `get_members` | | Listen | `get_lists` | | Tasks (Lesen) | `get_tasks` (inkl. `category_id`, `due_date`, `assignee_ids`), `get_categories` (inkl. `custom`-Flag) | | Wall | `get_activities`, `like_post` | | Tasks (Schreiben) | `create_task` (inkl. `category_id`, `due_date`, `assignee_ids`), `update_task` (inkl. `category_id`, `due_date`, `assignee_ids`, `list_id`), `toggle_task`, `delete_task` | | Kategorien (Schreiben) | `create_category` (inkl. `icon`), `delete_category` (System-Kategorien geschützt) | ## Roadmap - v0.x: Erweiterter Lese- + Schreibzugriff ← aktuell - Offen: Unlike (`like_post(like=False)`) ## Referenzprojekt Im Ordner `reference/` liegen Dateien aus einem anderen MCP-Server-Projekt als Orientierung für Struktur und Patterns: | Datei | Zweck | |---|---| | `reference/pyproject.toml` | Projektstruktur, Dependencies, Entry-Points, Build-System | | `reference/config.py` | Config-Pattern: YAML laden, validieren, speichern | | `reference/auth.py` | Keyring-Integration, Credential-Resolution-Reihenfolge | | `reference/cli.py` | Setup-Wizard, check, serve – CLI-Struktur | **Wichtig:** Diese Dateien sind Referenz, kein Copy-Paste. Alle Synology/DSM-spezifischen Teile werden nicht übernommen. Family Wall nutzt ein anderes Auth-Schema – siehe SPEC.md. ## Architektur-Entscheidungen ### Session-Strategie Kein Session-Caching. Jeder Tool-Call führt Login → API-Call → Logout durch. Credentials liegen im OS Keyring (nur `email` + `password`), kein `session_id`. ### Kreise (Scopes) Family Wall kennt mehrere Kreise (z.B. Familie, erweiterter Familienkreis). `get_lists` unterstützt optionalen `scope`-Parameter zur Filterung. Ohne `scope` werden alle Kreise zurückgegeben. ### Listen-Namen Systembezeichnungen (z.B. `SYS-CAT-SHOPPINGLIST`) werden in deutsche Klarnamen übersetzt. Mapping-Tabelle in `modules/lists.py`. ## Claude Code – Implementierungsregeln - Keine destruktiven Operationen in v1.0 → kein Confirmation-Pattern erforderlich - Fehlerbehandlung: API-Fehler als verständliche Meldung zurückgeben, keine Stacktraces - Keine Secrets in stderr-Ausgaben (Passwort bei Debug-Logging maskieren) - Type Hints und Docstrings konsequent verwenden - Formatter: `ruff format`, Linter: `ruff check`, Tests: `pytest` - Alle Texte (Docstrings, Kommentare, README): Englisch - Debug-Logging via `FW_DEBUG=1` Umgebungsvariable - Nach jeder Aufgabe: git commit + push. Bei Berechtigungsfehler: 1s warten, bis zu 2 Retries - .gitignore eigenständig pflegen (Credentials, __pycache__, .venv, .env, *.pyc etc.) - README.md im Projekt-Root pflegen und bei jedem Aufruf aktualisieren ## Implementierungsreihenfolge ### Gruppe 1 – Projektgerüst + Auth + CLI ✦ Prio: hoch - `pyproject.toml`: Package `mcp-familywall`, Entry-Point `mcp-familywall` - `src/mcp_familywall/config.py`: `~/.config/mcp-familywall/config.yaml`, schema_version 1 - `src/mcp_familywall/auth.py`: Keyring-Service `mcp-familywall`, Keys: `email`, `password`. Credential-Resolution: 1. Umgebungsvariablen `FW_EMAIL`, `FW_PASSWORD` 2. OS Keyring - `src/mcp_familywall/fw_client.py`: HTTP-Client mit `httpx`. Methoden: `login()`, `logout()`, `call(endpoint, params)`. Debug-Logging wenn `FW_DEBUG=1` (Passwort maskieren). - `src/mcp_familywall/cli.py`: - `setup`: fragt E-Mail + Passwort, führt Login/Logout durch, speichert Credentials im Keyring, gibt Claude-Desktop-Snippet aus - `check`: testet Auth und API-Erreichbarkeit - `serve`: startet MCP-Server Config-Datei enthält nur: ```yaml schema_version: 1 ``` ### Gruppe 2 – MCP Tools ✦ Prio: hoch `src/mcp_familywall/server.py` + `src/mcp_familywall/modules/lists.py` **`get_circles`** - Ruft `famlistfamily` auf - Gibt alle Kreise zurück: `id`, `name` - Confirmation: nein **`get_lists`** - Signatur: `get_lists(scope: str = None) -> str` - Ruft `accgetallfamily` auf (Parameter: `a01call=taskcategorysync`, `a02call=tasksync`) - Gibt zurück: `id` (metaId), `name` (übersetzt), `type`, offene Einträge, Gesamteinträge, Kreis-Name - Ohne `scope`: alle Kreise; mit `scope`: nur dieser Kreis - Confirmation: nein **`get_tasks`** - Signatur: `get_tasks(list_id: str, only_open: bool = True) -> str` - `list_id`: metaId aus `get_lists` - Gibt zurück: `id`, `text`, `description`, `completed` - Confirmation: nein ## Test-Credentials (nur für Entwicklung) | | | |---|---| | E-Mail | `marcus@gecheckt.de` | | Passwort | `Lasdas1234` | ## Hintergrund Marcus ist Senior Software Engineer (Java, Jakarta EE). Präferenz: State-of-the-Art, Best Practices, saubere Architektur. Automatisierung spart Zeit für die Familie. 🌱