Local RAG MCP server for markdown docs. Retrieval only (no answer LLM): ask_docs returns grounded passages plus citations that resolve to real files on disk. Index any local path or git repo, filter by layer, embed offline.
- ✓Open-source license (MIT)
- ✓Actively maintained (<30d)
- ✓Clear description
- ✓Topics declared
- ✓Documented (README)
claude mcp add mcp-docs-ask -- uvx mcp-docs-ask{
"mcpServers": {
"mcp-docs-ask": {
"command": "uvx",
"args": ["mcp-docs-ask"]
}
}
}MCP Servers overview
# mcp-docs-ask
[](https://github.com/alyiox/mcp-docs-ask/actions/workflows/ci.yml)
[](https://pypi.org/project/mcp-docs-ask/)
[](https://www.python.org/downloads/)
[](LICENSE)
<!-- mcp-name: io.github.alyiox/mcp-docs-ask -->
Local RAG MCP for documentation. Point `source` at any markdown repository
(local path or git URL).
The server does **retrieval only** (no answer LLM). `ask_docs` returns grounded
passages and citations; the MCP host (Cursor / Claude) synthesizes the answer.
## Features
- Any markdown repo as a source: a local path, or a git URL fetched on `reindex`
- Runs locally: sentence-transformers embeddings, no API keys, no answer LLM
- Path-based layers to narrow a search (e.g. guides vs. API reference)
- Full passages with heading paths and `[n]` citations, capped by a character budget
- No manual rebuilds: the index refreshes itself when local files, config, or the
embedding model change
## Requirements
- Python 3.13+
- [`uv`](https://docs.astral.sh/uv/)
- `git` on PATH (only if `source` is a git URL)
- Git credentials on the machine when `source` is a **private** git URL
(`gh auth login`, HTTPS credential helper, or SSH). No tokens in config.
- First run downloads the embedding model weights once (sentence-transformers)
## Quick start
```bash
git clone git@github.com:alyiox/mcp-docs-ask.git
cd mcp-docs-ask
uv sync
mkdir -p ~/.config/mcp-docs-ask
cp config.example.json ~/.config/mcp-docs-ask/config.json
# Prefer a local checkout while developing:
# set docs.<id>.source to your docs repo path
npx -y @modelcontextprotocol/inspector@latest uv run mcp-docs-ask
```
## Configuration
Config path: `~/.config/mcp-docs-ask/config.json`
> **Windows:** `%USERPROFILE%\.config\mcp-docs-ask\config.json`
```json
{
"docs": {
"product": {
"source": "https://github.com/example/docs.git",
"desc": "Product guides and API reference",
"ref": "main",
"include": ["**/*.md"],
"exclude": ["archive/**"],
"layers": {
"guides": {
"desc": "How-to and onboarding guides",
"include": ["docs/guides/**"]
},
"api": {
"desc": "HTTP API reference",
"include": ["docs/api/**"]
}
},
"embedding_model": "sentence-transformers/all-MiniLM-L6-v2"
},
"team-notes": {
"source": "/path/to/docs",
"desc": "Internal team notes (local path; ref unused)",
"include": ["**/*.md"],
"exclude": ["archive/**"]
}
},
"default": {
"docs": "product",
"embedding_model": "sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2",
"top_k": 8,
"chunk_max_chars": 1500,
"max_context_chars": 8000
}
}
```
`product` is a git URL (`ref` applies). `team-notes` is a filesystem path (`ref` unused).
Optional `desc` on each docs collection and layer helps agents pick the right target.
`embedding_model`, `top_k`, `chunk_max_chars`, and `max_context_chars` resolve as:
`docs.<id>.X` → `default.X` → built-in. Omit per-docs keys to inherit.
**Embedding model recommendation**
Any Hugging Face id loadable by `sentence-transformers` works. Pick by language mix:
| Docs / queries | Recommended `embedding_model` |
|---|---|
| **English-only** (built-in when omitted) | `sentence-transformers/all-MiniLM-L6-v2` |
| **Chinese-only** | `BAAI/bge-small-zh-v1.5` |
| **Multilingual** (~50 langs) | `sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2` |
Changing `embedding_model` rebuilds the index on the next call; no `reindex` needed.
| Field | Description |
|---|---|
| `docs.<id>.source` | Docs **repo root**: local path or git URL |
| `docs.<id>.desc` | Short description for discovery (`list_docs`) |
| `docs.<id>.ref` | Branch / tag / SHA for git URL sources only (default `main`; ignored for local paths) |
| `docs.<id>.include` | Globs relative to repo root (default `**/*.md`) |
| `docs.<id>.exclude` | Globs to skip |
| `docs.<id>.layers.<name>.include` | Path globs for that layer (first match wins) |
| `docs.<id>.layers.<name>.desc` | Short layer description for discovery |
| `docs.<id>.embedding_model` | Optional override (see recommendation above) |
| `docs.<id>.top_k` | Optional override for default retrieval count |
| `docs.<id>.chunk_max_chars` | Optional override for max body chars per heading chunk |
| `docs.<id>.max_context_chars` | Optional override for the `answer_context` passage budget |
| `default.docs` | Default docs collection id |
| `default.embedding_model` | Default sentence-transformers model id |
| `default.top_k` | Default retrieval count |
| `default.chunk_max_chars` | Default max body chars per heading chunk |
| `default.max_context_chars` | Default total passage chars in `answer_context` (min 500) |
**Layers** partition indexed files by path glob. First match wins. Names are
case-insensitive; `all` is reserved (cannot be configured as a layer name).
| `ask_docs` `layer` | Meaning |
|---|---|
| `all` (default) | Every indexed chunk (named layers and paths outside them) |
| `<named>` | Only chunks whose path matched that named layer’s `include` globs |
Paths that match no named-layer glob are still indexed and only appear under
`layer=all`. Omit `layers` (or set `"layers": {}`) for flat repos — use
`layer=all`.
Cache layout:
- Repos (git URL): `~/.cache/mcp-docs-ask/repos/<docs-id>/`
- Indexes: `~/.cache/mcp-docs-ask/indexes/<docs-id>/`
## Tools
| Tool | Description |
|---|---|
| `list_docs` | List configured docs collections, layer filters, and index state |
| `ask_docs` | Retrieve grounded passages + citations (`layer`: `all` or a named layer) |
| `reindex` | Sync git source (if URL) and rebuild the vector index |
`list_docs` returns a `default` block with the same keys as the config `default`
block (`docs`, `embedding_model`, `top_k`, `chunk_max_chars`,
`max_context_chars`), plus a `docs` list where each entry carries its resolved
values, a `default` flag, and an `index` block (`null` when the collection has
never been indexed). Valid `layer` values are `all` plus the named layer ids —
see **Layers** above.
### Index block
`list_docs` and `reindex` return the same `index` keys: `origin`, `root`, `rev`,
`files`, `chunks`, `layers`.
`origin` mirrors the configured source: `file` for a filesystem path, `git` for
a URL the server clones into `~/.cache/mcp-docs-ask/repos/<docs-id>/` and
fetches on `reindex`. `root` is where the files actually are — `null` only when
a built index outlived its source directory. `rev` is the checkout HEAD when
there is one, so a `file` source that is itself a git clone still reports one;
its working tree may hold uncommitted edits, so `rev` labels the checkout, not
the exact indexed content.
`ask_docs` carries only the two answer-scoped keys, `root` and `rev`: the
checkout that produced the passages, and the revision they came from.
### Passages
`ask_docs` retrieves up to `top_k` chunks, then assembles them into passages:
- Each passage is the full chunk text, with line breaks kept, labeled with its
heading path (`Guide > Configuration > Layers`).
- Retrieved parts of one oversized section are joined back in file order;
`…` marks parts in between that did not rank.
- Passages fill `max_context_chars` best-first. The one that overflows is
trimmed at a line break and ends with `…`; the first passage is always kept.
So `citations` can hold fewer entries than `top_k`.
### Reading a full source file
`citations[].path` is repo-relative and stable; `answer_context` holds the
passage text once, keyed by the `[n]` markers that match `citations[].n`. To read
a whole source file, join `index.root` from the same `ask_docs` response with a
citation path:
```
/home/you/docs-repo + product/features/budget.md
```
Take `root` from the response that produced the citations rather than an earlier
`reindex` — `ask_docs` rebuilds a stale index itself, so its `rev` is the one
that matches the passages in hand.
## MCP host examples
The examples below launch the server with `uvx`, which installs the package on first
use. Run it once in a terminal beforehand so your host does not block on that install:
```bash
$ uvx mcp-docs-ask
Installed 84 packages in 275ms
```
The server then starts on stdio and waits for input — press Ctrl-C once you see the
install line. Embedding model weights are fetched separately, on the first `ask_docs`
or `reindex` call. `uvx mcp-docs-ask --version` prints the build `uvx` resolved.
> **Linux (including WSL, containers, and CI):** the PyPI `torch` wheel for Linux is
> the CUDA build. It pulls ~15 `nvidia-*` packages whether or not the machine has an
> NVIDIA GPU — about 2.7 GB of wheels and ~4 GB on disk. Windows and macOS resolve to
> a CPU-only wheel (~1 GB) and never download CUDA. Pre-warming matters most here:
> expect the first `uvx` run to take minutes, not milliseconds.
### Cursor
Add to `.cursor/mcp.json`:
```json
{
"mcpServers": {
"docs-ask": {
"command": "uvx",
"args": ["mcp-docs-ask"]
}
}
}
```
### Claude Code
Add to your Claude Code MCP config:
```json
{
"mcpServers": {
"docs-ask": {
"command": "uvx",
"args": ["mcp-docs-ask"]
}
}
}
```
### Codex
```toml
[mcp_servers.docs-ask]
command = "uvx"
args = ["mcp-docs-ask"]
```
### OpenCode
```json
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"docs-ask": {
"type": "local",
"enabled": true,
"command": ["uvx", "mcp-docs-ask"]
}
}
}
```
### GitHub Copilot
```json
{
"inputs": [],
"servers": {
"docs-ask": {
"type": "stdio",
"command": "uvx",
"args": ["mcp-docs-ask"]
}
}
}
```
## Development
```bash
uv sync
uv run ruff checkWhat people ask about mcp-docs-ask
What is alyiox/mcp-docs-ask?
+
alyiox/mcp-docs-ask is mcp servers for the Claude AI ecosystem. Local RAG MCP server for markdown docs. Retrieval only (no answer LLM): ask_docs returns grounded passages plus citations that resolve to real files on disk. Index any local path or git repo, filter by layer, embed offline. It has 0 GitHub stars and its last recorded update is dated 2026-10-13.
How do I install mcp-docs-ask?
+
You can install mcp-docs-ask by cloning the repository (https://github.com/alyiox/mcp-docs-ask) or following the README instructions on GitHub. ClaudeWave also provides quick install blocks on this page.
Is alyiox/mcp-docs-ask safe to use?
+
Our security agent has analyzed alyiox/mcp-docs-ask and assigned a Trust Score of 95/100 (tier: Verified). See the full breakdown of passed checks and flags on this page.
Who maintains alyiox/mcp-docs-ask?
+
alyiox/mcp-docs-ask is maintained by alyiox. The last recorded GitHub activity is dated 2026-10-13, with 0 open issues.
Are there alternatives to mcp-docs-ask?
+
Yes. On ClaudeWave you can browse similar mcp servers at /categories/mcp, sorted by popularity or recent activity.
Deploy mcp-docs-ask to your cloud
Ship this repo to production in minutes. Each platform spins up its own environment with editable env vars.
Maintain this repo? Add a badge to your README
Drop the badge into your GitHub README to show it's tracked on ClaudeWave. Each badge links back to this page and reflects the live Trust Score.
[](https://claudewave.com/repo/alyiox-mcp-docs-ask)<a href="https://claudewave.com/repo/alyiox-mcp-docs-ask"><img src="https://claudewave.com/api/badge/alyiox-mcp-docs-ask" alt="Featured on ClaudeWave: alyiox/mcp-docs-ask" width="320" height="64" /></a>More MCP Servers
Fair-code workflow automation platform with native AI capabilities. Combine visual building with custom code, self-host or cloud, 400+ integrations.
Reverse engineer anything with agents, from app behavior down to native binaries.
User-friendly AI Interface (Supports Ollama, OpenAI API, ...)
An open-source AI agent that brings the power of Gemini directly into your terminal.
Real-time global intelligence dashboard. AI-powered news aggregation, geopolitical monitoring, and infrastructure tracking in a unified situational awareness interface
🕷️ An adaptive Web Scraping framework that handles everything from a single request to a full-scale crawl! Don't be shy, join here: https://discord.gg/EMgGbDceNQ and follow here for daily tips and tricks: https://x.com/Scrapling_dev