Claude Media
MCP_PROTOCOL_NEGOTIATIONとは — Claude Codeの新プロトコル交渉を切り替える

MCP_PROTOCOL_NEGOTIATIONとは — Claude Codeの新プロトコル交渉を切り替える

MCP_PROTOCOL_NEGOTIATIONは、Claude CodeがMCPサーバーにプロトコル改訂2026-07-28を尋ねるかを決める環境変数です。autoとlegacyの違い、対象サーバー、legacyを選ぶ場面をまとめます。

MCP_PROTOCOL_NEGOTIATIONは、Claude CodeがMCPサーバーへ接続するとき「プロトコル改訂2026-07-28を話せますか」と尋ねるかどうかを決める環境変数です。値はautoとlegacyの2つ。autoは尋ねる対象を広げ、legacyはどのサーバーにも尋ねず、従来のハンドシェイクで接続します。

v2.1.292でローカルのstdioサーバーが既定で尋ねられる側に入り、v2.1.295ではclaude.aiコネクタも同じ扱いになりました。自分のMCPサーバーが急に遅くなった、チャンネルとして登録されなくなった、という症状の切り分けに、この変数が使えます。

この変数が切り替えるのは「尋ねるか」だけ

Claude CodeにはMCPクライアントのランタイムが2つあります。v1はMCP TypeScript SDK 1.xの上に作られ、v2は同じコードをMCP TypeScript SDK 2.0に載せ替えたものです。新しいプロトコル改訂2026-07-28を扱えるのはv2だけで、MCP_PROTOCOL_NEGOTIATIONもv2ランタイムにだけ効きます。要件はv2.1.221以降です。

役割は次のように分かれます。

変数決めること値
MCP_SDK_GENERATION決めることどのランタイムで接続するか値v1 / v2
MCP_PROTOCOL_NEGOTIATION決めることv2で新改訂を尋ねるか値auto / legacy

ランタイムの固定はMCP_SDK_GENERATIONの仕事です。legacyを設定してもv2ランタイムのままなので、v2側で変わった他の挙動は戻りません。たとえばMCPのOAuthサインインで、認可レスポンスの発行者が想定と違えば失敗する動きは、ランタイム側の仕様です。

2つの変数の組み合わせは、次のとおりです。

MCP_SDK_GENERATIONMCP_PROTOCOL_NEGOTIATION接続の結果
未設定またはv2MCP_PROTOCOL_NEGOTIATION未設定・auto接続の結果v2ランタイムで、HTTP・stdio・claude.aiコネクタに新改訂を尋ねる
未設定またはv2MCP_PROTOCOL_NEGOTIATIONlegacy接続の結果v2ランタイムのまま、どのサーバーにも尋ねない
v1MCP_PROTOCOL_NEGOTIATION何を入れても接続の結果v1ランタイムで接続し、MCP_PROTOCOL_NEGOTIATIONは効かない

MCP_SDK_GENERATIONが未設定のとき、v2が選ばれる版はセッションの種類で違います。フラグを取得するセッションはv2.1.232以降、取得しないセッションはv2.1.274以降です。後者にはBedrock、Claude Platform on AWS、Google CloudのAgent Platform、Microsoft Foundryのセッション、Claude appsゲートウェイ経由のサインイン、テレメトリやフラグ取得を止めた環境が入ります。

新改訂で接続すると何が変わるか

新改訂で接続したサーバーは、扱いが3点変わります。1つ目はlist_changed通知の受け方です。v2ランタイムは、新改訂のサーバーからの通知を、開いたままにしたストリームで受け取ります。ツール一覧の動的な更新を使うサーバーを作っているなら、この経路の違いが再接続の挙動に出ます。仕組みはMCPの動的ツール更新と再接続で扱っています。

2つ目はチャンネルです。新改訂はチャンネルメッセージを運べないので、新改訂で接続したチャンネルサーバーは登録されません。3つ目はElicitationで、フォーム形式とURL形式の両方を宣言して接続します。この3点のどれにも当たらないサーバーは、改訂が変わっても使い勝手はほぼ同じです。

