docs(usability): enforce ID→name resolution in all tool docstrings (v1.4.3)
Add explicit guidance to resolve raw API IDs to human-readable names before user display. Affected tools: get_tasks, get_lists, get_activities, get_wall_posts, get_members, get_circles, get_categories, get_meal_plan. Add general usability rule to CLAUDE.md implementation section: never present raw numeric/metaIDs to the user. No breaking changes; docstring improvements only. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -10,6 +10,25 @@ 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.3] – 2026-04-18
|
||||
|
||||
### Improved
|
||||
- **Usability: ID resolution in docstrings** — enforce transparent display of human-readable names:
|
||||
- `get_tasks`: Document required member/category name resolution before user display
|
||||
- `get_lists`: Document required circle name resolution before user display
|
||||
- `get_activities`: Document required author name resolution before user display
|
||||
- `get_wall_posts`: Document required author name resolution before user display
|
||||
- `get_members`: Added proactive call guidance before presenting member-ID data
|
||||
- `get_circles`: Added proactive call guidance before presenting circle-ID data
|
||||
- `get_categories`: Added proactive call guidance for shopping list tasks
|
||||
- `get_meal_plan`: Document required recipe name resolution for recipe_id before user display
|
||||
- `CLAUDE.md`: Added general usability rule at top of implementation section
|
||||
|
||||
### Notes
|
||||
- No breaking changes; docstring enhancements only
|
||||
- All tools remain backward compatible
|
||||
- Ensures consistent UX: no raw numeric/metaIDs shown to users in any context
|
||||
|
||||
## [1.4.2] – 2026-04-18
|
||||
|
||||
### Fixed
|
||||
|
||||
@@ -27,7 +27,7 @@ und wird in Claude Desktop eingebunden.
|
||||
|
||||
## Aktueller Stand
|
||||
|
||||
### Version: **v1.3.0** ← aktuell
|
||||
### Version: **v1.4.3** ← aktuell
|
||||
|
||||
### Implementierte Tools
|
||||
|
||||
@@ -97,6 +97,9 @@ können den echten Request-Body in diesen Fällen nicht sehen.
|
||||
|
||||
## Claude Code – Implementierungsregeln
|
||||
|
||||
**Usability rule:** Never present raw API IDs (numeric IDs, metaIds, category IDs, circle IDs, member IDs) to the user.
|
||||
Always resolve them to human-readable names before responding.
|
||||
|
||||
- **Feature complete before next feature** – jedes Feature vollständig
|
||||
implementieren, testen und verifizieren bevor das nächste beginnt
|
||||
- **Kein destruktives Probing** – keine Probe-Calls auf System-Kategorien,
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
||||
|
||||
[project]
|
||||
name = "mcp-familywall"
|
||||
version = "1.4.2"
|
||||
version = "1.4.3"
|
||||
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"
|
||||
|
||||
@@ -146,7 +146,10 @@ def _extract_tasks(data: dict[str, Any]) -> list[dict[str, Any]]:
|
||||
|
||||
@mcp.tool()
|
||||
def get_circles() -> str:
|
||||
"""Return all Family Wall circles as JSON list of {id, name}."""
|
||||
"""Return all Family Wall circles as JSON list of {id, name}.
|
||||
|
||||
Call this proactively before presenting any data that contains circle IDs to the user.
|
||||
"""
|
||||
try:
|
||||
raw_circles = _famlistfamily()
|
||||
except RuntimeError as exc:
|
||||
@@ -220,6 +223,9 @@ def _famlistfamily() -> list[dict[str, Any]]:
|
||||
def get_members(circle_id: str | None = None) -> str:
|
||||
"""Return Family Wall circle members as JSON, optionally filtered by circle.
|
||||
|
||||
Call this proactively before presenting any data that contains member IDs
|
||||
(assignee_ids, author_id, creator) to the user.
|
||||
|
||||
Args:
|
||||
circle_id: Optional circle ID from get_circles (e.g. ``family/23431854``).
|
||||
When omitted all members across all circles are returned.
|
||||
@@ -311,6 +317,9 @@ def get_lists(scope: str | None = None) -> str:
|
||||
Returns:
|
||||
JSON list of list objects with keys id, name, type, open, total,
|
||||
emoji, color, circle_id.
|
||||
|
||||
IMPORTANT: When presenting lists to the user, always resolve
|
||||
circle_id to the circle name via get_circles. Never show raw IDs.
|
||||
"""
|
||||
try:
|
||||
email, password = get_credentials()
|
||||
@@ -419,6 +428,12 @@ def get_tasks(list_id: str, only_open: bool = True) -> str:
|
||||
JSON array of task objects with keys: id, text, description, completed,
|
||||
category_id, due_date, assignee_ids, recurrency, recurrency_interval,
|
||||
rrule, reminder.
|
||||
|
||||
IMPORTANT: Before presenting results to the user, always resolve:
|
||||
- assignee_ids → member names via get_members
|
||||
- category_id → category name via get_categories
|
||||
- circle context → circle name from get_lists
|
||||
Never show raw IDs to the user.
|
||||
"""
|
||||
# Extract circle number from list_id format: taskList/<circleNum>_<listNum>
|
||||
try:
|
||||
@@ -541,6 +556,9 @@ def get_categories(list_id: str, locale: str = "de") -> str:
|
||||
Use the returned ``id`` values as the ``category_id`` parameter in
|
||||
``create_task`` and ``update_task``.
|
||||
|
||||
Call this proactively before presenting shopping list tasks to the user so
|
||||
category_id values can be shown as readable names.
|
||||
|
||||
Args:
|
||||
list_id: List ID from get_lists (e.g. ``taskList/23431854_29740942``).
|
||||
locale: BCP-47 language code for category names (default ``"de"``).
|
||||
@@ -772,6 +790,9 @@ def get_activities(limit: int = 20) -> str:
|
||||
Returns:
|
||||
JSON list of activity objects sorted by date descending,
|
||||
including wall, task, and taskList activity entries.
|
||||
|
||||
IMPORTANT: Before presenting to the user, resolve author_id to
|
||||
the member name via get_members. Never show raw IDs.
|
||||
"""
|
||||
try:
|
||||
email, password = get_credentials()
|
||||
@@ -2035,6 +2056,9 @@ def get_wall_posts(limit: int = 20) -> str:
|
||||
JSON list of post objects with keys:
|
||||
id, type, text, date, author, author_id,
|
||||
liked_by_me, like_count, comment_count.
|
||||
|
||||
IMPORTANT: Before presenting to the user, resolve author_id to
|
||||
the member name via get_members. Never show raw IDs.
|
||||
"""
|
||||
try:
|
||||
email, password = get_credentials()
|
||||
@@ -2776,6 +2800,9 @@ def get_meal_plan(date_from: str, date_to: str) -> str:
|
||||
- ``can_update`` — whether the entry can be updated
|
||||
- ``can_delete`` — whether the entry can be deleted
|
||||
|
||||
IMPORTANT: When recipe_id is present, use get_recipe to resolve it to the
|
||||
recipe name for display. Never show raw recipe IDs.
|
||||
|
||||
Returns an error message string on failure.
|
||||
"""
|
||||
if date_err := _validate_date(date_from):
|
||||
|
||||
Reference in New Issue
Block a user