Skip to content

Commit 94ecf40

Browse files
feat(calendar): add nc_calendar_complete_todo convenience tool
Add a one-shot "complete this todo" wrapper around update_todo. It sets STATUS=COMPLETED, PERCENT-COMPLETE=100, and the COMPLETED timestamp in a single call. The same operation has always been possible via nc_calendar_update_todo with three explicit fields, but for AI clients the phrasing "complete this task" is much more natural than "set status to COMPLETED, set percent_complete to 100, and set completed to <now>" — the latter forces the client to compute a timestamp and remember three field names. A dedicated tool also pairs naturally with the existing delete_todo, update_todo, and create_todo trio. The implementation is a thin wrapper: it delegates to client.calendar.update_todo with a fixed three-field payload, defaulting completed_at to dt.datetime.now(dt.timezone.utc).isoformat() when the caller doesn't supply one. No client-side or model changes are needed. Verified end-to-end against Nextcloud 33.0.2: create_todo -> complete_todo -> search_todos shows status=COMPLETED, percent_complete=100, completed=<timestamp>.
1 parent 61cadf7 commit 94ecf40

1 file changed

Lines changed: 44 additions & 0 deletions

File tree

nextcloud_mcp_server/server/calendar.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1104,6 +1104,50 @@ async def nc_calendar_delete_todo(
11041104
client = await get_client(ctx)
11051105
return await client.calendar.delete_todo(calendar_name, todo_uid)
11061106

1107+
@mcp.tool(
1108+
title="Complete Todo Task",
1109+
annotations=ToolAnnotations(idempotentHint=True, openWorldHint=True),
1110+
)
1111+
@require_scopes("todo.write", "calendar.read")
1112+
@instrument_tool
1113+
async def nc_calendar_complete_todo(
1114+
calendar_name: str,
1115+
todo_uid: str,
1116+
ctx: Context,
1117+
completed_at: Optional[str] = None,
1118+
):
1119+
"""Mark a todo/task as completed.
1120+
1121+
Convenience wrapper around nc_calendar_update_todo that sets
1122+
STATUS=COMPLETED, PERCENT-COMPLETE=100, and the COMPLETED
1123+
timestamp in one call. Equivalent to invoking update_todo with
1124+
those three fields populated; useful for AI clients where
1125+
"complete this task" is a more natural phrasing than "set status
1126+
to COMPLETED, set percent_complete to 100, set completed
1127+
timestamp".
1128+
1129+
Args:
1130+
calendar_name: Name of the calendar containing the todo
1131+
todo_uid: UID of the todo to mark complete
1132+
ctx: MCP context
1133+
completed_at: Optional ISO 8601 completion timestamp.
1134+
Defaults to the current UTC time if not provided.
1135+
1136+
Returns:
1137+
Dict with the update result.
1138+
"""
1139+
client = await get_client(ctx)
1140+
if completed_at is None:
1141+
completed_at = dt.datetime.now(dt.timezone.utc).isoformat()
1142+
todo_data = {
1143+
"status": "COMPLETED",
1144+
"percent_complete": 100,
1145+
"completed": completed_at,
1146+
}
1147+
return await client.calendar.update_todo(
1148+
calendar_name, todo_uid, todo_data
1149+
)
1150+
11071151
@mcp.tool(
11081152
title="Search Todo Tasks",
11091153
annotations=ToolAnnotations(readOnlyHint=True, openWorldHint=True),

0 commit comments

Comments
 (0)