perf: delete_category uses single API session (v0.4.13)
Previously delete_category made two separate login cycles (accgetallfamily to verify + taskcategorydelete to delete) = 6 HTTP calls. Now both happen in one session = 4 HTTP calls. Halves latency and eliminates the risk of a compounding timeout when the API is temporarily slow. FW_DEBUG=1 investigation confirmed the API itself is fast (<1s); the reported 4-min timeout was transient API slowness amplified by the double session overhead. Also recreated 'Obst & Gemüse' (emoji 🍎) as taskCategory/23431854_4956806 after it was accidentally consumed by the debug script. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -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.12)
|
||||
## Features (v0.4.13)
|
||||
|
||||
### Read
|
||||
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
||||
|
||||
[project]
|
||||
name = "mcp-familywall"
|
||||
version = "0.4.12"
|
||||
version = "0.4.13"
|
||||
description = "MCP server for Family Wall — read your family's lists and tasks via Claude"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.12"
|
||||
|
||||
@@ -1 +1 @@
|
||||
__version__ = "0.4.12"
|
||||
__version__ = "0.4.13"
|
||||
|
||||
@@ -502,42 +502,57 @@ def delete_category(category_id: str) -> str:
|
||||
Returns:
|
||||
JSON success indicator or an error message.
|
||||
"""
|
||||
# Safety check: look up the category and verify it is custom (canDelete=true).
|
||||
# This prevents accidental deletion of shared system categories.
|
||||
# Safety check + delete in a SINGLE session to minimise API round-trips.
|
||||
# Previously two separate sessions were used (accgetallfamily + taskcategorydelete),
|
||||
# causing 6 HTTP calls. One session = 4 HTTP calls (login, check, delete, logout).
|
||||
try:
|
||||
data = _accgetallfamily()
|
||||
email, password = get_credentials()
|
||||
except RuntimeError as exc:
|
||||
return f"Error: {exc}"
|
||||
|
||||
cat_obj: dict[str, Any] | None = None
|
||||
try:
|
||||
raw_cats: list[dict[str, Any]] = data["a01"]["r"]["r"]["updatedCreated"]
|
||||
except (KeyError, TypeError):
|
||||
raw_cats = []
|
||||
with FamilyWallClient() as client:
|
||||
client.login(email, password)
|
||||
|
||||
cat_obj: dict[str, Any] | None = next(
|
||||
(c for c in raw_cats if c.get("metaId") == category_id), None
|
||||
)
|
||||
# Fetch categories and verify the target is custom (canDelete=true).
|
||||
data = client.call(
|
||||
"accgetallfamily",
|
||||
{"a01call": "taskcategorysync", "a02call": "tasksync"},
|
||||
)
|
||||
try:
|
||||
raw_cats: list[dict[str, Any]] = data["a01"]["r"]["r"]["updatedCreated"]
|
||||
except (KeyError, TypeError):
|
||||
raw_cats = []
|
||||
|
||||
if cat_obj is None:
|
||||
return f"Error: Category '{category_id}' not found."
|
||||
cat_obj = next(
|
||||
(c for c in raw_cats if c.get("metaId") == category_id), None
|
||||
)
|
||||
if cat_obj is None:
|
||||
client.logout()
|
||||
return f"Error: Category '{category_id}' not found."
|
||||
|
||||
can_delete: str | None = cat_obj.get("rights", {}).get("canDelete")
|
||||
if can_delete != "true":
|
||||
return json.dumps(
|
||||
{
|
||||
"error": "System categories cannot be deleted.",
|
||||
"id": category_id,
|
||||
"name": cat_obj.get("name"),
|
||||
"hint": "Only custom categories (custom=true in get_categories) can be deleted.",
|
||||
},
|
||||
ensure_ascii=False,
|
||||
indent=2,
|
||||
)
|
||||
can_delete: str | None = cat_obj.get("rights", {}).get("canDelete")
|
||||
if can_delete != "true":
|
||||
client.logout()
|
||||
return json.dumps(
|
||||
{
|
||||
"error": "System categories cannot be deleted.",
|
||||
"id": category_id,
|
||||
"name": cat_obj.get("name"),
|
||||
"hint": "Only custom categories (custom=true in get_categories) can be deleted.",
|
||||
},
|
||||
ensure_ascii=False,
|
||||
indent=2,
|
||||
)
|
||||
|
||||
try:
|
||||
_authenticated_call("taskcategorydelete", {"id": category_id})
|
||||
except RuntimeError as exc:
|
||||
return f"Error: {exc}"
|
||||
# Verified — delete in the same session.
|
||||
client.call("taskcategorydelete", {"id": category_id})
|
||||
client.logout()
|
||||
except FamilyWallError as exc:
|
||||
return f"Error: Family Wall API error: {exc}"
|
||||
except Exception as exc:
|
||||
return f"Error: Connection error: {exc}"
|
||||
|
||||
return json.dumps(
|
||||
{"deleted": True, "id": category_id, "name": cat_obj.get("name")},
|
||||
|
||||
Reference in New Issue
Block a user