todoist_tasks_bulk_create
Create multiple Todoist tasks simultaneously with full attributes to save time on task management.
Instructions
Create multiple tasks at once for improved efficiency. Each task can have full attributes like individual task creation.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| tasks | Yes | Array of task objects to create |
Implementation Reference
- src/handlers/task-handlers.ts:552-660 (handler)The core handler function that implements the tool logic: validates input, loops over the 'tasks' array, constructs TodoistTaskData for each, calls todoistClient.addTask(), collects results and errors, clears cache, and returns formatted summary.export async function handleBulkCreateTasks( todoistClient: TodoistApi, args: BulkCreateTasksArgs ): Promise<string> { try { const createdTasks: TodoistTask[] = []; const errors: string[] = []; for (const taskArgs of args.tasks) { try { // Validate each task input validateTaskContent(taskArgs.content); validatePriority(taskArgs.priority); validateDateString(taskArgs.deadline_date, "deadline_date"); validateLabels(taskArgs.labels); validateProjectId(taskArgs.project_id); validateSectionId(taskArgs.section_id); const taskData: TodoistTaskData = { content: taskArgs.content, description: taskArgs.description, dueString: taskArgs.due_string, }; const apiPriority = toApiPriority(taskArgs.priority); if (apiPriority !== undefined) { taskData.priority = apiPriority; } if (taskArgs.labels && taskArgs.labels.length > 0) { taskData.labels = taskArgs.labels; } if (taskArgs.deadline_date) taskData.deadlineDate = taskArgs.deadline_date; if (taskArgs.project_id) taskData.projectId = taskArgs.project_id; if (taskArgs.section_id) taskData.sectionId = taskArgs.section_id; const task = await todoistClient.addTask(taskData); createdTasks.push(task); } catch (error) { const errorMessage = error instanceof Error ? error.message : String(error); // Provide more specific error messages based on the error if ( errorMessage.includes("400") || errorMessage.includes("Bad Request") ) { errors.push( `Failed to create task "${taskArgs.content}": Invalid request format. Check that all parameters are correct.` ); } else if ( errorMessage.includes("401") || errorMessage.includes("Unauthorized") ) { errors.push( `Failed to create task "${taskArgs.content}": Authentication failed. Check your API token.` ); } else if ( errorMessage.includes("403") || errorMessage.includes("Forbidden") ) { errors.push( `Failed to create task "${taskArgs.content}": Access denied. You may not have permission to add tasks to this project.` ); } else if ( errorMessage.includes("404") || errorMessage.includes("Not Found") ) { errors.push( `Failed to create task "${taskArgs.content}": Project or section not found. Verify the IDs are correct.` ); } else { errors.push( `Failed to create task "${taskArgs.content}": ${errorMessage}` ); } } } // Clear cache after bulk creation taskCache.clear(); const successCount = createdTasks.length; const errorCount = errors.length; // Check if we're in dry-run mode const isDryRun = process.env.DRYRUN === "true"; const prefix = isDryRun ? "[DRY-RUN] " : ""; let result = `${prefix}Bulk task creation completed: ${successCount} created, ${errorCount} failed.\n\n`; if (successCount > 0) { result += "Created tasks:\n"; result += createdTasks .map((task) => `- ${task.content} (ID: ${task.id})`) .join("\n"); result += "\n\n"; } if (errorCount > 0) { result += "Errors:\n"; result += errors.join("\n"); } return result.trim(); } catch (error) { ErrorHandler.handleAPIError("bulk create tasks", error); } }
- src/tools/task-tools.ts:218-278 (schema)Defines the Tool object with name, description, and detailed inputSchema for bulk tasks array, each mirroring single task create schema.export const BULK_CREATE_TASKS_TOOL: Tool = { name: "todoist_tasks_bulk_create", description: "Create multiple tasks at once for improved efficiency. Each task can have full attributes like individual task creation.", inputSchema: { type: "object", properties: { tasks: { type: "array", items: { type: "object", properties: { content: { type: "string", description: "The content/title of the task", }, description: { type: "string", description: "Detailed description of the task (optional)", }, due_string: { type: "string", description: "Natural language due date like 'tomorrow', 'next Monday' (optional)", }, priority: { type: "number", description: "Task priority from 1 (highest) to 4 (lowest) (optional)", enum: [1, 2, 3, 4], }, labels: { type: "array", items: { type: "string", }, description: "Array of label names to assign to the task (optional)", }, deadline_date: { type: "string", description: "Task deadline in YYYY-MM-DD format (optional)", }, project_id: { type: "string", description: "Project ID to assign the task to (optional)", }, section_id: { type: "string", description: "Section ID to assign the task to (optional)", }, }, required: ["content"], }, description: "Array of task objects to create", minItems: 1, }, }, required: ["tasks"], }, };
- src/index.ts:212-217 (registration)Registers the tool handler in the main request handler switch statement, validates args with isBulkCreateTasksArgs type guard, and calls handleBulkCreateTasks.case "todoist_tasks_bulk_create": if (!isBulkCreateTasksArgs(args)) { throw new Error("Invalid arguments for todoist_tasks_bulk_create"); } result = await handleBulkCreateTasks(apiClient, args); break;
- src/type-guards.ts:133-145 (schema)Type guard function for validating BulkCreateTasksArgs: ensures 'tasks' is non-empty array where each item passes isCreateTaskArgs validation.export function isBulkCreateTasksArgs( args: unknown ): args is BulkCreateTasksArgs { if (typeof args !== "object" || args === null) return false; const obj = args as Record<string, unknown>; return ( "tasks" in obj && Array.isArray(obj.tasks) && obj.tasks.length > 0 && obj.tasks.every((task) => isCreateTaskArgs(task)) ); }
- src/tools/index.ts:62-69 (registration)Aggregates all tools including TASK_TOOLS (which contains todoist_tasks_bulk_create) into ALL_TOOLS array, exported for server.listTools() to return.export const ALL_TOOLS = [ ...TASK_TOOLS, ...PROJECT_TOOLS, ...COMMENT_TOOLS, ...LABEL_TOOLS, ...SUBTASK_TOOLS, ...TEST_TOOLS, ];