todoist_task_complete
Mark Todoist tasks as complete using task ID or partial name search to manage your to-do list efficiently.
Instructions
Mark a task as complete found by ID or partial name search (case-insensitive)
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| task_id | No | Task ID to complete (optional, takes precedence over task_name) | |
| task_name | No | Partial task name to search for completion (used if task_id not provided) |
Implementation Reference
- src/handlers/task-handlers.ts:485-507 (handler)The core handler function for todoist_task_complete. Finds the task by ID or partial name, clears cache, calls todoistClient.closeTask(id), and returns success message.export async function handleCompleteTask( todoistClient: TodoistApi, args: any ): Promise<string> { // Handle both snake_case and camelCase const { taskId, taskName } = extractTaskIdentifiers(args); // Validate that at least one identifier is provided validateTaskIdentifier(taskId, taskName); // Clear cache since we're completing taskCache.clear(); const matchingTask = await findTaskByIdOrName(todoistClient, args); await todoistClient.closeTask(matchingTask.id); // Check if we're in dry-run mode const isDryRun = process.env.DRYRUN === "true"; const prefix = isDryRun ? "[DRY-RUN] " : ""; return `${prefix}Successfully completed task: "${matchingTask.content}"`; }
- src/tools/task-tools.ts:196-216 (schema)Defines the Tool schema including name, description, and inputSchema for parameters task_id and task_name.export const COMPLETE_TASK_TOOL: Tool = { name: "todoist_task_complete", description: "Mark a task as complete found by ID or partial name search (case-insensitive)", inputSchema: { type: "object", properties: { task_id: { type: "string", description: "Task ID to complete (optional, takes precedence over task_name)", }, task_name: { type: "string", description: "Partial task name to search for completion (used if task_id not provided)", }, }, required: [], }, };
- src/index.ts:177-182 (registration)Registers the tool handler in the main switch statement, validating args with isCompleteTaskArgs and calling handleCompleteTask.case "todoist_task_complete": if (!isCompleteTaskArgs(args)) { throw new Error("Invalid arguments for todoist_task_complete"); } result = await handleCompleteTask(apiClient, args); break;
- src/tools/task-tools.ts:436-441 (schema)Includes COMPLETE_TASK_TOOL in the TASK_TOOLS array, which is likely aggregated into ALL_TOOLS for tool listing.export const TASK_TOOLS = [ CREATE_TASK_TOOL, GET_TASKS_TOOL, UPDATE_TASK_TOOL, DELETE_TASK_TOOL, COMPLETE_TASK_TOOL,
- src/handlers/task-handlers.ts:68-116 (helper)Helper function used by handleCompleteTask to find task by ID (getTask) or partial name search (getTasks and filter).async function findTaskByIdOrName( todoistClient: TodoistApi, args: any ): Promise<TodoistTask> { // Handle both snake_case and camelCase from MCP framework const { taskId, taskName } = extractTaskIdentifiers(args); if (!taskId && !taskName) { throw new Error( "Either task_id/taskId or task_name/taskName must be provided" ); } let task: TodoistTask | null = null; // Try to find by ID first if provided if (taskId) { try { const response = await todoistClient.getTask(taskId); task = response as TodoistTask; } catch { // If not found by ID, continue to try by name if provided if (!taskName) { ErrorHandler.handleTaskNotFound(`ID: ${taskId}`); } } } // If not found by ID or ID not provided, try by name if (!task && taskName) { const result = await todoistClient.getTasks(); const tasks = extractArrayFromResponse<TodoistTask>(result); const matchingTask = tasks.find((t: TodoistTask) => t.content.toLowerCase().includes(taskName.toLowerCase()) ); if (matchingTask) { task = matchingTask; } else { ErrorHandler.handleTaskNotFound(taskName); } } if (!task) { ErrorHandler.handleTaskNotFound(taskId ? `ID: ${taskId}` : taskName!); } return task!; }