Skip to content

Connect Todoist to Claude: Manage Labels, Sections, and Files via MCP

Learn how to connect Todoist to Claude using a managed MCP server. Give AI agents secure read/write access to manage tasks, sections, labels, and files.

Uday Gajavalli Uday Gajavalli · · 10 min read
Connect Todoist to Claude: Manage Labels, Sections, and Files via MCP

If you need to connect Todoist to Claude to automate task delegation, sprint planning, or file management, you need a Model Context Protocol (MCP) server. This server acts as the translation layer between Claude's tool calls and Todoist's REST API. You can either build, host, and maintain this infrastructure yourself, or use a managed integration platform like Truto to dynamically generate a secure, authenticated MCP server URL. If your team uses ChatGPT, check out our guide on connecting Todoist to ChatGPT or explore our broader architectural overview on connecting Todoist to AI Agents.

Giving a Large Language Model (LLM) read and write access to a personal or enterprise Todoist workspace is an engineering challenge. You have to handle OAuth 2.0 token lifecycles, map JSON schemas to MCP tool definitions, and deal with Todoist's specific hierarchical data structures. Every time the integration breaks, or an LLM hallucination causes a bad payload, you have to debug the raw API logs.

This guide breaks down exactly how to use Truto to generate a secure, managed MCP server for Todoist, connect it natively to Claude, and execute complex workflows using natural language.

The Engineering Reality of the Todoist API

A custom MCP server is a self-hosted integration layer. While the open MCP standard provides a predictable way for models to discover tools, the reality of implementing it against Todoist's REST API is complex.

If you decide to build a custom MCP server for Todoist, you own the entire API lifecycle. Here are the specific challenges you will face:

Strict Idempotency Requirements When creating tasks via the Todoist REST API, the system relies heavily on idempotency keys (typically passed via the X-Request-Id header) to prevent duplicate task creation on network retries. LLMs are notoriously bad at generating consistent UUIDs and managing idempotency state across multiple tool calls. If Claude's connection drops and it retries a task creation without the exact same UUID, you get duplicate tasks. A managed platform abstracts this requirement, ensuring that the proxy layer handles request uniqueness.

Complex Hierarchical Data States Todoist's data model is deeply nested: Projects contain Sections, Sections contain Tasks, Tasks can have parent Tasks (sub-tasks), and Tasks contain Comments and Attachments. Deleting a parent item (like a project or a section) cascade-deletes all of its children. Furthermore, moving a section to a different project can result in the API returning a 301 Moved Permanently redirect with a new URL for the section. Exposing raw endpoints to Claude often results in the model getting confused by these relational constraints. Truto normalizes this by flattening the input namespace for MCP tools, allowing Claude to cleanly target specific resource IDs.

Attachment Extraction and File Handling Comments in Todoist often contain attachments, but extracting these files for an LLM to read is non-trivial. The API returns a file_url, but accessing it requires properly authenticated HTTP GET requests. If Claude tries to fetch the URL directly without the right context, the request will fail. An MCP server needs a dedicated tool just to proxy file downloads so the model can ingest the attachment content securely.

How to Generate a Todoist MCP Server with Truto

Truto automatically generates MCP tools dynamically from an integration's underlying resource definitions and API documentation. Rather than hand-coding tool definitions for every Todoist endpoint, Truto derives them instantly.

Each MCP server is scoped to a single connected Todoist account. The server URL contains a cryptographic token that encodes which account to use and what tools to expose.

There are two ways to create a Todoist MCP server in Truto: via the UI or programmatically via the API.

Method 1: Creating the MCP Server via the Truto UI

