MCPクライアントの仕組み — ローカル接続とリモート接続の違い
MCPのホストとクライアントの違い、Elicitation/Roots/Samplingという3つの機能、stdioとStreamable HTTPで接続方法がどう変わるかを整理する。
ホストとクライアント、混同されやすい2つの言葉
MCPの用語では「ホスト」と「クライアント」は別物です。ホストはClaude DesktopやIDEのようにユーザーが直接操作するアプリケーション本体を指し、クライアントはそのホストが内部で生成する、1台のMCPサーバーと通信するためのプロトコル部品を指します。
ホストが複数のMCPサーバーに同時接続する場合、ホストはサーバーの数だけクライアントをインスタンス化します。1つのクライアントが担当する通信相手は常に1つのサーバーだけです。ユーザーから見えるのはホストの画面だけですが、裏側では「filesystem用クライアント」「Slack用クライアント」のように接続ごとに独立した通信路が動いています。
この区別が効いてくるのは、複数のMCPサーバーを同時に使うときの挙動を追うときです。あるサーバーへの接続が切れても、他のクライアントの通信には影響しません。クライアントはサーバー単位で独立しているからです。トラブルシューティングでも、まず疑うべきは「ホスト全体」ではなく「問題のサーバーに対応するクライアント1本」だと分かっていれば、切り分けが早くなります。
クライアントが提供する3つの機能
サーバーから情報を受け取るだけでなく、クライアントの側もサーバーに機能を提供します。コア機能は3つです。
| 機能 | 何をするか | 2026-07-28リビジョンでの状態 |
|---|---|---|
| Elicitation | 何をするか対話の途中でサーバーがユーザーに追加情報を求める | 2026-07-28リビジョンでの状態現役 |
| Roots | 何をするかクライアントがサーバーに操作対象のディレクトリ境界を伝える | 2026-07-28リビジョンでの状態非推奨(移行先あり) |
| Sampling | 何をするかサーバーがクライアント経由でLLM補完をリクエストする | 2026-07-28リビジョンでの状態非推奨(移行先あり) |
RootsとSamplingは2026-07-28リビジョンで非推奨になりました。仕様から即座に消えるわけではなく、最短でも2027-07-28以降の改訂まで仕様には残ります。ただし新規実装がこの2つを採用することは推奨されません。Rootsの代わりはツールパラメータやリソースURI、サーバー設定でのディレクトリ指定、Samplingの代わりはLLMプロバイダーAPIへの直接統合です。
Elicitationには2つのモードがあります。フォームモードはJSON Schemaで定義された構造化データをクライアント側のUIで収集する方式、URLモードはサーバーが提示するURLをユーザーが開き、その先でのやり取りがクライアントを経由しない方式です。パスワードやAPIキー、支払い情報のような機密情報は、フォームモードでは要求してはいけないと仕様が明記しています。クライアントやLLMのコンテキストにその値が渡らないURLモードだけが、この種の入力に使える設計です。
サーバーがユーザーに割り込む仕組み — MRTRという往復パターン
ElicitationとSamplingはどちらも、サーバーが処理の途中でクライアント側に割り込んで追加情報を求める点が共通しています。この割り込みはMulti Round-Trip Requests(MRTR)という1つのパターンで実装されています。
流れはこうです。クライアントがtools/callのようなリクエストを送ると、サーバーは即座に最終結果を返さず、resultTypeが"input_required"のInputRequiredResultを返します。この中のinputRequestsフィールドに、elicitation/createやsampling/createMessageのリクエストが1つ以上入っています。クライアントはユーザーに確認を取り、得られた回答をinputResponsesとして、同じtools/callを新しいリクエストIDで再送します。サーバーはその回答を使って処理を続け、今度こそ"complete"な結果を返します。
この設計のポイントは、サーバーからクライアントへの一方的な指示ではなく、「元のリクエストをやり直す」形を取っていることです。Samplingの場合、ユーザーは最初のプロンプトと、モデルが生成した結果の両方を確認・修正できる2段階の承認ポイントを持ちます。旅行予約サーバーが複数のフライト候補をLLMに評価させる例で言えば、ユーザーは「この内容でLLMに送っていいか」と「LLMが出した推薦をそのまま使っていいか」の両方を止められる立場にあります。RootsとSamplingが非推奨になった後も、この往復パターン自体はElicitationの基盤として仕様に残ります。
ローカルサーバーに接続する — stdioの場合
ローカル接続では、ホストがMCPサーバーをサブプロセスとして起動します。通信はサブプロセスの標準入出力(stdio)経由で行われ、サーバーはstdinからJSON-RPCメッセージを読み、stdoutに書き込みます。メッセージは改行区切りの1行1メッセージで、サーバーがstdoutに書いてよいのは有効なMCPメッセージだけです。ログ出力はstderrに流す決まりになっています。
Claude Desktopでの実例はclaude_desktop_config.jsonへの追記です。macOSなら~/Library/Application Support/Claude/claude_desktop_config.json、Windowsなら%APPDATA%\Claude\claude_desktop_config.jsonに、次の内容を書きます。
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"/Users/username/Desktop",
"/Users/username/Downloads"
]
}
}
}設定ファイルのargsに列挙したディレクトリだけがサーバーの操作対象になります。保存後はClaude Desktopを完全に再起動しないと設定が反映されません。動作確認だけなら、サーバーを単体でコマンドラインから起動してエラーが出ないか見るのが手早い方法です。
npx -y @modelcontextprotocol/server-filesystem \
/Users/username/Desktop /Users/username/Downloadsローカル接続は、ホストがサブプロセスを起動できる環境でしか成立しません。ブラウザはサンドボックスの制約で任意のローカルプロセスを起動できないため、公式のクイックスタートもClaude Desktopを対象にしています。ブラウザ版のclaude.aiでファイルシステムに直接アクセスするMCPサーバーを使いたい場合、選択肢は後述するリモート接続経由に限られます。
リモートサーバーに接続する — Custom Connectorの場合
リモート接続では、サーバーはインターネット上で独立したプロセスとして動作し、複数クライアントからの接続を同時にさばきます。Claudeでの窓口はCustom Connectorです。設定画面の「Connectors」から「Add custom connector」を選び、サーバーのURL(例: https://example-server.modelcontextprotocol.io/mcp)を入力すると接続が始まります。
ローカル接続と違い、リモート接続はほとんどの場合OAuthなどの認証を経由します。接続直後に認証画面が表示され、完了するとサーバーの提供するツールやリソースが会話内で使えるようになります。接続後は、どのツールを有効にするかを個別に制御できるので、必要なものだけを許可するのが安全です。
通信プロトコルはStreamable HTTPです。サーバーは単一のHTTPエンドポイントでPOSTを受け付け、応答は単発のJSONオブジェクトか、そのリクエストに紐づくSSE(Server-Sent Events)ストリームのどちらかで返ります。2026-07-28リビジョンでこの部分は大きく変わりました。以前あったGETストリーム用エンドポイントと、接続単位で状態を保持するプロトコルレベルのセッション(Mcp-Session-Idヘッダー)は、どちらも削除されています。そのためtools/listのようなリスト系エンドポイントは、どの接続から呼んでも同じ結果を返すようになっています。サーバー側で呼び出しをまたいだ状態が必要な場合は、ツール引数として渡す明示的なハンドルで代替する設計です。認証もOAuthのような仕組みを別途組み合わせる前提で、Streamable HTTP自体はセッションの永続化を持たない構成に変わりました。詳しい設定手順はリモートMCPサーバーとOAuth認証にまとめています。
ローカル接続とリモート接続、責任の置き場所が違う
どちらを選ぶかは、単なる好みではなく責任の所在で決まります。
| 観点 | ローカル(stdio) | リモート(Streamable HTTP) |
|---|---|---|
| 実行主体 | ローカル(stdio)ユーザーのマシン上のサブプロセス | リモート(Streamable HTTP)サーバー運営者のインフラ |
| 認証 | ローカル(stdio)不要(OS権限がそのまま境界) | リモート(Streamable HTTP)通常はOAuth等の認証が必須 |
| アクセス範囲 | ローカル(stdio)設定ファイルで明示した範囲のみ | リモート(Streamable HTTP)サーバー運営者が公開した範囲 |
| 対応ホスト | ローカル(stdio)サブプロセスを起動できるネイティブアプリ | リモート(Streamable HTTP)ブラウザ版・デスクトップ版の両方 |
| 典型用途 | ローカル(stdio)ファイルシステムなどローカルリソース | リモート(Streamable HTTP)外部SaaS、社内システムなど |
ローカル接続はサーバーがユーザー自身のアカウント権限で動くため、設定ファイルに書いたディレクトリ以外にはそもそも触れません。安全性の境界は「どのディレクトリをargsに書いたか」というシンプルな話に還元されます。一方リモート接続は、サーバー運営者のインフラを信頼するかどうかという、質的に異なる判断が必要です。Streamable HTTPの仕様は、すべてのサーバーにOriginヘッダーの検証を求めています。さらにローカルで動かす場合は、0.0.0.0ではなく127.0.0.1にだけバインドすることを推奨しています。リモートのWebサイトからDNSリバインディングでローカルのMCPサーバーに接続される攻撃を防ぐためです。
リモート接続で最低限やっておくこと
リモートMCPサーバーは、自分のマシンの外で動くコードを信頼するという行為そのものです。実務上の注意点は大きく2つあります。ローカル接続がディレクトリ単位で権限を切れるのに対し、リモート接続は「繋ぐか繋がないか」のオンオフに近い粒度になりがちなので、次の2点を怠ると許可の範囲がなし崩しに広がります。
- 接続前の確認: 認証時にどんな権限を要求されているかを見て、信頼できる提供元のサーバーだけに繋ぐ
- 接続後の棚卸し: 複数のCustom Connectorを繋ぎっぱなしにせず、用途ごとに整理し、使わなくなったものは定期的に外す
サーバーごとにどこまで権限を絞るべきかの具体的な判断基準はMCPセキュリティガイドで扱っています。
まとめ
MCPのクライアントは、ホストが1サーバーごとに立てる通信担当です。持っている機能はElicitation・Roots・Samplingの3つですが、RootsとSamplingは2026-07-28で非推奨になり、新規実装では避ける対象になりました。接続方式は大きくローカル(stdio、サブプロセス起動)とリモート(Streamable HTTP、認証必須)の2つに分かれ、選択はセキュリティ責任をどちらに置くかの判断でもあります。ローカルなファイルシステム連携を試すならClaude DesktopのMCP設定ガイド、Filesystemサーバーの権限設計を詰めるならFilesystem MCPサーバーの使い方、接続がうまくいかないときはMCPサーバーに接続できないときの切り分け手順が助けになります。MCP自体の全体像はMCPとはにまとめています。