bdc-doc-mcp
This server provides a single tool for searching the BDC documentation database.
Search BDC docs by natural-language query or literal keywords and return top-k matching chunks with content, metadata (source, doc_type, datetime when available), and a score.
Control result count with
k(default 5; raise to 10–20 for broad or multi-part questions).Choose search mode:
embeddingfor semantic similarity orkeywordfor fuzzy literal matching of exact names, acronyms, tools, or error messages.Filter by
doc_typeCSV across docs, page, faq, video, fellow, update, and event; omitted defaults to docs, page, faq, and video.Filter by inclusive dates with
date_from/date_to(YYYY-MM-DD), which effectively narrows to dated event and update docs.Results are relevance-ranked, not date-ranked; for “recent/latest” questions, set
date_fromand compare returned dates.
Allows searching over documentation ingested from a GitBook repository, enabling AI agents to retrieve relevant content from the BDC GitBook documentation.
Integrates with Google Sheets and Google Drive to ingest video transcripts (SRT files) into the searchable index.
Uses Ollama to generate embeddings for indexing and semantic search.
Click on "Deploy 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., "@bdc-doc-mcp search the docs for how to query BDC data"
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.
r-doc-mcp
The documentation RAG MCP of r-assist.
Serving side only: the API/MCP servers and the vector DB. Content is built and pushed by r-doc-builder, which lives outside this security boundary and talks to the ingest API — nothing here scrapes, chunks, or calls a completion LLM.
r_doc_mcp/config.py env-driven query embeddings + DB settings
r_doc_mcp/db.py vector-DB backends behind one interface (chroma today; DB_BACKEND selects)
r_doc_mcp/api.py FastAPI: /health /search + token-guarded /ingest/upsert /ingest/reset
r_doc_mcp/mcp_server.py search_docs MCP tool for AI agents — self-contained, same search as the API
tests/ self-checks + API / agent notebooksSetup
uv sync
cp .env.example .env # then fill in keys/URLsEmbeddings (for queries) use a local Ollama, e.g. bge-m3. This must be the same model
r-doc-builder embedded the documents with — vectors from different models don't mix
(bge-m3 is 1024-dim, text-embedding-3-small 1536); switching models means a full
re-push from the builder.
To run the three repos together from scratch, follow "From clone to chat" in r-assist's README.
Related MCP server: okfy
API
uv run uvicorn r_doc_mcp.api:app --port 8000 # docs at /docs (or: python -m r_doc_mcp.api, binds API_HOST:API_PORT)Endpoint | Body | Returns |
| — |
|
|
| ranked chunks + metadata + score |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| — |
|
mode is embedding (default; semantic similarity, score = distance, lower is better)
or keyword (fuzzy literal word matching — ignores case/punctuation and tolerates
small typos, so picsure finds "PIC-SURE"; score = occurrence count, higher is
better — use for exact names/acronyms).
doc_type is a CSV of types to search (e.g. page,faq). Types and the default scope
come from <CONFIG_DIR>/doc_types.yaml (default config/; examples/bdc/doc_types.yaml is a
filled-in one). When doc_type is omitted only the types flagged default are searched;
with no defaults declared, everything is.
date_from/date_to (YYYY-MM-DD, inclusive) filter by date; only chunks that carry
a date match, so a date filter implicitly narrows to those.
The /ingest/* endpoints are the write path for r-doc-builder: they take finished
records (embeddings pre-computed on the builder side) and require
Authorization: Bearer $INGEST_TOKEN; with INGEST_TOKEN unset, ingest is disabled.
r-doc-builder looks up what is stored for a file's sources before embedding, so a re-push
embeds only new or changed chunks. Metadata merges into what is stored on upsert and update;
a null value deletes that key.
Answering is the caller's job — an agent brings its own LLM.
Doc types
config/doc_types.yaml declares the doc_type values r-doc-builder pushes for this
project — it drives the default search scope and the search_docs tool description,
so a new deployment only needs a new YAML file, not a code change. Each type has a
description (shown to the agent) and a default flag (searched when the caller
gives no doc_type). Set CONFIG_DIR=examples/bdc (or examples/fastapi) to see a
filled-in example. examples/fixture serves r-doc-builder's fake, BDC-shaped test corpus: the
same doc_types and default scope as examples/bdc (tests/test_doc_types.py keeps them in step). Each CONFIG_DIR gets its own collection in the DB, named after the folder
(config, bdc, ...; COLLECTION_NAME overrides it), so switching examples never mixes or
overwrites another's chunks, and --reset only clears the current one.
The wording of the search_docs tool description lives in config/prompts.yaml, a template
with {project}, {k}, {types} and {scope} filled from doc_types.yaml and SEARCH_K.
Edit it freely (literal braces as {{ }}); the server reads it once at startup.
DB backends
r_doc_mcp/db.py keeps the vector DB behind a five-method interface
(count/search/scan/upsert/reset); everything chroma-specific — filter syntax,
DB_PATH, the collection — lives in its ChromaDB class. To swap in a remote DB
(postgres/pgvector, qdrant, ...), implement the same methods, register the class in
BACKENDS, and set DB_BACKEND.
MCP
uv run python -m r_doc_mcp.mcp_server # stdio
uv run python -m r_doc_mcp.mcp_server --http # streamable HTTP on MCP_HOST:MCP_PORT (default 127.0.0.1:8001), plus the APIExposes one tool, search_docs — same search as the API but queries the DB directly,
so the API service doesn't need to run. Needs a pushed DB + embeddings.
Stdio clients (Claude Desktop/Code, Cursor) launch the server themselves — register it:
{"mcpServers": {"r-doc-mcp": {
"command": "uv",
"args": ["--directory", "/path/to/r-doc-mcp", "run", "python", "-m", "r_doc_mcp.mcp_server"]
}}}The mcpServers key above is the client's own label for the server; the name the server
reports for itself is MCP_SERVER_NAME (default r-doc-mcp).
Network clients: run --http and point them at http://host:8001/mcp instead. --http also
serves the API routes (/health /search /ingest/*) from the same process, so a deployment runs one
server and r-doc-builder pushes to DOC_MCP_URL=http://host:8001: chroma isn't process-safe, so a
separate API process ingesting into the same DB_PATH would write under the MCP server's index.
Only /ingest/* is token-guarded; keep /mcp and /search on a trusted network.
/mcp is stateless (no session state, plain JSON replies): every request stands alone, so a
client can keep one session open across server restarts (r-assist's keep_session: true).
FastMCP logs at WARNING only: its per-request INFO lines cost 35% of the CPU under load.
Smoke test: uv run python tests/test_mcp.py
Tests
uv run python tests/test_doc_types.py # doc_types.yaml + prompts.yaml -> default scope + tool description — no network
uv run python tests/test_api.py # ingest+search round-trip over a temp DB, auth — no network
uv run python tests/test_compare_db.py # the DB comparison below, on throwaway DBs — no network
uv run python tests/compare_db.py DIR_A DIR_B [--collection C] [--atol X] # do two DB dirs hold the same chunks? (servers stopped)
uv run python tests/test_keyword.py # keyword ranking, pure function, no DB or API
uv run python tests/test_mcp.py # starts the server over stdio and exercises its tools; needs a pushed DB + embeddingsNotebooks (each starts the API on a free port and shuts it down at the end; both need a pushed DB):
tests/api_test.ipynb— plain API walkthrough:/health,/search,doc_typefilter. Only needs the local embeddings.tests/agent_test.ipynb— a tool-calling agent (deepagents): the configured LLM getssearch_docsas a LangChain tool and decides when to call it. Also needs the completion provider reachable.
Available Tools
1 toolsearch_docsA
Search the BDC (NHLBI BioData Catalyst) documentation database.
Returns the top-k matching chunks with content, metadata (source, doc_type, datetime when available), and a score.
query is the search text. In embedding mode phrase it as a question or topic (e.g. "how do I bring my own data"); in keyword mode give the literal terms to match.
k is the number of chunks to return (default 5). Raise it (10-20) for broad or multi-part questions; each chunk is a small section of a document.
mode toggles the search engine:
"embedding" (default): semantic similarity — best for questions, topics, and paraphrased wording. score is a distance (lower = more similar).
"keyword": fuzzy literal word matching — ignores case and punctuation ("picsure" finds "PIC-SURE") and tolerates small typos — best for exact names, acronyms, tool names, or error messages the embedding may blur. Chunks matching more of the query terms rank first; score is the total number of occurrences (higher = better).
doc_type is a CSV string of types to search (e.g. "page,faq" or "video"). Available types:
docs: BDC GitBook platform documentation — user guides, how-tos, and technical reference (bdcatalyst.gitbook.io)
page: key pages of the BDC website — about/overview, joining BDC, analyzing & sharing data, usage costs and terms
faq: Freshdesk help-desk FAQ articles (support questions & answers)
video: transcripts of BDC YouTube tutorials/webinars, with timestamped links into the video
fellow: BDC Fellows profiles — fellowship recipients and their research projects
update: dated news posts ("latest updates") from the BDC website
event: dated BDC events — webinars, workshops, deadlines When doc_type is omitted, only docs, page, faq, and video are searched — name fellow, update, or event explicitly to search them.
date_from / date_to ("YYYY-MM-DD", inclusive) filter by date. Only event and update docs carry a date, so a date filter implicitly narrows to those types. Results are ranked by relevance, NOT date — for "recent"/"latest" questions, always set date_from to bound the range, then compare the dates returned.
Inputs: query (required), k, mode, date_to, +2 more.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 1 tool
With only a single tool, there is no possibility of ambiguity. The tool has a clearly defined purpose for searching documentation.
The tool name 'search_docs' follows a consistent verb_noun pattern and is descriptive. Since it is the only tool, naming is inherently consistent.
The server exposes only one tool, which is extremely thin. Even though the tool is multi-functional, a single tool does not constitute a well-scoped set; most servers with this purpose would benefit from at least a couple of complementary tools (e.g., retrieving a document by ID or listing available types).
The search tool covers multiple documentation sources and provides filtering and multiple modes, which addresses the core purpose. However, it lacks any other operation such as fetching a specific document, listing available doc types, or managing content, leaving notable gaps for a documentation server.
Maintenance
Related MCP Connectors
Team docs served to AI agents over MCP - search, Markdown reads, version pinning, read audit.
Agentic search over your Dewey document collections from any MCP-compatible client.
Agent-driven search: build, import, tune, search, and score result quality — all over MCP.
Make your knowledge agent-ready. One MCP endpoint, 5 connectors, 3 search modes.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceProvides semantic search over markdown documentation using RAG, allowing natural language queries and integration with MCP clients.1MIT
- AlicenseNot gradedqualityDmaintenanceEnables AI agents to search, read, and traverse documentation bundles in Open Knowledge Format via MCP tools.674 npm74MIT
- AlicenseNot gradedqualityDmaintenanceProvides RAG (Retrieval Augmented Generation) access to technical documentation through MCP, enabling LLMs to search and retrieve relevant documentation on-demand.5MIT
- AlicenseNot gradedqualityBmaintenanceCrawl documentation sites, index them with hybrid search, and expose them as MCP tools so LLM agents can search and retrieve current docs.MIT