Claude Desktop MCP Extension
2Do for Mac ships a standard MCP server, so local AI agents can work with your real, live tasks. Claude Co-Work (the Claude Desktop extension) is the first-class experience: with it installed, Claude can browse your 2Do lists, query tasks, create and update tasks, manage projects and checklists, pause tags, and open tasks in the 2Do window. Any other MCP-capable agent can drive 2Do through the same server.
The Claude extension uses the same strict automation engine as AppleScript Automation. MCP and AppleScript both expose the same canonical snake_case command names. Argument keys, response fields, and validation rules are shared across both surfaces. 2Do's native Shortcuts actions run on this engine too.
Inside 2Do, this integration is introduced as Claude Co-Work. Claude Desktop launches the extension's standard MCP stdio server. That local bridge forwards tool calls to 2Do's private app socket, so 2Do itself does not expose a network server.
2Do for Mac needs to be running to handle requests — the extension talks to the Mac app's local automation socket.
If 2Do or a password-protected list is locked, unlock it in the app before asking Claude to access that data. MCP follows the same current interactive unlock session as AppleScript.
What You Can Do
With 2Do connected to Claude, you can ask for help with:
- Discovery - list your 2Do lists, List Groups, Smart Lists, tags, tag groups, and locations, and ask which list new tasks go to by default.
- Task lookup - get one task by
task_id, list sub-tasks under a project or checklist, or read the tasks currently selected in the Mac app. - Task queries - query a normal list, a List Group's dynamic group task view, a saved Smart List, built-in Today/Starred/Scheduled focus scopes, or the default All focus scope, with optional plain-text search, date windows, paused-tag filtering, sorting, offset/limit pagination, and completed-task inclusion.
- Task creation - create tasks, projects, checklists, and sub-tasks with title, notes, starred state, due date/time, start date/time, duration, priority, tags, locations, alarms, recurrence, and action. Projects and checklists can also be created with inline
subtasks. - Task updates - change fields, convert the task type between normal, project, and checklist, replace sound alarms, replace recurrence, set or clear actions, move tasks, duplicate tasks, complete tasks, uncomplete tasks, and delete tasks. Complete, uncomplete, delete, and move also support
task_idsbatches. - Tag pausing - pause or unpause a tag so matching tasks hide or resume normally.
- Navigation - select a list, a List Group, a Smart List, or a built-in Focus scope, or open a task in 2Do.
- Pre-sorted results - ask Claude to sort a query by title, due date, start date, priority, duration, created date, modified date, or completed date.
Examples:
"List the first 10 tasks due soon in 2Do"
"For our recent travel plans, add things to pack as a checklist"
"Apply the paused Waiting tag to all the projects in my Work list for now"
"Find tasks in my Errands in 2Do, list the most urgent ones I can complete this afternoon"
Available Tools
Claude sees these canonical tool names. You do not need to remember them during a chat, but they are useful when reviewing what Claude is doing.
Read and Discovery
| Tool | What it does |
|---|---|
list_lists | List normal 2Do lists. Optional include_archived (default false). |
list_list_groups | List List Groups. |
list_smart_lists | List saved Smart Lists. |
list_tags | List tags, including paused. Can filter by tag_group_id. |
list_tag_groups | List Tag Groups. |
list_locations | List task locations. |
get_default_task_destination | Return the list new tasks go to by default, as a destination record with destination_id, list_id, and title. Password-aware: it uses the same destination logic as task creation, so it always returns an editable normal list. |
get_task | Get one task, project, checklist, or sub-task by task_id. |
query_tasks | Query tasks from a list, List Group, Smart List, built-in focus scope, or the default All focus scope. Supports search, inclusive due/start date windows, paused_filter, sort, offset, limit (minimum 1), and include_completed; responses include total_count. |
list_subtasks | List children under a parent task, project, or checklist. |
selected_tasks | Return the tasks currently selected in the 2Do Mac app. |
search accepts 1 through 256 characters and matches literal text only: a case-insensitive and diacritic-insensitive substring of the task title, notes, current tag titles, and current location titles. There is no query-operator or boolean syntax. Date windows are the inclusive yyyy-MM-dd fields due_on_or_after, due_on_or_before, start_on_or_after, and start_on_or_before; tasks without the corresponding date never match a window. In responses, item_count is the number of tasks returned after offset/limit, and total_count is the number of matching tasks before pagination.
Mutation
| Tool | What it does |
|---|---|
create_task | Create a task, project, checklist, or sub-task. |
update_task | Update task fields and replace alarms, recurrence, or action. |
update_task_action | Set, replace, or clear only the task action. |
delete_task | Delete a task, or a batch with task_ids. |
duplicate_task | Duplicate a task. |
move_task | Move a task, or a batch with task_ids, to another list or parent task. |
complete_task | Mark a task complete, or complete a batch with task_ids. |
uncomplete_task | Mark a completed task incomplete, or uncomplete a batch with task_ids. |
pause_tag | Pause a tag by tag_id. |
unpause_tag | Unpause a tag by tag_id. |
delete_task, complete_task, and uncomplete_task accept an optional recursive (default true) covering sub-tasks; uncomplete_task additionally takes update_parent (default false) to reconcile a completed parent. Setting update_parent:true requires recursive:true. Each command, including a batch, is a single undo step in the app.
Completing a recurring task advances it to its next occurrence. Repeating the same complete_task call advances it again, so clients must not retry recurring completion as an idempotent operation.
Navigation
| Tool | What it does |
|---|---|
select_list | Select a normal list in the Mac app. |
select_list_group | Select a List Group as the dynamic group filter in the Mac app. |
select_smart_list | Select a saved Smart List in the Mac app. |
select_focus | Select a built-in Focus scope in the Mac app: all, today, starred, scheduled, or done. |
open_task | Open or focus one task in the Mac app. |
Task Editing Support
Claude can create or update these task fields:
| Field | Notes |
|---|---|
title, notes | Task title and notes. |
starred | Boolean starred state. |
task_type | normal, project, or checklist. For create_task, root tasks only. |
due_date, due_time | Date is yyyy-MM-dd; time is HH:mm. Send null to clear. |
start_date, start_time | Date is yyyy-MM-dd; time is HH:mm. Send null to clear. |
duration_seconds | Estimated duration from 0 through 2147483647 seconds. |
priority | none, low, medium, or high. |
tag_update | Object with operation (set, append, or remove) and tag_ids. |
location_update | Object with operation (set, append, or remove) and location_ids. |
alarms | Sound alarms only. Omitted means unchanged; empty array clears; non-empty array replaces. A task may have at most 10 total alarms. |
recurrence | Basic daily, weekly, monthly, yearly, weekdays, and custom rules. |
action | none, call, message, mail, visit, url, or google. |
Actions can also be updated directly through update_task_action, which makes requests like "change this task to call Sarah" easier for Claude to express.
create_task accepts inline subtasks only when creating a root task in a list. The array must contain 1 through 100 children, and each child requires a non-empty title. Project children support the task-editing fields. Checklist children cannot set due/start fields, duration, recurrence, or relative alarms because they inherit scheduling from the checklist; absolute sound alarms remain supported.
task_ids batches for complete, uncomplete, delete, and move are capped at 100 unique task IDs. 2Do validates the whole batch before applying it in order.
Paused Tags
Paused tags are first-class in the MCP API.
pause_tagtakestag_idand setspausedtotrue.unpause_tagtakestag_idand setspausedtofalse.- Both commands are safe to repeat. If the tag is already in the requested state, 2Do returns the current tag record.
query_tasksandlist_subtaskssupportpaused_filter:
paused_filter | Behavior |
|---|---|
hide | Default. Hide tasks paused by tags. |
include | Include paused and unpaused tasks. |
only | Return only paused tasks. |
Useful requests:
"Pause my Waiting tag."
"Show only the tasks hidden by paused tags."
"Include paused tasks when you review my Work list."
Dates, Alarms, and Recurrence
2Do's MCP tools use stable machine formats:
- Dates use
yyyy-MM-dd, for example2026-07-03. - Times use
HH:mm, for example09:30. - Absolute alarm triggers use floating local
yyyy-MM-dd HH:mmstrings, for example2026-07-03 09:15. - Relative alarm triggers use seconds, for example
-900for 15 minutes before. - Relative alarm offsets must be between
-63071999and63071999seconds. - Relative alarms require a due date or start date.
- Recurrence requires a due date or start date unless the recurrence payload clears recurrence with
{"frequency":"none"}. - Recurrence uses
based_on(due_dateorcompletion) and anend_rule. Anafter_countend rule usesoccurrence_countfrom 1 through 99. - Only
due_date,due_time,start_date, andstart_timeaccept JSONnull, which clears the stored value. Other optional fields must be omitted when unchanged.
Do not include timezone names, Z suffixes, or UTC offsets in date/time fields. 2Do treats automation dates and times as local floating values.
For the full schema reference, see AppleScript Automation. The schema is the same for MCP, except MCP sends JSON objects instead of AppleScript records.
Requirements
- 2Do for Mac with the
2Do Automation Suiteinstalled on your Mac. - Claude Desktop (macOS) with extension support.
Installing the Extension
The 2Do extension connects Claude Desktop to 2Do's local automation socket.
Step 1: Download the extension
Download the latest 2do.<version>.mcpb file from the 2Do extension releases page on GitHub.
Step 2: Install it in Claude Desktop
Open Claude Desktop and go to Settings > Extensions > Advanced Settings, then click Install Extension and select the 2do.<version>.mcpb file you downloaded.
Step 3: Confirm the installation
You may see a message saying "Installing will grant access to everything on your computer." This is a standard warning Claude Desktop shows for all manually installed extensions — it does not mean 2Do gains any new access to your system.
2Do is a sandboxed macOS app. The extension talks only to 2Do's local automation socket and can only read and write your 2Do task data. It cannot access your files, other apps, or anything outside of 2Do.
Click Install to continue.
Step 4: Start using it
Launch 2Do, then open a new chat in Claude Desktop and try:
"List my 2Do lists."
If Claude shows your lists, the extension is working and you are ready to go.
If you are testing an unreleased build, the extension package and app build must come from the same automation generation. The command vocabulary is intentionally strict, so an older extension may fail if it sends a command or argument the app does not advertise.
Privacy and Security
The transport between the Claude extension and 2Do is local to your Mac. Claude still receives the tool inputs and results needed to answer your request, under the privacy terms for your Claude account. The 2Do extension does not add another network relay.
The app-side socket is a Unix-domain socket inside 2Do's App Group container. 2Do removes stale socket files when starting, creates the selected socket with 0600 permissions, and responds with newline-delimited JSON frames.
The automation API never accepts account passwords or sync credentials. It exposes only data available in 2Do's current interactive unlock session; locked app data and locked password-protected lists remain unavailable.
Troubleshooting
Claude says 2Do is not available Make sure 2Do for Mac is open — the extension talks to the running app.
Claude cannot find a list or tag
Ask Claude to run list_lists, list_list_groups, list_smart_lists, or list_tags first, then refer to the returned name. Claude should use the stable returned identifier in follow-up calls.
Claude reports an invalid argument The API is strict. Unknown keys, aliases, and enum values are rejected. Start a new chat after updating the extension or app so Claude reloads the current tool schema.
Claude reports "automation socket isn't available" This means the extension could not connect to 2Do's local socket. Check these in order:
- Confirm 2Do is running.
- Confirm you installed a 2Do build with MCP support.
- Quit and reopen 2Do so it recreates the socket.
- Quit and reopen Claude Desktop so the extension reconnects.
- If you are using a direct release build, the documented socket path is:
~/Library/Group Containers/EKT6323JY3.com.guidedways/Automation/2do-mcp.sock
If that path is too long for the Unix socket limit in a particular environment, 2Do falls back to:
~/Library/Group Containers/EKT6323JY3.com.guidedways/mcp
Debug and internal builds use their matching debug App Group suite. Support logs include the actual group and socket path selected at launch.
Advanced Protocol Note
Claude users do not need the raw protocol. The current extension negotiates MCP 2025-11-25 or 2025-06-18 through the standard initialize / notifications/initialized handshake. The tool catalog is static for each server process.
For local diagnostics, the app socket receives one newline-delimited JSON object:
{"command":"query_tasks","arguments":{"paused_filter":"include","sort":{"field":"due_date","direction":"ascending"},"limit":10}}
Successful response:
{"ok":true,"result":{"tasks":[],"item_count":0,"total_count":0}}
Error response:
{"ok":false,"error":{"code":"invalid_arguments","message":"Unknown argument 'id' for get_task."}}
The public tool schema is the contract. Prefer the Claude extension or AppleScript API instead of hand-writing socket requests.