For internal tooling, one-off automation, or testing, generating the server through the dashboard is the fastest route.

  1. Navigate to the Integrated Accounts page in your Truto dashboard and select your connected Todoist account.
  2. Click the MCP Servers tab.
  3. Click Create MCP Server.
  4. Configure your server settings. You can name it, set an expiration date, or restrict it to specific methods (e.g., read-only).
  5. Click Create and copy the generated MCP server URL (e.g., https://api.truto.one/mcp/a1b2c3d4...).

Method 2: Creating the MCP Server via the API

If you are building an AI agent product for your customers, you should generate MCP servers programmatically after the user completes the OAuth flow.

Send a POST request to the /integrated-account/:id/mcp endpoint:

curl -X POST https://api.truto.one/integrated-account/{integrated_account_id}/mcp \
  -H "Authorization: Bearer YOUR_TRUTO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Claude Desktop - Todoist Project Manager",
    "config": {
      "methods": ["read", "write", "custom"]
    },
    "expires_at": "2026-12-31T23:59:59Z"
  }'

The response will return the secure MCP server URL:

{
  "id": "mcp_abc123",
  "name": "Claude Desktop - Todoist Project Manager",
  "config": { "methods": ["read", "write", "custom"] },
  "expires_at": "2026-12-31T23:59:59Z",
  "url": "https://api.truto.one/mcp/a1b2c3d4e5f6g7h8i9j0"
}

This URL is fully self-contained. It handles authentication against Todoist, validates the JSON-RPC requests, and proxies the API calls.

Connecting the MCP Server to Claude

Once you have your Truto MCP URL, you need to register it with your LLM client. You can do this through the Claude UI or via a configuration file for Claude Desktop.

Method A: Via the Claude UI (Web)

If you are using Claude for Work (Team or Enterprise) or ChatGPT Plus/Enterprise, you can add the connector directly in the browser.

  1. In Claude, navigate to Settings -> Integrations -> Add MCP Server. (If you are using ChatGPT, go to Settings -> Apps -> Advanced settings -> Developer mode -> Custom connectors -> Add).
  2. Name the connector (e.g., "Todoist Workspace").
  3. Paste the Truto MCP URL generated in the previous step.
  4. Click Add. Claude will instantly send an initialize request to the server, fetch the available Todoist tools, and register them in its context window.

Method B: Via Manual Config File (Claude Desktop)

If you are using the Claude Desktop application for local development or local agent execution, you connect the server by editing the claude_desktop_config.json file.

Since Truto's MCP server speaks Server-Sent Events (SSE) over HTTP, you will use the official @modelcontextprotocol/server-sse transport proxy to connect Claude Desktop to the remote Truto URL.

Open your configuration file:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json

Add the Todoist server block:

{
  "mcpServers": {
    "todoist_truto": {
      "command": "npx",
      "args": [
        "-y",
        "@modelcontextprotocol/server-sse",
        "https://api.truto.one/mcp/a1b2c3d4e5f6g7h8i9j0"
      ]
    }
  }
}

Restart Claude Desktop. The application will boot the SSE client, handshake with Truto, and load the Todoist tools (indicated by a small hammer icon in the input bar).

Hero Tools for Todoist Workflows

Truto exposes the entirety of the Todoist REST API, but agentic workflows rely heavily on a specific subset of high-leverage tools. Here are the 6 hero tools you will use most often.

list_all_todoist_tasks

Retrieves all active tasks in the Todoist account. Crucial for agent context gathering. It returns fields including id, content, description, is_completed, due, project_id, section_id, and labels.

Usage note: Truto normalizes pagination into a standard limit and next_cursor schema. If a user has thousands of tasks, Claude knows exactly how to iterate through the pages without guessing Todoist's specific pagination parameters.

"Fetch all my active tasks. Filter them locally to find any that are overdue or missing a project assignment, and summarize them for me."

create_a_todoist_task

Creates a new task. Requires the content field. Optional fields include description, due_string (natural language parsing supported by Todoist like "next monday at 3pm"), project_id, section_id, and priority.

Usage note: Because Todoist supports natural language for due dates in its REST API, Claude can pass raw text like "tomorrow" directly into the due_string parameter, relying on Todoist's backend to calculate the exact timestamp.

