Files
mcp-familywall/SPEC.md
T
2026-04-16 11:11:48 +02:00

9.5 KiB
Raw Blame History

Family Wall API Spezifikation

Erarbeitet durch Browser-Traffic-Analyse und React-Fiber-Analyse (April 2026). Es gibt keine offizielle API-Dokumentation.

Base URL

https://api.familywall.com/api

Authentifizierung

Login

POST https://api.familywall.com/api/log2in Content-Type: application/x-www-form-urlencoded

Request-Parameter:

Parameter Wert
identifier E-Mail-Adresse
password Passwort
type "email" (verifiziert)

Response (Erfolg):

{ "r": { "r": <SessionObject> } }

Response (Fehler):

{ "ex": { "ex": <ErrorObject> } }
{ "un": { "un": <ErrorObject> } }

Der Server setzt nach erfolgreichem Login ein Session-Cookie: Set-Cookie: JSESSIONID=<session-id>

Folgecalls (nach Login)

Cookie JSESSIONID=<session-id>
Header Tokencsrf: <session-id> (identisch zur JSESSIONID)
Content-Type application/x-www-form-urlencoded

Logout

POST https://api.familywall.com/api/log2out

Keine Parameter. Session wird serverseitig invalidiert.

Session-Strategie

Kein Session-Caching. Jeder MCP-Tool-Call führt folgende Sequenz aus:

POST /api/log2in        → Session-ID
POST /api/<endpoint>    → Nutzdaten (ggf. mehrere Calls in einer Session)
POST /api/log2out       → Session invalidieren

Credentials (E-Mail + Passwort) werden einmalig via mcp-familywall setup im OS Keyring gespeichert (Keys: email, password).

Fehlerbehandlung

Silent-Fail Warnung

Die API gibt Fehler manchmal NICHT auf Top-Level zurück, sondern eingebettet:

{"a00": {"un": {"un": {"message": "missing value in: taskId"}}}}

fw_client.py prüft beide Ebenen (a00.un.un und Top-Level ex/un) und wirft FamilyWallError. Nie eine Response als Erfolg werten ohne beide Fehlerebenen zu prüfen.

Sentinel-Wert $empty

Das FiZ-Server-Framework nutzt $empty als Sentinel-String um optionale Felder zu löschen. Alle anderen Werte ("", null, "null", "0", "-1", "remove", "clear", Epoch-Timestamps) werden vom Server mit "is not a valid Date" abgelehnt.

Aktuell genutzt für:

  • dueDate=$empty → löscht Fälligkeitsdatum in taskupdate2

Gefunden durch: React-Fiber-Analyse des nativen datetime-local-Inputs nach Klick auf "Löschen" im Custom-Datepicker wird der Input-Wert auf "$empty" gesetzt, was beim Speichern an die API gesendet wird.

Bekannte Endpoints

famlistfamily Kreise + Mitglieder abrufen

POST https://api.familywall.com/api/famlistfamily

Body-Parameter: keine

Response-Struktur:

