things3-mcp
by snellingio
README.md
# Things MCP
A deliberately small MCP server for the parts of Things used in daily work.
This project is based on
[hald/things-mcp](https://github.com/hald/things-mcp). It was rebuilt around a
much smaller tool and code surface rather than preserving the full upstream
feature set.
## Tools
### `list_projects`
Lists active Things projects.
Parameters: none.
Each result contains:
- `id`: Project ID used by the other tools.
- `title`: Project title.
### `list_tasks`
Lists tasks from Today or from one project.
Parameters:
- `view` (required): `today` or `project`.
- `project_id`: Required when `view` is `project`; omit it for `today`.
Each result contains:
- `id`: Task ID used by `update_task`.
- `title`
- `notes`
- `when`: Scheduled date, when present.
- `status`
- `project_id`: `null` for a standalone task.
- `project`: Project title, or `null` for a standalone task.
Examples:
```text
list_tasks(view="today")
list_tasks(view="project", project_id="PROJECT_ID")
```
### `create_task`
Creates a standalone task or a task inside an existing project.
Parameters:
- `title` (required)
- `project_id`: Optional ID returned by `list_projects`.
- `when`: Optional Things schedule such as `today`, `tomorrow`, or
`YYYY-MM-DD`.
- `notes`: Optional task notes.
Examples:
```text
create_task(title="Buy milk", when="today")
create_task(
title="Prepare meeting notes",
project_id="PROJECT_ID",
when="tomorrow",
notes="Cover the launch plan"
)
```
Things does not return the new task ID through this URL operation. Call
`list_tasks` afterward when the ID is needed.
### `update_task`
Updates an existing task without moving it or changing unrelated Things data.
Parameters:
- `task_id` (required): ID returned by `list_tasks`.
- `title`: Replacement title.
- `notes`: Replacement notes. Pass an empty string to clear them.
- `when`: Replacement schedule.
- `status`: `open`, `completed`, or `canceled`.
At least one change is required. Updating a task requires the Things
authorization token described below.
Examples:
```text
update_task(task_id="TASK_ID", notes="Updated context", when="tomorrow")
update_task(task_id="TASK_ID", status="completed")
update_task(task_id="TASK_ID", status="open")
```
## Scope
The server does not expose search, deadlines, tags, areas, headings, checklists,
project creation, task movement, bulk operations, or deletion.
## Requirements
- macOS with Things 3 installed
- Things URLs enabled in Things Settings
- [uv](https://docs.astral.sh/uv/)
Updating tasks also requires the Things authorization token. Enable it under
Things → Settings → General → Enable Things URLs → Manage.
### Enable task updates
Things requires a private authorization token before another app can modify an
existing task. The token stays in Things and is read locally by this server; do
not paste it into the MCP configuration or share it with an assistant.
On your Mac:
1. Open Things.
2. Go to Things → Settings → General.
3. Enable **Things URLs**.
4. Click **Manage** next to Things URLs.
5. Enable or generate the authorization token.
Creating tasks only requires Things URLs. Editing, completing, canceling, and
reopening tasks require the authorization token.
## Run
Run directly from GitHub:
```bash
uvx --from git+https://github.com/snellingio/things3-mcp things-mcp
```
Or clone the repository for local development:
```bash
git clone https://github.com/snellingio/things3-mcp.git
cd things3-mcp
uv sync --extra test
uv run things-mcp
```
Example MCP configuration using GitHub:
```json
{
"mcpServers": {
"things": {
"command": "uvx",
"args": [
"--from",
"git+https://github.com/snellingio/things3-mcp",
"things-mcp"
]
}
}
}
```
Set `THINGS_MCP_TRANSPORT=http` to use HTTP instead of stdio. The optional
`THINGS_MCP_HOST` and `THINGS_MCP_PORT` variables default to `127.0.0.1` and
`8000`.
## Test
```bash
uv sync --extra test
uv run pytest
uv run ruff check .
```
TDQS
A3.7/5.0
Scored across 4 tools
Disambiguation5/5
Each tool targets a distinct resource and action: listing tasks vs listing projects, creating vs updating tasks. Even though list_tasks and update_task both involve tasks, their purposes are clearly separated.
Naming Consistency5/5
All tool names follow a consistent verb_noun pattern with lowercase and underscores: list_tasks, list_projects, create_task, update_task. No mixed conventions.
Tool Count5/5
4 tools is well-scoped for a simple Things integration, covering core task interactions without unnecessary bloat. Each tool is useful and distinct.
Completeness4/5
The set covers listing, creating, and updating tasks, as well as listing projects. Missing delete operation, but update_task with status likely allows completing tasks, mitigating the gap.
Maintenance
ActivityStale
ResponsivenessNo issues