Skip to content

thebackpackdevorg/vault-mcp-server

Repository files navigation

vault-mcp-server

Give Claude Code persistent memory with a Markdown vault.

An MCP server that turns any folder of Markdown files into a searchable, structured knowledge base. Claude Code can list, read, write, edit, search, and summarize your vault — across sessions, across machines.

What it does

  • 7 tools exposed via MCP: vault_list, vault_read, vault_write, vault_edit, vault_summary, vault_search, vault_reindex
  • Semantic search powered by ChromaDB + sentence-transformers — ask questions in natural language, get relevant chunks back instead of full files
  • Metadata parsing — extracts status, dates, and custom fields from **Key:** Value patterns in your Markdown
  • Multilingual — search and metadata work in English and Spanish out of the box
  • Incremental indexing — only re-embeds files that changed since last startup

Why Markdown

Markdown is the only format that is simultaneously human-readable, version-controllable, and LLM-friendly. No database to manage, no migration scripts. Your vault is just files — back them up with git, sync them with Nextcloud, edit them in Obsidian.

Architecture

┌─────────────────────┐     ┌──────────────────────┐
│  Claude Code         │────>│  vault-mcp-server     │
│  (any machine)       │<────│  (FastMCP + HTTP)     │
└─────────────────────┘     └──────┬───────────────┘
                                   │
                          ┌────────▼────────┐
                          │  Markdown Vault  │
                          │  (any folder)    │
                          └────────┬────────┘
                                   │
                          ┌────────▼────────┐
                          │  ChromaDB        │
                          │  (semantic index)│
                          └─────────────────┘

Quick start

1. Clone and configure

git clone https://github.com/thebackpackdevorg/vault-mcp-server.git
cd vault-mcp-server

Edit docker-compose.yml to point to your Markdown folder:

volumes:
  - /path/to/your/markdown-vault:/vault

2. Run

docker compose up -d

The server starts on port 8091 with Streamable HTTP transport.

3. Register in Claude Code

claude mcp add vault http://localhost:8091/mcp -t http

Or add to ~/.claude/settings.json:

{
  "mcpServers": {
    "vault": {
      "type": "http",
      "url": "http://localhost:8091/mcp"
    }
  }
}

4. Use it

You: "What do I have documented about Docker networking?"

Claude: *calls vault_search("Docker networking")* → returns relevant chunks

You: "Update the status in homeserver-backlog.md to Done"

Claude: *calls vault_edit("homeserver/homeserver-backlog.md", "**Status:** Active", "**Status:** Done")*

Remote deployment

To access the vault from other machines, expose it through a reverse proxy. The server supports an optional OAuth layer for authentication when deployed remotely.

With Cloudflare Tunnel + Access

  1. Create a Cloudflare Tunnel pointing to localhost:8091
  2. Add a Cloudflare Access policy with a Service Token
  3. Configure Claude Code on remote machines:
{
  "mcpServers": {
    "vault": {
      "type": "http",
      "url": "https://vault.yourdomain.com/mcp",
      "headers": {
        "CF-Access-Client-Id": "${VAULT_CF_CLIENT_ID}",
        "CF-Access-Client-Secret": "${VAULT_CF_CLIENT_SECRET}"
      }
    }
  }
}

With built-in OAuth

Set OAUTH_ISSUER_URL and optionally OAUTH_PIN in your environment to enable the built-in OAuth 2.1 provider with a PIN-based approval page.

The SSE vs Streamable HTTP gotcha

If you're deploying behind Cloudflare (or any proxy that buffers SSE), you may hit a silent failure where Claude Code connects but never gets responses.

The fix: This server uses Streamable HTTP (not SSE). Make sure your proxy passes through the Accept: application/json, text/event-stream header correctly. The server includes a middleware that injects this header if missing.

Tools reference

Tool Description
vault_list List files with optional domain/status filters
vault_read Read a file with parsed metadata, sections, and cross-references
vault_write Create or overwrite a file
vault_edit String replacement edit (like Claude's Edit tool)
vault_summary Dashboard: file counts by domain, active projects, recent changes
vault_search Semantic search — returns relevant chunks, not full files
vault_reindex Force full re-index after external changes

Configuration

config.yaml

vault:
  path: "/vault"

server:
  host: "0.0.0.0"
  port: 8080

search:
  chroma_path: "/app/chroma_data"
  model: "paraphrase-multilingual-MiniLM-L12-v2"

Environment variables (override config.yaml)

Variable Default Description
VAULT_PATH /vault Path to your Markdown vault inside the container
SERVER_HOST 0.0.0.0 Bind address
SERVER_PORT 8080 Internal port
CHROMA_PATH /app/chroma_data ChromaDB storage path
EMBEDDING_MODEL paraphrase-multilingual-MiniLM-L12-v2 Sentence-transformers model
OAUTH_ISSUER_URL (empty) Set to enable OAuth (e.g. https://vault.yourdomain.com)
OAUTH_PIN (empty) Optional PIN for the OAuth approval page

Metadata conventions

The server parses **Key:** Value patterns in the first 15 lines of each file:

# My Project

**Status:** Active
**Created:** 2026-01-15
**Last Updated:** 2026-03-01

Recognized status values: Active, Pending, Paused, Done (and Spanish equivalents).

Stack

  • Python 3.12 + FastMCP
  • ChromaDB for vector storage
  • sentence-transformers (paraphrase-multilingual-MiniLM-L12-v2) for embeddings
  • Docker + uv for fast builds

License

MIT

About

MCP server that gives Claude Code persistent memory with a Markdown vault

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors