Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

mcp-docs-template

手元の md を Claude から関連度順に検索できるようにする MCP サーバのテンプレート。

docs/ に md を置くだけで、## 見出しごとに BM25 で索引化される。追加依存は mcp パッケージのみ、 索引は起動時にメモリ上に作るので DB もビルド手順も要らない。

devcontainer 込みなので、clone して開けば Claude Code と Codex がそのまま使える (claude-devcontainer-template と同じ構成)。

先に読むこと: 本当に MCP が要るか

完全一致で足りるなら Grep のほうが速い。 このサーバが効くのは次の2つが要るときだけ:

  • 語を分けても拾える — 「節 検索」で検索すると、同梱の docs/example.md の 「検索のしかた」節が返る。rg "節 検索" のほうは 0 件(連続していないと当たらない)
  • 関連度順の上位N件 — grep のヒット順はファイル順なので、100件当たったら100件読むことになる

さらに、Claude Code だけで使うなら Skill でも同じことができる。BM25 の実装(scripts/)は どちらの形でもそのまま使えるので、MCP を選ぶ理由は次のどちらかに絞られる:

MCP にする Skill で足りる
使う側 Claude Desktop や他エディタからも使う Claude Code だけ
コンテキスト ツール定義が常時載る description 1行だけ

使い方

1. テンプレートから作る

GitHub の "Use this template"、またはローカルで:

git clone <this-repo> my-docs && cd my-docs && rm -rf .git && git init

2. md を置く

docs/ に置く。ファイル名が文書 id、本文の # 行がタイトルになる。 docs/example.md が形式の見本なので、確認したら消す。

元資料が Word / PowerPoint / Excel / PDF / Web ページなら、同梱の import-docs スキルに変換させる:

/import-docs  この資料を取り込んで

検索の単位は ##なので、変換の主目的は意味のまとまりごとに見出しを付けることになる。 単にテキストを抜いただけでは索引が効かない。スキルはそこまで面倒を見る。

出典を残すなら先頭にフロントマターを書く。索引には入らない:

---
source: https://example.com/some-document
captured: 2026-01-01
---

節が検索の単位なので、見出しを細かく切るほど結果が絞り込まれる。見出しの無い長文は 1節として丸ごと返るため、長い資料は ## を入れてから置く。

3. コンテナを開く

VS Code で Dev Containers: Reopen in Containerpip install -r requirements.txtpostCreateCommand が済ませる。

.mcp.json はプロジェクトスコープの設定なので、Claude Code が自動で読む。初回は ワークスペースの信頼を尋ねられるので承認する。接続できているかは claude mcp list で分かる。

パスはリポジトリルートからの相対にしてある。絶対パスに書き換えるとディレクトリ名を変えたときに 壊れる。${workspaceFolder}(VS Code の変数)や ${CLAUDE_PROJECT_DIR}.mcp.json では 展開されず、未定義の環境変数として警告になるので使わない。

4. 使う

list_documents()                     索引している文書を出典つきで一覧
get_document(document, section)      指定文書の全文、または節だけ
search_docs(query, limit)            節単位で横断検索(関連度順)
reload_index()                       docs/ を読み直して索引を作り直す

資料を取り込む流れ

例として Word 文書を取り込む場合:

1. source/報告書.docx に置く
2. Claude に「source/報告書.docx を取り込んで」と頼む
     → import-docs スキルが起動し、pandoc で変換して ## 見出しを整え、
       出典つきで docs/report.md を書く
3. Claude が reload_index() を呼ぶ
4. search_docs("...") で引けるようになる

3 を飛ばすと引けない。 索引は起動時にメモリ上に作るので、md を足しただけでは反映されない。 stdio の MCP サーバは Claude Code から再起動されないため、セッションを続けたまま反映するには reload_index() を呼ぶ(スキルの手順にも入っている)。

リポジトリ外の md も索引する

個人メモなど、コミットしたくない md を足したいとき:

// .mcp.json
"env": { "MCP_EXTRA_DOCS_DIRS": "/path/to/notes:/path/to/more" }

os.pathsep(Linux では :)区切りで複数指定できる。docs/ と同じ形式で索引される。 中身は検索時に LLM へ渡る点に注意。

ツールを足す

scripts/mcp_server.py@mcp.tool() を付けた関数を書くだけ。 型注釈と docstring がそのまま Claude 側のツール定義になるので、引数の説明は docstring の Args: に書く。

@mcp.tool()
def count_sections(document: str) -> str:
    """指定した文書の節数を返す。

    Args:
        document: 文書id か タイトル(部分可)
    """
    ...

構成

docs/      変換後の md。コミットする(索引対象)
source/    変換元の .docx / .pptx / .xlsx / .pdf。gitignore 済みでコミットしない
scripts/   MCP サーバ本体

変換元をコミットしないのは、機密や著作物を公開リポジトリに入れる事故を防ぐため。 出所は変換後の md のフロントマターに残るので、URL のあるものは取り直せる。

ファイル 中身
scripts/mcp_server.py MCP サーバ本体、BM25、md のパース
scripts/common.py パス解決、表記の正規化、bigram トークナイザ
.mcp.json プロジェクトスコープの MCP サーバ登録
.claude/skills/import-docs/ 元資料を md に変換するスキル

変換に使うもの(MCP の実行には不要。使うときだけ入れる):

形式 手段
Word (.docx) pandoc -t gfm
PowerPoint (.pptx) 同梱の pptx_to_md.py(pandoc は pptx を読めない)
Excel (.xlsx) 同梱の xlsx_to_md.py(同上)
PDF Read ツールでページを読んで書き起こす(抽出ツールより表の再現が効く)
Web WebFetch

検索の限界

形態素解析を使わない。英数字は単語、かな漢字は文字bigramに分割して BM25 にかけるだけなので、 辞書も追加依存も要らないかわりに次が効かない:

  • 同義語や言い換え — 「価格」で「値段」は出ない
  • 英数字・かな・漢字以外の文字。ハングルやキリル文字はトークンが空になり、 エラーも出さずに検索結果から消える。使うなら common.py_CJK / _WORD を広げる

長い文書は get_document が全文を返さず節の一覧を返す(既定 8,000 文字超)。 資料1本でコンテキストを使い切らないための制限で、閾値は mcp_server.py_MAX_FULL

About

MCP server template for searching your own documents by relevance — BM25 over Markdown sections, with a skill to import Word/PowerPoint/Excel/PDF

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages