mcp · model context protocol

your notes are
your LLM's second brain.

outl ships an MCP server. Claude Desktop, Claude Code, Cursor, Zed, ChatGPT — anything that speaks the Model Context Protocol — reads and writes your local markdown the same way you do. No upload. No cloud. No copy-paste.

start the server
$ outl --workspace ~/notes mcp serve

Same binary as the CLI. JSON-RPC over stdio. Protocol revision 2024-11-05.

why this matters

a second brain that stays yours.

Notion AI, Roam AI, Mem — all of them solve the second-brain problem by shipping your notes to their servers and renting the answer back to you. The "AI second brain" market got "second" right and "yours" backwards.

local-first

The .md files stay on your disk. outl is a binary that reads them. The LLM host runs locally too. Nothing is uploaded by outl.

host-agnostic

MCP is an open protocol. Today: Claude, Cursor, Zed, ChatGPT. Tomorrow: whatever wins. You don't migrate your second brain when you switch models.

same code path

Every MCP tool maps 1:1 to a CLI subcommand. Same handlers, same JSON envelope, same exit codes. No parallel logic to drift.

The flow: you write markdown in your editor. outl runs an MCP server in the background. Your LLM client (Claude Desktop, Cursor, …) connects to it. The model can now read any page, search the graph, append to today's journal, move a block — the same set of operations the CLI exposes. The contract is the same one documented at /docs/cli.

setup

wire it into your
LLM host.

The shape is the same everywhere: register a server whose command is outl and whose args point at the workspace. Restart the host. Done.

01
anthropic · macOS, Windows

Claude Desktop

config path
~/Library/Application Support/Claude/claude_desktop_config.json
claude desktop config
{
  "mcpServers": {
    "outl": {
      "command": "outl",
      "args": ["--workspace", "/Users/you/notes", "mcp", "serve"]
    }
  }
}

Restart Claude Desktop. The outl tools show up under the server name. Pin outl://daily/today as a resource and Claude reads today's journal without a tool call.

02
anthropic · CLI / editors

Claude Code

config path
~/.claude.json (or per-project .mcp.json)
claude code config
{
  "mcpServers": {
    "outl": {
      "command": "outl",
      "args": ["--workspace", "/Users/you/notes", "mcp", "serve"]
    }
  }
}

Same JSON shape as Claude Desktop. Inside Claude Code, your notes become tools (outl_page_get, outl_search, etc.) and resources you can @-mention.

03
ide · macOS, Windows, Linux

Cursor

config path
Settings → MCP → Add Server
cursor config
{
  "mcpServers": {
    "outl": {
      "command": "outl",
      "args": ["--workspace", "/Users/you/notes", "mcp", "serve"]
    }
  }
}

Cursor reads MCP servers from the same JSON shape. Once enabled, the composer can grep your notes, append to today's journal, and turn a block into a draft — all without leaving the editor.

04
ide · macOS, Linux

Zed

config path
~/.config/zed/settings.json → context_servers
zed config
{
  "context_servers": {
    "outl": {
      "command": {
        "path": "outl",
        "args": ["--workspace", "/Users/you/notes", "mcp", "serve"]
      },
      "settings": {}
    }
  }
}

Zed exposes MCP as context servers. The Assistant panel can pull outl://page/<slug> straight into the conversation.

05
openai · macOS, Windows

ChatGPT (desktop)

config path
Settings → Connectors → Add MCP server
chatgpt (desktop) config
command: outl
args:    ["--workspace", "/Users/you/notes", "mcp", "serve"]
transport: stdio

ChatGPT desktop's MCP support is rolling out per region. The transport is stdio, same binary. Once the connector is enabled, ChatGPT can call outl_search and read outl://daily/today.

06
stdio JSON-RPC

Any other MCP host

config path
host-specific
any other mcp host config
command: outl
args:    ["--workspace", "<absolute path>", "mcp", "serve"]
transport: stdio (JSON-RPC 2.0)
protocol: MCP 2024-11-05