a00.r.r[]               → Kreise
  .metaId               → Kreis-ID (z.B. "family/23431854")
  .name                 → Kreis-Name
  .members[]            → Mitglieder des Kreises
    .accountId          → numerische User-ID
    .firstName          → Anzeigename (bevorzugen)
    .name               → E-Mail als Fallback
    .role               → Familienrolle (Parent/Child/Unknown)
    .right              → Berechtigung (SuperAdmin etc.)
    .color              → Profilfarbe (#RRGGBB)
    .medias[0].pictureUrl → Avatar-URL
    .identifiers[type=Email].value → E-Mail-Adresse

accgetallfamily Listen, Tasks, Kategorien abrufen

POST https://api.familywall.com/api/accgetallfamily

Body-Parameter:

Parameter Wert
a01call "taskcategorysync"
a02call "tasksync"

Response-Struktur:

a00.r.r[]                   → Kategorien (taskcategorysync)
  .metaId                   → Kategorie-ID
  .name                     → Kategoriename (Systembezeichnung)
  .taskListType             → SHOPPING_LIST oder TODOS
  .sortingIndexByTaskList   → Sortierreihenfolge pro Liste
  .rights.canDelete         → "true" = custom, null = System
  .locale                   → Sprachcode (de/en/fr/...), fehlt bei custom

a02.r.r.updatedCreated[]    → Tasks (tasksync)
  .metaId                   → Task-ID
  .text                     → Aufgabentext
  .description              → optionale Beschreibung
  .taskListId               → Listen-ID
  .complete                 → "true" / "false" (String!)
  .taskCategoryId           → Kategorie-ID (optional)
  .dueDate                  → Fälligkeitsdatum (ISO 8601, optional)
  .assignee[]               → Liste von Member-IDs (optional)
  .assigneeIds[]            → alternativ zu assignee[]

wallget Wall-Aktivitäten abrufen

POST https://api.familywall.com/api/wallget

Response-Struktur:

a00.r.r[]
  .metaId                   → Post-ID (z.B. "wall/23431854_31119189")
  .type                     → STATUS, FAMILY_CREATED, etc.
  .text                     → Post-Text
  .modifDate                → Timestamp (ISO 8601)
  .creator.accountId        → Author-ID
  .moodMap                  → {"<accountId>": ["STAR"]} für Likes
  .moodStarShortcut         → true wenn geliked
  .comments[]               → Kommentare

taskcreate2 Task erstellen

POST https://api.familywall.com/api/taskcreate2

Body-Parameter:

Parameter Pflicht Wert
taskListId ja Listen-metaId
text ja Aufgabentext
description nein Beschreibung
taskCategoryId nein Kategorie-metaId (vollständig, z.B. taskCategory/23431854_200)
dueDate nein ISO 8601 (z.B. 2026-04-30T18:00:00)
assignee nein Member-accountId, mehrfach sendbar für mehrere Zuweisungen

Response:

a00.r.r                     → vollständiges Task-Objekt
  .metaId                   → neue Task-ID

taskupdate2 Task aktualisieren

POST https://api.familywall.com/api/taskupdate2

Body-Parameter:

Parameter Pflicht Wert
metaId ja Task-metaId
text nein neuer Titel
description nein neue Beschreibung
taskCategoryId nein neue Kategorie-metaId
dueDate nein ISO 8601 oder $empty zum Löschen
assignee nein Member-accountId (mehrfach sendbar), "" zum Entfernen aller
taskListId nein neue Listen-metaId (verschiebt Task)

Hinweis: taskListId ist NICHT Pflicht beim Update.

Response:

a00.r.r                     → vollständiges Task-Objekt

taskmark Task abhaken/wiedereröffnen

POST https://api.familywall.com/api/taskmark

Body-Parameter:

Parameter Wert
taskId Task-metaId ⚠️ nicht metaId!
complete "true" oder "false" (String!)

Response:

a00.r.r                     → Task-Objekt mit lastAction: "MARK_COMPLETED"

metadelete Task löschen

POST https://api.familywall.com/api/metadelete

Body-Parameter:

Parameter Wert
id Task-metaId ⚠️ nicht metaId!

Response:

a00.r.r                     → "true" (String)

wallmood Post liken

POST https://api.familywall.com/api/wallmood

Body-Parameter:

Parameter Wert
wall_message_id Post-metaId ⚠️ nicht wallId oder id!
moodType "STAR" für Like

Bekannte Einschränkungen:

  • Unlike: Endpoint/Parameter unbekannt (Service Worker verschlüsselt Request-Body)
  • Self-Like: API antwortet 200, macht aber serverseitig nichts
  • moodType="NONE" und andere Werte haben keine Wirkung

Response:

a00.r.r                     → Wall-Objekt mit moodMap, refAction: "MOOD_STAR"

taskcategoryput Kategorie erstellen/aktualisieren

POST https://api.familywall.com/api/taskcategoryput

Body-Parameter:

Parameter Pflicht Wert
name ja Kategoriename
emoji nein Unicode-Emoji oder beliebiger String

Hinweis: Kategorien sind family-wide listId hat keine Wirkung.

Response:

a00.r.r                     → Kategorie-Objekt mit metaId

taskcategorydelete Kategorie löschen

POST https://api.familywall.com/api/taskcategorydelete

Body-Parameter:

Parameter Wert
id Kategorie-metaId ⚠️ nicht metaId!

Hinweis: System-Kategorien (rights.canDelete=null) können technisch gelöscht werden, sind dann aber dauerhaft weg und nicht wiederherstellbar. MCP-Server schützt dagegen durch Check auf rights.canDelete.

taskgettasklists Listen abrufen (alternativ)

POST https://api.familywall.com/api/taskgettasklists

Wird intern zur Verifikation von taskListType genutzt.

Systembezeichnungen für Listen-Namen

Systembezeichnung Deutsch
SYS-CAT-SHOPPINGLIST Einkaufsliste
SYS-CAT-TODOLIST Aufgaben

Debug-Logging

Wenn die Umgebungsvariable FW_DEBUG=1 gesetzt ist, loggt fw_client.py vollständige Request-Bodies und Responses nach stderr.

Wichtig: Keine Secrets in Debug-Ausgaben (Passwort maskieren).

Wann FW_DEBUG=1 nutzen:

  • Neue Endpoints verifizieren
  • Parameter-Namen unbekannt
  • Silent-Fail debuggen
  • Service Worker blockiert Browser-DevTools

Service Worker

Die Family Wall Web-App registriert einen Service Worker der bestimmte HTTP-Requests abfängt und modifiziert bevor sie das Netzwerk erreichen. Betroffen sind u.a. Unlike-Calls und möglicherweise andere schreibende Operationen.

Folge: Browser-DevTools Network-Tab und JS-Interceptoren (XHR/Fetch) zeigen nicht den echten Request-Body für diese Calls. Lösung: FW_DEBUG=1 auf MCP-Server-Seite zeigt was tatsächlich gesendet wird.

Offene Punkte

  • Unlike-Endpoint (Service Worker blockiert Analyse)
  • Erinnerungen (reminder) nur Premium-Account
  • Wiederholungen (repeat) nur Premium-Account
  • Sortierung von Kategorien via API