Skip to content

spec: MCP 2026-07-28 migration plan - single-lane flip, no dual-lane fallback #224

Description

@liplus-lin-lay

目的

github-rag-mcp の Worker を MCP 仕様 2026-07-28(ステートレスコア)へ移行する。
互換レーンを持たない 単レーン一括切替とし、破断の吸収はコードではなく minor リリース + README 注意書きで行う。

前提

依存の現在地

  • Worker = agents@0.19.0 + @modelcontextprotocol/sdk@1.29.0chore(deps): bump agents to 0.19.0, the last beta-free line #225 / chore(deps): bump agents to 0.19.0, the last beta-free line [deps, mcp] #226 で引き上げ済み、LATEST_PROTOCOL_VERSION = 2025-11-25)。McpAgent.serve("/mcp") による Streamable HTTP
  • 新仕様の SDK は別パッケージへ分割。@modelcontextprotocol/server@2.0.0 / @modelcontextprotocol/client@2.0.0(2026-07-28 公開、beta 初版)
  • agents@0.20.0 以降が v2 beta を非 optional な必須 peerとして要求し、dist/mcp/index.js が静的 import する。0.19.0 が beta を踏まない最終版
  • agents@0.20.1McpAgent は deprecated / feature-frozen。移行先は createMcpHandler

経路の実測(重要 — 当初の前提を訂正する)

mcp-server/server.json"transport": { "type": "stdio" } のみを宣言し、npm / npx パッケージだけを配布している。リモートトランスポートの宣言は無い。 したがって全利用者が npx ブリッジ経由で Worker に到達する。

ブリッジは二面を持ち、両面は独立している:

実装
Claude Desktop に対してサーバー SDK v1 stdio (new Server) 2025-11-25 まで
Worker に対してクライアント mcp-server/server/index.js:354 の手書き fetch 2024-11-05 を宣言

Worker のプロトコル版は、本 repo の 2 成果物のあいだの私的な契約である。 Claude 側の対応状況は Worker 側移行の条件ではない。

Claude Desktop 側の実測(別軸の記録)

  • インストール実体 Claude_1.25927.0.0(リリース 2026-08-04、仕様公開の 7 日後)
  • バンドル内 LATEST_PROTOCOL_VERSION = "2025-11-25"
  • バンドル内に "2026-07-28" の文字列は存在しない(grep ヒット 0)
  • 同版の変更履歴に MCP プロトコル関連の項目なし(ただし版引き上げは利用者非可視のため、履歴の不在は単独では弱い根拠。バイナリ側の直接観測が主)

これは Desktop ↔ ブリッジ間の移行条件であり、本 issue(Worker ↔ ブリッジ間)の条件ではない。

決定 1 — 互換レーンを実装しない

Cloudflare は「ステートレス経路を既存 McpAgent 経路と並走させ、クライアントが移りセッションが枯れるまで待つ」手順を推奨しているが、採用しない。

理由:

  1. 保守されないフォールバック経路は放置され死にコード化する。rules/model/subtractive-structural-beauty.md が禁じる「念のため残す」に該当する
  2. 畳む条件が観測可能(旧レーンへの到達がゼロになる)であっても、観測できることと観測しに行くことは別。運用上、外す判断は忘れられる
  3. 破断の吸収は、コードではなく版とドキュメントという別チャネルで行う(決定 2)

先例(Cloudflare の推奨手順)は採用理由にならない。上記が本体。

決定 2 — 破断の扱い: minor リリース + README 注意書き

何が壊れるか

Worker がステートレス化した時点で、旧ブリッジ(initialize + mcp-session-id 前提)は動作しなくなる。

旧ブリッジの動作 新 Worker での結果
1 POST /mcpmethod: "initialize" メソッドが存在しない → エラー
2 レスポンスヘッダから mcp-session-id を取得 ヘッダが返らない → _sessionId = ""
3 tools/call に session ヘッダを付与 _meta にプロトコル版が無い → UnsupportedProtocolVersionError

落ち方は静か。ブリッジは JSON-RPC エラーをツール出力テキストとして返すため、クラッシュせず「エラー文字列を返すツール」になる。

