
MCPの「逆方向リクエスト」を理解する — Sampling・Elicitation・Client-Server構造の全体像
はじめに
MCP(Model Context Protocol)を学んでいると、こんな疑問が出てきませんか?
- ツール実行中にユーザーに確認を取りたいとき、どうするの?
- ツール自身が「考える」必要があるとき、LLM にどう頼むの?
- そもそも MCP の「Client」と「Server」って、誰が誰?
筆者も MCP の Sampling と Elicitation の違いを調べるうちに、Client-Server の役割が「逆転」する仕組みや、Claude Code の内部アーキテクチャまで深掘りすることになりました。本記事では、MCP のプリミティブ全体像と「逆方向リクエスト」の仕組みを整理します。
MCP プリミティブの全体像
MCP では、Server が Client に公開する機能を**プリミティブ(Primitive)**として定義します。まず全体像を把握しましょう。

Client → Server(順方向)のプリミティブ
| プリミティブ | 役割 | 具体例 |
|---|---|---|
| Resources | Server が持つデータ・ファイルを Client に公開する | ドキュメント、設定ファイル、DB のスキーマ情報 |
| Tools | Server が提供するアクション(関数)を Client が呼び出す | ファイル操作、API 呼び出し、DB クエリ |
| Prompts | 定型的な指示テンプレートを Server が提供する | 「苦情分析」「コードレビュー」などのプリセット |
Server → Client(逆方向)のプリミティブ
ここが MCP の面白いところです。通常は Client が Server に「やって」と頼みますが、Server 側から Client に助けを求める仕組みも用意されています。
| プリミティブ | 役割 | 誰が答える? |
|---|---|---|
| Sampling | Server が LLM の推論を借りたいとき | LLM(AI) |
| Elicitation | Server がユーザーの確認・入力を求めたいとき | 人間(ユーザー) |
その他のプリミティブ
| プリミティブ | 役割 | 方向 |
|---|---|---|
| Roots | Client が Server にアクセス可能なワークスペース境界を宣言する(例: /home/user/project 配下のみ) |
Client → Server |
| Logging | Server が診断情報を Client に通知する(notifications/message) |
Server → Client(一方通行) |
Roots はセキュリティ境界の宣言、Logging はデバッグ用の通知であり、双方向のやり取りには使えません。
Sampling と Elicitation — 「脳を借りる」と「許可を求める」
MCP の逆方向リクエストの中核が Sampling と Elicitation です。この2つの違いを理解することが、MCP アーキテクチャを正しく設計する鍵になります。
Sampling:ツールが LLM に「考えて」と頼む
sampling/createMessage を使って、Server(ツール)が Client 経由で LLM の推論を要求します。
典型的なユースケース: ツールが曖昧なエラーに遭遇し、自分では解決策が分からないとき。
例えば、ファイルアップロードツールが 422 Unprocessable Entity: Date format is invalid for region 'JP' というエラーを受け取ったとします。ツール自身はこのエラーを修正するロジックを持っていません。そこで Sampling を使って LLM に聞きます。
Server → Client: sampling/createMessage
"このエラーが出ました。日付フォーマットをどう修正すればいいですか?"
Client(LLM)→ Server:
"YYYY/MM/DD 形式に変換してください。送信されたデータは DD/MM/YYYY でした。"
ツールはこの回答をもとにデータを修正し、リトライします。
Elicitation:ツールがユーザーに「確認して」と頼む
ツール実行中に人間の判断や入力が必要な場面で使います。
典型的なユースケース: 認証情報の入力、破壊的操作の確認。
例えば、API ツールが 401 Unauthorized を受け取ったとき、LLM に聞いても API キーは分かりません。Elicitation を使ってユーザーに直接聞きます。
Server → Client: elicitation/create (※メソッド名は仕様改定で変更の可能性あり)
"認証が必要です。API キーを入力してください。"
Client → ユーザー: UIにフォームを表示
ユーザー → Client → Server: "sk-abc123..."
判断フロー:どのプリミティブを使うか
ツールがエラーに遭遇したとき、HTTP ステータスコード別の対処戦略をまとめると以下のようになります。
| ステータスコード | 状況 | 対処戦略 | 使うプリミティブ |
|---|---|---|---|
| 5xx(503, 523 など) | サーバー側の一時的障害 | 指数バックオフでリトライ | なし(内部ロジック) |
| 401 / 403 | 認証・認可の問題 | ユーザーに資格情報を求める | Elicitation |
| 422 / 400 | リクエストデータの問題 | LLM にデータ修正を相談 | Sampling |
覚え方:鍵が必要なら Elicitation(人間に聞く)、頭が必要なら Sampling(LLM に聞く)。
ツールの「脳のギャップ」— Sampling + Elicitation の組み合わせ
ここで重要な疑問が出てきます。ツール(Server)はただのコードです。コード自体は「考える」ことができません。では、ユーザーに何を聞くべきかをどう判断するのでしょうか?
パターン1:ハードコードされたロジック
開発者が予見できるエラーには、あらかじめ対応を書いておけます。
if error.status == 401:
elicit_input("API キーを入力してください")
この場合、LLM は関与しません。
パターン2:Sampling → Elicitation の連携
予期しないエラーに遭遇した場合、ツールはまず Sampling で LLM に「何をユーザーに聞くべきか」を相談し、その回答をもとに Elicitation でユーザーに質問します。

