diff --git a/README.md b/README.md index 0416904..6cbf513 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ MCP server for [Family Wall](https://www.familywall.com) -- read and manage your family's circles, lists, and tasks directly from Claude. -## Features (v0.4.11) +## Features (v0.4.12) ### Read @@ -10,7 +10,7 @@ MCP server for [Family Wall](https://www.familywall.com) -- read and manage your - `get_members` -- list members of a circle (or all circles) - `get_lists` -- list all task lists (optionally filtered by circle) - `get_tasks` -- list tasks in a specific list (includes `category_id` field) -- `get_categories` -- list categories for a list (locale-filtered; `custom` flag marks user-created ones) +- `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) ### Write (with confirmation prompt) diff --git a/SPEC.md b/SPEC.md index 2c88e67..5a77912 100644 --- a/SPEC.md +++ b/SPEC.md @@ -150,6 +150,9 @@ a01.r.r.updatedCreated[] → taskcategorysync (Kategorien/Abteilung .locale → Sprache des Namens (z.B. "de", "en", "ru", "fr", "es", "it", "nl", "pt", "sv", "ko", "ja") Jede Sprache = eigener Eintrag mit eigenem metaId/systemCategoryId + **Wichtig:** Custom-Kategorien (rights.canDelete='true') haben + kein locale-Feld gesetzt — sie werden sprachunabhängig + zurückgegeben und dürfen nie über locale gefiltert werden. .hiddenByTaskList → Liste von Listen-IDs, in denen die Kat. versteckt ist a02.r.r.updatedCreated[] → tasksync (Tasks) .metaId → eindeutige Task-ID diff --git a/pyproject.toml b/pyproject.toml index 0c6ceba..50a29a7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "mcp-familywall" -version = "0.4.11" +version = "0.4.12" 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 3d26edf..9b084a6 100644 --- a/src/mcp_familywall/__init__.py +++ b/src/mcp_familywall/__init__.py @@ -1 +1 @@ -__version__ = "0.4.1" +__version__ = "0.4.12" diff --git a/src/mcp_familywall/server.py b/src/mcp_familywall/server.py index 3aec20f..55b7407 100644 --- a/src/mcp_familywall/server.py +++ b/src/mcp_familywall/server.py @@ -391,12 +391,17 @@ def get_categories(list_id: str, locale: str = "de") -> str: # Filter by locale (exact match) and taskListType (when known). # sortingIndexByTaskList is NOT used for filtering: all categories are # assigned to all lists regardless of type, making it an unreliable signal. + # + # Custom categories (rights.canDelete=true) bypass both filters: they have + # no locale or taskListType set by the API and must always be returned. matched: list[tuple[int, dict[str, Any]]] = [] for cat in raw_cats: - if cat.get("locale") != locale: - continue - if list_type is not None and cat.get("taskListType") != list_type: - continue + is_custom = cat.get("rights", {}).get("canDelete") == "true" + if not is_custom: + if cat.get("locale") != locale: + continue + if list_type is not None and cat.get("taskListType") != list_type: + continue sort_val = int(cat.get("initialSortingIndex") or 0) matched.append((sort_val, cat))