fix(get_tasks): support for secondary circles by deriving scope from list_id (v1.4.2)

This commit is contained in:
2026-04-18 00:03:38 +02:00
parent dd42dc2845
commit 0e34b067e6
3 changed files with 44 additions and 8 deletions
+12
View File
@@ -10,6 +10,18 @@ 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.4.2] 2026-04-18
### Fixed
- **`get_tasks` support for secondary circles** — lists in non-primary circles now return tasks correctly
- Circle is automatically derived from `list_id` format (`taskList/<circleNum>_<listNum>`)
- Scope parameter passed to `accgetallfamily` call; matches `get_lists` pattern
- Docstring updated to clarify circle support and list_id format requirement
### Notes
- `_accgetallfamily()` now accepts optional `scope` parameter for secondary circle support
- No breaking changes; all existing code remains compatible
## [1.4.1] 2026-04-17 ## [1.4.1] 2026-04-17
### Improved ### Improved
+1 -1
View File
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
[project] [project]
name = "mcp-familywall" name = "mcp-familywall"
version = "1.4.1" version = "1.4.2"
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"
+31 -7
View File
@@ -44,9 +44,13 @@ def _validate_date(date: str) -> str | None:
return None return None
def _accgetallfamily() -> dict[str, Any]: def _accgetallfamily(scope: str | None = None) -> dict[str, Any]:
"""Login, call accgetallfamily, logout and return the response body. """Login, call accgetallfamily, logout and return the response body.
Args:
scope: Optional circle metaId (e.g. "family/16473836") to fetch data for
a specific circle. When None (default), fetches data for the primary circle.
Raises: Raises:
RuntimeError: On credential or API errors. RuntimeError: On credential or API errors.
""" """
@@ -58,10 +62,10 @@ def _accgetallfamily() -> dict[str, Any]:
try: try:
with FamilyWallClient() as client: with FamilyWallClient() as client:
client.login(email, password) client.login(email, password)
data = client.call( params: dict[str, Any] = {"a01call": "taskcategorysync", "a02call": "tasksync"}
"accgetallfamily", if scope:
{"a01call": "taskcategorysync", "a02call": "tasksync"}, params["scope"] = scope
) data = client.call("accgetallfamily", params)
client.logout() client.logout()
return data return data
except FamilyWallError as exc: except FamilyWallError as exc:
@@ -402,9 +406,29 @@ def get_lists(scope: str | None = None) -> str:
@mcp.tool() @mcp.tool()
def get_tasks(list_id: str, only_open: bool = True) -> str: def get_tasks(list_id: str, only_open: bool = True) -> str:
"""Return tasks for a list as JSON. list_id from get_lists. only_open=True filters completed.""" """Return tasks for a list as JSON.
Lists from all circles are supported. The circle is automatically derived from
the list_id — always use IDs from get_lists, never construct them manually.
Args:
list_id: List ID from get_lists (e.g. ``taskList/23431854_29740942``).
only_open: When True (default), filter to incomplete tasks only.
Returns:
JSON array of task objects with keys: id, text, description, completed,
category_id, due_date, assignee_ids, recurrency, recurrency_interval,
rrule, reminder.
"""
# Extract circle number from list_id format: taskList/<circleNum>_<listNum>
try: try:
data = _accgetallfamily() circle_num = list_id.split("/")[1].split("_")[0]
scope = f"family/{circle_num}"
except (IndexError, ValueError):
return _err(f"Invalid list_id format: {list_id!r}")
try:
data = _accgetallfamily(scope)
except RuntimeError as exc: except RuntimeError as exc:
return _err(str(exc)) return _err(str(exc))