AI

MCP TypeScript SDK v2とは?パッケージ分割とステートレス化の移行要点

MCP TypeScript SDKのv2は、単一の@modelcontextprotocol/sdkを畳み、@modelcontextprotocol/serverと@modelcontextprotocol/clientという別名のパッケージ群へ分かれました。npmのメタデータでは2.0.0が2026年7月27日23時55分(UTC)に公開済みで、すでにベータ段階ではありません。この記事ではパッケージ構成と前提条件、2026-07-28仕様に対応するAPI、codemodによる移行手順、v1据え置きが妥当な条件を実装目線で整理します。MCP自体の仕組みはMCP(Model Context Protocol)の標準規格としての役割を先に押さえておくと読みやすくなります。

まとめ|v2は別名パッケージへの移植であり、v1据え置きも成立する

v2はバージョン番号の更新ではなく、パッケージ名そのものが変わる移植です。v1の@modelcontextprotocol/sdkは1.30.0が公開されたまま非推奨の印も付いておらず、名前が違うため両者は同じpackage.jsonに共存できます。「v2が出たから上げる」ではなく、2026-07-28仕様を配信する必要があるかで決めます。

移行の価値があるのは、ステートレスなHTTP配信で水平に並べたい場合、Mcp-Methodヘッダでルーティングしたい場合、長時間ストリームなしでユーザー入力を挟むツールを作りたい場合の3つです。逆にNode 18固定の基盤、SSEServerTransport依存のクライアント群、SDKをpeerDependencyで公開しているライブラリのいずれかなら、据え置きが合理的です。

v2のパッケージ分割とNode 20・zod 4という前提条件の整理

v1は依存を1パッケージへ抱え込む構成でしたが、v2はサーバー実装・クライアント実装・スキーマ定数・フレームワーク接続を切り出しました。

@modelcontextprotocol/sdkから分かれた5系統のパッケージ構成

v2の全パッケージは@modelcontextprotocolスコープ配下にあります。以下はスコープを省いた表記です。

パッケージ 担当範囲 7月30日時点
server サーバー実装とHTTP入口 2.0.0
client クライアントとOAuth 2.0.0
core 公開Zodスキーマ定数 2.0.0
core-internal 非公開・直接importしない 未公開
アダプタ4種 既存HTTP基盤への接続 2.0.0
server-legacy 凍結版SSEと認可サーバー 移行用

アダプタ4種の実体は@modelcontextprotocol/node、同/express、同/hono、同/fastifyです。v2のアダプタはフレームワーク側をpeerDependencyとして宣言するため、express本体は自分でインストールします。core-internalは非公開で、型やエラークラスはserverかclientから受け取ります。

Node 20以上・ESM優先とCommonJS併載という実行環境の条件

engines表記はnode >=20で、v1の1.30.0はnode >=18でした。Node 18で固定された基盤はここで止まります。モジュール形式は二次情報に「ESM専用」と残っていますが、実際のパッケージメタは違いました。2.0.0のexportsにはimport条件とrequire条件の両方が入り、mainにはdist/index.cjsが指定されています。beta.1はimportだけでCommonJSから読めず、beta.5以降でmainに.cjsが現れました。効くのはテスト環境です。Jestのようにrequireで解決するランナーでも、moduleNameMapper回避を外せます。

2.0.0安定版が公開された時点とbeta系からの主な変更差分

npm registryのtimeフィールドでは、server・client・coreとも2.0.0が7月27日23時55分(UTC)に公開されています。日本時間なら7月28日の朝で、2026-07-28仕様の確定と同じタイミングです。系列はalpha.4が6月30日、そこからbeta.1からbeta.5を経て安定版へ至りました。移植に響く差分は、スキーマ定数の実体が@modelcontextprotocol/coreへ集約された点、serverInfoが応答の_metaへ移った点、ワイヤスキーマ構築が遅延化され事前構築にはpreloadSchemasが要る点の3つです。alphaでワイヤ専用メンバーを直接読んでいたコードは手直しが必要になります。

zod 4系への依存とzod 3固定環境で起きるバンドル増加

serverとclientはzod ^4.2.0に依存します。v1はzod 3系と4系の両方を許すpeer範囲だったため、zod 3をホイストしたワークスペースでも重複しませんでした。v2では重複排除が効かず、各パッケージが自分の下にzod 4のコピーを抱えます。公式ガイドは大規模なSPAでの実測として、zod 3のままclientとserverを追加するとJS全体がgzipで約83KB(全体比約0.7%)増えたという記載です。zodをパスの部分一致で拾うmanualChunksは、ネストしたコピーも先読みチャンクへ引き込みます。zod ^4.2.0へ上げれば重複が消えるため、移行と同時にzodを上げる順序が手戻りを減らします。

