things-mcp-server
v0.2.10
Published
MCP server for controlling Things on macOS
Downloads
373
Readme
things-mcp-server
A Model Context Protocol (MCP) server for controlling Things 3 on macOS. Lets AI assistants read, create, update, and organize your tasks through a safe, structured interface.
Quick Start
No source checkout needed. Run directly via npx:
{
"mcpServers": {
"things": {
"command": "npx",
"args": ["-y", "things-mcp-server"],
"env": {
"THINGS_AUTH_TOKEN": "your-token-here"
}
}
}
}Place this in your MCP client config file:
- Claude Desktop —
~/Library/Application Support/Claude/claude_desktop_config.json - Cursor —
~/.cursor/mcp.json - Claude Code —
~/.claude.jsonor project-level.mcp.json
Auth Token
Most write operations use AppleScript directly and don't need a token. The token is required for operations that use the Things URL Scheme: heading placement, tag updates, natural language dates (e.g. "next Monday"), reveal, custom creation/completion dates, bulk add, and uncomplete project.
To get the token: Things → Settings → General → Enable Things URLs → copy the auth token.
Requirements
- macOS with Things 3 installed
- Node.js ≥ 20
- First-run macOS Automation permission approval for AppleScript access
Tools
Read (19 tools)
| Tool | Description |
| ----------------------------------------- | -------------------------------------------------------------- |
| things_list_todos | List todos from a Things list with pagination |
| things_list_projects | List projects with pagination |
| things_list_areas | List areas with pagination |
| things_list_tags | List tags with pagination |
| things_list_area_items | List items (projects + todos) under an area |
| things_list_project_todos | List todos under a project |
| things_list_project_todos_with_headings | List todos under a project with heading info (requires SQLite) |
| things_list_tag_todos | List todos by tag name or tag ID |
| things_list_project_headings | List headings in a project (requires SQLite) |
| things_search_todos | Search todos by title |
| things_search_projects | Search projects by name |
| things_get_todo | Get full detail for a single todo, including checklist items |
| things_get_project | Get full detail for a single project |
| things_get_area | Get detail for an area, including its projects |
| things_get_checklist_items | Get checklist items for a todo (requires SQLite) |
| things_get_selected_todos | Get the currently selected todos in the Things UI |
| things_get_server_status | Runtime status including SQLite enrichment state |
| things_show_item | Focus an item in the Things UI |
| things_open_search | Open the Things search UI with a query |
Write (21 tools)
All write tools require confirm: true as a safety guard.
| Tool | Description |
| --------------------------- | -------------------------------------------------------------------- |
| things_add_todo | Create a todo (AppleScript; URL Scheme when heading is specified) |
| things_add_project | Create a project with optional inline todos |
| things_add_area | Create an area |
| things_add_tag | Create a tag |
| things_bulk_add_todos | Create multiple todos in a single operation via Things JSON command |
| things_update_todo | Update todo fields (AppleScript; URL Scheme for heading/tag changes) |
| things_update_project | Update project fields |
| things_update_tag | Rename a tag |
| things_update_area | Rename an area |
| things_complete_todo | Mark a todo as completed |
| things_complete_project | Mark a project as completed |
| things_cancel_todo | Mark a todo as canceled |
| things_cancel_project | Mark a project as canceled |
| things_uncomplete_todo | Reopen a completed todo |
| things_uncomplete_project | Reopen a completed or canceled project |
| things_move_todo | Move todo to list, project, area, or heading |
| things_delete_todo | Delete a todo |
| things_delete_project | Delete a project |
| things_delete_area | Delete an area |
| things_delete_tag | Delete a tag |
| things_empty_trash | Permanently delete all items in the Things trash |
Architecture
┌─────────────┐
│ MCP Client │ (Claude Desktop, Cursor, etc.)
└──────┬──────┘
│ stdio
┌──────▼──────┐
│ MCP Server │ things-mcp-server
├─────────────┤
│ AppleScript │ Primary adapter — sync, returns IDs
│ URL Scheme │ Fallback for heading placement / tag writes
│ SQLite (r/o)│ Optional enrichment for dates & recurrence
└─────────────┘
│
┌──────▼──────┐
│ Things 3 │
└─────────────┘- AppleScript is the primary adapter for both reads and writes. It's synchronous, returns created IDs, and doesn't require an auth token.
- URL Scheme is used as a fallback when heading placement, tag updates, natural language dates,
reveal, or custom creation/completion dates are needed (AppleScript limitations). Also powers bulk add (jsoncommand) and search. - SQLite (read-only, optional) enriches todo metadata with due dates, reminder times, recurrence details, checklist items, and project heading info that AppleScript doesn't expose.
SQLite Enrichment
The server auto-discovers the Things database under ~/Library/Group Containers/ for read-only metadata enrichment. No configuration needed in most setups.
If auto-discovery fails, set the path explicitly:
THINGS_DB_PATH="/Users/you/Library/Group Containers/JLMPQHK86H.com.culturedcode.ThingsMac/ThingsData-XXXX/Things Database.thingsdatabase/main.sqlite"Enriched fields include: dueDate, activationDate, reminderTime, recurrence (structured), inferredDate, isRepeating, recurrenceRule. SQLite also powers project headings, checklist item reads, and heading-aware todo listings.
Security
- Command whitelist: only
osascriptandopenare executable - No shell interpolation (
shell: false) - URL command whitelist: only
add,add-project,update,update-project,show,search,json - Input validation on IDs, dates, titles, notes, and tags
- All writes require explicit
confirm: true - Auth tokens are redacted from error output
Troubleshooting
SQLite not enabled
- Call
things_get_server_status— checksqlite.enabled. - Inspect
resolvedPath,existingCandidateCount,lastOpenError. - If needed, set
THINGS_DB_PATHexplicitly. - If
lastOpenErrormentions permissions, grant your MCP host Full Disk Access.