"Create a new task in the 'Engineering' project under the 'Backlog' section called 'Refactor Auth Middleware'. Set the priority to high and make it due next Friday."

update_a_todoist_task_by_id

Modifies an existing task. You must pass the task id. This is heavily used by agents during triage to reassign dates, move tasks between sections, or update labels.

Usage note: Do not attempt to use this to close a task. Use the dedicated todoist_tasks_close tool instead.

"Look up task ID 123456789. Move it to the 'Sprint 4' section and add the label 'frontend'."

list_all_todoist_comments

Retrieves the comments on a specific task or project. Requires either task_id or project_id.

Usage note: Comments are where the actual context of a task usually lives. If a task is named "Fix bug 402", the agent must call this tool to read the comments and understand the bug before taking action.

"Get all the comments on task ID 987654321 and summarize the discussion between the engineering team."

todoist_attachment_download

Downloads an attachment file from the Todoist system.

Usage note: When list_all_todoist_comments returns an attachment object, it includes a file URL. The agent must pass that reference to this download tool to securely retrieve the file bytes. This is critical when PRDs, spec sheets, or error logs are attached to tasks.

"There is an attachment on the latest comment for the 'Q3 Planning' task. Download it, read the contents, and list the 5 main objectives mentioned in the document."

get_single_todoist_section_by_id

Retrieves a specific section within a project. Returns id, project_id, order, and name.

Usage note: If a section has been moved between projects, the Todoist API issues a 301 redirect. Truto's proxy layer handles the underlying HTTP complexities, allowing the agent to confidently target section IDs.

"Get the details for section ID 555666777. Which project does it currently belong to?"

For the complete tool inventory, including project management, shared label renaming, and collaborator fetching, view the Todoist Integration Page.

Workflows in Action

Exposing individual tools is only the first step. The true value of an MCP integration is the ability to orchestrate complex, multi-step operations autonomously.

Scenario 1: Weekly Project Triage

Product managers spend hours every Monday reviewing old tasks, pushing back due dates, and organizing the current week's sprint. An AI agent can automate this entirely.

"Review all tasks in the 'Product Roadmap' project. Find any tasks that were due last week and are still open. Add a comment to each asking 'Still blocked?', update their due date to this coming Friday, and list them out for me here."

Agent Execution Path:

  1. Calls list_all_todoist_projects to find the ID for "Product Roadmap".
  2. Calls list_all_todoist_tasks with the project_id parameter to filter tasks.
  3. Claude locally analyzes the returned tasks against the current date to identify overdue items.
  4. Loops over the overdue tasks:
    • Calls create_a_todoist_comment with task_id and content: "Still blocked?".
    • Calls update_a_todoist_task_by_id with due_string: "this Friday".

Result: The user gets a summarized list in the chat window, while Todoist is updated in the background. The agent handled pagination, ID lookups, and chronological calculations automatically.

Scenario 2: Spec Ingestion and Sub-Task Breakdown

When a new feature specification is finalized, a lead engineer typically has to manually break that document down into individual tracking tasks.

sequenceDiagram
    participant User
    participant Claude as Claude (via MCP)
    participant Truto as Truto MCP Server
    participant Todoist as Todoist API

    User->>Claude: "Read the spec attached to task X and generate sub-tasks"
    Claude->>Truto: call list_all_todoist_comments(task_id: X)
    Truto->>Todoist: GET /comments?task_id=X
    Todoist-->>Truto: Returns comment with file_url
    Truto-->>Claude: JSON response with attachment data
    Claude->>Truto: call todoist_attachment_download(file_url)
    Truto->>Todoist: GET file_url
    Todoist-->>Truto: Raw file bytes
    Truto-->>Claude: Extracted text content
    Note over Claude: Claude reads the spec and identifies 4 required steps
    Claude->>Truto: call create_a_todoist_task (x4)
    Truto->>Todoist: POST /tasks (x4)
    Todoist-->>Truto: 200 OK (x4)
    Truto-->>Claude: Success
    Claude-->>User: "I have created 4 sub-tasks based on the spec document."

