docs-rag-mcp
docs-rag-mcp
これは、あなたのドキュメントに対するより良い検索エンジンではありません。エージェントが信じることを許可される内容へのフィルターです: 廃止された決定は消え、しきい値は捏造する代わりに*「わかりません」*と言い、結果がなぜ入ったのかを常に確認できます。
Markdownドキュメントのフォルダを、任意のMCPクライアント(Claude Code、Claude Desktop、Codex、Cursor、Zed…)に対して1つの検索ツールsearch_notesとして公開するMCPサーバーです。すべてはあなたのマシン上で動作します。埋め込みはOllama経由で行われ、インデックス作成時もクエリ時も、あなたのコンピュータから何も出て行きません。
npx -y docs-rag-mcp init # guided questions -> config.json
npx -y docs-rag-mcp index # builds the index検索するドキュメントを書いていますか? Markdownファイルの構造が、どれだけ見つかりやすいかを決定します。 AUTHORING.md を参照してください。うまく取得できるドキュメントを書くための短いガイドです。 そこに5分費やすだけで、すべての検索が改善されます。
実際に何が違うのか
このツールが行うことのほとんどは、他のローカルRAGサーバーも行います。本当に珍しいのはドキュメントライフサイクルです。インデックスはドキュメントが置き換えられたことを認識し、それに基づいて動作します。
frontmatterに
status: supersededと記されたドキュメントは、デフォルトでは返却されなくなります。 明示的に履歴を要求したために戻ってくる場合は、[superseded → reference/auth.md; 2026-03-01]というラベル付きで返り、 後継ドキュメントも一緒に付いてきます。minScoreを下回ると、ツールは見つかった最も近いノイズを手渡す代わりに**「関連する結果がありません(最良スコア 0.41、しきい値 0.55)」**と言います。 悪い一致を渡されたエージェントはそれを真実として扱いますが、人間ならためらったはずです。しきい値は、そのためらいが生きる場所です。すべてのヒットには、それがなぜそこにあるのかが表示されます。
[semantic 0.712]、[both 0.712]、[exact match]というように。信じるしかないブラックボックスではありません。
他の誰もがファイルの鮮度——再同期、再インデックス、変更の監視——を行います。真実の鮮度を扱うものは誰もいません。それがこのツールの存在意義です。
アプローチ | ドキュメントライフサイクルを扱う? | |
docs-rag-mcp | dense + 語彙, SQLite, Ollama | はい — |
| hybrid BM25+dense, ASTチャンキング, Milvus | いいえ |
| semantic+keyword, LanceDB, PDF/DOCX/MD | いいえ |
| markdown, 見出しチャンキング, Milvus | いいえ |
| sqlite-vec + Olla ma, graph-aware | いいえ |
| pgvector | いいえ |
それ以外の部分——ローカルのみ、見出しによるチャンキング、SQLite保存、インクレメンタル・インデックス——は、この分野では参加条件であり、差別化要因ではありません。それは以下の機能テーブルにはありますが、売り文句にはありません。
Related MCP server: Notes RAG MCP Server
これが不要なとき
正直なところ、この分野は進化しました:
シンボルの完全一致には、エージェントはすでにgrepを持っています。しかもgrepは高速で、インデックスも不要です。関数名、エラーコーど、設定キー:そのた めにベクトルインデックスを構築する必要はありません。
ドキュメントが数十未満なら、エージェント検索で十分です。 エージェントがファイルツリーを読み、grepし、関連しそうなものを開きます。それで機能します。
Anthropic は Claude Code 内にベクトルDBを備えたRAGを出荷し、その後それを削除しました(2025年5月)。エージェント検索がそれより優れていたからです。Curso r、Windsurf、Clineなども同じ道をたどりました。そうでないふりをするのは不誠実です。
それを生き残るのが、これが存在する理由です:grep は、あなたが名指すものを見つけます。 ドキュメントがそれを「トークン更新ウィンドウ」と呼び、あなたが「セッション失効」と呼んでも、grep は何も返さず、セマンティック検索がそのドキュメントを返します。そして、長くて層状のコーパスでは、セマンティック取得は、エージェントがツリーを歩くよりも少ないラウンドトリップと少ないトークンで済みます。**「より良い結果」**ではなく、より安い結果です。
したがって、適合する範囲は狭く、特定的です:廃止された資料を含む、markdown で書かれた長く層状の決定・仕様・ADR のコーパスであり、エージェントに死んだ決定を復活させたくない場合です。
前提条件
Node.js ≥ 22.5 — インデックスは内蔵の
node:sqliteモジュールを使用するため、ビルドが必要なネイティブ依存関係はありません。Nodeのバージョンによっては、stderrに1行の警告(ExperimentalWarning: SQLite is an experimental feature)が表示されることがありますが、無害です。埋め込みモデルを備えたOllama。 モデルはインデックス構築とすべての検索の両方に必要です。クエリはその場で埋め込まれるため、Ollama はインデックス作成時だけでなく、MCPサーバーが使用されている間は常に実行されている必要があります。
# install Ollama from https://ollama.com, then:
ollama pull bge-m3インストール
公開されているパッケージは、クローンもビルドも不要です:
npx -y docs-rag-mcp init # guided questions -> writes config.json
npx -y docs-rag-mcp index # builds the index自動再インデックスフックを使用する場合は、代わりにグローバルにインストールしてく ださい:
npm i -g docs-rag-mcpnpx はスポーンされるたびにパッケージを再解決し、最初の使用時にダウンロードします。MCPサーバーはセッションごとに一度起動するだけなのでそれは関係ありませんが、フックはゼロ秒で終了するように設計されており、すべてのファイル編集後に実行されます。グローバルインストールはそのオーバーヘッドを完全に取り除きます。docs-rag scaffold はグローバルインストールを検出し、短いコマンド形式を自動的に書き込みます。
設定ファイルを手で編集したい場合? config.example.json を config.json にコピーして vaultPath を設定してください。他のすべてには適切なデフォルトがあります。
git clone https://github.com/andreaselmi/docs-rag-mcp
cd docs-rag-mcp
yarn install
yarn setup # -> config.json
yarn index
yarn build # compiles to dist/yarn スクリプトは、サブコマンドと一対一で対応しています(setup→init、serve、index、search、scaffold)。ソースチェックアウトからプロジェクトをスキャフォルドする場合は、--local を渡してください。生成されるファイルには、公開パッケージではなく作業ツリーを解決する npx コマンドの代わりに、node /abs/path/dist/server.js が書き込まれます。
コマンド
docs-rag init interactive wizard, writes config.json
docs-rag scaffold <dir> give a project its own scoped instance
docs-rag index build or update the index
docs-rag search "question" query the index from the terminal
docs-rag serve run the MCP server on stdio
docs-rag hook Claude Code hook entry point (auto re-index)すべてのコマンドは --config <path> を受け付けます。
端末から取得をテストする
docs-rag search "how do we handle authentication"一致したセクションが、それぞれ返された理由とともに表示されます:
[semantic 0.712] reference/auth.md › Auth > How the client refreshes the token
[both 0.688] decisions/2026-01-session-length.md › Session length [2026-01-14]
[exact match] reference/errors.md › Error codes > ERR_TOKEN_EXPIREDこれはMCPクライアントが使用する取得とまったく同じものです。まずここで確認してください。
単一のクエリでフォルダをスキップするには、--exclude を渡します(カンマ区切りのパス断片、大文字小文字を区別しません):
docs-rag search "how do we handle auth" --exclude archive,draftsMCPツールは同じものを search_notes のオプショナルな exclude 配列として公開しているため、会話の中で*「検索して、ただしアーカイブフォルダは無視して」*と頼むことができます。
一部のフォルダ(デフォルトでは archive、plans — defaultExclude を参照)は、--exclude を渡したときだけでなく、すべてのクエリでスキップされます。それでも1つのクエリで検索したい場合は、--all(CLI)または searchAll: true(ツールパラメータ)を渡します。同じフラグは、frontmatter で superseded/archived とマークされたドキュメントも再含めます。これらもデフォルトの検索では非表示になります。
2つの取得トラックとラベル
Dense 埋め込みは、仕様書に溢れているもの——頭字語、エラーコーど、関数名、バージョン番号——が苦手です。そこ で、各クエリは2つのトラックを実行し、それらを統合します。
セマンティックトラックは、各チャンクをコサイン類似度で順位付けし、しきい値を適用します。
語彙トラックは、クエリの稀な用語に限定した全文(FTS5)検索です。「稀」はあなた自身のインデックスを基準に測定されます。ある用語が対象となるのは、それが最大
max(5, lexicalMaxDocFreq × total chunks)個のチャンクに現れ、かつその半数以下にしか現れない場面です。すべての単語に対してFTSを実行すると、一般的な用語の一致で結果が溢れてしまいます。稀さのゲートが精度を保っているのです。
各ヒットのラベルは、どのトラックがそこに置いたかを示します:
label | meaning |
| 意味によって発見、コサインスコア |
| 両方のトラックで発見 — 最も強いシグナル |
| 語彙のみ。意図的にスコアを表示しない:コサイン値はこのヒットがここにある理由ではないため、表示するとそうでないかのように誤解される |
語彙のみのヒットには上限(2スロット)があり、常にセマンティックの後ろに来ます。そのため、稀な用語での一致は回答に付け加えることはできても、回答を支配することはありません。
埋め込みモデル
Ollamaで利用可能な任意の埋め込みモデルが動作します。設定で embedModel を設定してください。bge-m3 がデフォルトで、しきい値はそれに合わせて調整されて出荷されています。
embedModel を変更すると、今度は完全な再ビルドが強制されます。 インデックスはどのモデルが構築したかを記録しており、異なるモデルで開くことは、互換性のないベクトルに対して黙ってスコアリングされるのではなく、拒否されます。以前のバージョンはそれらを静かに混ぜ合わせ、エラーもなしに誤った結果を返していたでしょう。
一部のモデルは入力にタスクプレフィックスを必要とします(nomic-embed-text は search_query: / search_document: を必要とします)。これらは小さなレジストリに登録されており、自動的に適用されます。レジストリが知らないモデルを選んだ場面、docs-rag index がその旨を伝えます。検索は引き続き機能しますが、プレフィックスの規約やしきい値は誰も検証していません。
キャリブレーションレポート
インデックス実行のたびに、最後に次のような行が表示されます:
Calibration: background noise p99 = 0.421 over 500 random pairs -> suggested minScore 0.45 (in use: 0.55, from the model registry).これは、自分のコーパスからランダムなチャンクのペアをサンプリングします。これらは定義上無関係であり、それでも到達する類似度スコアを報告します。それがモデルのノイズフロアです。これを下回るスコアは、互いに何の関係もない2つのドキュメントと区別がつきません。
これはコピーする設定ではなく、下限として使ってください。提案された値が設定した minScore をはるかに上回る場面、しきい値はノイズを許容しています。はるかに下回る場面は、より厳しくしてもかまいません。設定した値が常に優先されます。レポートはあなたの選択を上書きすることはなく、測定した内容を知らせるだけです。
プロジェクトごとに1つのインスタンス(推奨)
通常、プロジェクトごとに独立したナレッジベースが必要です。プロジェクトごとにこのツールのコピーは必要ありません。一度インストールして、各プロジェクトに独自の設定を与え、プロジェクトスコープで登録してください:
docs-rag scaffold /path/to/some-project # asks a few questions (or pass flags)そのプロジェクトに対して、次のものを書き込みます:
some-project/.rag/config.json— その設定です(vaultPathはプロジェクトルートで、インデックスはその隣の.rag/index.dbに置かれます)。すでにscaffoldされたプロジェクトでscaffoldを再実行すると、このファイルは保持されます:調整済みのpathBoostsとしきい値は残り、その実行でフラグとして明示的に渡したキーだけが上書きされます。some-project/.mcp.json— プロジェクトスコープのMCP登録です。既存のサーーは保持されます。コマンドがマシン固有のパスを含まないため、このファイルはコミット可能です:リポジトリをクローンした人は、何も手動でインストールしなくても、そのドキュメントに対する検索を利用できます。プロジェクトの
.gitignoreに.rag/index.db*とレガシーの.rag/index.json*を追記します。--hookを付けると:some-project/.claude/settings.local.json— すべてのmarkdown編集後にバックグラウンドで再インデックスするClaude Codeフック(下記参照)。
次に:
docs-rag index --config /path/to/some-project/.rag/config.json非対話的で、多くのリポジトリにまたがってスクリプト化可能:
docs-rag scaffold /path/to/proj --name proj-docs --include "**/docs/**/*.md" \
--desc "What's in this project's docs" --hook --yes--config の解決方法
すべてのコマンドは --config を受け付けます。設定ファイルは自身のインデックスを「保持」します(相対的な indexPath は設定ファイルの隣に解決されます)。そのため、インスタンスが干渉することはありません。解決順序:
絶対パスが常に優先されます。
CLAUDE_PROJECT_DIR— Claude Code が起動するサーバーとフックの環境でプロジェクトルートに設定される変数。作業ディレクトリから上位へ、パスが存在する最初の祖先ディレクトリまで遡ります。これにより、独自の環境変数を設定しないクライアントでも
--config .rag/config.jsonが機能します。それ以外の場合は作業ディレクトリ。
--config をまったく指定しない場合も、同じディレクトリ遡行で .rag/config.json が探されるため、scaffold されたプロジェクト内のどこで docs-rag search "…" を実行してもそのまま動作します。
.mcp.json の args に ${CLAUDE_PROJECT_DIR} を自分で書いてはいけません。Claude Code はそこでは変数を展開しないため、文字通りそのまま渡されてしまいます。
MCP クライアントへの組み込み
Claude Code
プロジェクトスコープは docs-rag scaffold が設定するものです。代わりに すべての セッションで使いたいナレッジベースの場合は、ユーザースコープで登録します:
claude mcp add work-docs -s user -- npx -y docs-rag-mcp serve --config ~/vaults/work.jsonclaude mcp list で接続を確認し、"search_notes: なぜ X を選んだのか?" のような質問をしてみてください。
Codex CLI、Cursor、Zed、その他の MCP クライアント
このサーバーはプレーンな stdio MCP なので、プロトコルを話せるクライアントならどれでも実行できます。Codex CLI の ~/.codex/config.toml では:
[mcp_servers.docs-search]
command = "npx"
args = ["-y", "docs-rag-mcp", "serve", "--config", "/absolute/path/to/.rag/config.json"]Cursor と Zed も、それぞれの MCP 設定で同じコマンドと args を使用します。
ここでは 絶対パスの --config を使うべきです。何にも依存しないからです。相対パスでも上記のディレクトリ遡行によって機能しますが、そのパスは構造上とユニットテストで検証されており、それらのクライアントに対してはテストされていません。いずれかのクライアントで実行した場合は、レポートを歓迎します。
各インスタンスに独自の serverName と toolDescription を設定してください。説明文は、モデルがそもそもツールを呼び出すかどうかを判断するために読むものなので、ツールが何をするかではなく、このナレッジベースに何が含まれているか を説明してください。
インデックスを最新に保つ
インデックスはビルド成果物です。index.db は WAL モードの SQ Lite データベースで、- wal と - shm のサイドカーを伴います。ドキュメントを編集したら docs-rag index を再実行してください — 増分更新なので、mtime が変更されたファイルだけを再エンベベッドします。実行中の MCP サーバーは再インデックスをすべて自動的に反映するため、再起動は不要です。古いインデックスは古い内容で答えます — ヒットなしより悪い結果です。
自動再インデックス (Claude Code のみ、オプトイン)
--hook を指定して scaffold すると、Claude Code の PostToolUse フック が、Claude がそのプロジェクト内のマークダウンファイルを書き込むか編集するたびに、増分インデクサーをバックグラウンドで再実行します。30 秒ごとに最大 1 回の実行にまとめられ、編集が取り残されることはありません。Claude Code 以外で行った編集は、手動での実行が必要です。
フックはプロジェクトの .claude/settings.local.json (個人用であり、コミットされません) に置かれます。無効にするには PostToolUse エントリを削除してください。バックグラウンド実行が機能しない場合 — ほとんどの場合は Ollama が実行されていないため — セッション内でエピソードごとに 1 回警告されるだけで、保存のたびに警告されることはありません。詳細は .rag/hook.log に記録されます。他の MCP クライアントは Claude Code のフックを実行しないため、そこでは手動で再インデックスしてください。
既存インデックスのアップグレード
アップグレード後の最初の docs-rag index は、通常の 1 秒未満の no-op ではなく、一度きりの完全な再エンベッド です。スキーマにモデル識別テーブルと FTS5 テーブルが追加され、古いベクトルは引き継げないためです。フックを有効にしている場合、最初の編集時にバックグラウンドで開始されるため、最初の実行は 1 秒ではなく数分かかると想定してください。
元の index.json からのアップグレード: index.json.bak にリネームされ、ゼロから再構築されます。結果に満足したら .bak を削除してください。
設定リファレンス
フィールド | デフォルト | 備考 |
| — (必須) | インデックス対象フォルダ。絶対パス、または設定ファイルからの相対パス |
`includeGl |
This server cannot be deployed
Maintenance
Related MCP Connectors
Serve a folder of Markdown notes as an MCP server: hybrid search, reading, and sourced answers.
Search, read, and write your Apple Notes from ChatGPT/Claude via a local Mac agent + MCP relay.
Search and reason over your Obsidian-style Markdown vault, right from ChatGPT.
- TaprootOAuthcom.taproothq
Persistent memory layer for AI tools. Save and recall notes across Claude and other MCP clients.
Related MCP Servers
- AlicenseNot gradedqualityBmaintenanceEnables Claude Code to search and retrieve from a local knowledge base of markdown notes using hybrid semantic+keyword search, keeping data entirely offline.6 npmMIT
- FlicenseNot gradedqualityAmaintenanceEnables semantic search over personal markdown notes by indexing them into a vector database and exposing search, reindex, and status tools via MCP.-
- AlicenseNot gradedqualityCmaintenanceProvides a search_docs tool for MCP clients to perform local semantic search over indexed files using embeddings, enabling grounded answers from personal notes.MIT
- AlicenseNot gradedqualityAmaintenanceProvides hybrid search (BM25 + vector) and staleness reporting for local markdown notes, exposing search and indexing tools to AI assistants via MCP.14 npmMIT