ローカルMCPとリモートMCPの違い — Claude Codeでの選び方
ローカルMCPは自分のPCでプロセスを起動し、リモートMCPはHTTPでクラウドに接続します。Claude Codeでの違いを、チーム共有・レイテンシ・監査ログ・保守性で比べます。
Claude CodeのMCPサーバーは、自分のマシンでプロセスとして起動するローカル(stdio)接続と、ネットワーク越しにHTTPで呼び出すリモート接続のどちらかで動きます。ローカルMCPとリモートMCPの違いは、サーバーがどこで動くかにあります。どちらが優れているという話ではありません。チームに設定をどう共有するか、レイテンシと監査ログのどちらを優先するかで、答えが変わります。
ローカルとリモートは「誰が何を管理するか」の違い
サーバーが動く場所が変わると、追加方法・認証・切断時の挙動・保守の担い手がまとめて変わります。
| 比べる点 | ローカルMCP(stdio) | リモートMCP(HTTP) |
|---|---|---|
| サーバーが動く場所 | ローカルMCP(stdio)自分のマシン上のプロセス | リモートMCP(HTTP)クラウドなど別の場所 |
| 追加のしかた | ローカルMCP(stdio)claude mcp add <名前> -- <起動コマンド> | リモートMCP(HTTP)claude mcp add --transport http <名前> <URL> |
| 向く用途 | ローカルMCP(stdio)ファイルや端末への直接アクセス、自作スクリプト | リモートMCP(HTTP)クラウドのサービスへの接続 |
| 認証 | ローカルMCP(stdio)環境変数(--env)で渡す | リモートMCP(HTTP)OAuthまたはヘッダー |
| 切れたとき | ローカルMCP(stdio)自分で再起動する | リモートMCP(HTTP)最大5回まで自動で再接続する |
| 更新と保守 | ローカルMCP(stdio)自分でランタイムとバージョンを管理 | リモートMCP(HTTP)多くは提供者がサーバー本体を更新 |
公式ドキュメントはクラウドのサービスにはHTTPを推奨し、直接的なシステムアクセスやカスタムスクリプトにはstdioが向くとしています。ローカルのnpx -y ...のような起動コマンドはあなたのマシン上でプロセスになり、リモートはクラウド上で運用されているサーバーに接続するだけです。
リモートにはHTTPのほかにSSEとWebSocketがあります。SSEは非推奨で、v2.1.265以降は--transport httpで追加するとHTTPを先に試し、サーバーが受け付けなければSSEに切り替わります。WebSocketはclaude mcp add --transportのフラグが対応しておらず、.mcp.jsonかclaude mcp add-jsonで設定します。OAuthにも対応せず、認証はヘッダー(headersかheadersHelper)だけです。
判断軸はチーム共有、レイテンシ、監査ログ、保守性の4つです。ローカル接続の具体例はDesktop CommanderでClaudeにPCのファイルとターミナルを任せる導入と安全面にあります。変換処理だけをリモートに逃がせる例はDocling MCPのローカル文書変換です。
チーム共有はスコープが決める、接続方式ではない
Claude CodeのMCPサーバーには、接続方式(stdio/HTTP)とは別に「スコープ」という設定の可視範囲があります。この2つを混同しないことが大切です。
| スコープ | 読み込まれる範囲 | チームと共有されるか | 保存先 |
|---|---|---|---|
| ローカルスコープ(既定) | 読み込まれる範囲追加したプロジェクトのみ | チームと共有されるかされない(自分専用) | 保存先~/.claude.json |
| プロジェクトスコープ | 読み込まれる範囲追加したプロジェクトのみ | チームと共有されるかされる(バージョン管理経由) | 保存先プロジェクト直下の.mcp.json |
| ユーザースコープ | 読み込まれる範囲すべてのプロジェクト | チームと共有されるかされない(自分専用) | 保存先~/.claude.json |
チームで同じサーバーを使うなら、接続方式に関係なくプロジェクトスコープを選び、.mcp.jsonをコミットします。違いが出るのはその先です。stdioサーバーを共有すると、メンバー全員がNode.jsやuv、Dockerといったランタイムを自分のマシンに用意しなければなりません。HTTPサーバーなら認証さえ済ませればよく、ローカル環境の差に左右されにくくなります。
手元で追加したときの実際の出力
Claude Code v2.1.287で、空のHOMEと一時ディレクトリを使って2種類を追加しました。プロジェクトスコープのHTTPサーバーは、作業ディレクトリの.mcp.jsonに書き込まれます。
claude mcp add --transport http notion --scope project https://mcp.notion.com/mcp
# Added HTTP MCP server notion with URL: https://mcp.notion.com/mcp to project config
# File modified: ./.mcp.json
cat .mcp.json
# {
# "mcpServers": {
# "notion": {
# "type": "http",
# "url": "https://mcp.notion.com/mcp"
# }
# }
# }スコープを省いたstdioサーバーはローカルスコープになり、リポジトリには何も書かれません。出力の末尾には、書き込み先が~/.claude.jsonの中のどのプロジェクトかが付きます。
claude mcp add local-tool --env API_KEY=your-key -- npx -y @example/mcp-server
# Added stdio MCP server local-tool with command: npx -y @example/mcp-server to local config
# File modified: ~/.claude.json [project: <作業ディレクトリ>]~/.claude.jsonを開くと、サーバーは{"type": "stdio", "command": "npx", "args": ["-y", "@example/mcp-server"], "env": {"API_KEY": "your-key"}}として入っていました。サーバー定義はprojects以下の当該プロジェクトのパスの配下にあります。ローカルスコープのサーバーが他のプロジェクトに現れないのは、このためです。
共有の手順
チームにリモートサーバーを配る流れ
- 1
プロジェクトスコープで追加する
--scope projectを付けて追加します。 - 2
`.mcp.json`をコミットする
メンバーはリポジトリを更新するだけでサーバー定義を受け取ります。
- 3
各自が承認と認証を済ませる
対話セッションで
claudeを起動し、承認プロンプトを通します。OAuthを使うサーバーなら、サインインも各自で行います。
承認の扱いは実行形態で変わります。対話セッションでは、承認するまでサーバーがPending approvalのままです。claude -p、Agent SDKセッション、クラウドセッションではプロンプトを出せないため、プロジェクトスコープのサーバーは承認なしでそのまま読み込まれます。入れたくないサーバーはdisabledMcpjsonServersで除外するか、--strict-mcp-configで--mcp-configに渡したものだけに絞ります。
同じ名前のサーバーが複数のスコープにあるときは、優先順位はローカル、プロジェクト、ユーザー、プラグイン、claude.aiコネクタの順です。組織がmanagedMcpServersの管理設定で配るサーバーは、これらすべてより優先されます(v2.1.259以降)。プラグインとコネクタは名前でなく接続先で重複を判定します。最も優先度の高い定義が丸ごと使われ、フィールドは混ぜ合わされません。名前が同じで接続先が違うと、claude mcp listと/mcpで警告が出ます。OAuthのサインインは接続先ごとに別管理なので、別の定義が読み込まれるプロジェクトでは再度サインインします。
レイテンシは通信経路の有無で決まる
stdioサーバーは標準入出力で完結し、ネットワークの往復がありません。HTTPサーバーは呼び出しのたびにネットワークを経由するので、体感差はサーバー自身の応答速度と回線に左右されます。頻繁に呼ぶツールで気になるなら、先に計測してから決めるのが安全です。
タイムアウトの掛かり方は接続方式で変わります。数字だけ並べると次のとおりです。
接続方式で変わるタイムアウトと再試行
HTTP・SSEのアイドル打ち切り
5分
応答も進捗通知も無いままツール呼び出しが中断される。WebSocketも同じ
stdioのアイドル打ち切り
30分
v2.1.203より前は、stdioはこの検査の対象外だった
HTTP・SSEの初回接続の再試行
最大3回
5xx・接続拒否・タイムアウトのとき。stdioは対象外
リモートの切断後の再接続
最大5回
1秒から倍々に延びる。stdioは自動再接続なし
HTTP・SSE・claude.aiコネクタのサーバーには、各リクエストが最初の応答バイトを返すまでを見張る「per-requestタイマー」もあります。値は60秒、そのサーバーのツールタイムアウト、MCP_TIMEOUTのうち最も長いものです。stdioとWebSocketにはこのタイマーがありません。
接続が切れたときの挙動も違う
リモートサーバーがセッション中に切れると、Claude Codeは自動で再接続します。対話セッションでは/mcpに保留中と表示されます。5回失敗するとfailed(認証が必要な場合は認証待ち)に変わり、MCP server "<name>" disconnected · open /mcp to reconnectという通知が出ます。claude -pやAgent SDKでも同じ間隔で再接続しますが、状況を映す/mcpはありません。
サーバーが落ちたとき
リモート(HTTP/SSE)
認証エラーとnot foundは設定の修正が要るため再試行しません。ただしheadersHelperがAuthorizationヘッダーの唯一の供給元のときは、認証エラーも再試行します。
ローカル(stdio)
プロセスが落ちたら、サーバーを起動し直してから/mcpで再接続します。
接続後の機能一覧の取得(tools/listなど)も、一時的なネットワークエラーやサーバーエラーなら最大3回再試行します。認証エラーと4xx、リクエストのタイムアウトは再試行されません。失敗した全サーバーをまとめて試し直すなら/mcp reconnect allで、対話端末ではv2.1.284以降が必要です。
リモートサーバーには、起動を軽くする仕組みもあります。使ったことのあるHTTP・SSEサーバーは、前回のツール一覧を保存したキャッシュから読み込まれ、/mcpにcached 2h ago · connects on first useのように表示されます。実際の接続は、Claudeがそのサーバーのツールを初めて呼んだときです(v2.1.221以降)。
監査ログはOTelイベントで残せるが、取得は自分で設定する
Claude CodeはOpenTelemetryのログイベントで、監査に使えるデータを出します。mcp_server_connection(接続・切断・失敗。transport_typeとserver_scopeが付く)、tool_result(ツール呼び出しの結果)、tool_decision(許可・拒否の判断)の3種類です。stdioでもHTTPでも同じ仕組みで出るので、接続方式そのものが監査ログの有無を左右することはありません。
ただし既定では、ユーザーが設定したMCPサーバーのtool_decisionイベントでtool_nameが"mcp_tool"という文字列に固定され、サーバー名とツール名は出ません。名前と呼び出し引数まで残すにはOTEL_LOG_TOOL_DETAILS=1を設定し、OTLPログの送信先をSIEM(セキュリティ情報イベント管理)側に向けます。
export CLAUDE_CODE_ENABLE_TELEMETRY=1
export OTEL_LOGS_EXPORTER=otlp
export OTEL_LOG_TOOL_DETAILS=1
export OTEL_EXPORTER_OTLP_LOGS_ENDPOINT="https://siem.example.com:4318/v1/logs"引数はtool_inputに入り、512文字を超える値は切り詰められ、全体も約4K文字で打ち切られます。長い引数を渡すツールの監査には、この上限が効きます。
保守性はランタイムを誰が持つかで変わる
stdioサーバーのバージョンを固定せずに起動すると、サーバー側の更新で動作が急に変わることがあります。原因調査が難しくなるので、本番ではバージョンを固定しておくのが無難です。Node.jsやuv、Dockerの導入と更新も各自のマシンで行います。
stdioサーバーには、Claude CodeがCLAUDE_PROJECT_DIRという環境変数でプロジェクトのルートを渡します。サーバー側でプロジェクト相対のパスを解決でき、作業ディレクトリに依存しません。サーバーが触れるディレクトリを自分で絞りたいときは、MCPのroots/listリクエストを実装します。Claude Codeはここに、起動ディレクトリと--add-dirで追加した作業ディレクトリを返します。
HTTPサーバーは、サーバー本体の更新を提供者が担います。マシンには何もインストールせず、残るのは認証情報の管理だけです。個人の検証やファイルに直接触るツールはローカル、チームで使う外部サービスはリモート、という住み分けが自然です。
遅いサーバーを調整する設定は3つあります。
MCP_TIMEOUT: サーバーの起動待ちの上限.mcp.jsonエントリのtimeout: そのサーバーのツール呼び出しの上限。1000ミリ秒未満の値は無視されますCLAUDE_CODE_MCP_TOOL_IDLE_TIMEOUT: アイドル打ち切りの時間(ミリ秒)。0で検査そのものを止めます
timeoutは呼び出しごとの壁時計の上限で、進捗通知では延びません。1000以上の値は、アイドル打ち切りがその値より早く働かないための下限にもなります(v2.1.203以降)。リモートサーバーではper-requestタイマーが別に掛かるため、応答が遅いサービスにはこちらも合わせて確認します。
判断軸の早見表
| 軸 | ローカル(stdio)が向く場面 | リモート(HTTP)が向く場面 |
|---|---|---|
| レイテンシ | ローカル(stdio)が向く場面頻繁に呼ぶツールで往復を減らしたい | リモート(HTTP)が向く場面ある程度の往復を許容できる |
| 保守性 | ローカル(stdio)が向く場面自分だけが使う個人ツール | リモート(HTTP)が向く場面サーバー本体の更新を提供者に任せたい |
| チーム共有 | ローカル(stdio)が向く場面全員がランタイムを用意できる | リモート(HTTP)が向く場面ランタイムを揃えられない、揃えたくない |
よくあるつまずき
.mcp.jsonのサーバーがPending approvalのまま動かない。クローンしたリポジトリでは、ワークスペースを信頼するダイアログと承認プロンプトを通るまで、サーバーは接続されません。v2.1.196以降は、claude mcp listとclaude mcp getは、ワークスペースを信頼するまでは、リポジトリにコミットされていない設定ファイルの承認だけを見ます。クローンしたリポジトリが自分自身を承認することはできません。
urlだけを書いた.mcp.jsonのエントリが読み込まれない。 typeを省くとstdioサーバーとして解釈されるため、urlを持つエントリは設定ミスになります。"type": "http"(またはsse・ws)を足します。v2.1.202より前は、このミスがcommand: expected string, received undefinedと報告されていました。
リモートサーバーを削除すると認証情報も消える。 claude mcp removeすると、保存していたOAuthトークンとクライアント登録情報が一緒に削除され、再追加すれば再度サインインが要ります。トークンは各自のマシンに保存されるため、影響を受けるのは削除した本人だけです。
stdioサーバーが落ちたのに気づかない。長いセッションでは/mcpでサーバーの状態を見ておくと安心です。
まとめ
迷ったら、共有したいかどうかでスコープを先に決め、そのうえで落ちたときに自分で再起動できるかで接続方式を選びます。プロトコルレベルの違いはMCPクライアントの仕組み、リモートMCPのOAuth認証はリモートMCPのOAuth認証にまとめています。