From 6d9f358e7696d9084411f39bd2d6da784a19f281 Mon Sep 17 00:00:00 2001 From: Marcus van Elst Date: Fri, 17 Apr 2026 09:02:44 +0200 Subject: [PATCH] feat(tasks): add recurrency, rrule, reminder fields to get_tasks (v0.9.0) Co-Authored-By: Claude Sonnet 4.6 --- CLAUDE.md | 6 ++--- README.md | 4 +-- pyproject.toml | 2 +- src/mcp_familywall/__init__.py | 2 +- src/mcp_familywall/server.py | 47 ++++++++++++++++++++++++++++++++++ 5 files changed, 54 insertions(+), 7 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index d63f8a6..a0d3681 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -24,7 +24,7 @@ und wird in Claude Desktop eingebunden. ## Aktueller Stand -### Implementierte Tools (v0.8.3) +### Implementierte Tools (v0.9.0) | Kategorie | Tools | |---|---| @@ -54,9 +54,9 @@ und wird in Claude Desktop eingebunden. - v0.8.0: Rezept-Kategorien (get_recipe_categories, create_recipe + category_ids, update_recipe + category_ids) ✓ - v0.8.1: Bugfixes (recipe categories) ✓ - v0.8.2: get_lists() ohne scope → alle Kreise ✓ -- v0.8.3: OTHER-Listentyp dokumentiert + create_list unterstützt ihn; FW_DEBUG=1 loggt unbekannte Task-Felder (Vorbereitung Wiederholungen) ✓ ← aktuell +- v0.8.3: OTHER-Listentyp dokumentiert + create_list unterstützt ihn; FW_DEBUG=1 loggt unbekannte Task-Felder (Vorbereitung Wiederholungen) ✓ - v0.8.x: mpadditemtolist (gestrichen – Family Wall kann das nativ) -- v0.9.x: Erinnerungen + Wiederholungen (Premium-Account erforderlich) +- v0.9.0: get_tasks liefert recurrency, recurrency_interval, rrule, reminder (read-only) ✓ ← aktuell - v2.0: Schreibzugriff auf Wall-Posts (Erstellen, Kommentieren) diff --git a/README.md b/README.md index 008b67e..e1fdf46 100644 --- a/README.md +++ b/README.md @@ -2,14 +2,14 @@ MCP server for [Family Wall](https://www.familywall.com) -- read and manage your family's circles, lists, tasks, and recipes directly from Claude. -## Features (v0.8.3) +## Features (v0.9.0) ### Read - `get_circles` -- list all family circles - `get_members` -- list members of a circle (or all circles) - `get_lists` -- list all task lists (includes `emoji`, `color`, `circle_id`; `null` when unset; list types: `SHOPPING_LIST`, `TODOS`, `OTHER`); without scope parameter returns lists from **all circles**; optional `scope` parameter filters by circle metaId or circle name -- `get_tasks` -- list tasks in a specific list (includes `category_id`, `due_date`, `assignee_ids`) +- `get_tasks` -- list tasks in a specific list (includes `category_id`, `due_date`, `assignee_ids`, `recurrency`, `rrule`, `reminder`) - `get_categories` -- list categories for a list (locale-filtered; custom categories always included; `custom` flag marks user-created ones) - `get_activities` -- list recent wall activities (author resolved to display name) - `get_recipes` -- list all family recipes (compact summary: id, name, prep/cook time, serves) diff --git a/pyproject.toml b/pyproject.toml index deb89cc..119f0bd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "mcp-familywall" -version = "0.8.3" +version = "0.9.0" 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/__init__.py b/src/mcp_familywall/__init__.py index 732155f..3e2f46a 100644 --- a/src/mcp_familywall/__init__.py +++ b/src/mcp_familywall/__init__.py @@ -1 +1 @@ -__version__ = "0.8.3" +__version__ = "0.9.0" diff --git a/src/mcp_familywall/server.py b/src/mcp_familywall/server.py index a61bcac..82deb2b 100644 --- a/src/mcp_familywall/server.py +++ b/src/mcp_familywall/server.py @@ -398,6 +398,7 @@ def get_tasks(list_id: str, only_open: bool = True): _fw_debug = os.environ.get("FW_DEBUG") == "1" _known_fields = { + # output fields "metaId", "text", "description", @@ -406,6 +407,34 @@ def get_tasks(list_id: str, only_open: bool = True): "dueDate", "assigneeIds", "taskListId", + # recurrency fields + "recurrency", + "recurrencyInterval", + "rrule", + "byDay", + "recurrencyDeletedOccurence", + "reminder", + # always-present housekeeping fields + "moodStarShortcut", + "bestMoment", + "lastAction", + "lastActionAuthor", + "lastActionDate", + "categories", + "moodMap", + "sortingIndex", + "comments", + "editable", + "creationDate", + "completedDate", + "familyId", + "toAll", + "accountId", + "medias", + "modifDate", + "assignee", + "taskId", + "clientOpId", } result = [] @@ -425,6 +454,20 @@ def get_tasks(list_id: str, only_open: bool = True): file=sys.stderr, ) + raw_recurrency = task.get("recurrency") + raw_interval = task.get("recurrencyInterval") + recurrency_interval = int(raw_interval) if raw_interval is not None else None + + raw_reminder = task.get("reminder") + if raw_reminder and isinstance(raw_reminder, dict): + raw_val = raw_reminder.get("value") + reminder = { + "unit": raw_reminder.get("unit"), + "value": int(raw_val) if raw_val is not None else None, + } + else: + reminder = None + result.append( { "id": task.get("metaId"), @@ -434,6 +477,10 @@ def get_tasks(list_id: str, only_open: bool = True): "category_id": task.get("taskCategoryId"), "due_date": task.get("dueDate"), "assignee_ids": task.get("assigneeIds") or [], + "recurrency": raw_recurrency, + "recurrency_interval": recurrency_interval, + "rrule": task.get("rrule"), + "reminder": reminder, } )