todoist_move_task
Move a Todoist task to a different project, section, or make it a subtask of another task, including all subtasks.
Instructions
Move a single task (and its subtasks, if any) to a different project, section, or make it a subtask of another task. Provide the taskId and exactly one of: projectId, sectionId, or parentId.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| taskId | Yes | The ID of the task to move. | |
| projectId | No | The ID of the destination project. (Optional, use only one of projectId, sectionId, parentId) | |
| sectionId | No | The ID of the destination section. (Optional, use only one of projectId, sectionId, parentId) | |
| parentId | No | The ID of the parent task to move this task under. (Optional, use only one of projectId, sectionId, parentId) |
Implementation Reference
- src/index.ts:1622-1646 (handler)Executes the tool logic: validates args with isMoveTaskArgs, constructs moveArgs, calls todoistClient.moveTasks([taskId], moveArgs), fetches updated task with getTask, formats and returns success response or error.if (name === "todoist_move_task") { if (!isMoveTaskArgs(args)) { return { content: [{ type: "text", text: "Invalid arguments for move_task. Provide taskId and exactly one of: projectId, sectionId, or parentId (must be a non-empty string)." }], isError: true }; } try { const moveArgs: { projectId?: string; sectionId?: string; parentId?: string } = {}; if (args.projectId) moveArgs.projectId = args.projectId; else if (args.sectionId) moveArgs.sectionId = args.sectionId; else if (args.parentId) moveArgs.parentId = args.parentId; // Use moveTasks from SDK v4+ await todoistClient.moveTasks([args.taskId], moveArgs as any); // Cast to any for MoveTaskArgs as it expects RequireExactlyOne const movedTask = await todoistClient.getTask(args.taskId); return { content: [{ type: "text", text: `Task ${args.taskId} moved successfully.\nNew details:\n${formatTask(movedTask)}` }], isError: false }; } catch (error: any) { return { content: [{ type: "text", text: `Error moving task: ${error.message}` }], isError: true }; } }
- src/index.ts:228-256 (schema)JSON schema defining the input parameters for the todoist_move_task tool: taskId (required), and exactly one optional destination: projectId, sectionId, or parentId.const MOVE_TASK_TOOL: Tool = { name: "todoist_move_task", description: "Move a single task (and its subtasks, if any) to a different project, section, or make it a subtask of another task. Provide the taskId and exactly one of: projectId, sectionId, or parentId.", inputSchema: { type: "object", properties: { taskId: { type: "string", description: "The ID of the task to move." }, projectId: { type: "string", description: "The ID of the destination project. (Optional, use only one of projectId, sectionId, parentId)" }, sectionId: { type: "string", description: "The ID of the destination section. (Optional, use only one of projectId, sectionId, parentId)" }, parentId: { type: "string", description: "The ID of the parent task to move this task under. (Optional, use only one of projectId, sectionId, parentId)" } }, required: ["taskId"] // Note: Validation for providing exactly one of projectId, sectionId, or parentId // is handled in the isMoveTaskArgs type guard and the tool handler. // A more complex JSON schema with oneOf could enforce this, but client support varies. } };
- src/index.ts:1083-1121 (registration)Registers the todoist_move_task tool (as MOVE_TASK_TOOL) in the list of available tools returned by the ListToolsRequest handler.server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: [ // Task tools CREATE_TASK_TOOL, QUICK_ADD_TASK_TOOL, GET_TASKS_TOOL, GET_TASK_TOOL, UPDATE_TASK_TOOL, DELETE_TASK_TOOL, COMPLETE_TASK_TOOL, REOPEN_TASK_TOOL, SEARCH_TASKS_TOOL, MOVE_TASK_TOOL, BULK_MOVE_TASKS_TOOL, // Project tools GET_PROJECTS_TOOL, GET_PROJECT_TOOL, CREATE_PROJECT_TOOL, UPDATE_PROJECT_TOOL, DELETE_PROJECT_TOOL, // Section tools GET_SECTIONS_TOOL, CREATE_SECTION_TOOL, UPDATE_SECTION_TOOL, DELETE_SECTION_TOOL, // Label tools CREATE_LABEL_TOOL, GET_LABEL_TOOL, GET_LABELS_TOOL, UPDATE_LABEL_TOOL, DELETE_LABEL_TOOL, // Comment tools CREATE_COMMENT_TOOL, GET_COMMENT_TOOL, GET_COMMENTS_TOOL, UPDATE_COMMENT_TOOL, DELETE_COMMENT_TOOL, ], }));
- src/index.ts:926-942 (helper)Type guard helper that validates the input arguments for todoist_move_task, ensuring taskId is a string and exactly one non-empty destination (projectId, sectionId, or parentId) is provided.function isMoveTaskArgs(args: unknown): args is { taskId: string; projectId?: string; sectionId?: string; parentId?: string; } { if (typeof args !== 'object' || args === null || !('taskId' in args) || typeof (args as any).taskId !== 'string') { return false; } const { projectId, sectionId, parentId } = args as any; const destinations = [projectId, sectionId, parentId]; const providedDestinations = destinations.filter(dest => dest !== undefined && dest !== null && String(dest).trim() !== ''); // Exactly one destination must be provided and be a non-empty string return providedDestinations.length === 1 && providedDestinations.every(dest => typeof dest === 'string'); }