diff --git a/README.md b/README.md index 82ea6db..ec16e87 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ MCP server for [Family Wall](https://www.familywall.com) -- read and manage your family's circles, lists, and tasks directly from Claude. -## Features (v0.4.5) +## Features (v0.4.6) ### Read diff --git a/SPEC.md b/SPEC.md index c7ea6b8..cfb01ac 100644 --- a/SPEC.md +++ b/SPEC.md @@ -324,8 +324,25 @@ a00.r.r → vollständiges Wall-Message-Objekt .rights.canDelete → "true"/"false" ``` -**Like-Zustand bestimmen:** `moodMap[accountId]` enthält `["STAR"]` wenn der -jeweilige Account geliked hat. Leere Map oder fehlender Key = kein Like. +**Like-Zustand bestimmen (zwei Indikatoren, beide auswerten):** + +| Feld | Typ | Bedeutung | +|---|---|---| +| `moodStarShortcut` | `"true"` / `"false"` | Primär: direktes User-Like-Flag für den anfragenden Account | +| `moodMap[accountId]` | `["STAR"]` | Sekundär: accountId → Mood-Liste; enthält `"STAR"` wenn geliked | + +Beide Indikatoren können den Like-Zustand korrekt abbilden — je nach API-internem +Speicherpfad ist nur einer gesetzt. Immer beide prüfen. + +**Silent-Fail-Szenarien (API antwortet 200, aber Like wird nicht gesetzt):** +- **Self-Like-Restriction**: Eigener Post kann nicht geliked werden + (verifiziert: Account 23431898 kann Post `wall/23431854_31119189` nicht liken, + obwohl API regulär antwortet — `modifDate` bleibt eingefroren) +- **Unsupported Post-Typ**: `FAMILY_CREATED`-Posts ignorieren wallmood-Calls +- **Rate-Limit**: Nach vielen Calls kann die API Still-Fails zurückgeben + +Erkennungsmerkmal für Silent-Fail: `modifDate` im Response identisch zum Vorherigen +AND `moodStarShortcut: false` AND `moodMap: {}`. ## Noch zu verifizieren diff --git a/pyproject.toml b/pyproject.toml index d3a3e24..0346725 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "mcp-familywall" -version = "0.4.5" +version = "0.4.6" description = "MCP server for Family Wall — read your family's lists and tasks via Claude" readme = "README.md" requires-python = ">=3.12" diff --git a/src/mcp_familywall/server.py b/src/mcp_familywall/server.py index 333dbfc..5ff2e16 100644 --- a/src/mcp_familywall/server.py +++ b/src/mcp_familywall/server.py @@ -532,14 +532,27 @@ def like_post(post_id: str, like: bool = True) -> str: indent=2, ) - # Confirm the STAR is present in moodMap (server-side representation of a like). - now_liked = any("STAR" in moods for moods in mood_map.values()) + # Two complementary indicators for the like state: + # - moodStarShortcut: direct boolean per-user flag on the post object (primary) + # - moodMap: dict of accountId → [mood types]; contains "STAR" when liked (secondary) + # Use both so either storage path is covered. + star_shortcut = wall_obj.get("moodStarShortcut") == "true" + star_in_map = any("STAR" in moods for moods in mood_map.values()) + now_liked = star_shortcut or star_in_map - return json.dumps( - {"liked": now_liked, "id": post_id, "author": account_id}, - ensure_ascii=False, - indent=2, - ) + result: dict[str, Any] = {"liked": now_liked, "id": post_id, "author": account_id} + + # Surface a warning when the like call apparently had no effect, so the + # caller can distinguish a successful like from a silent API rejection + # (e.g. rate limit, unsupported post type, or self-like restriction). + if not now_liked: + result["warning"] = ( + "Like may not have been applied. " + "Possible causes: rate limit, unsupported post type (e.g. FAMILY_CREATED), " + "or self-like restriction." + ) + + return json.dumps(result, ensure_ascii=False, indent=2) # ---------------------------------------------------------------------------