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:
@@ -24,7 +24,7 @@ und wird in Claude Desktop eingebunden.
|
|||||||
|
|
||||||
## Aktueller Stand
|
## Aktueller Stand
|
||||||
|
|
||||||
### Implementierte Tools (v0.11.0)
|
### Implementierte Tools (v0.11.1)
|
||||||
|
|
||||||
| Kategorie | Tools |
|
| 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.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.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.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)
|
- v2.0: Schreibzugriff auf Wall-Posts (Erstellen, Kommentieren)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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.
|
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
|
### Read
|
||||||
|
|
||||||
|
|||||||
@@ -734,9 +734,23 @@ POST https://api.familywall.com/api/mpcreateByRecipeId
|
|||||||
| `type` | ja | Mahlzeiten-Typ: `BREAKFAST`, `LUNCH`, `SNACK`, `DINNER` |
|
| `type` | ja | Mahlzeiten-Typ: `BREAKFAST`, `LUNCH`, `SNACK`, `DINNER` |
|
||||||
| `clientOpId` | nein | Optionale Client-seitige Idempotenz-ID (wird weggelassen) |
|
| `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)
|
### Weitere Meal Planner Endpoints (nicht implementiert)
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "mcp-familywall"
|
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"
|
description = "MCP server for Family Wall — read your family's lists and tasks via Claude"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
requires-python = ">=3.12"
|
requires-python = ">=3.12"
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
__version__ = "0.11.0"
|
__version__ = "0.11.1"
|
||||||
|
|||||||
@@ -2359,8 +2359,32 @@ def add_recipe_to_meal_plan(
|
|||||||
except RuntimeError as exc:
|
except RuntimeError as exc:
|
||||||
return f"Error: {exc}"
|
return f"Error: {exc}"
|
||||||
|
|
||||||
# Return raw response until the structure is verified in production.
|
try:
|
||||||
return json.dumps(data, ensure_ascii=False, indent=2)
|
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)
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|||||||
Reference in New Issue
Block a user