Skip to main content
Glama
greirson

Todoist MCP Server

todoist_task_create

Create a new task in Todoist with details like description, due date, priority, labels, and project assignment to organize your work.

Instructions

Create a new task in Todoist with optional description, due date, priority, labels, deadline, project, and section

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
contentYesThe content/title of the task
descriptionNoDetailed description of the task (optional)
due_stringNoNatural language due date like 'tomorrow', 'next Monday', 'Jan 23' (optional)
priorityNoTask priority from 1 (highest) to 4 (lowest) (optional)
labelsNoArray of label names to assign to the task (optional)
deadline_dateNoTask deadline in YYYY-MM-DD format (when user mentions 'deadline') (optional)
project_idNoProject ID to assign the task to (optional)
section_idNoSection ID within the project to assign the task to (optional)

Implementation Reference

  • Core handler function that validates input parameters, constructs the task data object, calls the Todoist API to add the task, clears the task cache, and returns a formatted success message with task details.
    export async function handleCreateTask(
      todoistClient: TodoistApi,
      args: CreateTaskArgs
    ): Promise<string> {
      return ErrorHandler.wrapAsync("create task", async () => {
        // Validate and sanitize input
        const sanitizedContent = validateTaskContent(args.content);
        const sanitizedDescription = validateDescription(args.description);
        validatePriority(args.priority);
        validateDateString(args.deadline_date, "deadline_date");
        validateLabels(args.labels);
        validateProjectId(args.project_id);
        validateSectionId(args.section_id);
    
        const taskData: TodoistTaskData = {
          content: sanitizedContent,
          description: sanitizedDescription,
          dueString: args.due_string,
        };
    
        const apiPriority = toApiPriority(args.priority);
        if (apiPriority !== undefined) {
          taskData.priority = apiPriority;
        }
    
        if (args.labels && args.labels.length > 0) {
          taskData.labels = args.labels;
        }
    
        if (args.deadline_date) {
          taskData.deadlineDate = args.deadline_date;
        }
    
        if (args.project_id) {
          taskData.projectId = args.project_id;
        }
    
        if (args.section_id) {
          taskData.sectionId = args.section_id;
        }
    
        const task = await todoistClient.addTask(taskData);
    
        // Clear cache after creating task
        taskCache.clear();
    
        const displayPriority = fromApiPriority(task.priority);
        const dueDetails = formatDueDetails(task.due);
    
        // Check if this was a dry-run operation
        const isDryRun = (task as any).__dryRun === true;
        const prefix = isDryRun ? "[DRY-RUN] " : "";
    
        return `${prefix}Task created:\nID: ${task.id}\nTitle: ${task.content}${
          task.description ? `\nDescription: ${task.description}` : ""
        }${dueDetails ? `\nDue: ${dueDetails}` : ""}${
          displayPriority ? `\nPriority: ${displayPriority}` : ""
        }${
          task.labels && task.labels.length > 0
            ? `\nLabels: ${task.labels.join(", ")}`
            : ""
        }${args.deadline_date ? `\nDeadline: ${args.deadline_date}` : ""}${
          args.project_id ? `\nProject ID: ${args.project_id}` : ""
        }${args.section_id ? `\nSection ID: ${args.section_id}` : ""}`;
      });
    }
  • Defines the Tool object for todoist_task_create including name, description, and detailed inputSchema with properties, types, descriptions, enums, and required fields.
    export const CREATE_TASK_TOOL: Tool = {
      name: "todoist_task_create",
      description:
        "Create a new task in Todoist with optional description, due date, priority, labels, deadline, project, and section",
      inputSchema: {
        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', 'Jan 23' (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 (when user mentions 'deadline') (optional)",
          },
          project_id: {
            type: "string",
            description: "Project ID to assign the task to (optional)",
          },
          section_id: {
            type: "string",
            description:
              "Section ID within the project to assign the task to (optional)",
          },
        },
        required: ["content"],
      },
    };
  • src/index.ts:149-154 (registration)
    Registers the tool handler in the main switch statement of CallToolRequestSchema: validates args with isCreateTaskArgs and calls handleCreateTask.
    case "todoist_task_create":
      if (!isCreateTaskArgs(args)) {
        throw new Error("Invalid arguments for todoist_task_create");
      }
      result = await handleCreateTask(apiClient, args);
      break;
  • Aggregates all tools including TASK_TOOLS (which contains todoist_task_create) into ALL_TOOLS array, used by ListToolsRequestSchema to expose the tool.
    export const ALL_TOOLS = [
      ...TASK_TOOLS,
      ...PROJECT_TOOLS,
      ...COMMENT_TOOLS,
      ...LABEL_TOOLS,
      ...SUBTASK_TOOLS,
      ...TEST_TOOLS,
    ];
  • Type guard function used to validate arguments before dispatching to the handler, ensuring 'content' is present as string.
    export function isCreateTaskArgs(args: unknown): args is CreateTaskArgs {
      return (
        typeof args === "object" &&
        args !== null &&
        "content" in args &&
        typeof (args as { content: string }).content === "string"
      );
    }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/greirson/mcp-todoist'

If you have feedback or need assistance with the MCP directory API, please join our Discord server