Todoist AI MCP Server
OfficialServer Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| TODOIST_API_KEY | Yes | Your Todoist API token, used to authenticate the client and access your account data. |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
Todoist Task and Project Management Tools
You have access to comprehensive Todoist management tools for personal productivity and team collaboration. Use these tools to help users manage tasks, projects, sections, comments, and assignments effectively.
Core Capabilities:
Create, update, complete, and search tasks with rich metadata (priorities, due dates, durations, assignments)
Manage projects and sections with flexible organization
Handle comments and collaboration features
Bulk assignment operations for team workflows
Get overviews and insights about workload and progress
Choosing between tools
What each tool does and how to fill its parameters is in the tool's own description and input schema. This section covers only what those cannot: which tool to reach for, and how tools relate to each other.
Dates
To move a task to a different date or time use reschedule-tasks, never update-tasks. It also sets duration, for time-blocking. update-tasks replaces the whole due string, so it refuses a dueString on a recurring task unless replaceRecurrence is true.
Never send a task's existing projectId, sectionId or parentId back to update-tasks — those fields are treated as a move.
All dates respect the user's timezone.
Todoist apps only display task durations under 24 hours. A longer one ("36h") or a day-based one ("3d") is stored and reported faithfully, but the apps show the task as having no duration — only set one when the user explicitly asks for it.
Finding things
For "what did I complete?", call user-info for the asker's user ID, then find-activity with objectType="task", eventType="completed", initiatorId, and dateFrom/dateTo. Without initiatorId the answer covers every collaborator. find-activity reports completion events, including each occurrence of a recurring task; find-completed-tasks lists completed tasks, which is not the same question.
To resolve a person's name or email to a user ID, or to answer "who is X?", use find-project-collaborators with just a searchTerm. It covers every shared project you can access plus yourself, so an empty result means they collaborate on none of them — not that they do not exist.
Before assigning work to someone, call find-project-collaborators again with the target projectId. Resolving an ID only proves they collaborate on some project you can see; assignment fails unless they collaborate on that one.
To find out whether a task hides subtasks, use fetch-object with includeChildren rather than a speculative find-tasks call.
Filter tasks by label name. Label IDs are only for delete-object and update-labels. Shared labels can be renamed but not recoloured, reordered or favourited.
Comments
Comments notify only the people add-comments is handed. When a comment mentions someone, name them in
notifyUsers— writing "@Ana" in the text notifies nobody. OmitnotifyUsersto notify whoever the Todoist apps would, or pass["none"]to stay silent.Notification cannot be sent when editing a comment, only when adding one.
Deleting and archiving
delete-object removes every object type; there is no per-type delete tool. Reminders use type "reminder", location reminders "location_reminder".
A workspace project must be archived with project-management before it can be deleted. A personal project can be deleted directly.
Templates
Templates cannot be listed through this server, so only use an ID or URL the user gave you. To start a new project from one, call add-projects first and import into it. Imports write immediately and cannot be undone.
Project health
Health data may be stale — check the isStale flag, and call analyze-project-health to refresh it before reading again.
Batches
Prefer a batch tool over one call per item.
Where a batch tool returns per-item
failuresalongside successes, one failure does not undo the rest: never retry the whole batch, re-send only the items whose failure reason is fixable. reschedule-tasks is the exception — it has no per-item failures and throws if any task fails, so retry it as a whole.
Use the productivity-analysis prompt for a combined productivity review — it pulls together user-info, get-productivity-stats and find-completed-tasks.
Always provide clear, actionable task titles and descriptions. Use the overview tools to give users context about their workload and project status.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": true
} |
| prompts | {
"listChanged": true
} |
| resources | {
"listChanged": true
} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| add-tasksB | Add one or more tasks to a project, section, or parent. Supports assignment to project collaborators. |
| complete-tasksA | Complete one or more tasks by their IDs. |
| uncomplete-tasksA | Uncomplete (reopen) one or more completed tasks by their IDs. |
| update-tasksA | Update existing tasks including content, dates, priorities, and assignments. Send only the fields that change. |
| reschedule-tasksA | Reschedule tasks to new dates while preserving recurring schedules. Unlike update-tasks (which replaces the entire due string and can wipe recurrence), this tool changes only the date (and duration, if given), keeping recurrence patterns intact. Use this when moving recurring tasks to a different date or time without altering their repeat pattern. Without a due date, the deadline moves. |
| find-tasksA | Find tasks by text search, project/section/parent container, responsible user, labels, a raw Todoist filter string, or a saved filter by ID or name (filterIdOrName). At least one filter must be provided. |
| find-tasks-by-dateA | Get tasks by date range. startDate='today' includes overdue items. Default responsibleUserFiltering='unassignedOrMe' excludes others' tasks. |
| find-completed-tasksA | Get completed tasks in a date range. Neither getBy mode returns completions of a recurring task that is still active. For "what did I complete/get done" questions, or whenever recurring work should count, use find-activity instead — it reports completion events, including every occurrence of a recurring task. since/until are optional and default to a 7-day window when omitted. Includes all collaborators by default. Person-specific queries (summaries, plans, reports) require responsibleUser. |
| add-projectsC | Add one or more new projects. |
| update-projectsC | Update multiple existing projects with new values. |
| find-projectsA | List or search by name the projects the user has joined. By default only active projects are returned; use archivedStatus ('archived' or 'all') to include archived projects. When searching or when archivedStatus is 'all', all matching projects are returned (pagination is ignored). Otherwise projects are returned with pagination. Workspace projects the user hasn't joined are left out unless includeUnjoined is set, or a search matches no joined project. |
| project-managementA | Archive or unarchive a project by its ID, or join a workspace project the user hasn't joined (see find-projects includeUnjoined) when they ask to. |
| project-moveC | Move a project between personal and workspace contexts. |
| add-sectionsC | Add one or more new sections to projects. |
| update-sectionsB | Update multiple existing sections with new values. |
| find-sectionsA | Search for sections by name or other criteria in a project. When searching, uses server-side search to avoid fetching all sections. |
| add-commentsA | Add multiple comments to tasks or projects, optionally notifying collaborators. Each comment must specify either taskId or projectId. |
| find-commentsA | Find comments by task, project, or get a specific comment by ID. Exactly one of taskId, projectId, or commentId must be provided. |
| update-commentsC | Update multiple existing comments with new content. |
| add-remindersA | Add reminders to tasks. Supports three types: "relative" (minutes before due), "absolute" (specific date/time), or "location" (geofence-triggered). Each reminder must specify a taskId. Reminders notify their creator unless notifyUser says otherwise. |
| find-remindersA | Find reminders by task ID (returns all reminder types), or get a specific reminder by its ID. Use reminderId for time-based reminders and locationReminderId for location reminders. |
| update-remindersB | Update existing reminders. Each reminder must specify its type ("relative", "absolute", or "location") and ID. Only include fields that need to change. |
| view-attachmentA | View a file attachment from a Todoist comment. Pass the fileUrl from a comment's fileAttachment field. Supports images (returned inline), text files (returned as text), and binary files like PDFs (returned as embedded resources). |
| add-labelsC | Add one or more new personal labels. |
| update-labelsA | Update one or more existing labels. Personal labels (identified by ID) can have their name, color, order, and favorite flag updated. Shared labels (identified by name) can only be renamed. |
| find-labelsA | List personal labels and shared labels. Personal labels have full metadata (id, name, color, order, isFavorite) and support pagination and name search (partial, case insensitive). Shared labels are labels used on tasks shared with you — they are returned as names only (no IDs or metadata). When searching, all matching personal labels are fetched across all pages and returned as a single result set (limit and cursor are ignored). When not searching, personal labels are returned with pagination. |
| find-filtersA | List all personal filters or search for filters by name. Filters are saved custom views that use query syntax to organize tasks (e.g. "today & p1", "#Work & overdue"). |
| add-filtersA | Add one or more new personal filters. Filters are saved custom views using query syntax to organize tasks. |
| update-filtersB | Update one or more existing personal filters with new values. |
| find-activityA | Retrieve activity logs to monitor and audit changes in Todoist. Shows events from all users by default (use initiatorId to filter by specific user). To answer what someone completed in a period, including recurring task occurrences, use objectType "task", eventType "completed", and dateFrom/dateTo. For a first-person question ("what did I get done"), also set initiatorId to the current user from user-info, or the answer includes collaborators' completions. Track task completions, updates, deletions, project changes, and more with flexible filtering. Activity history availability and retention depend on the user plan. |
| get-productivity-statsA | Get comprehensive productivity statistics including daily/weekly completion breakdowns, goal streaks (current, last, max), karma score and trends, and historical karma data. Useful for productivity analysis and tracking goal progress. Reports counts, streaks and karma only, never the tasks themselves — for "what did I complete", use find-activity. |
| get-project-healthB | Get a comprehensive health assessment for a project including completion progress, health status (EXCELLENT, ON_TRACK, AT_RISK, CRITICAL), and optional detailed context with project metrics and task-level data. Use includeContext=true for that full detail. |
| get-project-activity-statsA | Get daily and optional weekly task completion counts for a project over a configurable time window (1-12 weeks). Useful for identifying completion trends and patterns. |
| analyze-project-healthA | Trigger a new health analysis for a project. Use this when the health data is stale or you want a fresh assessment. The analysis may take time to complete — use get-project-health afterward to see updated results. |
| get-workspace-insightsA | Get aggregated health and progress insights across all projects in a workspace. Accepts workspace name or ID, with optional project ID filtering. Useful for a cross-project health overview. |
| get-overviewA | Get a Markdown overview. Called without a projectId, returns the account's project and section structure only — no tasks — for navigation. Pass a projectId (or "inbox" for the Inbox) to get that project's tasks grouped by section. |
| delete-objectA | Delete a project, section, task, comment, label, filter, reminder, or location_reminder by its ID. Projects can be deleted whether active or archived (find archived ones via find-projects with archivedStatus); note a workspace project must be archived before it can be deleted, while personal projects can be deleted regardless. |
| fetch-objectA | Fetch a single task, project, comment, or section by its ID. Use this when you have a specific object ID and want to retrieve its full details. Set includeChildren to also get its direct subtasks or sub-projects. |
| reorder-objectsA | Reorder projects or sections, and optionally move personal projects to a new parent. Personal projects: order places a project among its siblings; parentId moves it ("root" for top level). Workspace projects: order places a project within its folder, in the shared default ordering every member sees; needs permission to reorder the workspace. Sections: order places a section within its project. |
| user-infoB | Get comprehensive user information including user ID, full name, email, timezone with current local time, week start day preferences, current week dates, daily/weekly goal progress, and user plan (Free/Pro/Business). |
| get-user-statusA | Get the user's status, the message and emoji shown next to their name in Todoist and Comms, with when it ends and whether it pauses Comms notifications or Karma and streaks. Returns no status when none is set or it has expired. |
| set-user-statusA | Set or clear the user's status, shown next to their name in Todoist and Comms. Replaces the whole status: an omitted emoji, end or effect is removed, not kept. Use clear to remove the status. |
| find-project-collaboratorsA | Find Todoist users (collaborators, teammates) by name or email to look up their user ID. Use this whenever the user asks to find, look up, or identify a person — e.g. "find Carrie's user ID", "who is Ernesto", "look up a user". When projectId is omitted, searches across the collaborators of every shared project the authenticated user has access to, plus the authenticated user themselves — an empty result means the person is not a collaborator on any project you share with them, not necessarily that they do not exist in Todoist. When projectId is provided, searches only that project. Partial, case-insensitive match on name and email. |
| manage-assignmentsA | Assign, unassign or reassign up to 50 tasks at once. Assigning notifies the new assignee. Each task is updated independently, so one failure does not undo the others; failures are reported per task. Use dryRun to check the changes first. |
| export-project-templateA | Export an existing project as a Todoist template, either as CSV content or as a shareable URL. Use it to duplicate a project, share its structure, or hand the CSV to import-project-template. To read a project rather than export it, use find-tasks instead — it returns structured tasks rather than raw CSV. The project itself is not modified, but the "url" format uploads a copy and returns a link that anyone holding it can open. |
| import-project-templateA | Import a template into an existing project, adding its tasks, sections and comments to whatever is already there. Source it by template ID/URL or by passing CSV content from export-project-template. To start a new project from a template, create the project with add-projects first, then import into it. This writes immediately and cannot be undone, so only run it against a project the user named. |
| list-workspacesA | Get all workspaces for the authenticated user. Returns workspace details including ID, name, plan type (STARTER/BUSINESS), user role (ADMIN/MEMBER/GUEST), link sharing settings, guest permissions, creation date, and creator ID. |
| searchA | Search across tasks and projects in Todoist. Returns a list of relevant results with IDs, titles, and URLs. |
| fetchA | Fetch the full contents of a task or project by its ID. The ID should be in the format "task:{id}" or "project:{id}". (Comments may exist; use find-comments to retrieve them.) |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
| productivity-analysis | Analyze your Todoist productivity with insights on completion trends, goal streaks, project distribution, and actionable recommendations. Gathers data from multiple tools and synthesizes a comprehensive report. |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
| todoist-task-list | Interactive task list widget |
TDQS
Scored across 49 tools
Most tools have distinct resource+action targets, and the descriptions proactively cross-reference each other (find-activity vs find-completed-tasks, reschedule-tasks vs update-tasks, export vs find-tasks). However a few pairs genuinely overlap: fetch vs fetch-object both retrieve an object by ID, search vs find-tasks both locate tasks, and get-project-health vs analyze-project-health vs get-project-activity-stats require careful reading to distinguish.
The dominant convention is clear verb-noun hyphenated (find-tasks, add-comments, update-labels, delete-object). A handful of outliers break it: bare verbs 'search' and 'fetch', noun-only 'user-info' and the vague 'project-management', and reversed-order 'project-move'.
49 tools is far beyond a well-scoped surface for a task manager; the 3-15 range would be typical. Several tools exist only for narrow variants (get-project-activity-stats, analyze-project-health, project-move, view-attachment) that inflate the set and increase selection cost.
The surface covers full lifecycle CRUD for tasks, projects, sections, comments, reminders, labels, and filters, plus completion/uncompletion, activity logs, productivity stats, templates, workspaces, collaborators, assignments, and attachments. No obvious dead ends remain for the Todoist domain.