feat(recipes): implement get_recipes, get_recipe, create_recipe, delete_recipe (v0.6.0)

Adds 4 new MCP tools for the Family Wall recipe box:
- get_recipes: list all family recipes via metasync id='recipe'
- get_recipe: fetch full recipe detail by id (filters from metasync response)
- create_recipe: create a new recipe via mprecipeput (params use 'recipe.' prefix)
- delete_recipe: delete a recipe via metadelete (same endpoint as tasks)

Verified endpoints and parameter names via FW_DEBUG=1 probe scripts.
All 4 tools pass the create → read → get_single → delete integration test.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-16 14:51:53 +02:00
parent 7abe58dee2
commit ebbbf38ab9
7 changed files with 454 additions and 16 deletions
+86
View File
@@ -387,9 +387,95 @@ Operationen.
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.
### `mprecipeput` Rezept erstellen
POST https://api.familywall.com/api/mprecipeput
**Wichtig:** Alle Parameter haben das Präfix `recipe.` (verifiziert via FW_DEBUG=1).
**Body-Parameter:**
| Parameter | Pflicht | Wert |
|---|---|---|
| `recipe.name` | ja | Rezeptname |
| `recipe.isRecipe` | ja | immer `"true"` |
| `recipe.description` | nein | Kurzbeschreibung |
| `recipe.ingredients` | nein | Zutaten als Freitext (Zeilen mit `\n` trennen) |
| `recipe.instructions` | nein | Anleitung als Freitext (Zeilen mit `\n` trennen) |
| `recipe.prepTime` | nein | Zubereitungszeit in Minuten (String, z.B. `"30"`) |
| `recipe.cookTime` | nein | Kochzeit in Minuten (String, z.B. `"60"`) |
| `recipe.serves` | nein | Portionen (String, z.B. `"4"`) |
| `recipe.url` | nein | externe URL |
**Response:**
```
a00.r.r → vollständiges Rezept-Objekt
.metaId → neue Rezept-ID (z.B. "recipe/23431854_10968866")
.name → Rezeptname
.description → Beschreibung
.ingredients → Zutaten Freitext (API liefert \r\n als Zeilenumbrüche)
.ingredientsList[] → auto-geparste Zutaten (read-only, vom Server generiert)
.metaId → "recipeIngredient/<id>"
.name → Zutatname
.instructions → Anleitung Freitext
.prepTime → Zubereitungszeit als String ("30")
.cookTime → Kochzeit als String ("60")
.serves → Portionen als String ("4")
.url → externe URL (fehlt wenn leer)
.isRecipe → "true"
.isFavorite → "false"
.recipeCategories[] → []
.recipeCategoryIdList[] → []
.rights.canDelete → "true" für eigene Rezepte
.rights.canUpdate → "true" für eigene Rezepte
.familyId, .accountId, .creationDate, .moodMap, .moodStarShortcut
```
**Verifiziert am:** 2026-04-16 via FW_DEBUG=1
### `metasync` (id='recipe') Alle Rezepte abrufen
POST https://api.familywall.com/api/metasync
**Body-Parameter:**
| Parameter | Wert |
|---|---|
| `id` | `"recipe"` (lowercase, enum-Wert) |
**Response-Struktur:**
```
a00.r.r.updatedCreated[] → Liste aller Rezepte der Familie
→ Felder identisch mit mprecipeput-Response (siehe oben)
```
**Hinweis:** Der Parameter `id` nimmt einen MetaIdTypeEnum-Wert, kein tatsächliches Objekt.
Nur `"recipe"` (lowercase) funktioniert `"RECIPE"`, `"Recipe"` und andere Schreibweisen
liefern `MetaIdTypeEnum`-Fehler.
**Verifiziert am:** 2026-04-16 via FW_DEBUG=1
### `metadelete` Rezept löschen
POST https://api.familywall.com/api/metadelete
Identisch mit dem Task-Löschen-Endpoint. Funktioniert auch für Rezepte.
**Body-Parameter:**
| Parameter | Wert |
|---|---|
| `id` | Rezept-metaId (z.B. `"recipe/23431854_10968866"`) |
**Response:**
```
a00.r.r → "true" (String)
```
**Verifiziert am:** 2026-04-16 via FW_DEBUG=1
## Offene Punkte
- Unlike-Endpoint (Service Worker blockiert Analyse)
- Erinnerungen (reminder) nur Premium-Account
- Wiederholungen (repeat) nur Premium-Account
- Sortierung von Kategorien via API
- update_recipe (Rezept aktualisieren) Endpoint: mprecipeput mit metaId
- mpadditemtolist (Zutaten aus Rezept → Einkaufsliste)