A lot of knowledge lives in plain Markdown files: an Obsidian vault, a docs/ folder, years of meeting notes. AI assistants are very good at answering questions, but only about what they can see, and your notes usually aren't part of that.
The Model Context Protocol (MCP) is an open standard for giving assistants tools they can call. mcp-markdown-kb is an MCP server: point it at a folder, connect it to Claude Desktop or Claude Code, and ask things like “what do my notes say about rate limiting?” or “which notes link to the API gateway design doc?”.
01What the assistant can do
- Search every note by keyword, optionally filtered by tag, and get back the best matches with a short snippet.
- Read a whole note, with its title, tags, headings and outgoing links.
- Follow links backwards: find every note that links to a given one, through
[[wiki links]]or normal Markdown links. - Browse all notes or the tag list, and re-scan the folder after you edit something.
Each note is also published as an attachable resource, so assistants that support it can pull a specific note straight into the conversation.
02A real search
This is what comes back when the project's own code searches its four test notes for “rate limiting”, then asks which notes link to the top result:
search_notes { query: "rate limiting" } 2.4829 rate-limiting.md Rate limiting strategies "Token bucket allows bursts; sliding window log is exac…" 1.4403 projects/api-gateway.md API gateway "Design doc for the gateway. Uses [[Rate limiting strategies]] per API key…" get_backlinks { path: "rate-limiting.md" } → projects/api-gateway.md
03How it works
At startup the server walks the folder, parses every note (frontmatter, title, tags, headings and links) and builds two things in memory: a keyword search index and a map of which notes link to which. Words in a note's title, tags and headings count for more than words in the body, so a note about a topic outranks one that merely mentions it.
No database, no embeddings, no API keys. Just your files, indexed in memory.
04Decisions I made, and why
- A small search engine instead of a service. I wrote a compact BM25 implementation for this project rather than using embeddings or a vector database. There is nothing to set up, no keys to manage, and the notes stay on your machine.
- The folder is a boundary. Reading a note only works for paths that resolve inside the notes folder, so a client can't use the server to read arbitrary files.
- Honest about side effects. Five of the six tools are marked read-only, so hosts can skip confirmation prompts for them; only re-indexing isn't.
- Tested through the real protocol. The tests start the real server and a real MCP client, joined in memory, so tool listings, schemas and resources are exercised end to end: 23 tests, all passing.
- Two runtime dependencies. The official MCP SDK and Zod, which the SDK uses to validate inputs. Logs go to standard error, so they can never corrupt the protocol stream.
05Known limits
Search matches words, not meaning: a note about “throttling” won't be found by a search for “rate limiting” unless it uses those words. The frontmatter parser understands a small subset of YAML, not all of it. And after editing notes, the folder needs a re-scan (the assistant can trigger it with the reindex tool).
Try it or read the code
Open source under the MIT licence. Needs Node 22.18 or newer. With Claude Code:
git clone https://github.com/Rodzman/mcp-markdown-kb cd mcp-markdown-kb && npm install && npm run build claude mcp add markdown-kb -- node "$PWD/dist/cli.js" /path/to/notes