非対称の所在

  • Worker = 全員共有の 1 デプロイ。一斉に飛ぶ
  • ブリッジ = 利用者ごと。各自の Claude Desktop 再起動で追随する(#247 / #248 で実測・文書化済: @latest 指定でも起動済みプロセスは古い版を保持する

版を固定している外部利用者は再起動しても復旧しない。この層の切り捨てを受け入れるというのが本決定。

吸収チャネル

  • minor リリースrules/operations/release-version-rule.md の「構造変更 かつ user/system observable → minor」に該当(旧ブリッジが実際に壊れる = 観測可能)。v0.x のため破壊的変更を minor に載せることは規定内
  • README 注意書きREADME.md および mcp-server/README.md に、この版から Worker が新仕様のみを提供すること、旧ブリッジは動作しないこと、Claude Desktop の再起動でブリッジを更新する必要があることを明記する(#248 が追加した再起動導線と同じ場所)

決定 3 — beta の本番投入を受け入れる(2026-08-06、Master go-sign)

@modelcontextprotocol/server / client 2.0.0 はリリースノート上 "First beta release of SDK v2" と記載されるが、npm の latest タグで公開されている。着手時点で本番投入を受け入れる判断を取った。

技術的に塞いでいるものは無い、というのが着手前の確認結果:

  • Claude 側の対応は Worker 側移行の条件ではない(経路の実測、上記)
  • 旧リビジョンに廃止期限は無い
  • beta は「本番に入れたくない」という運用基準の問題であり、不可能ではない

制約

  • Worker とブリッジのクライアント面は同一 PR / 同一リリースで出す。 片方だけ先に出すと破断窓が伸びる。これが本 issue の最重要制約
  • 既存の Durable Object を全部畳むのではない。McpAgent が担っていた 2 役のうちセッション ID からのインスタンス解決だけが消える。ユーザー同一性はリクエストごとの OAuth props から取る形へ移す。実データを保持する DO(store 系)は別 DO であり、そのまま残す
  • mcp-server/ のブリッジは Desktop に対して SDK v1 / 旧仕様のままであること。変更するのは Worker に向けたクライアント面だけ。Desktop 側の移行は spec: decide the bridge stdio side when Claude Desktop ships 2026-07-28 #228 の範囲
  • リリースは minor。README 注意書きを同一 PR に含める(決定 2)
  • Desktop ↔ ブリッジ間の移行は本 issue の範囲外(spec: decide the bridge stdio side when Claude Desktop ships 2026-07-28 #228

対象ファイル

  • package.json / package-lock.jsonagents を 0.20.x へ、@modelcontextprotocol/server を追加。@modelcontextprotocol/sdk の扱いは spec(deps): decide version alignment policy for @modelcontextprotocol/sdk #227 の方針判断と衝突しないこと
  • src/index.tsRagMcpAgentV2.serve("/mcp")createMcpHandler ベースへ。OAuth 層との接続(ctx.props の受け渡し)が変わる
  • src/mcp.tsMcpAgent を継承した DO クラスから、リクエストごとに MCP サーバーを組み立てる factory へ
  • mcp-server/server/index.js — 手書きハンドシェイク(getSessionIdWithToken 系、initialize + mcp-session-id)の削除と、新仕様クライアントへの置き換え
  • README.md / mcp-server/README.md — 破壊的変更の注意書き
  • docs/ — 要求仕様の更新(実装と同一 PR。分割禁止)

受け入れ条件

  • Worker が 2026-07-28 のみを提供し、旧仕様のレーンを持たない
  • ブリッジが新仕様で Worker と疎通し、Desktop に対しては従来どおり動作する
  • README に「この版から旧ブリッジは動作しない / Claude Desktop の再起動でブリッジ更新が要る」旨が書かれている
  • CI green + デプロイ後の実機確認(ブリッジ経由でツールが応答すること)

仕様側の期限との関係

deprecated レジストリ 6 件のうち本 repo に該当するのは Dynamic Client Registration のみ/oauth/register, RFC 7591、@cloudflare/workers-oauth-provider 経由)。最短撤去 = 2027-07-28 以降の最初のリビジョン、移行先 = Client ID Metadata Documents。OAuth 周辺を触る本移行に相乗りさせる。

該当しないもの: Roots / Sampling / Logging / includeContext(未使用)、HTTP+SSE トランスポート(serve() 既定が transport: "streamable-http" のため未露出)。

「最短撤去」は撤去が可能になる時点であり、実際の撤去は Core Maintainer 判断でそれ以降にずれうる。仕様からの撤去は SDK に削除義務を課さない。

関連

参照

Metadata

Metadata

Assignees

No one assigned

    Labels

    done役目完了、orchestration (review / merge / close) フェーズ待ちready本文が実装開始できる形まで収束している状態。ただし更新は継続可能specLi+の挙動に影響する仕様・ポリシー・定義

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions