MCP server over Markdown

Your Markdown notes, searchable by every agent.

Point mcp-ragdown at a directory of Markdown folders. It splits every file into heading-scoped sections, embeds them into a local LanceDB index, keeps that index in sync as the files change, and serves hybrid search over MCP โ€” one server per folder, for the folders you turn on. Each folder opens as an Obsidian vault, and a prompt hook can call ragdown_context to add the related notes to every turn.

MCP http://host:3300/mcp/<folder> one folder, once MCP is on
MCP http://host:3300/mcp/<folder>/<sub> a subfolder of it
UI http://host:3300/ every folder, human-only ones too

See it

serve ships a small web UI: a switcher for the folders, each folder's files rendered with their wikilinks, tags and images, search, an editor for writing and editing notes, upload and delete, and a Settings page that turns MCP on per folder. Shown here in light mode.

localhost:3300/f/work?doc=runbooks/backups.md
The work folder: its files on the left, runbooks/backups.md rendered on the right with its tags, a wikilink and its size, line and chunk counts
One folder at a time. The sidebar lists the folders and which ones agents can reach. Filter or search a folder, narrow it by tag, and open a note to read it rendered โ€” wikilinks followed, embeds shown. The folder and note live in the URL, so a preview can be linked to.
localhost:3300/f/work?doc=runbooks/backups.md&edit=true
runbooks/backups.md open in the Markdown editor with an unsaved change
Write and edit. Start a note โ€” in a new subfolder if need be โ€” or edit one in place, with a preview a click away. A save never quietly overwrites a change made on disk since you opened the note.
New note
The New note dialog with a title and a subfolder
New note. A title and an optional subfolder; the note is created as Markdown on disk and opens in the editor.
localhost:3300/settings
Settings, Folders tab: each folder with its MCP switch, title, Copy MCP config, Rename and Delete
Folders. Turn MCP on or off per folder, retitle, rename or delete it, and copy the claude mcp add line for it. New folders start human-only.
Upload Markdown
The Upload Markdown dialog with a subfolder and a picked file
Upload and delete. Drop .md, .markdown or .mdx files into the open folder, optionally under a subfolder; they are indexed before the upload finishes. Delete removes a file from disk, not only from the index.

What it does

๐Ÿ“„

Your files are the truth

The Markdown files are the source of truth; the index is derived and disposable. Change the embedder or the chunker and the index rebuilds itself. Delete it and the next start rebuilds it.

๐Ÿงญ

Chunks follow headings

Every heading starts a section, and its breadcrumb (Backups โ€บ Restore) is embedded with it, so a paragraph that only says "run it twice" is still found by a question about restores.

๐Ÿ”

Hybrid search

Dense cosine search finds an answer in different words; BM25 full-text search finds an exact error string or flag name. Reciprocal rank fusion merges the two.

๐Ÿช

Context for every turn

ragdown_context is built for prompt hooks: the sections that clear a similarity bar, in a <ragdown-context> block, never repeated within a session โ€” or empty text when nothing fits.

๐Ÿ“

A server per folder

Every top-level folder is found automatically and is its own MCP server at /mcp/<folder>. Folders start human-only โ€” searchable in the web UI, invisible to agents โ€” until you turn MCP on.

๐Ÿ”—

Opens as an Obsidian vault

Frontmatter and inline #tags filter searches, aliases are searchable, and ragdown_read_doc follows [[wikilinks]] down to a heading. .obsidian/ is ignored.

๐Ÿ”„

Always in sync

A watcher diffs the folder: unchanged files are skipped by size and mtime, a content hash decides what to re-embed, and deleted files drop out. Searches never wait for indexing.

โœ๏ธ

Agents can write notes

ragdown_remember saves a new note and indexes it before returning. It never overwrites, and supersedes hides the notes a new one replaces. RAGDOWN_READ_ONLY turns writing off.

๐Ÿ’ป

Local by default

The default embedder, granite-embedding-small-english-r2, runs on ONNX Runtime on your CPU โ€” and is baked into the Docker image, so it starts offline. Other local models, or any OpenAI-compatible /embeddings endpoint, are a setting away.

๐Ÿ–ฅ๏ธ

Web UI

Browse, search and preview each folder, write and edit notes, upload and delete Markdown, and create, rename and switch MCP on for folders โ€” from the same serve process, behind the same token.

How it works

Your Markdown folders .md, .markdown, .mdx, one directory per folder
โ†’
MCP Ragdown chunk by heading ยท embed ยท LanceDB ยท dense + BM25
โ†’ /mcp/<folder> โ†’
Agents and hooks Claude Code, min-agent, any stdio or streamable-HTTP client

Everything an agent or a hook does goes through MCP โ€” there is no hook command and no hook-only HTTP route. Every folder shares one index, one model and one watcher. Several processes on the same docs directory share that index: the one that holds the socket lock indexes and watches, and the others search the same table and forward syncs to it.

Quickstart

Docker Compose recommended

services:
  ragdown:
    image: vantreeseba/mcp-ragdown:latest
    ports:
      - '3300:3000'
    volumes:
      - ~/notes:/docs          # one folder per directory in here
      - ragdown-data:/data     # the index, so restarts only diff
    environment:
      RAGDOWN_TOKEN: ${RAGDOWN_TOKEN}
    restart: unless-stopped

volumes:
  ragdown-data:
export RAGDOWN_TOKEN=$(openssl rand -hex 32)   # keep it; clients need it too
docker compose up -d

~/notes/work is now the folder work, human-only to start. Open http://localhost:3300, turn MCP on for it under Settings โ†’ Folders, and Copy MCP config gives you:

claude mcp add --transport http ragdown-work http://localhost:3300/mcp/work \
  --header "Authorization: Bearer $RAGDOWN_TOKEN"

Images are published for linux/amd64 to Docker Hub (vantreeseba/mcp-ragdown) and GHCR (ghcr.io/cubicecho/mcp-ragdown).

Without Docker Node 26+

npm install
claude mcp add ragdown -e RAGDOWN_DOCS_DIR=$HOME/notes/work -- node /path/to/mcp-ragdown/src/cli.ts stdio

Over stdio, RAGDOWN_DOCS_DIR is the one folder โ€” an Obsidian vault, say โ€” and it is served whatever its settings say. Node 26 runs the TypeScript directly; the default model (about 50 MB) downloads once on first start.

Upgrading from 4.x? /mcp is gone and every folder starts human-only. Four steps get you back.

Keep writing Markdown. Let agents find it.

Walk through stdio, Docker and a hook on the Get started page, or read the tools and configuration reference.