docs-mcp
Allows searching Celery documentation using hybrid retrieval, listing sources, and fetching chunks or full pages from the indexed Celery docs.
Allows searching FastAPI documentation using hybrid retrieval, listing sources, and fetching chunks or full pages from the indexed FastAPI docs.
Allows searching RabbitMQ documentation using hybrid retrieval, listing sources, and fetching chunks or full pages from the indexed RabbitMQ docs.
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., "@docs-mcpsearch celery docs for acks_late"
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.
docs-mcp
Documentation search over MCP for an AI model. Hybrid retrieval (exact phrase + keyword + vector), one container, no API keys, nothing leaves the machine.
Commands
docker compose up -d --build # build + start the server on :8765
docker compose run --rm indexer sync # reconcile sources.toml
docker compose run --rm indexer sync --rebuild # re-embed everything from scratch
docker compose run --rm indexer sync --source fastapi # sync one source only
docker compose run --rm indexer sync --dry-run # preview changes
docker compose run --rm indexer materialize --source manuals # rebuild rich docs without indexing
docker compose run --rm indexer inspect manuals manual.pdf --json
docker compose run --rm indexer search --source rabbitmq "per-message ttl" # query from the shell
docker compose logs -f server # follow logs
docker compose restart server # restart
docker compose down # stop
curl localhost:8765/health # {"status":"ok"} | {"status":"empty-index"}Related MCP server: local-Rag
Configure and sync sources
Copy sources.toml.example to
sources.toml, edit it, and run docs-mcp sync (or docker compose up -d). The real
sources.toml is intentionally local-only and is ignored by Git.
Sources are explicitly git or local. Markdown, MDX, reStructuredText, and TXT are indexed
directly. PDF and DOCX are accepted only from local sources and are first converted into one
inspectable Markdown file per source section under STATE_DIR/materialized; the original rich
document remains the source of truth. Generated paths look like
manual.pdf/p0012-b0003-deployment.md and work with the same search/fetch calls as native docs.
Git sources ignore repository PDF/DOCX artifacts. Unsupported files are skipped, hidden paths and
symlinks are never followed, and the configured origin is never modified. A failed rich-document
update retains its last usable topics while other files continue. No restart is needed — the
running server picks up a new index immediately.
PDF extraction prefers the embedded text layer and invokes local Tesseract heb+eng only for a
page whose native layer is missing or unusable. DOCX extraction walks XML body order so paragraphs
and tables stay interleaved and never fabricates page numbers. The generated manifest records the
original hash, parser identity, page/block ranges, methods, and warnings. Page markers are removed
from searchable prose and exposed as chunk provenance. Encrypted PDFs, macros, external DOCX
relationships, unsafe ZIP paths, and configured resource-limit violations are rejected.
docs-mcp materialize [--source NAME] [--force] [--strict] updates generated output without
publishing an index. docs-mcp inspect SOURCE PATH [--json] accepts either an original PDF/DOCX
path or a generated logical path and shows its provenance (plus Markdown for a topic). Strict mode
treats extraction warnings as failures.
With the included Compose configuration, relative local paths should live below docs/ (for
example, path = "docs/logic"). That directory is mounted into the one-shot indexer read-only and
is never mounted into the server. Native docs-mcp sync may use any local path.
Refresh the configured upstream doc sets:
docker compose run --rm indexer sync # fetches configured sources and embeds only what changedConnect a client
On the VM, set the address to serve on, then restart:
cp .env.example .env
echo 'BIND_ADDR=100.x.x.x' >> .env # Tailscale/WireGuard/LAN IP. 0.0.0.0 only if firewalled.
docker compose up -dFrom your machine:
claude mcp add --transport http docs http://100.x.x.x:8765/mcp
claude mcp list # -> docs: ... ✔ ConnectedWith a token: put AUTH_TOKEN=… in .env, restart, then add
--header "Authorization: Bearer …".
Tools the model gets
tool | does |
| which doc sets exist, file/chunk counts, last indexed |
| hybrid search — required singular |
| a source-scoped hit plus its neighbouring passages |
| a whole page, paginated |
Also exposed as resources: docs://<source>/<path>.
Settings
.env, all optional — see .env.example:
BIND_ADDR=127.0.0.1 # address the port is published on
PORT=8765
AUTH_TOKEN= # empty = no auth
ALLOWED_ORIGINS= # browser origins allowed; requests with no Origin always pass
RERANK=0 # 1 = add a cross-encoder rerank pass (see Notes)
DEFAULT_LIMIT=8 # hits per search
THREADS= # ONNX threads; blank = all cores
CANDIDATE_MEMORY_MB=64 # candidate data spills to disk above this threshold
SOURCES_CONFIG=sources.toml
STATE_DIR=.docs-mcp # private Git cache and temporary filtered snapshots
MATERIALIZED_DIR=... # omit to use STATE_DIR/materialized
MAX_RICH_BYTES=104857600
MAX_PDF_PAGES=2000
MAX_EXTRACTED_CHARS=20000000
MAX_DOCX_ENTRIES=10000
MAX_DOCX_EXPANDED_BYTES=524288000
MAX_RENDERED_PIXELS=50000000
MAX_RICH_PROCESSING_SECONDS=1800Verify by hand
curl -s localhost:8765/mcp \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-H 'MCP-Protocol-Version: 2026-07-28' \
-H 'Mcp-Method: tools/list' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{"_meta":{
"io.modelcontextprotocol/protocolVersion":"2026-07-28",
"io.modelcontextprotocol/clientCapabilities":{}}}}'One POST, no initialize handshake — MCP 2026-07-28 is stateless. Both _meta keys are required.
uv run pytest -q # unit, lifecycle, tool, and retrieval quality gatesNumbers
Measured on this corpus (1809 files, 4068 chunks, 4 sources):
full index | ~2 min native, ~8 min under Docker Desktop on macOS |
re-index, nothing changed | <1 s |
re-index, one file edited | ~1 s |
search | ~6 ms median |
image | 1.13 GB (both ONNX models baked in) |
index file |
|
Notes
Retrieval is three legs fused with weighted Reciprocal Rank Fusion: an exact-phrase leg for identifiers, BM25 for keywords, and vectors for meaning. The phrase leg is why
acks_lateandworker_concurrencywork — SQLite's tokenizer splits them into common words, so keyword-only search buries them.RERANK=0by default on purpose. A cross-encoder pass was measured on this corpus and gave no improvement on prose queries (fusion already ranks 6 of 7 first) while costing ~740 ms per search instead of 6 ms. It also hurts identifier queries — MRR 0.79 vs 0.92 — because cross-encoders score bare config keys as uniformly irrelevant. Identifier queries bypass it even when enabled. TryRERANK=1if your corpus is more prose-heavy.Search returns ranked candidates, not a relevance guarantee. A vector search always has nearest neighbours, and on this corpus the best-match distance for a real paraphrase (0.80) overlaps that of an invented word (0.83) — too close to threshold without losing real recall. A query with no searchable token at all returns nothing.
The index is a named volume (
docs-mcp_index), not a bind mount — the container runs as the non-rootappuser (uid 999), and a bind-mounted host directory arrives with the host's ownership, so/datais unwritable on a fresh Linux clone. Back up withdocker compose cp server:/data/index.db ./index.db; restore with the same in reverse.docker compose down -vdeletes it and starts over.The server mounts only the index volume. The docs tree goes to the indexer only, and
fetch_docserves from the index, so the server has no filesystem path to traverse.Rich-document output is deterministic for unchanged input and pipeline versions. Successful replacement is atomic and removes stale topics; a failed replacement records an inspectable error and leaves the prior materialization and searchable rows intact. The current PDF backend reconstructs text structure conservatively and does not generate descriptions for unlabeled figures or attempt handwritten recognition.
Embeddings run on CPU in the container (
bge-small-en-v1.5, 384-dim), models baked into the image,HF_HUB_OFFLINE=1. No network at runtime.Changing
DENSE_MODELforces a full rebuild automatically — vectors from two models aren't comparable.The SDK also serves pre-2026 MCP revisions, so
GET /mcpopens a legacy SSE stream instead of returning 405, and a request omittingMCP-Protocol-Versionis treated as2025-03-26. Both are the spec's backward-compatibility allowances, not strict-2026-only behaviour.
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.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceIndexes documentation sites by base URL and serves keyword search, optional semantic search, and Markdown page retrieval as MCP tools, all from a single SQLite file.
- AlicenseAqualityCmaintenanceA local-first document retrieval MCP server that enables AI coding tools like Codex to search private local documents via semantic search and keyword boost, supporting ingestion of PDF, DOCX, TXT, Markdown, and HTML files.7MIT
- AlicenseNot gradedqualityAmaintenanceProvides a local MCP server for searching and retrieving documentation from 22+ open-source projects, enabling AI coding assistants to access up-to-date docs without network dependency.202MIT
Related MCP Connectors
Agentic search over your Dewey document collections from any MCP-compatible client.
MCP server for accessing curated awesome list documentation
Serve a folder of Markdown notes as an MCP server: hybrid search, reading, and sourced answers.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- 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/kislevlevy/docs-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server