1. ツール: 未知のDBバリデーションエラーが発生
2. Sampling: 「このエラーを解決するためにユーザーに何を聞くべき?」
3. LLM: 「フォールバック用のDBスキーマを聞いてください」
4. Elicitation: 「使用するフォールバックDBスキーマを選択してください」
5. ユーザー: スキーマを選択 → ツールが処理を再開
なぜ Sampling だけで済ませないのか? — セキュリティです。削除やお金に関わる操作では、LLM の「推測」ではなく、人間が物理的に「確認」ボタンを押す必要があります。Elicitation はその正式な「一時停止」メカニズムです。
MCP の Client-Server 構造 — 「誰が誰?」
MCP のアーキテクチャで最も混乱しやすいのが、Client と Server の役割です。
基本ルール
| コンポーネント | MCP の役割 | 説明 |
|---|---|---|
| AI アプリ(Claude Desktop, Claude Code, Agent SDK) | Client(Host) | LLM を内包し、ユーザーとの接点を持つ |
| ツール / API / DB | Server | 具体的な機能・データを提供する |
| ユーザー | (外部) | Client を通じてのみやり取りする |
重要なポイント:LLM は Client の内部に存在します。Server は LLM やユーザーと直接通信できません。必ず Client を経由します。
なぜ Client が「ゲートウェイ」なのか
ユーザー ←→ Client(LLM + UI)←→ Server(ツール)
Server が LLM やユーザーに直接アクセスできない理由はセキュリティです。Client が仲介することで:
- 危険なリクエストをブロックできる
- 機密情報を LLM に渡す前にフィルタリングできる
- ユーザーの承認なしにツールが勝手に動くことを防げる
3つのリクエストパターン
A) 通常のツール呼び出し(Client → Server)
Client: 「file.txt を削除して」
Server: 削除実行 → 「完了」
B) Sampling(Server → Client → LLM)
Server: 「エラーが出た。LLM に聞いて」
Client: LLM に問い合わせ → 回答を Server に返す
C) Elicitation(Server → Client → ユーザー)
Server: 「パスワードが必要。ユーザーに聞いて」
Client: UI を表示 → ユーザー入力を Server に返す
B と C が「逆方向リクエスト」です。Server が Client に助けを求めますが、あくまで Client が制御権を持ちます。
Claude Code における MCP の活用 — 「Server は外部だけではない」
「Claude Code は全部ローカルで動くのだから、MCP Server は関係ないのでは?」と思うかもしれません。しかし MCP の設計思想では、**ツールを提供する側はすべて「Server」**です。
概念としての分離
MCP の Client-Server モデルでは、LLM がツールの内部実装を知る必要はありません。「read_file というツールがある」ということだけ知っていれば十分です。この抽象化により:
- LLM はツールの実装言語や実行環境を気にしなくてよい
- Client がセキュリティガードとして、すべてのツール呼び出しを監視・制御できる
実際の拡張性
Claude Code の強みは、外部 MCP Server をプラグインとして追加接続できる点です:
- 外部サービス連携: Jira, Slack, GitHub などの MCP Server を追加するだけで機能拡張できる
- 統一インターフェース: ローカルツールでもリモート API でも、MCP プロトコルに従っていれば同じように使える
- 安定性: 外部 Server がクラッシュしても、Claude Code セッション全体は影響を受けない
MCP プリミティブ比較表
最後に、MCP の全プリミティブを一覧で整理します。
| プリミティブ | 方向 | 目的 | 具体例 |
|---|---|---|---|
| Resources | Client → Server | データの公開・読み取り | ドキュメント、設定、スキーマ |
| Tools | Client → Server | アクション(関数)の実行 | ファイル操作、API 呼び出し |
| Prompts | Client → Server | 定型指示テンプレート | コードレビュー、分析タスク |
| Sampling | Server → Client | LLM の推論を借りる | エラー解析、データ修正 |
| Elicitation | Server → Client | ユーザーの確認・入力 | 認証情報、削除確認 |
| Roots | Client → Server | ワークスペース境界の宣言 | プロジェクトルートの指定 |
| Logging | Server → Client | 診断情報の通知(一方通行) | デバッグログ、進捗通知 |
まとめ
MCP のアーキテクチャを理解するための3つのポイント:
- Server は「役割」であり「場所」ではない — ローカルプロセスでもリモート API でも、ツールを提供する側は Server。これにより抽象化とサンドボックスが実現される
- 逆方向リクエストが MCP の核心 — Sampling(LLM に聞く)と Elicitation(人間に聞く)により、ツールが「行き詰まったとき」の対処が可能になる
- Client がゲートウェイ — LLM もユーザーも Client の内側にいる。Server は必ず Client を経由する。これがセキュリティの基盤
MCP は単なる「ツール呼び出しプロトコル」ではなく、AI・ツール・人間の三者が安全に協調するための設計哲学です。この構造を理解すると、自前の MCP Server を設計するときに「何を Server に置き、何を Client に任せるか」の判断がしやすくなります。