どのサーバーに尋ねるか

変数を設定したときの挙動は、サーバーの種類ごとに次のとおりです。

サーバーの種類未設定autolegacy
HTTP未設定尋ねるauto尋ねるlegacy尋ねない
stdio未設定尋ねるauto尋ねるlegacy尋ねない
claude.aiコネクタ未設定尋ねるauto尋ねるlegacy尋ねない
SSE・WebSocketなど未設定尋ねないauto尋ねないlegacy尋ねない

未設定のときは、HTTP・stdio・claude.aiコネクタのサーバーに新改訂を尋ね、対応していれば新改訂を使います。それ以外のサーバーはv1と同じ方法で接続します。autoはこの3種類に尋ねる設定、legacyはどれにも尋ねない設定です。

既定で尋ねる対象は、3回のリリースで広がりました。

あゆみ

既定で尋ねる対象が広がった経緯

  1. v2.1.274HTTPサーバー

    Bedrock、Vertex、Foundryとテレメトリ無効のインストールも、v2クライアントで直接のHTTPサーバーに尋ねる既定になりました。

  2. v2.1.292stdioサーバー

    ローカルのstdioサーバーが、Bedrock、Vertex、Foundryを含む全インストールで既定の対象になりました。

  3. v2.1.295claude.aiコネクタ

    フラグを取得しないインストールでも、claude.aiコネクタが既定で尋ねられるようになりました。

それぞれの項目に、MCP_PROTOCOL_NEGOTIATION=legacyで戻せるという注記が付いています。各版の全体像はv2.1.292のリリースノートとv2.1.295のリリースノートにあります。

MCP_PROTOCOL_NEGOTIATIONの設定方法

シェルで一時的に切り替えるなら、起動時に付けるだけです。

# 新しい改訂を一切尋ねない
MCP_PROTOCOL_NEGOTIATION=legacy claude
 
# 尋ねる対象を明示する
MCP_PROTOCOL_NEGOTIATION=auto claude

毎回付けたくないときは、settings.jsonのenvキーに入れます。

{
  "env": {
    "MCP_PROTOCOL_NEGOTIATION": "legacy"
  }
}

envの値は、claudeをどう起動しても読まれます。プロジェクトの.claude/settings.jsonに入れれば、チーム全員のstdioサーバーを同じ接続方式にそろえられます。

autoとlegacy以外の値は無視され、デバッグログに警告が出ます。Legacyやoffのような書き間違いは、エラーにならず既定の挙動のまま動くので、効いていないと感じたらまず綴りを見てください。

legacyを選ぶ場面

新しい改訂で困らない限り、既定のままで構いません。legacyを検討するのは次の3つの状況です。

チャンネルサーバーが登録されない

MCPサーバーがclaude/channelケイパビリティでメッセージを押し込む「チャンネル」の場合、v2ランタイムで新改訂を交渉すると、その改訂はチャンネルメッセージを運べないため、チャンネルとして登録されません。新改訂を話さないサーバーなら従来のハンドシェイクで接続し、これまでどおり登録されます。

stdioのチャンネルサーバーは既定で尋ねる側に入りました。更新後にチャンネル通知が来なくなったら、MCP_PROTOCOL_NEGOTIATION=legacyで従来のハンドシェイクに戻せます。legacyはすべてのサーバーを戻す設定です。チャンネルの仕組みはChannelsの解説、MCPサーバー側の設定はMCPチャンネルの手順で扱っています。

応じないstdioサーバーの最初の接続が遅い

新改訂の確認に応じないstdioサーバーは、最初の接続が1回だけ遅くなることがあります。v2.1.292では、その後そのサーバーを7日間覚えておき、待たずに従来の方式で接続する改善も入りました。毎回の起動で待たされるわけではありません。

それでも1回目の待ちが業務の都合で困る場合は、legacyを設定すれば最初から尋ねません。逆に、サーバーを新しい改訂に対応させたい開発者は、autoか未設定のまま接続を確かめられます。

