MCP 2026-07-28 の Beta SDK — ステートレス化の破壊的変更を本番前に通す

AI・テック動向

MCP 2026-07-28 の Beta SDK — ステートレス化の破壊的変更を本番前に通す

initialize ハンドシェイクが消える。MCP(Model Context Protocol)の2026-07-28仕様は、プロトコルからセッションの概念を外し、各リクエストを自己記述的にする。前回の当サイト記事でステートレス化の全体像を追った続報として、今回はBeta SDKが出揃った段階を使い、自作MCPサーバの移行が実際に何を壊すのかを手を動かして確かめる。

目次
  1. 何が起きたのか
  2. 旧仕様と新仕様はどう違うのか
  3. 移行で何が壊れて、何が楽になるか
  4. 後方互換があるので、一気に切らなくていい
  5. 自作サーバ2本に、実際に通してみた
    1. まず、いま何を話しているのか
    2. capabilities を見れば、壊れる範囲が絞れる
    3. 改名で触る行は4行だった
    4. ピン留めする版が、もう安定版になっていた
  6. 開発者としての実践ポイント
  7. 移行前によく出る疑問
  8. まとめ

何が起きたのか

公式ブログの投稿は6月29日。SDK Betas for the 2026-07-28 spec で、Tier-1の4言語すべてのBeta SDKが公開された。Python mcp v2.0.0b1、TypeScript v2、Go v1.7.0-pre.1、C# 2.0.0-preview.1。最終仕様の公開は2026年7月28日を予定していて、現時点ではRC相当の位置づけになる。確定リリースではない点は最初に押さえておきたい。

自作のMCPサーバを本番で回している人ほど、7月28日という日付が重く見えるはず。ハンドシェイクが消えると聞いて、まず気になるのは「うちのサーバは当日いきなり動かなくなるのか」だろう。結論を先に置くと、後方互換があるので当日いきなり全滅する設計にはなっていない。何もしないで済む話でもなく、Betaで壊れる箇所を今のうちに一つずつ潰せるかどうかで、当日の落ち着き方が変わる。

柱はステートレス化だ。旧仕様では、クライアントとサーバが最初に initialize をやり取りしてプロトコルレベルのセッションを張り、そのセッションの上で以降のリクエストが流れていた。新仕様はこのハンドシェイクとセッションを廃止する。各リクエストが自分の文脈を丸ごと抱える形になり、サーバの capabilities は server/discover で取りに行く。

これは破壊的変更だ。

効いてくるのは運用面だ。セッション状態を持たないので、どのサーバインスタンスが任意のリクエストを処理してもよい。ロードバランサの背後に同じMCPサーバを何台も並べ、素直なラウンドロビンで捌ける。特定クライアントを特定インスタンスへ固定するスティッキーセッションの設定が要らなくなる。この一点だけでも、コンテナで水平スケールさせている環境には効く。

旧仕様と新仕様はどう違うのか

移行の設計をする前に、差分を一枚で見渡しておく。

観点 旧(ステートフル:initialize+セッション) 新(ステートレス:自己記述)
接続開始 initialize ハンドシェイクでセッション確立 ハンドシェイクなし。各リクエストが自己完結
capabilities取得 initialize の応答に同梱 server/discover で個別取得
リクエストの性質 セッション文脈に依存 自己記述的(単体で処理可能)
負荷分散 スティッキーセッション前提 ラウンドロビン可。どのインスタンスでも処理可
ルーティング セッションIDで対応付け ヘッダ Mcp-Method / Mcp-Name で振り分け
リソース未検出のエラー JSON-RPC -32002 JSON-RPC -32602 に標準化

エラーコードの変更は地味だが見落としやすい。missing resource が旧 -32002 から -32602(invalid params 系)へ寄せられた。クライアント側でエラーコードを分岐に使っている実装は、ここでリソース未検出の分岐が死ぬ。ハンドリングを数値決め打ちで書いていた箇所は洗い出しておく。

ルーティングの発想も変わる。セッションIDでインスタンスに結びつけていた対応付けが消え、代わりに Mcp-MethodMcp-Name のヘッダでリクエストを振り分ける。プロキシやAPIゲートウェイでメソッド単位・ツール単位の振り分けを書けるので、重いツールだけ別プールへ逃がすといった制御がインフラ層で完結する。セッション固定の設定を外せるぶん、ここの設計はむしろ楽になる。

対話系の追加も入った。Multi Round-Trip Requests で、ツールが処理の途中に InputRequiredResult を返し、ユーザーへ追加入力を問い返せる。認可の追加確認や、不足パラメータの補完を一往復で挟めるようになる。