2026-07-28仕様のステートレス設計とv2実装の対応関係

前提として、v2へ上げただけでは2026-07-28のバイトはワイヤに出ません。手で組んだClientやMcpServerは、書かれた通りの2025年系プロトコルを話し続けます。新仕様の配信は常に明示的なオプトインです。

initializeハンドシェイク廃止とdiscoverへの機能一覧取得の移行

2026-07-28仕様では初期化ハンドシェイクが消え、機能一覧はserver/discoverで取得します。リクエストが自己記述的なので、どのインスタンスが処理してもかまいません。入口はClientOptionsのversionNegotiationで、modeにautoを指定すると探りを入れ、2025年系のみのサーバーなら従来のハンドシェイクへ落ちます。決着した世代はgetProtocolEraで読めます。癖があるのは失敗時の扱いです。HTTPの401や403は世代の証拠として扱われず、typedな認可失敗としてconnectが拒否されます。stdioでは探り専用に使い捨ての兄弟プロセスを起動します。初期化前の未知リクエストで終了する実装への配慮です。

セッションIDに代わるrequestStateの署名付き受け渡し

2026-07-28仕様はリクエスト単位で、Mcp-Session-Idがありません。v1でセッションIDを鍵に状態を持っていたサーバーは、requestStateへ置き換えます。クライアントがそのまま送り返す不透明な文字列で、読み出しはctx.mcpReq.requestStateで行います。間違えやすいのは信頼境界で、クライアントを経由して戻る値は信頼できない入力です。createRequestStateCodecに鍵とTTLを渡すとmintとverifyの対が返り、mintはJSONをHMAC-SHA256で封印し、verifyはrequestState.verifyへ割り当てます。署名であって暗号化ではないため、秘密を詰めてはいけません。検証に失敗した再入は、ツールの手前で-32602として弾かれます。

サーバーからクライアントへの要求を畳み込むinputRequiredの往復

2026-07-28仕様では、サーバーからクライアントへ向かうJSON-RPC要求チャネルが撤去されました。ユーザーへの問いかけ(elicitation)やモデル呼び出し(sampling)は、tools/callのハンドラからinputRequiredを返し、クライアントが同じ呼び出しを応答付きで再送する形へ変わります。クライアント側は既定で自動充足し、登録済みのハンドラで応答を作り、requestStateの完全一致エコーを添えて再送します。上限はmaxRoundsの既定10ラウンドです。2025年系の接続には互換シムが実際のサーバー発要求へ変換するため、世代の分岐は要りません。

Mcp-Method系ヘッダとttlMs必須化というHTTP層の変更

ゲートウェイがJSON本文を解析せずに振り分けられるよう、Streamable HTTP上にMCP-Protocol-Version、Mcp-Method、Mcp-Nameの3つの標準ヘッダが加わりました。createMcpHandlerは新仕様の経路でこれらを本文と突き合わせ、不一致なら400とJSON-RPCの-32020(HeaderMismatch)で拒否します。x-mcp-headerを指定した引数はMcp-Param-{Name}ヘッダへ写されますが、資格情報付きCORSで動的な名前を許可一覧へ載せられないため、ブラウザのクライアントは写し込みを行いません。キャッシュ側ではttlMsとcacheScopeが必須化され、既定は0とprivateです。方針はcacheHintsで与えます。詳細はMCPの新トランスポートであるStreamable HTTPとSSEの違いを押さえておくと整理しやすくなります。

codemodによるv1からv2への移行手順と手作業が残る領域

名前が変わる移植なので、import文の書き換え量は多くなります。公式はts-morphベースのcodemodを用意しており、機械的に決まる対応は自動で当たります。

codemod実行の正しい起点とpackage.jsonまで含む書き換え範囲

起点を間違えると効果が半分になります。公式ガイドはパッケージルート、つまりカレントディレクトリを対象に実行するよう指示しています。srcだけを渡すのは誤りです。package.jsonの依存関係も書き換え、testやscriptsからもSDKをimportしているためです。

  1. Node 20以上を用意する(前提確認)
  2. パッケージルートでcodemodのv1-to-v2を実行する
  3. @mcp-codemod-errorをgrepし、自動化できなかった箇所を洗い出す
  4. tsc –noEmit で型エラーを潰す
  5. フォーマッタをかける(codemodは整形しない)
  6. テストを実行する