If the host speaks MCP, it speaks outl. Zero special-casing — the server is the same binary, the same handlers, the same workspace lock as the CLI.

smoke test

verify before you wire it

Pipe two JSON-RPC frames into outl mcp serve. If both come back with valid responses, the server is healthy.

printf '%s\n%s\n' \
  '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{}}}' \
  '{"jsonrpc":"2.0","id":2,"method":"tools/list"}' \
  | outl --workspace ~/notes mcp serve
what the LLM sees

tools, resources,
prompts.

MCP surfaces three things to the host. Tools the model can call. Resources it can attach as context without a call. Prompts you can pick from a slash menu. outl exposes all three.

tools

Every tool is a 1:1 mirror of a CLI subcommand. Destructive tools (outl_page_delete, outl_block_delete) require confirm: true — the server fails closed.

tool name what it does
outl_page_get page meta + outline tree
outl_page_create new page with title/icon/tags
outl_page_update patch title/icon
outl_page_list list pages, filter by tag
outl_page_render projected .md (clean, no sidecar)
outl_block_get block content + children
outl_block_append append child to a page or block
outl_block_insert insert after a sibling
outl_block_update edit block text
outl_block_move reparent · cycle-safe
outl_block_toggle_todo None → TODO → DONE → None
outl_block_tree subtree as JSON
outl_daily_today today's journal (creates on first read)
outl_daily_get journal by ISO date
outl_daily_append append to a daily
outl_search full-text across pages + blocks
outl_query structured query on properties/tags
outl_tag_list all tags + counts
outl_backlinks what references this page/block
outl_prop_get read a block property
outl_prop_set write a block property
outl_export_md render a slice of the graph as .md

resources

URIs the host can attach as context — no explicit tool call. Pin outl://daily/today in Claude Desktop and the model sees the day's context every turn.

uri type body
outl://workspace/info application/json Workspace path, actor id, counts (pages, blocks, ops).
outl://daily/today text/markdown Today's journal projection. Lazily creates the file the first time it's read — same semantics as outl daily today in the CLI.
outl://page/{slug} text/markdown Projected markdown for any page by slug. Use it to attach a specific page as context without a tool call.

prompts

Slash shortcuts the host renders in the prompt picker. Optional sugar over tools.

prompt arguments does
outl-summarize-day date? (ISO) pulls the daily journal, asks the model for a summary.
outl-blog-from-block block_id expands a single block into a blog draft.
daily-driver patterns

what you'll actually do with it.

The point isn't "now the LLM knows about your notes". The point is the everyday glue: stop pasting context manually.

01

morning summary

prompt

you're my second brain. Summarize what's open from yesterday and what's on the journal for today. Pull outl://daily/today.

outcome: 1-paragraph status, links to the blocks Claude touched, ready to paste anywhere.

02

ask your notes

prompt

what did I write about the tree-CRDT trade-offs? call outl_search with q: "tree-crdt trade-offs" and quote the blocks.

outcome: search returns matching blocks with their parent page; the LLM cites them inline with stable block IDs.

03

block → blog draft

prompt

expand blk-9f12 into an 800-word blog post in my voice. tone: direct, terminal-flavored.

outcome: outl_block_get pulls the block + children; the model drafts; you keep the source unchanged.

04

task triage

prompt

list everything with status:: todo across the last 14 daily notes and group by tag.

outcome: outl_query filters by property + date range; the model formats the table; no agent loop needed.

05

append from chat

prompt

add this paragraph to today as a child of blk-3a1d.

outcome: outl_block_append writes one op. The CRDT log records it, the .md updates, your editor sees it on next open.

privacy & security

the honest data flow.

what outl does
  • Reads .md + sidecars on your disk.
  • Talks JSON-RPC over stdio to whatever process spawned it.
  • Holds an exclusive workspace lock — no race with the TUI.
  • Records every op in the local CRDT log.