"Task ID 11223344 has a spec document attached in the comments. Download it, extract the core requirements, and create a separate sub-task under the main task for each requirement. Label them all as 'backend'."

Agent Execution Path:

  1. Calls list_all_todoist_comments for the specified task ID to locate the attachment metadata.
  2. Calls todoist_attachment_download to pull the file contents into context.
  3. Claude parses the document, identifying the distinct engineering requirements.
  4. Calls create_a_todoist_task multiple times, passing the parent task_id (to make them sub-tasks), the content derived from the spec, and the labels array containing ["backend"].

Result: The agent effectively acts as a technical project manager, transposing unstructured document data into structured Todoist architecture.

Security and Access Control

When connecting a powerful LLM to a live productivity database, you must enforce strict boundaries. Truto provides four key security primitives at the MCP server configuration level:

  • Method Filtering (methods): Restrict an MCP server to only perform safe operations. By passing methods: ["read"] during server creation, Truto filters out all create, update, and delete tools. The LLM can read tasks and comments but cannot modify your workspace.
  • Tag Filtering (tags): Limit the scope of resources. If Todoist resources are tagged in your Truto configuration (e.g., tagging projects as "high-risk"), you can configure the MCP server to explicitly allow or deny those specific tool tags.
  • Double Authentication (require_api_token_auth): By default, possessing the MCP server URL is enough to execute tools. Setting require_api_token_auth: true forces the client to also provide a valid Truto API token in the Authorization header. This prevents abuse if an MCP URL is accidentally leaked in logs.
  • Automatic Expiration (expires_at): You can generate ephemeral servers by providing an ISO datetime string. Truto automatically schedules a Durable Object alarm to aggressively clean up the server and its underlying KV storage credentials the second it expires.

Handling Rate Limits

Factual note on rate limits: Truto does not retry, throttle, or apply automatic backoff on rate limit errors.

When the upstream Todoist API returns an HTTP 429 Too Many Requests error, Truto passes that error directly back to the caller. Truto normalizes the upstream rate limit information into standardized HTTP headers (ratelimit-limit, ratelimit-remaining, ratelimit-reset) per the IETF specification.

The caller (the LLM client, orchestration framework, or custom agent) is strictly responsible for interpreting these headers and implementing its own retry and exponential backoff logic. Do not assume the MCP server will absorb these errors for you.

Strategic Wrap-up

Integrating AI agents with Todoist requires more than just formatting API requests. You have to handle idempotency, nested entity lifecycles, and secure file extraction. By using Truto to generate a managed MCP server, you offload the infrastructure boilerplate entirely.

Instead of writing and maintaining massive JSON schemas and auth refresh logic, you can connect your LLM to Todoist in minutes and focus immediately on prompt engineering and workflow orchestration.

FAQ

How do I prevent Claude from deleting my Todoist tasks?
When creating the MCP server via the Truto UI or API, configure the `methods` array to only include `["read", "write"]` but explicitly exclude `delete`, or simply set it to `["read"]` for a completely read-only integration. The delete tools will not be generated for the LLM.
Does Truto automatically retry when Todoist rate limits are hit?
No. Truto passes the HTTP 429 error and standardized IETF rate limit headers (`ratelimit-limit`, `ratelimit-remaining`, `ratelimit-reset`) directly to the caller. Your AI framework or agent logic must handle the backoff and retry execution.
Can Claude read attachments uploaded to Todoist tasks?
Yes. Claude can use the `list_all_todoist_comments` tool to find the attachment metadata, and then use the `todoist_attachment_download` tool to pull the raw file contents into its context window.
Do I need to manage Todoist OAuth tokens when using Truto's MCP server?
No. Truto handles the entire OAuth 2.0 lifecycle securely in the background. The MCP server URL generated by Truto uses its own cryptographic token to route requests to the correct, actively authenticated integrated account.

More from our Blog