fix(wall-posts): add delete_wall_post and fix add_comment response parser (v1.3.1)

- Fix add_comment response parser: corrected to a00.r.r.comment.commentId structure
- Fix add_comment error handling: return errors directly instead of warnings
- Add delete_wall_post: permanently delete wall posts via metadelete endpoint
- Add delete_wall_post to README.md Wall & Activities section
- Update SPEC.md with correct walladdComment response structure
- Update SPEC.md metadelete to include wall posts as supported type
- Update CHANGELOG.md with v1.3.1 bugfixes and additions
- Version bumped to 1.3.1 in pyproject.toml

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-04-17 23:25:45 +02:00
parent 0e7c4da362
commit 35cbfd3061
5 changed files with 77 additions and 17 deletions
+15
View File
@@ -10,6 +10,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
This project follows Semantic Versioning (SemVer). This project follows Semantic Versioning (SemVer).
Breaking changes (removed tools, changed parameters) increment the major version. Breaking changes (removed tools, changed parameters) increment the major version.
## [1.3.1] 2026-04-17
### Fixed
- **`add_comment` response parser**: corrected response structure from `a00.r.r` with `metaId`
to nested `a00.r.r.comment.commentId`; response now includes `"created": true` flag
- **`add_comment` error handling**: now returns error messages directly instead of warnings
### Added
- **`delete_wall_post`** — permanently delete a wall post using the `metadelete` endpoint
(identical to deleting tasks and recipes)
### Notes
- All wall post tools now complete CRUD operations (Create, Read, Update via like_post, Delete)
- Test post (wall/16282169_31146617) removed from production after verification
## [1.3.0] 2026-04-17 ## [1.3.0] 2026-04-17
### Added ### Added
+2 -1
View File
@@ -2,7 +2,7 @@
MCP server for [Family Wall](https://www.familywall.com) — manage your family's circles, lists, tasks, recipes, and meal plan directly from Claude. MCP server for [Family Wall](https://www.familywall.com) — manage your family's circles, lists, tasks, recipes, and meal plan directly from Claude.
## Tools (v1.3.0) ## Tools (v1.3.1)
### Wall & Activities ### Wall & Activities
@@ -12,6 +12,7 @@ MCP server for [Family Wall](https://www.familywall.com) — manage your family'
| `create_wall_post` 🔒 | Create a new status post on the wall | | `create_wall_post` 🔒 | Create a new status post on the wall |
| `add_comment` 🔒 | Add a comment to a post | | `add_comment` 🔒 | Add a comment to a post |
| `like_post` 🔒 | Like or unlike a wall post/activity | | `like_post` 🔒 | Like or unlike a wall post/activity |
| `delete_wall_post` 🔒 | Permanently delete a wall post |
### Circles & Members ### Circles & Members
+4 -3
View File
@@ -269,6 +269,7 @@ POST https://api.familywall.com/api/metadelete
- Tasks: `task/<id>` - Tasks: `task/<id>`
- Rezepte: `recipe/<id>` - Rezepte: `recipe/<id>`
- Essensplan-Einträge: `dish/<id>` und `meal/<id>` - Essensplan-Einträge: `dish/<id>` und `meal/<id>`
- Wall-Posts: `wall/<id>` (v1.3.1+)
**Response:** **Response:**
``` ```
@@ -337,8 +338,8 @@ POST https://api.familywall.com/api/walladdComment
**Response:** **Response:**
``` ```
a00.r.r → Kommentar-Objekt a00.r.r.comment → Kommentar-Objekt (nested)
.metaId → neue Kommentar-ID .commentId → neue Kommentar-ID
.text → Kommentartext .text → Kommentartext
.creationDate → Timestamp (ISO 8601) .creationDate → Timestamp (ISO 8601)
``` ```
@@ -346,7 +347,7 @@ a00.r.r → Kommentar-Objekt
**Bekannte Einschränkungen:** **Bekannte Einschränkungen:**
- `mood` und `clientOpId` sind optional und werden ignoriert - `mood` und `clientOpId` sind optional und werden ignoriert
**Verifiziert am:** 2026-04-17 via Briefing und Integration **Verifiziert am:** 2026-04-17 via Briefing und Integration (Response-Struktur in v1.3.1 korrekt dokumentiert)
### `taskcategoryput` Kategorie erstellen/aktualisieren ### `taskcategoryput` Kategorie erstellen/aktualisieren
POST https://api.familywall.com/api/taskcategoryput POST https://api.familywall.com/api/taskcategoryput
+1 -1
View File
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
[project] [project]
name = "mcp-familywall" name = "mcp-familywall"
version = "1.3.0" version = "1.3.1"
description = "MCP server for Family Wall — manage your family's circles, lists, tasks, recipes, and meal plan via Claude" description = "MCP server for Family Wall — manage your family's circles, lists, tasks, recipes, and meal plan via Claude"
readme = "README.md" readme = "README.md"
requires-python = ">=3.12" requires-python = ">=3.12"
+55 -12
View File
@@ -2042,9 +2042,8 @@ def get_wall_posts(limit: int = 20) -> str:
raw_author: str = item.get("accountId", "") raw_author: str = item.get("accountId", "")
mood_map: dict[str, Any] = item.get("moodMap") or {} mood_map: dict[str, Any] = item.get("moodMap") or {}
liked_by_me = ( liked_by_me = item.get("moodStarShortcut") == "true" or any(
item.get("moodStarShortcut") == "true" "STAR" in moods for moods in mood_map.values()
or any("STAR" in moods for moods in mood_map.values())
) )
like_count = sum(len(moods) for moods in mood_map.values() if isinstance(moods, list)) like_count = sum(len(moods) for moods in mood_map.values() if isinstance(moods, list))
@@ -2164,22 +2163,66 @@ def add_comment(post_id: str, comment: str) -> str:
return _err(f"Connection error: {exc}") return _err(f"Connection error: {exc}")
try: try:
comment_obj = data["a00"]["r"]["r"] response_obj = data["a00"]["r"]["r"]
if not isinstance(comment_obj, dict) or "metaId" not in comment_obj: if not isinstance(response_obj, dict):
raise TypeError("unexpected shape") raise TypeError("a00.r.r is not a dict")
except (KeyError, TypeError): comment_obj = response_obj.get("comment")
if not isinstance(comment_obj, dict) or "commentId" not in comment_obj:
raise TypeError("comment object missing or invalid")
except (KeyError, TypeError) as exc:
return _err(f"Unexpected walladdComment response structure: {exc}")
return json.dumps(
{
"created": True,
"id": comment_obj.get("commentId"),
"post_id": post_id,
"text": comment_obj.get("text"),
"date": comment_obj.get("creationDate"),
},
ensure_ascii=False,
indent=2,
)
# ---------------------------------------------------------------------------
# Tool: delete_wall_post
# ---------------------------------------------------------------------------
@mcp.tool()
def delete_wall_post(post_id: str) -> str:
"""Permanently delete a wall post.
IMPORTANT: Ask the user for confirmation before calling this tool.
Args:
post_id: Wall post metaId from get_wall_posts
(e.g. ``"wall/16282169_31146617"``).
Returns:
JSON success indicator or an error message.
"""
try:
data = _authenticated_call("metadelete", {"id": post_id})
except RuntimeError as exc:
return _err(str(exc))
try:
result = data["a00"]["r"]["r"]
if result != "true":
raise ValueError(f"Unexpected result: {result}")
except (KeyError, ValueError) as exc:
return json.dumps( return json.dumps(
{"warning": "Unexpected walladdComment response structure", "raw": data}, {"warning": "Unexpected metadelete response structure", "error": str(exc), "raw": data},
ensure_ascii=False, ensure_ascii=False,
indent=2, indent=2,
) )
return json.dumps( return json.dumps(
{ {
"id": comment_obj.get("metaId"), "deleted": True,
"post_id": post_id, "id": post_id,
"text": comment_obj.get("text") or comment_obj.get("comment"),
"date": comment_obj.get("creationDate"),
}, },
ensure_ascii=False, ensure_ascii=False,
indent=2, indent=2,