fix(get_tasks): support for secondary circles by deriving scope from list_id (v1.4.2)
This commit is contained in:
@@ -10,6 +10,18 @@ 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.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
|
||||
|
||||
### Improved
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
||||
|
||||
[project]
|
||||
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"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.12"
|
||||
|
||||
@@ -44,9 +44,13 @@ def _validate_date(date: str) -> str | 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.
|
||||
|
||||
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:
|
||||
RuntimeError: On credential or API errors.
|
||||
"""
|
||||
@@ -58,10 +62,10 @@ def _accgetallfamily() -> dict[str, Any]:
|
||||
try:
|
||||
with FamilyWallClient() as client:
|
||||
client.login(email, password)
|
||||
data = client.call(
|
||||
"accgetallfamily",
|
||||
{"a01call": "taskcategorysync", "a02call": "tasksync"},
|
||||
)
|
||||
params: dict[str, Any] = {"a01call": "taskcategorysync", "a02call": "tasksync"}
|
||||
if scope:
|
||||
params["scope"] = scope
|
||||
data = client.call("accgetallfamily", params)
|
||||
client.logout()
|
||||
return data
|
||||
except FamilyWallError as exc:
|
||||
@@ -402,9 +406,29 @@ def get_lists(scope: str | None = None) -> str:
|
||||
|
||||
@mcp.tool()
|
||||
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:
|
||||
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:
|
||||
return _err(str(exc))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user