todoist_task_convert_to_subtask
Convert an existing task into a subtask under another task in Todoist to organize related items hierarchically.
Instructions
Convert an existing task to a subtask of another task
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| task_id | No | ID of the task to convert (provide this OR task_name) | |
| task_name | No | Name/content of the task to convert (provide this OR task_id) | |
| parent_task_id | No | ID of the parent task (provide this OR parent_task_name) | |
| parent_task_name | No | Name/content of the parent task (provide this OR parent_task_id) |
Implementation Reference
- src/handlers/subtask-handlers.ts:150-201 (handler)Core handler function that implements the tool logic: locates the task and parent task, validates it's not already a subtask, deletes the original task, and recreates it as a subtask under the parent while preserving properties.export async function handleConvertToSubtask( todoistClient: TodoistApi, args: ConvertToSubtaskArgs ): Promise<{ task: TodoistTask; parent: TodoistTask }> { try { // Find both tasks const [task, parent] = await Promise.all([ findTask(todoistClient, { task_id: args.task_id, task_name: args.task_name, }), findTask(todoistClient, { task_id: args.parent_task_id, task_name: args.parent_task_name, }), ]); // Check if already a subtask if (task.parentId) { throw new ValidationError(`Task "${task.content}" is already a subtask`); } // Delete the original task and recreate it as a subtask // This is a workaround since updateTask may not support parentId await todoistClient.deleteTask(task.id); const subtaskData: TaskCreationData = { content: task.content, parentId: parent.id, projectId: parent.projectId || task.projectId, }; // Preserve other task properties if (task.description) subtaskData.description = task.description; if (task.due?.string) subtaskData.dueString = task.due.string; if (task.priority) subtaskData.priority = task.priority; if (task.labels) subtaskData.labels = task.labels; if (task.deadline?.date) subtaskData.deadline = { date: task.deadline.date }; const updatedTask = (await todoistClient.addTask( subtaskData )) as TodoistTask; // Clear cache taskCache.clear(); return { task: updatedTask, parent }; } catch (error) { throw ErrorHandler.handleAPIError("convertToSubtask", error); } }
- src/tools/subtask-tools.ts:110-136 (schema)Defines the tool's metadata including name, description, and input schema specifying parameters for task identification (ID or name for both task to convert and parent).export const CONVERT_TO_SUBTASK_TOOL: Tool = { name: "todoist_task_convert_to_subtask", description: "Convert an existing task to a subtask of another task", inputSchema: { type: "object", properties: { task_id: { type: "string", description: "ID of the task to convert (provide this OR task_name)", }, task_name: { type: "string", description: "Name/content of the task to convert (provide this OR task_id)", }, parent_task_id: { type: "string", description: "ID of the parent task (provide this OR parent_task_name)", }, parent_task_name: { type: "string", description: "Name/content of the parent task (provide this OR parent_task_id)", }, }, }, };
- src/index.ts:324-332 (registration)Tool registration in the main server request handler: matches tool name, validates arguments using type guard, invokes the handler, and formats success response.case "todoist_task_convert_to_subtask": if (!isConvertToSubtaskArgs(args)) { throw new Error( "Invalid arguments for todoist_task_convert_to_subtask" ); } const convertResult = await handleConvertToSubtask(apiClient, args); result = `Converted task "${convertResult.task.content}" (ID: ${convertResult.task.id}) to subtask of "${convertResult.parent.content}" (ID: ${convertResult.parent.id})`; break;
- src/tools/index.ts:62-69 (registration)Aggregates all tools including SUBTASK_TOOLS (containing todoist_task_convert_to_subtask) into ALL_TOOLS array exposed to the MCP server.export const ALL_TOOLS = [ ...TASK_TOOLS, ...PROJECT_TOOLS, ...COMMENT_TOOLS, ...LABEL_TOOLS, ...SUBTASK_TOOLS, ...TEST_TOOLS, ];