新改訂側の機能を試したい

新改訂の接続では、Claude Codeがクライアントのケイパビリティとしてelicitation: {form: {}, url: {}}を宣言します。サーバーはフォーム形式とURL形式のどちらでも入力を求められます。ElicitationをMCPサーバー側で作っているなら、新改訂で接続されているかどうかが動作確認の前提です。違いはElicitationのフォームとURLにまとめています。

切り替えて確かめる手順

症状が新プロトコル交渉に関係するかどうかは、設定を1つだけ変えて比べると切り分けられます。

手順

切り分けの流れ

  1. 1

    バージョンを見る

    claude --versionでv2.1.292以降かを確かめます。stdioサーバーの既定化はこの版からです。

  2. 2

    legacyで起動する

    MCP_PROTOCOL_NEGOTIATION=legacy claudeで起動し、症状が消えるか見ます。消えれば、新改訂の交渉が関係しています。

  3. 3

    ランタイムの影響を分ける

    消えない場合はMCP_SDK_GENERATION=v1も付けて試します。ランタイム側の違いか、交渉の違いかを分けられます。

  4. 4

    サーバーを再接続する

    設定を変えたら、/mcpの画面から該当サーバーを再接続して、状態を見直します。

MCP_SDK_GENERATIONの値はプロセスごとに1回だけ読み取られます。

legacyにしてもサインインが通らないとき

MCP_PROTOCOL_NEGOTIATION=legacyにしても直らない症状が、OAuthまわりに2つあります。どちらもv2ランタイムの仕様で、尋ねるかどうかとは別の動きです。

症状原因対処
Issuer mismatch in authorization responseで始まるエラーでサインインに失敗する原因v2ランタイムが、認可レスポンスの発行者(issuer)を確かめ、一致しないと失敗させる。v2.1.221以降対処認可サーバーが返す発行者を正しい値にそろえる。v1ランタイムはこの確認をしないので、MCP_SDK_GENERATION=v1で挙動を比べられる
トークンエンドポイントが平文のhttp://のサーバーでサインインに失敗する原因v2ランタイムは、HTTPSかlocalhost、127.0.0.1、::1のトークンエンドポイントにだけ資格情報を送る対処ローカルネットワーク上の機器などは、エンドポイントをHTTPSにする。詳細はerrorsのページの「Refusing to send credentials to non-https token endpoint」の項

エラーが出た段階でlegacyを試して変わらなければ、交渉ではなくランタイムの確認に当たっています。切り分けの次の一手はMCP_SDK_GENERATIONです。

運用で気を付ける点

チームで使うときは、次の3点を決めておくと、更新後の挙動差で迷いにくくなります。

  • 共有設定ではautoかlegacyのどちらかを明示し、未設定の既定に頼らない
  • 版が上がるたびに既定の対象が広がるので、更新後は自作のstdioサーバーとチャンネルサーバーを1回ずつ起動して確かめる
  • Bedrockなどのセッションでは、Claude Codeを組み込むホスト側がCLAUDE_CODE_PROVIDER_MANAGED_BY_HOSTを設定していると、v2が既定になりません。この変数はCLAUDE_CODE_PROVIDER_MANAGED_BY_HOSTの記事にあります

新改訂に未対応のサーバーは、これまでどおり従来のハンドシェイクで動きます。ユーザー側が何もしなくても壊れる設計ではなく、設定が必要になるのは、チャンネルのように新改訂の側で制約がある用途に限られます。

まとめ

MCP_PROTOCOL_NEGOTIATIONは、v2ランタイムが新改訂2026-07-28を尋ねるかどうかの切り替えです。legacyは尋ねない、autoは尋ねる対象を広げる設定で、未設定でもHTTP、stdio、claude.aiコネクタには尋ねます。症状が出たら、legacyで起動して比べる1手で、原因が交渉にあるかどうかを分けられます。

この記事を共有:XはてブLinkedIn