問い返しの形はこうなる。ツールが最終結果の代わりに InputRequiredResult を投げ、クライアントへ追加入力を促す。

# Multi Round-Trip:処理の途中で追加入力を求める(形のイメージ)
from mcp.types import InputRequiredResult

@app.tool()
def deploy(target: str):
    if target == "production":
        return InputRequiredResult(
            prompt="本番へ反映します。確認コードを入力してください。"
        )
    return run_deploy(target)

接続を切って張り直す往復を挟まず、単発リクエストの中で対話の一往復を完結させられる。ステートレス化と噛み合う仕組みで、認可の再確認をツールの内側に閉じ込められる。

移行で何が壊れて、何が楽になるか

Pythonから見ると、破壊の実体は改名に集約される。エントリポイントの FastMCPMCPServer になった。ツール定義のデコレータまわりの書き味は近いので、まずはimportとクラス名の置換から入れる。

# v1(2025-11-25 仕様)
from mcp.server.fastmcp import FastMCP

app = FastMCP("weather")

@app.tool()
def get_forecast(city: str) -> str:
    return fetch(city)
# v2.0.0b1(2026-07-28 仕様)
from mcp.server import MCPServer

app = MCPServer("weather")

@app.tool()
def get_forecast(city: str) -> str:
    return fetch(city)

Beta は明示的にピン留めして入れる。安定版の依存に混ざって勝手に上がると事故になる。

# Python: Beta を明示ピン留め
pip install "mcp==2.0.0b1"

重いのはTypeScriptだ。単一パッケージだった @modelcontextprotocol/sdk が廃止され、機能ごとの分割パッケージに再編された。ESM専用になり、対応ランタイムはNode 20以上。スキーマ検証はStandard Schemaに寄せられた。CommonJSのまま動かしているプロジェクトや、Node 18で止めている環境は、SDKの入れ替えだけで済まず、モジュール形式とランタイムの移行がセットで乗ってくる。require ベースのビルド設定、__dirname の扱い、テストランナーのESM対応まで芋づるで確認が要る。

GoはBeta前段の v1.7.0-pre.1、C#は 2.0.0-preview.1。認可まわりは6本のSEPでOAuth/OIDCが強化された。筆者は以前、EVEダッシュボードでOAuth2/PKCEのトークン自動リフレッシュを実装したとき、リフレッシュの失敗時に無限リトライへ落ちる罠を踏んだことがある。認可の仕様が動く更新では、正常系より失敗系のテストを先に置くほうが安全だと考えている。

後方互換があるので、一気に切らなくていい

ここが今回いちばんの安心材料だ。v2サーバはレガシーの initialize にも応答する。2025-11-25 仕様のクライアントは、v2サーバに対して従来通り接続を維持できる。サーバを先に新仕様へ上げ、クライアント群を後から順に移す段階移行が成立する。

「サーバとクライアントを同時に切り替える」ビッグバン移行を強いられないので、本番の停止ウィンドウを取らずに進められる。まずサーバをv2化してレガシー応答で既存クライアントを生かし、疎通を確認しながらクライアントを一つずつ新仕様に寄せていく。この順番なら、どこかで壊れても切り戻す先が残る。

自作サーバ2本に、実際に通してみた

当サイトの運用で使っている自作の MCP サーバは2本ある。文字起こしの whisper-mcp と、X検索・YouTubeチャット収集の scraper-mcp。どちらも Python の mcp パッケージで書いて stdio で動かしている。この2本に何が起きるかを手元で確かめた。

まず、いま何を話しているのか

両サーバを起動して、クライアント側から protocolVersion: "2026-07-28" を要求する initialize を投げた。

// 送ったもの
{"method":"initialize","params":{"protocolVersion":"2026-07-28"}}

// 返ってきたもの(whisper-mcp / scraper-mcp とも同じ形)
{"protocolVersion":"2025-11-25",
 "serverInfo":{"name":"whisper-mcp","version":"1.28.1"},
 "capabilities":{"experimental":{},
   "prompts":{"listChanged":false},
   "resources":{"subscribe":false,"listChanged":false},
   "tools":{"listChanged":false}}}

新仕様を要求しても 2025-11-25 が返る。入っている SDK が mcp 1.28.1 で、まだ 2026-07-28 を話さないからだ。ネゴシエーションが働いて旧仕様へ落ちている。

