fix(tasks): send recurrency/reminder as flat top-level params (v1.1.1)
FiZ Ai() encoder does not support nested objects — recurrencyDescriptor
and reminder fields must be top-level params (recurrency=WEEKLY, not
recurrencyDescriptor={recurrency:WEEKLY}). Same fix for reminder fields.
SPEC.md and CLAUDE.md updated to document the flat encoding.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -10,6 +10,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
This project follows Semantic Versioning (SemVer).
|
||||
Breaking changes (removed tools, changed parameters) increment the major version.
|
||||
|
||||
## [1.1.1] – 2026-04-17
|
||||
|
||||
### Fixed
|
||||
- `update_task`: recurrency and reminder fields now sent as flat top-level parameters
|
||||
instead of nested objects — the FiZ `Ai()` encoder does not support nested objects;
|
||||
`recurrencyDescriptor`/`reminder` keys are never sent, fields go directly to top level
|
||||
(e.g. `recurrency=WEEKLY`, `reminderUnit=DAY` rather than `recurrencyDescriptor={...}`)
|
||||
- SPEC.md and CLAUDE.md corrected to document the flat encoding
|
||||
|
||||
---
|
||||
|
||||
## [1.1.0] – 2026-04-17
|
||||
|
||||
### Added
|
||||
|
||||
@@ -130,10 +130,11 @@ Fehler bei falschen Parametern kommen nicht immer auf Top-Level:
|
||||
| Endpoint | Parameter | Wert/Format |
|
||||
|---|---|---|
|
||||
| `taskcreate2` | `taskListId`, `text`, `description`, `taskCategoryId`, `dueDate`, `assignee` | – |
|
||||
| `taskupdate2` | `metaId`, `text`, `description`, `taskCategoryId`, `dueDate`, `assignee`, `taskListId`, `recurrencyDescriptor`, `reminder` | – |
|
||||
| `taskupdate2` | `metaId`, `text`, `description`, `taskCategoryId`, `dueDate`, `assignee`, `taskListId` | – |
|
||||
| `taskupdate2` | `dueDate` löschen | `$empty` |
|
||||
| `taskupdate2` | `recurrencyDescriptor` | `{recurrency, recurrencyInterval, rrule, byDay, byMonthDay, recurrencyEndDate, endOccurence}`; löschen: `{recurrency: "NONE"}` |
|
||||
| `taskupdate2` | `reminder` | `{reminderUnit: "MINUTE"\|"HOUR"\|"DAY", reminderValue: int, reminderType: "SNOOZE", localId: 0}`; löschen: `{reminderUnit: "", reminderValue: 0, ...}` |
|
||||
| `taskupdate2` | `recurrencyDescriptor` (flach!) | `recurrency, recurrencyInterval, rrule, byDay, byMonthDay, recurrencyEndDate, endOccurence` als Top-Level-Parameter; löschen: `recurrency="NONE"` |
|
||||
| `taskupdate2` | `reminder` (flach!) | `reminderUnit: "MINUTE"\|"HOUR"\|"DAY", reminderValue: int, reminderType: "SNOOZE", localId: 0` als Top-Level-Parameter; löschen: `reminderUnit=""` |
|
||||
| `taskupdate2` | **⚠️ Encoding** | FiZ `Ai()`-Encoder sendet alle Felder flach — KEINE verschachtelten Objekte für recurrencyDescriptor/reminder! |
|
||||
| `taskmark` | `taskId`, `complete` | `"true"`/`"false"` |
|
||||
| `metadelete` | `id` | metaId des Tasks / Rezepts |
|
||||
| `wallmood` | `wall_message_id`, `moodType` | `"STAR"` für Like |
|
||||
|
||||
@@ -201,35 +201,23 @@ POST https://api.familywall.com/api/taskupdate2
|
||||
| `dueDate` | nein | ISO 8601 oder `$empty` zum Löschen |
|
||||
| `assignee` | nein | Member-accountId (mehrfach sendbar), `""` zum Entfernen aller |
|
||||
| `taskListId` | nein | neue Listen-metaId (verschiebt Task) |
|
||||
| `recurrencyDescriptor` | nein | Objekt mit Wiederholungs-Feldern (siehe unten) |
|
||||
| `reminder` | nein | Objekt mit Erinnerungs-Feldern (siehe unten) |
|
||||
| `recurrency` | nein | `"DAILY"` \| `"WEEKLY"` \| `"MONTHLY"` \| `"YEARLY"` \| `"NONE"` (entfernen) |
|
||||
| `recurrencyInterval` | nein | int (z.B. `2` für "alle 2 Wochen") |
|
||||
| `rrule` | nein | vollständige iCal-RRULE (z.B. `"FREQ=WEEKLY;INTERVAL=2;BYDAY=FR"`) |
|
||||
| `byDay` | nein | z.B. `"FR"`, `"1SA"`, `"MO,TU,WE,TH,FR"` |
|
||||
| `byMonthDay` | nein | int (z.B. `7` für "am 7. des Monats") |
|
||||
| `recurrencyEndDate` | nein | ISO-Datum (z.B. `"2026-12-31"`) |
|
||||
| `endOccurence` | nein | int (nach N Wiederholungen aufhören) |
|
||||
| `reminderUnit` | nein | `"MINUTE"` \| `"HOUR"` \| `"DAY"` (löschen: `""`) |
|
||||
| `reminderValue` | nein | int (`0` = zum Zeitpunkt, `15` = 15 min vorher); löschen: `0` |
|
||||
| `reminderType` | nein | immer `"SNOOZE"` |
|
||||
| `localId` | nein | immer `0` |
|
||||
|
||||
**Hinweis:** `taskListId` ist NICHT Pflicht beim Update.
|
||||
|
||||
**`recurrencyDescriptor`-Felder** (verifiziert via JS-Bundle xb-Encoder):
|
||||
|
||||
| Feld | Wert |
|
||||
|---|---|
|
||||
| `recurrency` | `"DAILY"` \| `"WEEKLY"` \| `"MONTHLY"` \| `"YEARLY"` \| `"NONE"` |
|
||||
| `recurrencyInterval` | int (z.B. `2` für "alle 2 Wochen") |
|
||||
| `rrule` | vollständige iCal-RRULE (z.B. `"FREQ=WEEKLY;INTERVAL=2;BYDAY=FR"`) |
|
||||
| `byDay` | z.B. `"FR"`, `"1SA"`, `"MO,TU,WE,TH,FR"` |
|
||||
| `byMonthDay` | int (z.B. `7` für "am 7. des Monats") |
|
||||
| `recurrencyEndDate` | ISO-Datum (z.B. `"2026-12-31"`) |
|
||||
| `endOccurence` | int (nach N Wiederholungen aufhören) |
|
||||
|
||||
Wiederholung entfernen: `recurrencyDescriptor = {"recurrency": "NONE"}`
|
||||
|
||||
**`reminder`-Felder** (verifiziert via JS-Bundle fc-Encoder):
|
||||
|
||||
| Feld | Wert |
|
||||
|---|---|
|
||||
| `reminderUnit` | `"MINUTE"` \| `"HOUR"` \| `"DAY"` |
|
||||
| `reminderValue` | int (`0` = zum Zeitpunkt, `15` = 15 min vorher, `1` = 1 Einheit vorher) |
|
||||
| `reminderType` | immer `"SNOOZE"` |
|
||||
| `localId` | immer `0` |
|
||||
|
||||
Erinnerung entfernen: `reminder = {"reminderUnit": "", "reminderValue": 0, "reminderType": "SNOOZE", "localId": 0}`
|
||||
**⚠️ Encoding:** Der FiZ-`Ai()`-Encoder serialisiert alle Felder **flach** als Top-Level-Form-Parameter.
|
||||
`recurrencyDescriptor` und `reminder` sind **keine** verschachtelten JSON-Objekte — die Felder
|
||||
werden direkt auf Top-Level gesendet (verifiziert via xb-Encoder / fc-Encoder im JS-Bundle).
|
||||
|
||||
**Response:**
|
||||
```
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
||||
|
||||
[project]
|
||||
name = "mcp-familywall"
|
||||
version = "1.1.0"
|
||||
version = "1.1.1"
|
||||
description = "MCP server for Family Wall — manage your family's circles, lists, tasks, recipes, and meal plan via Claude"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.12"
|
||||
|
||||
@@ -1027,32 +1027,28 @@ def update_task(
|
||||
if list_id is not None:
|
||||
params["taskListId"] = list_id
|
||||
|
||||
recurrency_descriptor: dict[str, Any] = {}
|
||||
# The FiZ Ai() encoder serialises all fields flat at the top level of the
|
||||
# request body — nested objects are NOT supported. recurrencyDescriptor and
|
||||
# reminder fields must therefore be sent as plain top-level parameters.
|
||||
if clear_recurrency:
|
||||
recurrency_descriptor["recurrency"] = "NONE"
|
||||
params["recurrency"] = "NONE"
|
||||
elif recurrency is not None:
|
||||
recurrency_descriptor["recurrency"] = recurrency
|
||||
params["recurrency"] = recurrency
|
||||
if recurrency_interval is not None:
|
||||
recurrency_descriptor["recurrencyInterval"] = recurrency_interval
|
||||
params["recurrencyInterval"] = recurrency_interval
|
||||
if rrule is not None:
|
||||
recurrency_descriptor["rrule"] = rrule
|
||||
if recurrency_descriptor:
|
||||
params["recurrencyDescriptor"] = recurrency_descriptor
|
||||
params["rrule"] = rrule
|
||||
|
||||
if clear_reminder:
|
||||
params["reminder"] = {
|
||||
"reminderUnit": "",
|
||||
"reminderValue": 0,
|
||||
"reminderType": "SNOOZE",
|
||||
"localId": 0,
|
||||
}
|
||||
params["reminderUnit"] = ""
|
||||
params["reminderValue"] = 0
|
||||
params["reminderType"] = "SNOOZE"
|
||||
params["localId"] = 0
|
||||
elif reminder_unit is not None and reminder_value is not None:
|
||||
params["reminder"] = {
|
||||
"reminderUnit": reminder_unit,
|
||||
"reminderValue": reminder_value,
|
||||
"reminderType": "SNOOZE",
|
||||
"localId": 0,
|
||||
}
|
||||
params["reminderUnit"] = reminder_unit
|
||||
params["reminderValue"] = reminder_value
|
||||
params["reminderType"] = "SNOOZE"
|
||||
params["localId"] = 0
|
||||
|
||||
try:
|
||||
_authenticated_call("taskupdate2", params)
|
||||
|
||||
Reference in New Issue
Block a user