MCPのCompletion仕様 — 引数オートコンプリートAPIの仕組み
MCPのCompletion仕様はprompts/get・resources/readの引数をIDEのように補完させる機能。プロトコルの中身と、Claude Codeでの引数入力が実際にはどう扱われているかを整理する。
MCPのCompletionとは何か
MCPのCompletionは、Promptsの引数やResource Templateの変数を埋めるときに、サーバーが候補を返す仕組みです。仕様は「IDEのコード補完に似た体験を支える」と説明しています。ユーザーが引数を入力している途中で、ドロップダウンやポップアップに候補を出し、絞り込みながら選ばせる用途を想定しています。
呼び出し先は2種類あります。ref/promptはPromptの名前を指定し、その引数を補完します。ref/resourceはリソースのURIまたはURIテンプレートを指定し、URIの変数部分を補完します。プロトコル自体はどちらのUIパターンで見せるかを規定しません。ドロップダウンにするか、インラインの薄い候補表示にするかはクライアント実装の裁量です。
| 呼び出し先 | 指定するもの | 補完対象 |
|---|---|---|
ref/prompt | 指定するものPromptの名前(name) | 補完対象Promptの引数値 |
ref/resource | 指定するものリソースのURIまたはURIテンプレート(uri) | 補完対象URI中の変数部分 |
どちらも応答の形式は共通で、values / total / hasMoreの3フィールドを返します。対象がPromptの引数かリソースのURIかが違うだけで、クライアント側の処理は同じロジックで書けます。
completion/completeのやり取り
サーバーがcompletions能力を宣言していれば、クライアントはcompletion/completeリクエストで候補を取りに行けます。
{
"jsonrpc": "2.0",
"id": 1,
"method": "completion/complete",
"params": {
"ref": { "type": "ref/prompt", "name": "code_review" },
"argument": { "name": "language", "value": "py" }
}
}{
"jsonrpc": "2.0",
"id": 1,
"result": {
"resultType": "complete",
"completion": {
"values": ["python", "pytorch", "pyside"],
"total": 10,
"hasMore": true
}
}
}argument.valueに入力途中の文字列(この例ではpy)を渡すと、サーバーは前方一致や関連度でランキングした候補をvaluesに返します。totalは一致件数の総数、hasMoreはvaluesに含まれなかった残りがあるかを示します。候補は最大100件までという上限が仕様で決まっています。
応答に含まれる3つのフィールドが持つ意味
completionオブジェクトのvaluesは候補の配列で、サーバー側が関連度順に並べた状態で返す前提です。クライアントはこれをそのままの順序でリストに出せます。totalは一致件数の総数で、valuesに入りきらなかった候補も含めた数を示します。hasMoreはvaluesに含まれなかった残りの候補があるかどうかの真偽値です。
この3つを組み合わせると、クライアントは「今表示している候補が全体のうち何件で、まだ他にもあるか」をユーザーに伝えられます。例えばtotal: 10でvaluesが3件だけなら、「他に7件」という表示ができます。hasMoreだけを見て件数を出さない実装も許容されますが、totalが返ってくるサーバーであれば活用しない手はありません。
このうち仕様が明示的に任意としているのはtotalです。サーバーがtotalを省略してvaluesとhasMoreだけを返してくる実装もあり得るため、クライアント側はtotalが無い前提でも表示が破綻しないUIを設計しておく必要があります。「件数不明のままhasMoreだけで続きの有無を示す」というフォールバックを用意しておくのが安全です。
複数引数をまたぐ補完 — contextの役割
1つのPromptに複数の引数があるとき、後の引数の候補は前の引数の値に依存することがあります。例えば言語にpythonを選んだあとで、フレームワークの候補はflask / fastapi / djangoに絞りたい、といったケースです。この依存関係を表すのがcontext.argumentsです。
{
"jsonrpc": "2.0",
"id": 1,
"method": "completion/complete",
"params": {
"ref": { "type": "ref/prompt", "name": "code_review" },
"argument": { "name": "framework", "value": "fla" },
"context": { "arguments": { "language": "python" } }
}
}このリクエストでは、language: pythonという既に確定した引数をcontext.argumentsに含めたうえで、frameworkの入力途中の値flaを補完しています。応答はflask1件に絞られます(values: ["flask"])。クライアント実装者にとっての実装イメージは単純です。引数を1つ確定するたびに、それまでの確定値を全部context.argumentsに積み上げて次の補完リクエストを投げる、という蓄積モデルになります。
エラー処理で切り分けるべき4つのケース
completion/completeの標準エラーは4種類あります。原文のまま覚えるより、どこで切り分けるかを表で押さえたほうが実装で迷いません。
| エラーコード | 発生条件 | クライアント側の切り分け |
|---|---|---|
-32601(Method not found) | 発生条件サーバーがcompletions能力自体を未対応 | クライアント側の切り分け以降そのサーバーへの補完リクエストを止める(能力なし扱い) |
-32602(Invalid params) | 発生条件指定したPrompt名が存在しない | クライアント側の切り分けPrompt名の指定ミスとしてUI側で修正を促す |
-32602(Invalid params) | 発生条件必須引数が欠けている | クライアント側の切り分け引数の入力漏れとして扱う |
-32603(Internal error) | 発生条件サーバー内部の処理失敗 | クライアント側の切り分けリトライ可能なエラーとして扱う |
Prompts本体のprompts/getエラーには-32601が無く、-32602と-32603の2種類しかありません。Completion側にだけ-32601が加わっているのは、能力自体の有無を確認する段階が独立しているからです。補完機能そのものを実装していないサーバーにcompletion/completeを送ると、Prompt名の有効性を確認する前の段階で弾かれます。上の表の1行目の通り、-32601を受け取ったら以降そのサーバーへの補完リクエストを送らない実装にしておくと、無駄な往復を避けられます。
入力のたびに補完リクエストが往復する設計
仕様が想定するメッセージフローは単純です。ユーザーが引数を入力し始めると、クライアントはcompletion/completeを送って候補を受け取ります。ユーザーが入力を続けると、クライアントは更新された文字列で再びcompletion/completeを送り、絞り込まれた候補を受け取ります。この往復が入力のたびに繰り返されます。
キー入力のたびに毎回リクエストを送ると、サーバー負荷とネットワーク往復が増えます。だからこそ実装上の推奨事項に「デバウンス」(連続する入力をまとめて、一定時間止まってから最後の値だけでリクエストを送る)が挙がっています。IDEの補完機能を思い浮かべると分かりやすい設計で、1文字打つごとに補完候補が更新されるあの体験の裏側には、この頻繁な往復とデバウンスの調整があります。
デバウンスの間隔をどれくらいに設定するかは仕様が数値を指定していません。短すぎればリクエスト数が減らず、長すぎれば候補の表示が遅れて体感が悪化します。サーバー側のレート制限と合わせて、クライアント実装者が個別に調整する部分です。
サーバー・クライアント双方の実装で気をつけること
仕様は実装上の推奨事項をサーバー側とクライアント側に分けて挙げています。表に分解すると次の通りです。
| サーバー側 | クライアント側 |
|---|---|
| 関連度順に候補を並べる | クライアント側連続する入力に対して補完リクエストを間引く(デバウンス) |
| 可能ならあいまい一致(fuzzy matching)に対応する | クライアント側補完結果をキャッシュする |
| 補完リクエストにレート制限をかける | クライアント側候補が欠けていたり部分的だったりしても正しく扱う |
| すべての入力を検証する | クライアント側— |
セキュリティ面では、補完の入力すべてを検証すること、レート制限を実装すること、機密性の高い候補へのアクセスを制御すること、補完機能を通じた情報漏えいを防ぐことが必須(MUST)とされています。最後の項目は見落としやすいところです。補完候補の一覧そのものが、本来は見えるべきでない情報(他ユーザーのデータ、内部識別子など)を暴露する経路になり得ます。
Resource Templateも補完対象になる
Completion仕様が対象にするのはPromptsの引数だけではありません。ref/resourceを使えば、URIテンプレート(file:///{path}のような形式)の変数部分も補完できます。ファイルパスの一部を入力した時点で、実在するパスの候補を返す、といった使い方です。
{
"jsonrpc": "2.0",
"id": 2,
"method": "completion/complete",
"params": {
"ref": { "type": "ref/resource", "uri": "file:///{path}" },
"argument": { "name": "path", "value": "projects/myapp/src" }
}
}このリクエストのrefはref/promptと違ってnameではなくuri(URIテンプレートそのもの)を指定します。応答の形はref/promptのときと同じvalues / total / hasMoreです。ファイルシステムのように候補が頻繁に変わる、あるいは候補の数が多すぎて一覧を丸ごと持つのが非現実的なサーバーでは、サーバーに問い合わせるたびに最新の候補を動的に生成できるこの仕組みが理にかなった設計です。
Claude Codeはこの補完APIを使っているか
Claude Codeの/mcp__servername__promptnameの呼び出しでは、MCPサーバーが公開するPromptsを直接実行できます。しかし公式ドキュメントを確認する限り、引数入力の途中でサーバーにcompletion/completeを送り、ドロップダウンで候補を出すような、IDE的なオートコンプリート体験についての記載は見当たりません。ドキュメントが説明しているのは「スペース区切りで引数を渡す」という、テキストベースの単純な入力方式です。
対照的に、Claude Codeが実際にオートコンプリートを提供しているのはリソースの参照です。プロンプト中で@を入力すると、接続中の全MCPサーバーのリソースがファイルと並んで候補に出て、あいまい検索で絞り込めます。ただしこれはref/resource型のcompletion/completeを使う仕組みではありません。resources/listで取得済みの一覧をクライアント側でその場検索している可能性が高い実装です(公式ドキュメントはこの内部実装までは説明していません)。両者の違いは、@メンションがクライアント側で一覧を保持してその場検索するのに対し、前節のcompletion/completeはサーバー側で最新の候補を動的に生成できる点です。Filesystem MCPサーバーの使い方で扱っているような、ディレクトリを絞った権限設計と組み合わせると、補完の対象を安全な範囲に限定できます。
この2つの事実を合わせると、Completion仕様が想定する「サーバー主導で入力途中の値に応じた候補を動的に返す」体験は、Claude CodeのCLI上では現状確認できないということになります。MCPサーバー側でcompletions能力を実装しても、Claude Code経由で使う限りはその恩恵を体験できない可能性があります。
まとめ
MCPのCompletionは、Promptsの引数やResource TemplateのURI変数をIDEのように補完させるための標準APIです。completion/completeはref/promptとref/resourceの2種類を対象にし、context.argumentsで複数引数間の依存関係を扱え、候補は最大100件までという上限があります。ただしClaude CodeのCLI上では、Promptsの引数入力はスペース区切りのテキスト入力にとどまります。@メンションによるリソース補完も、仕様のCompletion APIとは別経路である可能性が高いというのが、公式ドキュメントから読み取れる現状です。自作サーバーでこの仕様への対応を検討する際は、対象になるクライアントが実際にこのAPIを使う実装かどうかを先に確認してください。サーバー自体の作り方はMCPサーバー自作ガイド、動作確認はMCP Inspectorで行えます。