当たる範囲はimportパスの付け替えに留まりません。McpErrorからProtocolErrorへの改名、setRequestHandlerの第1引数をメソッド文字列へ変える書き換え、extraからctxへの再割り当て、toolからregisterTool系への書き換えまで含みます。モノレポで書き換わるマニフェストは、上へ辿って最初の1つだけです。

@mcp-codemod-errorマーカーが残る手作業対応の代表例

安全に書き換えられなかった箇所には、@mcp-codemod-errorのコメントが差し込まれます。手作業が残る代表格は次の通りです。

  • ヘッダの読み出し。Headersへ改名されるが、ブラケット参照をget呼び出しへ直すのは手作業
  • OAuthのエラークラス統合。InvalidGrantErrorの判定をOAuthErrorとOAuthErrorCodeの組へ寄せる
  • 名前空間import経由のスキーマ参照。@modelcontextprotocol/coreから手で再import
  • SDKの型を引数で受け取るだけでimportを持たないファイル。codemodは到達しない

タスク機能はSEP-2663で削除され、GetTaskRequestSchemaを渡していた登録は診断として残ります。v2は.mjsと.cjsをdist直下へ並べるため、distを正規表現で読む自作ツールも壊れます。

SSEServerTransport廃止とStreamable HTTPへの寄せ方

SSEServerTransportは削除され、移行先はStreamable HTTPになりました。暫定の橋渡しとしてserver-legacyのsseサブパスに凍結版が置かれています。WebSocketClientTransportも仕様外という理由で消えました。codemodはNodeStreamableHTTPServerTransportへ改名しますが、Cloudflare WorkersやDeno、BunのようなWeb標準ランタイムならWebStandardStreamableHTTPServerTransportを選びます。判断はハンドラの入出力で決まり、NodeのIncomingMessageを受け取るなら前者、Web標準のRequestを受けてResponseを返すなら後者です。

v1とv2を同時導入する段階移行の手順と越えてはいけない境界

大きめのコードベースでは一括置換を避けられます。パッケージ名が違うので同居できるためです。安全な順序は、v2とzodの引き上げを先に入れてv1を残し、ディレクトリ単位で書き換え、誰もv1をimportしなくなってから依存を外す流れです。逆順にすると、書き換え前のimportがすべてTS2307で解決不能になります。越えてはいけない境界も1つあります。v1とv2のモジュールはクラスも型も別物で、instanceof判定も名前的な型検査も両者を跨ぎません。分割はプロセス境界かトランスポート境界で行い、共有をワイヤ形式だけに限定してください。

Go・C#・Python各SDKとの実装差と言語選定時の判断材料

2026-07-28仕様に向けたベータは4つのTier 1 SDKで同時に出ましたが、7月30日時点の成熟度は揃っていません。

Go SDK・C# SDK・Python版との版番号と移行負荷の差

言語 新仕様対応の版 7月30日時点
TypeScript server・client 2.0.0 安定版
Python mcp 2.0.0b1 ベータ
Go v1.7.0-pre.1 プレリリース
C# 2.0.0-preview.1 プレビュー

この非対称は選定に効きます。新仕様のステートレス配信を今期のプロダクトへ入れるなら、正式版のTypeScriptが最も摩擦の少ない選択です。GoならMCP Go SDKの環境構築と事前準備で押さえたv1系の作法がまだ現役で、プレリリース版を本番へ入れる判断は別途必要です。.NET側もMCP C# SDK v1.0と2025-11-25仕様準拠の全体像で扱った構成がしばらく安定運用の基準になります。Python版はFastMCPでMCPサーバーを構築する手順のとおりパッケージ名がmcpのままで、変更の主体はimportパスとAPI形状です。フレームワーク側のFastMCP 4は4.0.0b1というベータ段階で、PyPIの安定版は3系のままです。TypeScript版だけは名前そのものが変わるため、依存ピンのlintやCIのチェックが文字列として@modelcontextprotocol/sdkを持っていると差し替え後に落ちます。

既存Node資産の有無で変わるTypeScript版採用の妥当性

実務的な分かれ目は、既存のNode資産をどれだけ持っているかです。ExpressやFastify、Honoで動くAPIがあるなら、v2のアダプタで既存アプリの1エンドポイントとしてMCPを載せられます。専用サーバーを別に立てる必要はありません。逆にNodeの運用実績がない組織が新仕様のためだけにTypeScriptを選ぶと、ESMとCommonJSの混在、zodのメジャー差、Node 20への引き上げを同時に抱えます。Nodeの運用体制がなくMCPサーバーの設計と実装を外へ出す前提なら、生成AI開発・AI受託開発のように運用まで委託できる体制と自社で持つ範囲を先に切り分けておくと見積りがぶれません。

