mcp-docsearch
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mcp-docsearchsearch the docs for deployment process"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
mcp-docsearch
Semantic search over any markdown corpus, exposed as an MCP server.
Point it at a directory of markdown. It chunks the files, embeds them into a local
ChromaDB vector store, and gives your MCP client — Claude Code,
Claude Desktop, or anything else that speaks MCP — three tools: search_docs, reindex, and
index_stats.
Results come back with file paths, line numbers, and section breadcrumbs, so the model can cite and open the source rather than paraphrasing from a soup of context.
Everything runs locally. No API keys, no documents leaving your machine.
Why
Grep finds the word you typed. It does not find the paragraph that means what you meant.
Once a corpus — design docs, a knowledge base, a wiki, a novel — grows past a few dozen files, an agent needs retrieval, not string matching. This is a small, dependency-light way to give it one, over a corpus you already have sitting on disk as markdown.
Related MCP server: @remember-md/mcp
Install
git clone https://github.com/MrMattMunro/mcp-docsearch
cd mcp-docsearch
pip install -e .Quick start
export DOCSEARCH_CORPUS=/path/to/your/markdown
mcp-docsearch-index # build the index (first run embeds everything)Then register the server with your MCP client. For Claude Code (.mcp.json):
{
"mcpServers": {
"docsearch": {
"command": "mcp-docsearch",
"env": {
"DOCSEARCH_CORPUS": "/path/to/your/markdown",
"DOCSEARCH_COLLECTION": "my_docs"
}
}
}
}Ask your model something like "search the docs for how authentication is handled" and it will
call search_docs and get back ranked excerpts with line numbers.
In practice
This exists because I hit the problem from two directions at once: I wanted semantic search over a corpus of structured design docs and over a long-form fiction manuscript, and discovered that no single chunking strategy serves both. Splitting a novel on its headers gives you one useless mega-chunk per chapter. Sliding a fixed window over a reference doc slices sections in half and strands the heading from the thing it describes.
Hence two strategies. The examples below are the three corpus shapes I actually run it against.
A structured knowledge base
Design docs, runbooks, a team wiki. Sections are already self-contained ideas, and the header
chain (Runbook > Deploys > Rollback) is a ready-made breadcrumb.
DOCSEARCH_CORPUS=~/notes/handbook
DOCSEARCH_COLLECTION=handbook
DOCSEARCH_CHUNK_MODE=headerA long-form manuscript
A novel, a screenplay, interview transcripts. Hundreds of pages, barely a header in sight — the kind of corpus where "which scene was it where they argued about the money?" is exactly the question you can't grep for.
DOCSEARCH_CORPUS=~/writing/manuscript
DOCSEARCH_COLLECTION=manuscript
DOCSEARCH_CHUNK_MODE=window
DOCSEARCH_WINDOW=120 # prose needs more context per chunk than reference docs
DOCSEARCH_OVERLAP=30 # a scene straddling a seam still lands whole in one windowA mixed working directory
Plans, notes and reference material side by side, with no consistent shape. Let auto decide per
file, and use the group filter (the top-level folder) to scope a search to just plans/ or just
reference/.
DOCSEARCH_CORPUS=~/workspace
DOCSEARCH_COLLECTION=workspace
DOCSEARCH_CHUNK_MODE=auto
DOCSEARCH_EXCLUDE=archive,draftssearch_docs("what did we decide about the migration?", group="plans")One install, three corpora: give each its own DOCSEARCH_COLLECTION and they stay completely
independent.
Configuration
All configuration is environment variables, so one install can serve many corpora.
Variable | Default | Meaning |
| cwd | Root directory of the markdown corpus |
|
| Where the vector store is written |
|
| Collection name (use one per corpus) |
|
|
|
|
| Lines per window (window mode) |
|
| Overlapping lines between windows |
| — | Extra comma-separated directory names to skip |
How it works
Chunking — the part that decides whether retrieval is any good
Chunk badly and no amount of embedding quality will save you: split an idea in half and neither half retrieves. So there are two strategies, chosen per file.
header — split on markdown headers, one section per chunk. Right for structured docs,
where a section is already a self-contained idea. Each chunk carries its full header chain
(Guide > Setup > Windows), which gives the model a breadcrumb for free and makes results
readable at a glance.
window — fixed-size overlapping line windows. Right for long-form prose with few headers
(a novel chapter, a meeting transcript), where header-splitting would yield one giant useless
chunk. Windows overlap so an idea straddling a seam still appears whole in one of them. A runt
tail is absorbed into the previous chunk rather than emitted as a two-line fragment that matches
nothing.
auto (the default) picks per file: header split if the file has 2+ headers, else windows.
Incremental indexing
Re-embedding an entire corpus every time you fix a typo is slow and pointless. Each file's mtime
is recorded, so a normal reindex only re-embeds files that actually changed. Chunks belonging
to deleted files are removed from the store, so the index can't rot into a graveyard of stale
references.
reindex(force=True) does a full rebuild when you want one.
Retrieval
Cosine similarity over the collection. Results carry file_path, start_line, end_line, and
header_chain, and can be filtered by group (top-level directory) or path_prefix.
MCP tools
Tool | Purpose |
| Ranked excerpts with paths + line numbers |
| Incremental by default; one file or a full rebuild |
| What's indexed, and the active configuration |
A note on privacy
The vector store contains embedded copies of your documents. If your corpus is private, the
index is private too — even if the code around it isn't. .docsearch/ and .chromadb/ are in
.gitignore for exactly this reason. Don't commit an index.
Development
pip install -e ".[dev]"
pytestLicence
MIT
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/MrMattMunro/mcp-docsearch'
If you have feedback or need assistance with the MCP directory API, please join our Discord server