fix: get_categories always includes custom categories (v0.4.12)

Custom categories (rights.canDelete=true) have no locale field set by
the API and were silently excluded by the locale filter. They now bypass
both the locale and taskListType filters so they always appear in
get_categories output regardless of the locale parameter.

Also: deleted 7 test categories (TEmojiApple, Obst & Gemüse (old),
TestKategorie, ProbeKat2, [TEST]emoji=apple, ProbeKat1, TDelMeta)
and restored 'Obst & Gemüse' (emoji 🍎) as a clean custom category.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-16 08:06:21 +02:00
parent 5698196c43
commit 0d8036fd4a
5 changed files with 16 additions and 8 deletions
+2 -2
View File
@@ -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. 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 ### 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_members` -- list members of a circle (or all circles)
- `get_lists` -- list all task lists (optionally filtered by circle) - `get_lists` -- list all task lists (optionally filtered by circle)
- `get_tasks` -- list tasks in a specific list (includes `category_id` field) - `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) - `get_activities` -- list recent wall activities (author resolved to display name)
### Write (with confirmation prompt) ### Write (with confirmation prompt)
+3
View File
@@ -150,6 +150,9 @@ a01.r.r.updatedCreated[] → taskcategorysync (Kategorien/Abteilung
.locale → Sprache des Namens (z.B. "de", "en", "ru", "fr", "es", .locale → Sprache des Namens (z.B. "de", "en", "ru", "fr", "es",
"it", "nl", "pt", "sv", "ko", "ja") "it", "nl", "pt", "sv", "ko", "ja")
Jede Sprache = eigener Eintrag mit eigenem metaId/systemCategoryId 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 .hiddenByTaskList → Liste von Listen-IDs, in denen die Kat. versteckt ist
a02.r.r.updatedCreated[] → tasksync (Tasks) a02.r.r.updatedCreated[] → tasksync (Tasks)
.metaId → eindeutige Task-ID .metaId → eindeutige Task-ID
+1 -1
View File
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
[project] [project]
name = "mcp-familywall" 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" 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.4.1" __version__ = "0.4.12"
+5
View File
@@ -391,8 +391,13 @@ def get_categories(list_id: str, locale: str = "de") -> str:
# Filter by locale (exact match) and taskListType (when known). # Filter by locale (exact match) and taskListType (when known).
# sortingIndexByTaskList is NOT used for filtering: all categories are # sortingIndexByTaskList is NOT used for filtering: all categories are
# assigned to all lists regardless of type, making it an unreliable signal. # 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]]] = [] matched: list[tuple[int, dict[str, Any]]] = []
for cat in raw_cats: for cat in raw_cats:
is_custom = cat.get("rights", {}).get("canDelete") == "true"
if not is_custom:
if cat.get("locale") != locale: if cat.get("locale") != locale:
continue continue
if list_type is not None and cat.get("taskListType") != list_type: if list_type is not None and cat.get("taskListType") != list_type: