feat: use taskgettasklists endpoint for get_lists (v0.2.4)

This commit is contained in:
2026-04-15 14:05:58 +02:00
parent eedf9c2ce5
commit c954a245ca
4 changed files with 41 additions and 12 deletions
+8
View File
@@ -87,6 +87,14 @@ a00.r.r[] → Kreise
.name → Kreisname .name → Kreisname
``` ```
### `taskgettasklists` Listen abrufen
POST https://api.familywall.com/api/taskgettasklists
Content-Type: application/x-www-form-urlencoded
**Body-Parameter:** keine
**Response-Struktur:** zu verifizieren beim ersten echten Call
### `accgetallfamily` Listen + Tasks abrufen ### `accgetallfamily` Listen + Tasks abrufen
POST https://api.familywall.com/api/accgetallfamily POST https://api.familywall.com/api/accgetallfamily
Content-Type: application/x-www-form-urlencoded Content-Type: application/x-www-form-urlencoded
+1 -1
View File
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
[project] [project]
name = "mcp-familywall" name = "mcp-familywall"
version = "0.2.3" version = "0.2.4"
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
View File
@@ -1 +1 @@
__version__ = "0.2.3" __version__ = "0.2.4"
+31 -10
View File
@@ -166,6 +166,8 @@ def get_circles() -> str:
def get_lists(scope: str | None = None) -> str: def get_lists(scope: str | None = None) -> str:
"""Return all task lists, optionally filtered by circle name. """Return all task lists, optionally filtered by circle name.
Uses the taskgettasklists endpoint directly.
Args: Args:
scope: Optional circle name to filter by. When None, all lists from scope: Optional circle name to filter by. When None, all lists from
all circles are returned. all circles are returned.
@@ -175,30 +177,49 @@ def get_lists(scope: str | None = None) -> str:
id, name, type, open, total. id, name, type, open, total.
""" """
try: try:
data = _accgetallfamily() email, password = get_credentials()
except RuntimeError as exc: except RuntimeError as exc:
return f"Error: {exc}" return f"Error: {exc}"
raw_lists = _extract_lists(data) try:
if not raw_lists: with FamilyWallClient() as client:
# Return raw response for debugging if no lists found at expected path client.login(email, password)
data = client.call("taskgettasklists", {})
client.logout()
except FamilyWallError as exc:
return f"Error: {exc}"
except Exception as exc:
return f"Connection error: {exc}"
# Try known response patterns; fall back to raw JSON for verification.
raw_lists: list[dict[str, Any]] | None = None
try:
candidate = data["a00"]["r"]["r"]
if isinstance(candidate, list):
raw_lists = candidate
elif isinstance(candidate, dict) and isinstance(candidate.get("updatedCreated"), list):
raw_lists = candidate["updatedCreated"]
except (KeyError, TypeError):
pass
if raw_lists is None:
# Response structure not yet verified — return raw JSON for inspection.
return json.dumps( return json.dumps(
{"warning": "No lists found at expected path", "raw": data}, {"warning": "Unexpected taskgettasklists response structure", "raw": data},
ensure_ascii=False, ensure_ascii=False,
indent=2, indent=2,
) )
result = [] result = []
for item in raw_lists: for item in raw_lists:
# _extract_lists already normalises to {id, name, type, open, total}.
# TODO: apply scope filtering once the circle field is identified. # TODO: apply scope filtering once the circle field is identified.
result.append( result.append(
{ {
"id": item.get("id"), "id": item.get("metaId"),
"name": translate_name(item.get("name", "")), "name": translate_name(item.get("name", "")),
"type": item.get("type"), "type": item.get("taskListType"),
"open": item.get("open"), "open": item.get("remainingTaskNumber"),
"total": item.get("total"), "total": item.get("totalTaskNumber"),
} }
) )