Files
mcp-familywall/SPEC.md
T
marcus 5aff3ac9bf feat: add Task CRUD tools – create, update, toggle, delete (v0.4.0)
Implements four new MCP write tools via taskcreate2, taskupdate2,
taskmark, and metadelete endpoints. Confirmation prompts noted in
docstrings for destructive/mutating operations. Body parameters
documented in SPEC.md as pending verification via FW_DEBUG=1.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 15:06:38 +02:00

261 lines
8.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Family Wall API Spezifikation
Erarbeitet durch Browser-Traffic-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` | nicht senden — wird als `undefined` ignoriert (verifiziert per JS-Analyse) |
| `clientId` | weglassen |
| `clientSecret` | weglassen |
| `generateAutologinToken` | weglassen |
| `countryCode` | weglassen |
**Response (Erfolg):**
```json
{ "a00": { "r": { "r": <SessionObject> }, "cn": "log2in" } }
```
`SessionObject` enthält u.a. `tokenCsrf` und `webApiUrl`.
`tokenCsrf` ist die Session-ID identisch zur `JSESSIONID` im Cookie.
**Response (Fehler):**
```json
{ "ex": { "ex": <ErrorObject> } }
{ "un": { "un": <ErrorObject> } }
```
Der Server setzt nach erfolgreichem Login ein Session-Cookie:
Set-Cookie: JSESSIONID=<session-id> (= tokenCsrf)
### Folgecalls (nach Login)
Alle API-Calls nach dem Login benötigen:
| | |
|---|---|
| **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
Content-Type: application/x-www-form-urlencoded
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
POST /api/log2out → Session invalidieren
Credentials (E-Mail + Passwort) werden einmalig via `mcp-familywall setup`
im OS Keyring gespeichert (Keys: `email`, `password`). Kein Keyring-Eintrag
für `session_id`.
## Bekannte Endpoints
### `famlistfamily` Kreise abrufen
POST https://api.familywall.com/api/famlistfamily
Content-Type: application/x-www-form-urlencoded
**Body-Parameter:** keine (verifiziert)
**Response-Struktur (verifiziert):**
```
a00.r.r[] → Kreise
.metaId → eindeutige Kreis-ID
.name → Kreisname
```
### `taskgettasklists` Listen abrufen
POST https://api.familywall.com/api/taskgettasklists
Content-Type: application/x-www-form-urlencoded
**Body-Parameter:** keine
**Response-Struktur:** zu verifizieren beim ersten echten Call
### `accgetallfamily` Listen + Tasks abrufen
POST https://api.familywall.com/api/accgetallfamily
Content-Type: application/x-www-form-urlencoded
**Body-Parameter:**
| Parameter | Wert |
|---|---|
| `a01call` | `"taskcategorysync"` |
| `a02call` | `"tasksync"` |
Hinweis: `a03call=tasklistsync` ist **kein gültiger Endpoint** — API antwortet mit
"The call tasklistsync is not registered". Nicht verwenden.
`partnerScope`, `a03id`, `withStateBean` werden weggelassen.
**Response-Struktur (verifiziert):**
```
a00 → famlistfamily-Daten (Kreise) Nebeneffekt, nicht verwendet
a01.r.r.updatedCreated[] → taskcategorysync (Einkaufskategorien/Abteilungen)
.sortingIndexByTaskList → dict, Keys = Listen-IDs (z.B. "taskList/23431854_29740942")
→ Quelle der Listen-IDs (Namen/Zähler noch unbekannt)
a02.r.r.updatedCreated[] → tasksync (Tasks)
.metaId → eindeutige Task-ID
.text → Aufgabentext
.description → optionale Beschreibung
.taskListId → Zugehörigkeit zur Liste (= Listen-ID aus sortingIndexByTaskList)
.complete → "true" / "false" (String, nicht Boolean!)
```
## Systembezeichnungen für Listen-Namen
Bekannte Systembezeichnungen werden deutsch übersetzt:
| Systembezeichnung | Deutsch |
|---|---|
| `SYS-CAT-SHOPPINGLIST` | `Einkaufsliste` |
Unbekannte Bezeichnungen werden unverändert zurückgegeben.
Mapping-Tabelle bei Bedarf erweitern.
### `wallget` Aktivitäten (Wall) abrufen
POST https://api.familywall.com/api/wallget
Content-Type: application/x-www-form-urlencoded
**Body-Parameter:**
| Parameter | Wert |
|---|---|
| `nb` | Anzahl Einträge (z.B. `"20"`) |
| `date` | optional, für Paginierung (Datum des letzten Eintrags) |
| `accountId` | optional |
| `type` | optional |
| `nested` | optional |
| `masterNested` | optional |
| `sortBy` | optional |
**Response-Struktur (verifiziert):**
```
a00.r.r[]
.metaId → ID der Aktivität (= wallMessageId)
.refType → Aktivitätstyp (z.B. STATUS, FAMILY_CREATED)
.text → Text (optional, fehlt bei System-Events)
.creationDate → Datum (ISO 8601)
.accountId → Autor-ID
```
**Response-Struktur:** zu verifizieren beim ersten echten Call
### `wallactivityget` Einzelne Aktivität abrufen
POST https://api.familywall.com/api/wallactivityget
Content-Type: application/x-www-form-urlencoded
**Body-Parameter:**
| Parameter | Wert |
|---|---|
| `accountId` | optional |
| `masterNested` | optional |
**Response-Struktur:** zu verifizieren beim ersten echten Call
(Endpoint noch nicht implementiert — für spätere Versionen)
## Debug-Logging
Wenn die Umgebungsvariable `FW_DEBUG=1` gesetzt ist, loggt `fw_client.py`
vollständige Request-Bodies und Responses nach stderr. Dient zur Verifikation
offener Punkte (z.B. `type`-Parameter beim Login, Kreis-Felder in Response).
**Wichtig:** Keine Secrets in Debug-Ausgaben (Passwort maskieren).
### `taskcreate2` Task erstellen
POST https://api.familywall.com/api/taskcreate2
Content-Type: application/x-www-form-urlencoded
**Body-Parameter (aus API-Pattern abgeleitet, zu verifizieren):**
| Parameter | Pflicht | Wert |
|---|---|---|
| `taskListId` | ja | Listen-ID aus `get_lists` (z.B. `taskList/123_456`) |
| `text` | ja | Aufgabentitel |
| `description` | nein | Optionale Beschreibung |
**Response-Struktur (zu verifizieren):**
```
a00.r.r.metaId → metaId der neu erstellten Task
```
### `taskupdate2` Task aktualisieren
POST https://api.familywall.com/api/taskupdate2
Content-Type: application/x-www-form-urlencoded
**Body-Parameter (aus API-Pattern abgeleitet, zu verifizieren):**
| Parameter | Pflicht | Wert |
|---|---|---|
| `metaId` | ja | Task-ID aus `get_tasks` |
| `text` | nein | Neuer Titel (mindestens `text` oder `description` erforderlich) |
| `description` | nein | Neue Beschreibung |
| `taskListId` | unklar | Evtl. erforderlich zu verifizieren |
**Response-Struktur:** kein spezifischer Rückgabewert erwartet (Erfolg = kein `ex`/`un`-Key)
### `taskmark` Task als erledigt/offen markieren
POST https://api.familywall.com/api/taskmark
Content-Type: application/x-www-form-urlencoded
**Body-Parameter (aus API-Pattern abgeleitet, zu verifizieren):**
| Parameter | Pflicht | Wert |
|---|---|---|
| `metaId` | ja | Task-ID aus `get_tasks` |
| `complete` | ja | `"true"` oder `"false"` (String, nicht Boolean!) |
**Response-Struktur:** kein spezifischer Rückgabewert erwartet (Erfolg = kein `ex`/`un`-Key)
### `metadelete` Objekt löschen (Task)
POST https://api.familywall.com/api/metadelete
Content-Type: application/x-www-form-urlencoded
**Body-Parameter (aus API-Pattern abgeleitet, zu verifizieren):**
| Parameter | Pflicht | Wert |
|---|---|---|
| `metaId` | ja | Task-ID aus `get_tasks` |
Hinweis: `metadelete` ist ein generischer Lösch-Endpoint. Er löscht jedes Objekt
mit der angegebenen `metaId` nicht nur Tasks. Entsprechend vorsichtig verwenden.
**Response-Struktur:** kein spezifischer Rückgabewert erwartet (Erfolg = kein `ex`/`un`-Key)
## Noch zu verifizieren
- ~~Exakter Wert für `type`-Parameter beim Login~~ → nicht senden (verifiziert per JS-Analyse)
- ~~Response-Struktur von `famlistfamily` (Kreise)~~ → a00.r.r[], metaId + name (verifiziert)
- ~~Ob `a03call=tasklistsync` benötigt wird~~ → **nein**, kein gültiger Endpoint (verifiziert)
- Listen-IDs aus `a01.r.r.updatedCreated[].sortingIndexByTaskList`-Keys (verifiziert)
- Listen-Namen und Zähler (remainingTaskNumber, totalTaskNumber) → noch unbekannt
- Kreis-Zuordnung in `accgetallfamily`-Response → noch offen
- ~~Ob `partnerScope` / `withStateBean` benötigt werden~~ → nein (verifiziert)
- Session-Lebensdauer (irrelevant da kein Caching)
- `taskcreate2`: genaue Response-Struktur (metaId-Pfad), ob weitere Pflichtfelder existieren
- `taskupdate2`: ob `taskListId` Pflichtfeld ist; Response-Struktur
- `taskmark`: Response-Struktur
- `metadelete`: Response-Struktur, welche Objekt-Typen unterstützt werden