what outl never does
  • Open a network socket. No HTTP, no WebSocket.
  • Upload your notes anywhere. There is no outl cloud.
  • Send telemetry. The binary doesn't phone home.
  • Need an account. You install it and use it.
be honest about the host

The LLM host (Claude Desktop, Cursor, ChatGPT, …) is the party that does ship your prompt — including any block content the model loaded — to its model provider. That's how the model gets the context. outl's privacy story doesn't override the host's privacy story. Pick a host whose terms you're comfortable with. If you need air-gap, point an MCP-speaking local model (Ollama via an MCP bridge, etc.) at the same server.

frequently asked

mcp, claude, second brain —
straight answers.

What is MCP and why does outl need one?

+

MCP (Model Context Protocol) is the open standard from Anthropic for connecting LLMs to local tools and data. outl ships an MCP server (`outl mcp serve`) so Claude, Cursor, Zed, ChatGPT and anything else that speaks MCP can read and write your notes through a stable contract — no copy-paste, no upload, no parsing of human output.

Is outl as MCP server the same as Notion AI or Roam AI?

+

No. Notion AI and Roam AI send your workspace to a remote model on their servers. outl is local-first: your notes never leave your machine. The LLM client (Claude Desktop, Cursor, etc.) runs locally and talks to `outl mcp serve` on stdio. The model itself runs wherever you chose to run it. There is no outl cloud.

How do I configure Claude Desktop to use outl as a second brain?

+

Edit `~/Library/Application Support/Claude/claude_desktop_config.json` and add an `mcpServers.outl` entry with `command: "outl"` and `args: ["--workspace", "/absolute/path/to/notes", "mcp", "serve"]`. Restart Claude Desktop. The outl tools appear under the server name in the tools panel.

Does this work with ChatGPT or only Claude?

+

It works with anything that speaks MCP. Claude Desktop, Claude Code, Cursor, Zed all support MCP today. ChatGPT desktop is rolling out MCP connectors. Any new host that adopts the protocol picks outl up for free — the binary doesn't change.

What can the LLM actually do with my notes?

+

Read any page or block, search full-text, run structured queries on properties and tags, list backlinks, append to today's journal, create new pages, toggle TODOs, move blocks. Destructive operations (page delete, block delete) require `confirm: true` in the call — without it the server returns a recoverable error and nothing is touched.

Does outl upload my notes to Anthropic or OpenAI?

+

outl does not upload anything. outl is a local binary that reads and writes .md files on your disk. What the LLM host does with the data you feed it is governed by that host's privacy policy (e.g. Claude Desktop's terms with Anthropic). Pick a host you trust.

Can I run outl as an MCP server without the TUI?

+

Yes. `outl mcp serve` is its own subcommand and doesn't need the TUI to be open. It holds an exclusive lock on the workspace — you can't have `outl serve` and `outl mcp serve` writing to the same workspace at the same time. Two readers are fine.

What's the difference between the CLI and the MCP server?

+

Same logic, two surfaces. Every CLI subcommand (`outl page get`, `outl search`, `outl block append`, …) maps 1:1 to an MCP tool (`outl_page_get`, `outl_search`, `outl_block_append`). The MCP server holds the workspace in-memory between calls and caches the index, so it's faster than re-invoking the CLI. Both speak the same JSON envelope.

Is the MCP server free and open source?

+

Yes. The MCP server is a subcommand of the same MIT-licensed Rust binary as the rest of outl. No separate license, no paid tier, no telemetry. Source: github.com/avelino/outl.

Where do I find the full tools and resources reference?

+

On this page (tables below) and in the project docs at /docs/mcp. The CLI counterpart contract — same handlers, same error codes — lives at /docs/cli.

give your LLM
a second brain.

One binary. One config block. Same notes you already have.