feat: category assignment in create_task / update_task (v0.4.10)
Verified via FW_DEBUG=1 + systematic param-name probing that the correct parameter is `taskCategoryId` with value = full metaId from get_categories (e.g. taskCategory/23431854_200). Numeric systemCategoryId alone causes API error; full metaId is accepted and stored. Changes: - create_task: add optional category_id parameter → sent as taskCategoryId - update_task: add optional category_id parameter → sent as taskCategoryId; guard now accepts category_id-only updates - get_tasks: expose category_id field in returned task objects - get_categories: update docstring (param name now known) - SPEC.md: document verified taskCategoryId param + clarify categories[] vs taskCategoryId field distinction - scripts/find_category_param.py: discovery script used to find param name Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -325,6 +325,7 @@ def get_tasks(list_id: str, only_open: bool = True):
|
||||
"text": task.get("text"),
|
||||
"description": task.get("description"),
|
||||
"completed": completed,
|
||||
"category_id": task.get("taskCategoryId"),
|
||||
}
|
||||
)
|
||||
|
||||
@@ -344,8 +345,8 @@ def get_categories(list_id: str, locale: str = "de") -> str:
|
||||
lists return an empty list. Categories are filtered by locale so only
|
||||
the language-appropriate names are returned (default: German).
|
||||
|
||||
Note: the parameter name for assigning a category when creating or
|
||||
updating a task is not yet verified via FW_DEBUG=1. See SPEC.md.
|
||||
Use the returned ``id`` values as the ``category_id`` parameter in
|
||||
``create_task`` and ``update_task``.
|
||||
|
||||
Args:
|
||||
list_id: List ID from get_lists (e.g. ``taskList/23431854_29740942``).
|
||||
@@ -517,7 +518,12 @@ def _authenticated_call(endpoint: str, params: dict[str, Any]) -> dict[str, Any]
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
def create_task(list_id: str, text: str, description: str | None = None) -> str:
|
||||
def create_task(
|
||||
list_id: str,
|
||||
text: str,
|
||||
description: str | None = None,
|
||||
category_id: str | None = None,
|
||||
) -> str:
|
||||
"""Create a new task in the given list.
|
||||
|
||||
IMPORTANT: Ask the user for confirmation before calling this tool.
|
||||
@@ -526,6 +532,9 @@ def create_task(list_id: str, text: str, description: str | None = None) -> str:
|
||||
list_id: Target list ID from get_lists (e.g. ``taskList/123_456``).
|
||||
text: Task title / main text.
|
||||
description: Optional longer description.
|
||||
category_id: Optional category metaId from get_categories
|
||||
(e.g. ``taskCategory/23431854_200``). Only meaningful for
|
||||
shopping lists; ignored for TODO lists.
|
||||
|
||||
Returns:
|
||||
JSON with the new task's metaId on success, or an error message.
|
||||
@@ -533,6 +542,8 @@ def create_task(list_id: str, text: str, description: str | None = None) -> str:
|
||||
params: dict[str, Any] = {"taskListId": list_id, "text": text}
|
||||
if description:
|
||||
params["description"] = description
|
||||
if category_id:
|
||||
params["taskCategoryId"] = category_id
|
||||
|
||||
try:
|
||||
data = _authenticated_call("taskcreate2", params)
|
||||
@@ -559,28 +570,38 @@ def create_task(list_id: str, text: str, description: str | None = None) -> str:
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
def update_task(task_id: str, text: str | None = None, description: str | None = None) -> str:
|
||||
"""Update the text and/or description of an existing task.
|
||||
def update_task(
|
||||
task_id: str,
|
||||
text: str | None = None,
|
||||
description: str | None = None,
|
||||
category_id: str | None = None,
|
||||
) -> str:
|
||||
"""Update the text, description, and/or category of an existing task.
|
||||
|
||||
IMPORTANT: Ask the user for confirmation before calling this tool.
|
||||
At least one of *text* or *description* must be provided.
|
||||
At least one of *text*, *description*, or *category_id* must be provided.
|
||||
|
||||
Args:
|
||||
task_id: Task metaId from get_tasks.
|
||||
text: New title text (omit to leave unchanged).
|
||||
description: New description (omit to leave unchanged).
|
||||
category_id: New category metaId from get_categories
|
||||
(e.g. ``taskCategory/23431854_200``). Only meaningful for
|
||||
shopping lists; ignored for TODO lists.
|
||||
|
||||
Returns:
|
||||
JSON success indicator or an error message.
|
||||
"""
|
||||
if text is None and description is None:
|
||||
return "Error: At least one of 'text' or 'description' must be provided."
|
||||
if text is None and description is None and category_id is None:
|
||||
return "Error: At least one of 'text', 'description', or 'category_id' must be provided."
|
||||
|
||||
params: dict[str, Any] = {"metaId": task_id}
|
||||
if text is not None:
|
||||
params["text"] = text
|
||||
if description is not None:
|
||||
params["description"] = description
|
||||
if category_id is not None:
|
||||
params["taskCategoryId"] = category_id
|
||||
|
||||
try:
|
||||
_authenticated_call("taskupdate2", params)
|
||||
|
||||
Reference in New Issue
Block a user