Documentation Search について
Documentation Searchは、Markdownリポジトリを対象とするローカルRAGのMCPサーバーです。コーディングエージェント向けに引用付きの文書検索を行い、回答文の生成はMCPホストに委ねます。
主な機能
- 01ローカルパスまたはGit URLをソースに指定
- 02sentence-transformersによるローカル埋め込み
- 03パス階層による検索絞り込み
- 04引用付きの全文段落を返却
- 05変更時のインデックス自動更新
活用シーン
- 01製品ドキュメントから設定方法を検索
- 02APIリファレンスから関連箇所を取得
- 03ガイドやAPI階層に検索対象を絞る
MCP 対応
`list_docs`、`ask_docs`、`reindex`ツールを提供します。`ask_docs`は引用付きの検索段落を返し、回答の生成はMCPホストが行います。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
mcp-docs-ask
ドキュメント向けのローカル RAG MCP です。source に任意の Markdown リポジトリ
(ローカルパスまたは Git URL)を指定します。
サーバーは検索のみを行い、回答生成用 LLM は使用しません。ask_docs は根拠となる
文章と引用を返し、MCP ホスト(Cursor/Claude)が回答を生成します。
特長
- 任意の Markdown リポジトリをソースとして使用できます。ローカルパス、または
reindex時に取得する Git URL を指定できます - ローカルで実行できます。sentence-transformers の埋め込みを使用し、API キーも回答生成用 LLM も不要です
- パスベースのレイヤーで検索範囲を絞り込めます(例:ガイドと API リファレンス)
- 見出しのパスと
[n]形式の引用を含む文章全体を、文字数の上限内で返します - 手動で再構築する必要はありません。ローカルファイル、設定、または埋め込みモデルが変更されると、インデックスが自動更新されます
要件
- Python 3.13+
uv- PATH 上の
git(sourceが Git URL の場合のみ) sourceがプライベート Git URL の場合、マシン上の Git 認証情報 (gh auth login、HTTPS 認証情報ヘルパー、または SSH)。設定にトークンを含める必要はありません。- 初回実行時に埋め込みモデルの重みが一度ダウンロードされます(sentence-transformers)
クイックスタート
git clone [email protected]: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
設定
設定ファイルのパス:~/.config/mcp-docs-ask/config.json
Windows:
%USERPROFILE%\.config\mcp-docs-ask\config.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 は Git URL です(ref が適用されます)。team-notes はファイルシステムのパスです(ref は使用されません)。
各ドキュメントコレクションとレイヤーに任意の desc を設定すると、エージェントが適切な対象を選びやすくなります。
embedding_model、top_k、chunk_max_chars、max_context_chars は、次の順に解決されます:
docs.<id>.X → default.X → 組み込み値。継承する場合は、ドキュメントごとのキーを省略してください。
埋め込みモデルの推奨
sentence-transformers で読み込み可能な Hugging Face の ID であれば、どれでも使用できます。言語の構成に応じて選択してください。
| ドキュメント/クエリ | 推奨する embedding_model |
|---|---|
| 英語のみ(省略時の組み込み値) | sentence-transformers/all-MiniLM-L6-v2 |
| 中国語のみ | BAAI/bge-small-zh-v1.5 |
| 多言語(約 50 言語) | sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2 |
embedding_model を変更すると、次回の呼び出し時にインデックスが再構築されます。reindex は不要です。
| フィールド | 説明 |
|---|---|
docs.<id>.source | ドキュメントのリポジトリルート:ローカルパスまたは Git URL |
docs.<id>.desc | 検出用の短い説明(list_docs) |
docs.<id>.ref | Git URL ソースのみ対象のブランチ/タグ/SHA(デフォルトは main。ローカルパスでは無視されます) |
docs.<id>.include | リポジトリルートからの相対グロブ(デフォルトは **/*.md) |
docs.<id>.exclude | 除外するグロブ |
docs.<id>.layers.<name>.include | レイヤー用のパスグロブ(最初に一致したものを適用) |
docs.<id>.layers.<name>.desc | 検出用のレイヤーの短い説明 |
docs.<id>.embedding_model | 任意の上書き(上記の推奨を参照) |
docs.<id>.top_k | デフォルトの検索件数の任意の上書き |
docs.<id>.chunk_max_chars | 見出しごとのチャンクに含める本文の最大文字数の任意の上書き |
docs.<id>.max_context_chars | answer_context の文章予算の任意の上書き |
default.docs | デフォルトのドキュメントコレクション ID |
default.embedding_model | デフォルトの sentence-transformers モデル ID |
default.top_k | デフォルトの検索件数 |
default.chunk_max_chars | 見出しごとのチャンクに含める本文の最大文字数 |
default.max_context_chars | answer_context に含める文章の合計文字数(最小 500) |
レイヤーは、パスグロブによってインデックス対象のファイルを分類します。最初に一致したものを適用します。名前では大文字と小文字が区別されません。all は予約語のため、レイヤー名として設定できません。
ask_docs の layer | 意味 |
|---|---|
all(デフォルト) | インデックス内のすべてのチャンク(名前付きレイヤー内のものと、その外部のパス) |
<named> | パスが、その名前付きレイヤーの include グロブに一致したチャンクのみ |
名前付きレイヤーのグロブに一致しないパスもインデックス化されますが、layer=all の場合のみ表示されます。フラットなリポジトリでは layers を省略するか(または "layers": {} を設定して)、layer=all を使用してください。
キャッシュの構成:
- リポジトリ(Git URL):
~/.cache/mcp-docs-ask/repos/<docs-id>/ - インデックス:
~/.cache/mcp-docs-ask/indexes/<docs-id>/
ツール
| ツール | 説明 |
|---|---|
list_docs | 設定済みのドキュメントコレクション、レイヤーフィルター、インデックスの状態を一覧表示します |
ask_docs | 根拠のある文章と引用を取得します(layer:all または名前付きレイヤー) |
reindex | Git ソース(URL の場合)を同期し、ベクトルインデックスを再構築します |
list_docs は、設定の default ブロックと同じキー(docs、embedding_model、top_k、chunk_max_chars、max_context_chars)を含む default ブロックを返します。さらに、各エントリに解決済みの値、default フラグ、index ブロック(コレクションが一度もインデックス化されていない場合は null)を含む docs リストも返します。有効な layer の値は、all と名前付きレイヤーの ID です。上記のレイヤーを参照してください。
Index ブロック
list_docs と reindex は同じ index キーを返します:origin、root、rev、
files、chunks、layers。
origin は設定されたソースを示します。ファイルシステムのパスの場合は file、サーバーが
~/.cache/mcp-docs-ask/repos/<docs-id>/ にクローンし、reindex 時にフェッチする
URL の場合は git です。root はファイルが実際に存在する場所です。ビルド済みの
インデックスがソースディレクトリより長く残っている場合に限り、null になります。rev は
チェックアウトがある場合、その HEAD です。そのため、file ソース自体が git クローンでも
値が返されます。作業ツリーには未コミットの編集が含まれることがあるため、rev が示すのは
チェックアウトであり、インデックス化された正確な内容ではありません。
ask_docs が返すのは、回答に関連する次の 2 つのキーのみです:root と rev。これは、
抜粋の生成元となったチェックアウトと、その抜粋の元になったリビジョンです。
抜粋
ask_docs は最大 top_k 個のチャンクを取得し、それらを抜粋として組み立てます。
- 各抜粋はチャンクの全文で、改行を保持し、見出しの階層(
Guide > Configuration > Layers)が付与されます。 - 1 つの大きすぎるセクションから取得した複数の部分は、ファイル内の順序で結合されます。順位付けされなかった途中の部分は
…で示されます。 - 抜粋は優先度の高いものから
max_context_charsを満たすように追加されます。上限を超える抜粋は改行位置で切り詰められ、末尾に…が付きます。最初の抜粋は必ず保持されます。
そのため、citations のエントリ数は top_k より少なくなる場合があります。
ソースファイル全体を読む
citations[].path はリポジトリ相対パスであり、安定しています。answer_context には抜粋のテキストが一度だけ格納され、citations[].n と一致する [n] マーカーがキーとして使われます。ソースファイル全体を読むには、同じ ask_docs の応答に含まれる index.root と引用パスを結合します:
/home/you/docs-repo + product/features/budget.md
引用を生成した応答から root を取得し、以前の reindex の値は使わないでください。ask_docs は古くなったインデックスを自動的に再構築するため、その rev が手元の抜粋に対応する値です。
MCP ホストの例
以下の例では、初回使用時にパッケージをインストールする uvx を使ってサーバーを起動します。ホストがインストール処理でブロックされないよう、事前にターミナルで一度実行してください:
$ uvx mcp-docs-ask
Installed 84 packages in 275ms
その後、サーバーは標準入出力で起動し、入力を待ちます。インストールの行が表示されたら Ctrl-C を一度押してください。埋め込みモデルの重みは、最初の ask_docs または reindex 呼び出し時に別途取得されます。uvx mcp-docs-ask --version は、uvx が解決したビルドを表示します。
Linux(WSL、コンテナー、CI を含む): Linux 用の PyPI
torchホイールは CUDA ビルドです。マシンに NVIDIA GPU があるかどうかにかかわらず、約 15 個のnvidia-*パッケージ(ホイールで約 2.7 GB、ディスク上で約 4 GB)がダウンロードされます。Windows と macOS では CPU 専用のホイール(約 1 GB)が解決され、CUDA はダウンロードされません。ここでは事前のウォームアップが特に重要です。最初のuvxの実行には数ミリ秒ではなく、数分かかることを想定してください。
Cursor
.cursor/mcp.json に追加します:
{
"mcpServers": {
"docs-ask": {
"command": "uvx",
"args": ["mcp-docs-ask"]
}
}
}
Claude Code
Claude Code の MCP 設定に追加します:
{
"mcpServers": {
"docs-ask": {
"command": "uvx",
"args": ["mcp-docs-ask"]
}
}
}
Codex
[mcp_servers.docs-ask]
command = "uvx"
args = ["mcp-docs-ask"]
OpenCode
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"docs-ask": {
"type": "local",
"enabled": true,
"command": ["uvx", "mcp-docs-ask"]
}
}
}
GitHub Copilot
{
"inputs": [],
"servers": {
"docs-ask": {
"type": "stdio",
"command": "uvx",
"args": ["mcp-docs-ask"]
}
}
}
開発
uv sync
uv run ruff check src/ tests/
uv run ruff format --check src/ tests/
uv run pyright
uv run pytest
注意事項
- ローカルパス: ファイルの更新日時やサイズが変わると(フィンガープリントの確認により)、
ask_docsがインデックスを自動的に再構築します。ローカルのドキュメントを編集した後にreindexを実行する必要はありません。 - Git URL:
ask_docsはフェッチを行いません。設定されたrefをgit fetchして再構築するには、reindexを呼び出してください。 - フィンガープリントには
embedding_model、chunk_max_chars、レイヤーの glob、ディスク上のインデックス形式も含まれます。そのため、これらのいずれかを変更すると、次回の呼び出し時に再構築されます。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。