serverInfo.version1.28.1 なのは想定していなかった。pyproject.toml に書いた版は 0.1.0 で、そちらは出ていない。FastMCP は SDK の版を serverInfo に入れる。クライアント側でサーバの版を見て分岐しているなら、見ているのは自分のサーバの版ではない。

capabilities を見れば、壊れる範囲が絞れる

返ってきた capabilities に、移行の見積もりがそのまま出ていた。

項目 実測値 移行への影響
resources.subscribe false 購読を使っていない。セッション廃止の影響を受けない
listChanged(3箇所とも) false 動的なリスト変更通知を出していない
ツール構成既に同型 start / status / result / cancel 新仕様の Tasks と同じジョブ方式

2本とも5ツールで、時間のかかる処理を *_start でジョブ化し、*_status で進捗を返し、*_result で取りに行く形にしてある。文字起こしが数分かかるので、接続を張り続けない設計を先に選んでいた。新仕様の Tasks は、この形を標準化したものになる。手元にある仕組みを仕様の名前へ置き換えるだけで足りそうだ。

改名で触る行は4行だった

ここまでで移行の影響が小さいことは見えたので、実際に書き換える行を数えた。2本のソースを FastMCP で grep する。

whisper_mcp/server.py:100  from mcp.server.fastmcp import FastMCP
whisper_mcp/server.py:103  mcp = FastMCP("whisper-mcp")
scraper_mcp/server.py:73   from mcp.server.fastmcp import FastMCP
scraper_mcp/server.py:76   mcp = FastMCP("scraper-mcp")

実コードは4行だった。ツール定義のデコレータはどちらも @mcp.tool() のままで、触る必要がない。ステートレス化で消える機能を一つも使っていなかったので、破壊の実体はこの4行に収まっている。

この結果はサーバの作りに依存する。購読やサンプリングを使っていれば話は変わる。capabilities を1回取れば、自分がどちら側かは数秒で分かる。移行計画を立てる前に、まずこれを取るのが早い。

ピン留めする版が、もう安定版になっていた

上で mcp==2.0.0b1 のピン留めを書いた。2026年7月31日に PyPI を見に行ったら、2.0.0 が安定版として出ていた

2.0.0a1 → 2.0.0a2 → 2.0.0a3 → 2.0.0b1 → 2.0.0b2 → 2.0.0rc1 → 2.0.0

いま入れるなら 2.0.0b1 を指定する理由はない。未検証: 筆者の2本はまだ 1.28.1 のままで、2.0.0 へ上げて動かすところまでは確かめていない。上の4行を置換した後に何が出るかは、実際にやってから書く。

開発者としての実践ポイント

  1. 最終仕様の7月28日を待たず、いまBeta SDKで自作サーバを新仕様に通し、単発リクエストで疎通だけ先に取る。仕様確定前でも壊れる箇所は今の実装で洗い出せる。
  2. Pythonは FastMCPMCPServer の改名を起点に、import・クラス名・ツール定義の順で置換する。バージョンは mcp==2.0.0b1 でピン留め。
  3. TypeScriptはSDK入れ替えを、ESM移行・Node 20以上・Standard Schema対応と一つの作業単位として計画する。CommonJS前提の設定は先に棚卸しする。
  4. クライアントのエラーハンドリングで、リソース未検出を -32002 決め打ちにしている箇所を -32602 に直す。数値で分岐している場所を全部grepする。
  5. サーバを先にv2化し、レガシー initialize 応答で既存クライアントを生かしたまま、クライアントを段階移行する。実績のある旧経路をフォールバックとして残す。

仕様そのものの全体像は前回まとめた。MCP 2026-07-28ステートレス仕様の詳細(続報の元記事)を先に読むと、今回の移行手順が追いやすい。

移行前によく出る疑問

いま移行すべきか。最終仕様が7月28日から動く可能性は残るが、破壊箇所の洗い出しはBetaで先にやっておく価値がある。仕様確定を待つほど、まとめて直す作業が本番直前へ寄っていく。筆者なら、コードを書き換えるかは仕様確定後に決め、疎通と壊れ方の確認だけ今のBetaで済ませておく。

既存クライアントは壊れるのか。v2サーバがレガシー initialize に応答するかぎり、2025-11-25 仕様のクライアントはそのまま生き残る。壊れるのは、サーバとクライアントを同時に新仕様へ振り切ったとき。段階移行の順番を守れば、どこかの時点で必ず旧経路が残っている。

