Failure mode
Every read tool errors unable to open database file on the first call; URL-scheme writes (add_todo etc.) succeed. Instant failure on every call — distinct from thingsapi/things.py#125 / #141, which fail mid-scan on large databases.
Cause
The database path (~/Library/Group Containers/JLMPQHK86H.com.culturedcode.ThingsMac/…) is TCC-protected. Claude Desktop launches MCP servers through /Applications/Claude.app/Contents/Helpers/disclaimer, which disclaims TCC responsibility: the spawned server does not inherit Claude's Full Disk Access. Granting FDA to Claude.app therefore doesn't help. Granting FDA to the actual binaries (uv / uvx / the venv python in uv's cache) works but is fragile — grants break whenever Homebrew or uv updates the binaries, and the FDA picker often greys them out.
Non-obvious knock-on: things.token() reads the auth token from the database, so update_todo / update_project / bulk_update_todos also fail while add_* still works.
Reliable fix (tested)
Run the server with THINGS_MCP_TRANSPORT=http in a context that already holds disk access (Terminal, or a login app), then bridge stdio clients:
uvx fastmcp-remote@<version> http://127.0.0.1:8765/mcp --auth none (Python; or mcp-proxy --transport streamablehttp <url>, or npx mcp-remote <url>)
- Claude Code needs no bridge:
claude mcp add --transport http things http://127.0.0.1:8765/mcp
Ask
README troubleshooting currently covers "open Things once" and the uvx PATH issue only. Happy to PR a troubleshooting section with the symptom table (read-vs-write split, token knock-on) and the tested fix ladder.
Failure mode
Every read tool errors
unable to open database fileon the first call; URL-scheme writes (add_todoetc.) succeed. Instant failure on every call — distinct from thingsapi/things.py#125 / #141, which fail mid-scan on large databases.Cause
The database path (
~/Library/Group Containers/JLMPQHK86H.com.culturedcode.ThingsMac/…) is TCC-protected. Claude Desktop launches MCP servers through/Applications/Claude.app/Contents/Helpers/disclaimer, which disclaims TCC responsibility: the spawned server does not inherit Claude's Full Disk Access. Granting FDA to Claude.app therefore doesn't help. Granting FDA to the actual binaries (uv / uvx / the venv python in uv's cache) works but is fragile — grants break whenever Homebrew or uv updates the binaries, and the FDA picker often greys them out.Non-obvious knock-on:
things.token()reads the auth token from the database, soupdate_todo/update_project/bulk_update_todosalso fail whileadd_*still works.Reliable fix (tested)
Run the server with
THINGS_MCP_TRANSPORT=httpin a context that already holds disk access (Terminal, or a login app), then bridge stdio clients:uvx fastmcp-remote@<version> http://127.0.0.1:8765/mcp --auth none(Python; ormcp-proxy --transport streamablehttp <url>, ornpx mcp-remote <url>)claude mcp add --transport http things http://127.0.0.1:8765/mcpAsk
README troubleshooting currently covers "open Things once" and the uvx PATH issue only. Happy to PR a troubleshooting section with the symptom table (read-vs-write split, token knock-on) and the tested fix ladder.