feat(meal-planner): structured output for add_recipe_to_meal_plan (v0.11.1)

Map verified mpcreateByRecipeId response (a00.r.r dish object) to the
same field layout as get_meal_plan entries. is_from_recipe_box is always
true since this tool only creates recipe-box entries.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-17 11:52:16 +02:00
parent e7e242151f
commit d344251796
6 changed files with 48 additions and 9 deletions
+3 -2
View File
@@ -24,7 +24,7 @@ und wird in Claude Desktop eingebunden.
## Aktueller Stand
### Implementierte Tools (v0.11.0)
### Implementierte Tools (v0.11.1)
| Kategorie | Tools |
|---|---|
@@ -63,7 +63,8 @@ und wird in Claude Desktop eingebunden.
- v0.10.1: get_meal_plan strukturierter Output + SPEC.md mplistinterval Response verifiziert ✓
- v0.10.2: get_meal_plan mealList[] einbinden (Freitext-Notizen + Portionen), merged + sortiert ✓
- v0.10.3: get_meal_plan is_from_recipe_box Feld (recipeList[].isRecipe Lookup) ✓
- v0.11.0: add_recipe_to_meal_plan (mpcreateByRecipeId; raw response bis Struktur verifiziert) ✓ ← aktuell
- v0.11.0: add_recipe_to_meal_plan (mpcreateByRecipeId; raw response bis Struktur verifiziert) ✓
- v0.11.1: add_recipe_to_meal_plan strukturierter Output (Response verifiziert) ✓ ← aktuell
- v2.0: Schreibzugriff auf Wall-Posts (Erstellen, Kommentieren)
+1 -1
View File
@@ -2,7 +2,7 @@
MCP server for [Family Wall](https://www.familywall.com) -- read and manage your family's circles, lists, tasks, and recipes directly from Claude.
## Features (v0.11.0)
## Features (v0.11.1)
### Read
+16 -2
View File
@@ -734,9 +734,23 @@ POST https://api.familywall.com/api/mpcreateByRecipeId
| `type` | ja | Mahlzeiten-Typ: `BREAKFAST`, `LUNCH`, `SNACK`, `DINNER` |
| `clientOpId` | nein | Optionale Client-seitige Idempotenz-ID (wird weggelassen) |
**Response-Struktur:** TBD — Tool liefert Raw JSON zur Verifizierung (→ v0.11.1).
**Response-Struktur:**
```
a00.r.r → vollständiges dish-Objekt
.metaId → neue Dish-ID (z.B. "dish/16282169_20009811")
.date → Datum (z.B. "2026-04-18")
.type → Mahlzeiten-Typ (BREAKFAST/LUNCH/SNACK/DINNER)
.name → Rezeptname
.recipeId → verknüpfte Rezept-metaId
.familyId → Kreis-metaId
.accountId → Ersteller-accountId
.sortingIndex → Sortierung (numerischer Timestamp als String)
.rights.canUpdate → "true"
.rights.canDelete → "true"
a00.cn → "mpcreateByRecipeId" (Endpoint-Echo)
```
**Verifiziert am:** 2026-04-17 (Parameter aus JS-Bundle; Response TBD)
**Verifiziert am:** 2026-04-17 via FW_DEBUG=1
### Weitere Meal Planner Endpoints (nicht implementiert)
+1 -1
View File
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
[project]
name = "mcp-familywall"
version = "0.11.0"
version = "0.11.1"
description = "MCP server for Family Wall — read your family's lists and tasks via Claude"
readme = "README.md"
requires-python = ">=3.12"
+1 -1
View File
@@ -1 +1 @@
__version__ = "0.11.0"
__version__ = "0.11.1"
+26 -2
View File
@@ -2359,8 +2359,32 @@ def add_recipe_to_meal_plan(
except RuntimeError as exc:
return f"Error: {exc}"
# Return raw response until the structure is verified in production.
return json.dumps(data, ensure_ascii=False, indent=2)
try:
dish = data["a00"]["r"]["r"]
if not isinstance(dish, dict) or "metaId" not in dish:
raise TypeError("unexpected shape")
except (KeyError, TypeError):
return json.dumps(
{"warning": "Unexpected mpcreateByRecipeId response structure", "raw": data},
ensure_ascii=False,
indent=2,
)
rights = dish.get("rights") or {}
result: dict[str, Any] = {
"id": dish.get("metaId"),
"date": dish.get("date"),
"type": dish.get("type"),
"name": dish.get("name"),
"recipe_id": dish.get("recipeId") or None,
# mpcreateByRecipeId always creates entries from the recipe box.
"is_from_recipe_box": True,
"note": None,
"serves": None,
"can_update": rights.get("canUpdate") == "true",
"can_delete": rights.get("canDelete") == "true",
}
return json.dumps(result, ensure_ascii=False, indent=2)
# ---------------------------------------------------------------------------