ESM専用化はどこに効くのか。TypeScript SDKだけの話で収まらない。require で読み込んでいたビルド設定、__dirname を前提にしたパス解決、ESM未対応のテストランナーまで巻き込む。Node 18で止めている環境は、SDK差し替えにランタイム更新が同時に乗ってくると見積もっておきたい。

まとめ

破壊的変更を本番前に確かめるなら、筆者は7月28日の最終仕様を待たず、Beta SDKで自作MCPサーバを新仕様に通し、単発で疎通確認してからフォールバックを用意する。

この順番を徹底しているのには理由がある。筆者は過去に、廃止予定のAPIを検証しないまま全経路へ入れて、切り替え当日に全滅させた。以後は「単発の疎通確認を先に取り、実績のある経路をフォールバックに残す」を固定の手順にしている。今回のステートレス化は運用側に効く良い変更だが、initialize廃止もTypeScriptのESM移行も、当日に初めて触ると事故る種類の変更だ。後方互換が段階移行を許してくれる今のうちに、壊れる箇所を一つずつ本番外で潰しておく。

CodeQL 2.26.0 でプロンプトインジェクション検出 — LLMアプリをCIで守るCodeQL 2.26.0 でプロンプトインジェクション検出 — LLMアプリをCIで守る前のページ

Claude Code デスクトップ版に内蔵ブラウザ — 実画面で確かめる相棒次のページClaude Code デスクトップ版に内蔵ブラウザ — 実画面で確かめる相棒

ピックアップ記事

  1. Claude Mission Control の作り方 — Tauri+Pyth…

  2. New Eden Intelligence Hub の作り方 — EVE Onl…

  3. 高精度OCRデスクトップアプリの作り方 — PaddleOCR-VLとPyIns…

  4. 競艇予想AIの作り方 — LightGBMで「当たる順位」を学習させる実装ガイド…

関連記事

  1. Python 3.15 RC 目前と Pyrefly 1.0 — 毎キーストロークで走る型チェッカを mypy と比べる
  2. 「Opus級」の実像 — Grok 4.5 はベンチ4位、それでも $2/$6 が効く用途
  3. Google Chirp 3: Transcription が GA — 話者分離・多言語ASRと自作Whisperの使い分け

    AI・テック動向

    Google Chirp 3: Transcription が GA — 話者分離・多言語ASRと自…

    Chirp 3 が一般提供になり話者分離と自動言語検出に対応。fast…

  4. GPT-5.6 Sol/Terra/Luna が Copilot に — 従量課金で3層を使い分ける
  5. WordPressの管理画面に出ないバックドア — mu-pluginsを狙う7月の攻撃と、自分のサイトを実測点検する手順

    AI・テック動向

    WordPressの管理画面に出ないバックドア — mu-pluginsを狙う7月の攻撃と、自分のサ…

    2026年7月、管理画面のプラグイン一覧に表示されない mu-plug…

注目

AIで、ここまで作れる

AIで作った2D RPGを、ブラウザでそのまま遊べます。その「作り方=最後まで完成させる進め方」も実例つきで公開中。

▶ ゲームを遊ぶやり方を読む

PR

ロリポップ!レンタルサーバー(PR)

レンタルサーバ:ロリポップ!(本サイトの稼働環境・PR)

  1. ブラウザゲームを自動テスト&デプロイ⑥|puppeteerヘッドレス検証と静的配信【Archipelago Saga制作・完結】

    アプリの作り方

    ブラウザゲームを自動テスト&デプロイ⑥|puppeteerヘッドレス検証と静的配…
  2. バイブコーディングのやり方 — AIで「動くアプリ」を最後まで完成させる進め方を、実例7本で全部見せる

    バイブコーディング

    バイブコーディングのやり方 — AIで「動くアプリ」を最後まで完成させる進め方を…
  3. 壊れないようにアプリを育てる|機能追加・役割分け・動作確認の習慣【入門6】

    バイブコーディング

    壊れないようにアプリを育てる|機能追加・役割分け・動作確認の習慣【入門6】
  4. 背景除去アプリの作り方 — PyQt6+ONNX(BiRefNet)でローカル完結の透過ツールを作る

    アプリの作り方

    背景除去アプリの作り方 — PyQt6+ONNX(BiRefNet)でローカル完…
  5. 都市開発シミュを作る④|4度つまずいて座標系ごと作り直した話 — 真のアイソメグリッド移行【Aurum City制作】

    アプリの作り方

    都市開発シミュを作る④|4度つまずいて座標系ごと作り直した話 — 真のアイソメグ…
PAGE TOP

TAG CLOUD

ドラッグで回転・クリックでそのタグの記事一覧へ