v2へ今すぐ移行する条件と、v1に据え置くべき現場の判断基準の整理

v2の公開は済んでいますが、全案件が今上げるべきだとは考えません。

2026-07-28仕様を今すぐ配信する必要がある案件の条件

次の3つのどれかに当たるなら、移行を先送りする理由はありません。1つ目は、クライアントが新仕様を固定で要求してくる場合です。versionNegotiationでpin指定を受けると、2025年系のみのサーバーへの接続はEraNegotiationFailedで拒否され、フォールバックが働きません。2つ目は、サーバーレスやエッジで水平にスケールさせたい場合です。セッションIDが消えるため、セッションアフィニティ前提のルーティングを捨てられます。3つ目は、問いかけを挟むツールを長時間の接続保持なしで作りたい場合です。逆にステートレス化もヘッダルーティングも使わず、stdioでローカル起動するツールを配るだけなら書き換えコストに見合いません。

v1に据え置くほうが正解になる3つの条件と移行を見送る判断基準

次の3条件は、新仕様の機能要求がない限り据え置きを選びます。第1にNode 18で固定された実行基盤です。v2のenginesはnode >=20なので、ランタイムを上げられないなら選択肢に入りません。第2にSSEServerTransport前提のクライアント群を抱えている場合です。server-legacyで延命はできますが、Streamable HTTPへ寄せる工事の先送りで、v2の利得を相殺します。第3にSDKをpeerDependencyとして公開しているライブラリです。ピア宣言の差し替えは利用者にとって破壊的変更であり、semverのメジャー更新として出す必要があります。どれにも当たらないなら判断は「急がない」で、四半期の計画へ組み込みます。

移行で失敗する典型パターンとリリース前に必ず確認すべき項目の整理

公式ガイドが警告する失敗形は、どれも踏みやすいものです。

  • codemodをsrcだけに当て、上位のマニフェストが書き換わり段階移行が崩れる
  • ホストのv1 SDKを型解決している社内パッケージの接点にcodemodを当て、実行時に落とす
  • v1時代のダブルキャストを残したまま移行し、v2の型で検出できたエラーを抑制し続ける

リリース前の確認は4点です。src配下の外まで含めた@modelcontextprotocol/sdkのgrep、tsc –noEmitの通過、moduleNameMapperの削除、バンドル予算でネストしたzodを除外できているかを見ます。導入判断そのものはMCPサーバーの役割と標準規格としての仕組みが整理に使えます。

よくある質問

移行判断でよく問われる論点を、npmのパッケージメタと公式ガイドの記載に沿って整理します。

v1の@modelcontextprotocol/sdkはもう使えなくなりますか?

いいえ。1.30.0が2026年7月27日に公開されており、npm上に非推奨の印は付いていません。名前が別なので同じpackage.jsonに同時に置けます。ただしv1側とv2側のオブジェクトを行き来させると、instanceof判定が通らなくなります。

v2はCommonJSのプロジェクトでも使えますか?

使えます。2.0.0のexportsにはrequire条件があり、mainに.cjsが指定されています。beta.1はimport条件だけだったため、その時期の情報に基づく「ESM専用」という記述は現状と合いません。Jestのようなランナーでも、moduleNameMapper回避を外せます。

Node 18のままでv2を動かせますか?

公式にはサポートされません。v2のenginesはnode >=20で、公式ガイドもNode 20以上を前提に求めています。v1の1.30.0はnode >=18なので、ランタイムを上げられない基盤ではv1に留まる判断です。移行計画では、Nodeの引き上げを先行タスクに分けます。

v2に上げるだけで2026-07-28仕様を話すようになりますか?

なりません。手で組んだClientやMcpServerは、2025年系プロトコルを話し続けます。新仕様の配信はHTTPならcreateMcpHandler、stdioならserveStdio、クライアント側はversionNegotiationという明示的なオプトインが必要です。検証では、どちらへ落ちたかをgetProtocolEraで確認します。

codemodを流すだけで移行は完了しますか?

完了しません。codemodは一意に決まる書き換えだけを当て、判断が必要な箇所には@mcp-codemod-errorのコメントを残します。手作業が残るのは、Headersのブラケット参照をgetへ直す作業、OAuthエラークラスの統合、SdkErrorCodeの分岐選択などです。実行後はgrepと型チェック、テストの順で確認します。

関連記事

資料請求

RELATED POSTS 関連記事