Skip to main content
Glama
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