Semantic search over a Markdown knowledge base, served over MCP.
GrooveSeek が接続クライアントに公開する MCP の面。
English version: mcp-tools.md
| ツール | 説明 | 主なパラメータ |
|---|---|---|
search |
ベクトル + FTS5 全文検索を Reciprocal Rank Fusion でマージしたハイブリッド検索、任意で cross-encoder 再ランク + MMR 多様性再ランク + parent retriever 展開。{ results, low_confidence, filter_applied } ラッパで関連度ランク付き chunk を返す。parent retriever が発火した行には expanded_from も付く。chunk がソースファイル由来なら (v1.2.0+) start_line / end_line (1 始まり、定義ではなく chunk の範囲) と symbol_kind (grammar が呼ぶ定義の種別) も付く。この 3 つは、それ以外では null ではなくキーごと現れない。詳細: docs/citations.ja.md、docs/filters.ja.md、docs/retrieval-pipeline.ja.md |
query (必須。空白区切りの group の先頭に - を付けると (例: -async)、検索するのではなく両脚から除外する — v1.1.0+、詳細は retrieval-pipeline.ja.md — 同じ 3 文字の trigram 下限が効くので -ab は何も除外しない)、limit、category、topic、rerank (サーバ既定を上書き)、min_quality、include_low_quality、path_globs (! 始まりは exclude)、tags_any / tags_all、date_from / date_to (YYYY-MM-DD)、min_confidence_ratio、mmr / mmr_lambda / mmr_same_doc_penalty (v0.7.0+)、parent_retriever (v0.7.0+) |
list_topics |
index 済みの全トピック / カテゴリと文書数を列挙。(v1.1.0+) 各 entry に children が付く: そのカテゴリ / トピック配下の directory tree で、topic より下の path segment 1 つが 1 node。node は segment / file_count (その prefix 配下の文書数。親は配下すべてを数える) / 自身の children を持つ。root と category のみの entry、および文書が topic 直下にしか無い topic では []。tree は保存された path から作るので、frontmatter の topic: で path 由来の topic を上書きした文書も、2 番目の path segment より後の directory をその group に寄与させる。この segment はその文書自身の path から取ったものなので、<category>/<topic>/ の下に directory として実在するとは限らない — client はこれを繋げて path prefix を組み立ててはいけない。MCP の面の安定性 を参照 |
(なし) |
get_document |
相対パスから文書の全文 + メタデータを取得 | path (例: "deep-dive/mcp/overview.md") |
get_best_practice |
opt-in: groove.toml の [best_practice].path_templates を設定しているときのみ機能する。対象向けの best practice 文書を取得し、任意で特定 h2 セクションを抽出。未設定時は “not configured” エラーを返す |
target (例: "claude-code")、category (任意) |
rebuild_index |
すべてのソースファイル (Markdown + [parsers].enabled で有効化された拡張子) を走査してインデックス再構築。同時に 1 本だけ (v1.0.0+): 実行中に来た呼び出しは「実行中のものが何秒前に始まったか」を添えたエラーで断る。再構築は embedder と DB を握り続けるので、終わるまで検索が使えないため。制限がかかるのはこのツールで、groove index は別プロセスなので対象外 |
force (任意、既定 false) |
get_connection_graph |
ドキュメントパスを起点に意味的に関連するチャンクを BFS 展開。parent_id / depth / score / snippet 付きのノード配列を返し、呼び出し側でコンテキスト発見を連鎖させられる。上限で探索が切られた場合は truncated / truncation[] が付く |
start (必須、探索の起点パス — groove graph --start)、depth (既定 2、最大 3)、fan_out (既定 5、最大 20)、min_similarity (既定 0.3)、seed_strategy (all_chunks / centroid。all-chunks も受け付ける)、dedup_by_path、category、topic、exclude_paths、max_nodes (既定 100、最大 2000)、max_seed_chunks (既定 32、最大 1000) |
(v0.22.0+) 4 つの prompt を同梱している。クライアントはこれをユーザが選ぶコマンドとして出す (Claude Code では /mcp__<server>__<name>。<server> は .mcp.json でこのサーバに付けた鍵であって、GrooveSeek が決める名前ではない)。存在理由は「ツールだけでは組み合わせ方が分からない」こと — search は「次に get_connection_graph を呼べ」とも「low_confidence が立ったらそう言え」とも言わない。
| Prompt | 引数 | 何を指示するか |
|---|---|---|
summarize_topic |
topic (必須) |
list_topics でトピックの存在を確認 → search で集める → 重要な文書は get_document で全文を読む → 要約する。カバーされていないことも書かせる |
deep_dive |
question (必須) |
最初の検索だけで答えない。上位ヒットを get_connection_graph の depth 2 で広げ、全文を読み、そこで得た語彙で再検索する |
whats_new |
since (任意、YYYY-MM-DD。省略時は 30 日前) |
その日付以降の文書を概観する。date_from が絞るのは frontmatter の date = 著者が書いた値であって、ファイルの更新時刻ではないことを prompt 自身に明記させ、近似であると断らせる。加えて date_from は文字列として比較されるので、YYYY-MM-DD 以外を渡すとエラーにならず全文書が落ちることも警告する |
find_gaps |
topic (任意) |
欠落を探す。low_confidence が立つ問い、include_low_quality: true でしか出てこない stub。欠けているものを報告させ、内容の提案はさせない |
4 つとも text のみで、引用規則を共有する: 使った文書の path を必ず引用する / low_confidence を握り潰さず表に出す / ナレッジベースが沈黙している時は一般知識で埋めずにそう言う。
設定ファイルではなくコンパイル時固定にしてある。 prompt 本文はモデルに渡るテキストで、groove.toml は cwd や .git 祖先から発見されるため、設定で定義できるようにすると untrusted config に対して kb_path と同じ制限が必要になる。MCP 仕様も助けにならない — tool annotation と違い、クライアントに「prompt の内容を信用するな」と言う指針が無い。
(v0.22.0+) ナレッジベースを kb:// スキームの MCP resource としても公開する。Claude Code では @ メニューに出る。
| URI | 中身 |
|---|---|
kb://topic/<prefix> |
topic group = パスの先頭 1〜2 セグメント。indexer が category / topic を導出するのと同じ規則。read するとその配下の文書一覧 (URI 付き) が Markdown で返る。kb://topic/ は root group |
kb://doc/<path> |
索引済みの文書 1 件。列挙はせずテンプレートとして公開する |
resources/list が返すのは topic group であって、文書 1 件ごとではない。ナレッジベースの文書は数百でもグループは数十であり、listing は接続のたびにクライアントが取りに来るもの。個々の文書はテンプレートと、search hit に付くようになった uri から辿れる — spec は「listing に出ていない文書へのリンクを tool が返すこと」を明示的に許している。listing もこの uri も同一の述語から来るので、同じ文書について両者が食い違うことはない。索引に残り検索でも見つかるまま、提示だけ外れる要因が 2 つある。1 つは現在の parser registry: [parsers].enabled を狭めて再 index しないと、外した拡張子の行は索引にも検索結果にも残るが、read が拒否する以上提示しない。もう 1 つは size (v0.23.0+): 1 MiB を超える Markdown / テキスト文書は resources/read が返す量を超えるので、これも提示しない (search hit は残り、uri だけが付かない)。同じサイズでも PDF や表計算は提示され続ける — read が拒否ではなく抽出テキストを切り詰めるため。size は index 時に記録される。以前のバージョンで索引した文書は size 未記録で、次の groove index まで提示されたままになる (その 1 回で再 embed 無しに埋まる)。件数は groove doctor が報告する。根拠は ADR-0005。
区切りは forward slash のまま、それ以外は percent-encode するので、空白や非 ASCII を含むパスでも正しい ASCII URI になる。
read は索引で縛られる。 提供されるのは索引に入っている文書のみで、そのうえで get_document と同一の検査 (symlink / hardlink 拒否、path traversal、拡張子 membership、size cap、handle 束縛の read) を通す。これは get_document (= kb_path 配下で拡張子が registry にあれば返す) より狭い。resource は「サーバが提示したもの」なので、提示していない URI を提供するのは別の操作だから。したがって .grooveignore された文書は resource には出ないが get_document からは従来どおり読める — これは ADR-0003 の契約が不変であることの帰結。判断の正本は ADR-0004。
内容はテキストとして返り、media type は提供物の型にする: Markdown は text/markdown、抽出テキストとして出すものは text/plain。PDF や表計算は groove が抽出したテキストとして返り、元のバイト列ではない。
未実装: resources/subscribe と notifications/resources/list_changed。これらが無くても "resources": {} は準拠した宣言であり、固定の topic group は滅多に変わらない。
docs/citations.ja.md — match_spans とバイトオフセットdocs/filters.ja.md — 検索結果の絞り込みdocs/clients.ja.md — そもそもクライアントを繋ぐ手順