Local stdio MCP server exposing Todoist operations — a Zapier replacement.
Solid foundation with clear naming and comprehensive parameter schemas. All 9 tools have descriptions and input schemas with typed parameters. However, descriptions lack LLM-optimized guidance on WHEN to use each tool vs. alternatives, and output schemas are not documented. Error handling is minimal, API errors return structured dicts but lack recovery guidance. No tool annotations (readOnlyHint/destructiveHint) despite clear risk profiles. Parameter descriptions are adequate but could be more prescriptive about constraints and dependencies.
Mark a Todoist task as complete. Returns {completed, task_id}.
Create a new Todoist project. Returns the created project.
Create a new Todoist task. priority: 1=normal (lowest) through 4=urgent (highest). due_string: natural language like "tomorrow at 3pm", "every monday". Returns the created task.
Fetch one task by id with its FULL description (search truncates to 200 chars). Use this whenever you need the whole description: it is a read, so it never changes the task. Returns the same shape as update_task.
List all Todoist labels. Returns id, name, color, is_favorite for each.
List all Todoist projects. Returns id, name, and parent_id for each.
No output schemas documented. LLMs cannot infer what fields to expect from responses (e.g., task object structure, pagination info for search results). This forces agents to guess field names and risks downstream tool call failures.
Missing tool annotations. All tools lack readOnlyHint/destructiveHint/idempotentHint. Agents cannot distinguish safe reads (list_projects, search_tasks) from destructive writes (complete_task, create_task) without reading descriptions. This violates current MCP spec (2026-07-28).
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 61 | 2026-07-28+ | v2 |
List sections in a Todoist project. Returns id, name, project_id, order for each.
Search Todoist tasks using the native filter syntax. Filter examples: "@waiting-on" — tasks with the waiting-on label "p1 & today" — priority-1 tasks due today "#Inbox & no date" — Inbox tasks with no due date "overdue" — anything past its due date "7 days & !@waiting-on" — due in next 7 days, excluding waiting-on limit caps at 200 (default 50). Descriptions are truncated to 200 chars. Response: {tasks: [...], count: int, truncated: bool}. truncated=true means there are more matches than `limit` — refine the filter or raise the limit.
Update a Todoist task. Only fields you pass are changed. Moves (project_id / section_id / parent_id) are handled automatically via the move endpoint — you can change section + content in one call. Returns the updated task.
Error handling lacks recovery guidance. API errors return {error, code, message} but do not tell the LLM what to do next. E.g., 429 rate-limit errors include retry_after but no guidance on backoff strategy. 404 errors do not suggest alternatives.
Parameter descriptions lack constraint details. E.g., priority is '1-4' but no description states this range. due_string accepts 'natural language' but no examples of valid formats. filter in search_tasks references Todoist syntax but does not explain what happens on invalid filters.
search_tasks returns truncated descriptions (200 chars) but does not document this in the output schema. Agents may not realize they need to call todoist_get_task for full content, leading to incomplete reasoning.