Feature

MCP server.

Curtis is an MCP client — it calls tools from servers you run. Server mode is the reverse: Curtis serves your vault as MCP tools so external AI apps (Claude Desktop,…

Curtis is an MCP client — it calls tools from servers you run. Server mode is the reverse: Curtis serves your vault as MCP tools so external AI apps (Claude Desktop, coding agents, anything that speaks MCP) can list, read, and search your notes without a line of Curtis chat.

Enable

Settings → Curtis.ai → MCP server → Enable MCP server. Desktop only — mobile Obsidian has no listening sockets, so the toggle is disabled there.

The server binds to 127.0.0.1 (never the network) and requires a bearer token, generated on first start. Copy the ready-made registration command from the settings row:

claude mcp add --transport http curtis-vault http://127.0.0.1:24783/mcp --header "Authorization: Bearer <token>"

Any MCP client that speaks Streamable HTTP works: point it at http://127.0.0.1:<port>/mcp with an Authorization: Bearer <token> header. The transport matches the MCP 2025-06-18 protocol, stateless — no session handling client-side.

Tools

ToolWhat it does
list_notesPaths, alphabetically, optionally under a folder. Paginated.
read_noteFull note text; large notes truncate with a marker.
search_notesCase-insensitive text search with line-numbered excerpts.
semantic_searchHybrid search over the vault's index — semantic embeddings fused with keyword (BM25) matching. Present when RAG is on — this is the one generic vault servers can't match.
get_memoryThe user's saved memory facts — durable preferences and project context.
write_noteCreate / overwrite / append. Only exists when Allow writes is on — off by default, so a fresh install is read-only.
list_agentsThe user's named agents — name, emoji, short description, and model per agent.
run_agentRun one named agent headlessly: { name, task, max_turns? } → the agent's final answer as text. Only agents with Remote invocation on.

Agents as tools

The server also serves the user's named agents as callable tools: list_agents to browse them, run_agent to hire one. Every agent carries a Remote invocation gate in the agent editor — off by default, so an agent can only ever run in chats the user started until it's switched on. One toggle gates both this tool and the plugin API's runAgent.

A run_agent call is a fresh engagement: no conversation history, the task text is the whole prompt, and the agent's persona is the system prompt. The run routes through the agent's own provider/model on the user's own key — cost lands where the user already configured it, and the agent's tool ceilings still apply. Call list_agents first and pass an exact name; unknown names and gate-off agents are refused.

Remote runs are capped at 2 concurrent — extra calls are rejected with a busy error — and every run is recorded: a completion Notice, plus a "Recent remote runs" list under Settings → Curtis.ai → MCP server.

Security

A localhost server that can read (and optionally write) a vault is a real surface. The defenses, in order of what they stop:

  • Bearer token on every request — constant-time compared; a process without the token gets 401.
  • 127.0.0.1 bind + Host check — the server is unreachable from the network and ignores DNS-rebinding requests that arrive with a non-loopback Host.
  • Origin allowlist — a web page in any browser is refused (403) before auth; drive-by pages cannot probe the port.
  • Writes are a separate toggle — and write_note stays out of the advertised catalog entirely while off, so clients never even see it.
  • Every path passes a vault-jail — absolute paths, drive letters, and .. segments are rejected before a file is touched.

Treat the token like a key to your vault: it lives in data.json, and Regenerate (settings) invalidates the old one for every client at once.

See also