feat: Gruppe 1 – Projektgerüst, Auth, CLI (v0.1.0)
- pyproject.toml: hatchling build, mcp-familywall entry-point, deps - src/mcp_familywall/__init__.py: version 0.1.0 - src/mcp_familywall/config.py: YAML config loader (schema_version: 1) - src/mcp_familywall/auth.py: keyring credential resolution (FW_EMAIL/FW_PASSWORD → keyring) - src/mcp_familywall/fw_client.py: httpx client, login/logout/call, FW_DEBUG logging - src/mcp_familywall/cli.py: click CLI with setup / check / serve commands - .gitignore, README.md, CLAUDE.md, SPEC.md Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,137 @@
|
||||
# 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` | zu verifizieren beim ersten echten Login-Call (vermutlich `"email"`) |
|
||||
| `clientId` | weglassen |
|
||||
| `clientSecret` | weglassen |
|
||||
| `generateAutologinToken` | weglassen |
|
||||
| `countryCode` | weglassen |
|
||||
|
||||
**Response (Erfolg):**
|
||||
|
||||
```json
|
||||
{ "r": { "r": <SessionObject> } }
|
||||
```
|
||||
|
||||
**Response (Fehler):**
|
||||
|
||||
```json
|
||||
{ "ex": { "ex": <ErrorObject> } }
|
||||
{ "un": { "un": <ErrorObject> } }
|
||||
```
|
||||
|
||||
Der Server setzt nach erfolgreichem Login ein Session-Cookie:
|
||||
Set-Cookie: JSESSIONID=<session-id>
|
||||
|
||||
### 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 (zu verifizieren beim ersten echten Call)
|
||||
|
||||
**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: `partnerScope`, `a03call`, `a03id`, `withStateBean` werden
|
||||
weggelassen. Falls der Server sie erfordert, beim ersten echten Call
|
||||
nachbessern.
|
||||
|
||||
**Response-Struktur (relevant für v1.0):**
|
||||
a00.r.r[] → Listen (taskcategorysync)
|
||||
.metaId → eindeutige Listen-ID
|
||||
.name → Name (ggf. Systembezeichnung, s.u.)
|
||||
.taskListType → Typ der Liste
|
||||
.remainingTaskNumber → offene Einträge (String)
|
||||
.totalTaskNumber → Gesamteinträge (String)
|
||||
.<Kreis-Feld> → zu verifizieren beim ersten echten Call
|
||||
a02.r.r.updatedCreated[] → Tasks (tasksync)
|
||||
.metaId → eindeutige Task-ID
|
||||
.text → Aufgabentext
|
||||
.description → optionale Beschreibung
|
||||
.taskListId → Zugehörigkeit zur Liste (= metaId der Liste)
|
||||
.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.
|
||||
|
||||
## 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).
|
||||
|
||||
## Noch zu verifizieren
|
||||
|
||||
- Exakter Wert für `type`-Parameter beim Login
|
||||
- Response-Struktur von `famlistfamily` (Kreise)
|
||||
- Kreis-Zuordnung in `accgetallfamily`-Response
|
||||
- Ob `partnerScope` / `withStateBean` benötigt werden
|
||||
- Session-Lebensdauer (irrelevant da kein Caching)
|
||||
Reference in New Issue
Block a user