Skip to content

Serve MCP protocol revision 2026-07-28 only, single lane [worker, bridge, deps, docs, tests] - #229

Merged
liplus-lin-lay merged 1 commit into
mainfrom
224-spec-mcp-2026-07-28-migration-plan-single-lane-flip-no-dual-lane-fallback
Aug 6, 2026
Merged

Serve MCP protocol revision 2026-07-28 only, single lane [worker, bridge, deps, docs, tests]#229
liplus-lin-lay merged 1 commit into
mainfrom
224-spec-mcp-2026-07-28-migration-plan-single-lane-flip-no-dual-lane-fallback

Conversation

@liplus-lin-lay

Copy link
Copy Markdown
Member

Closes #224

何をしたか

Worker とブリッジのクライアント面を、MCP プロトコル版 2026-07-28(ステートレスコア)へ同一 PR で切り替えた。互換レーンは実装していない(決定 1)。

Worker (src/)

  • RagMcpAgentV2.serve("/mcp")agents/mcp/servercreateMcpHandler へ置換。legacy: "reject" を指定しており、単レーンという決定がそのままコードの literal になっている。2025 系の request(initialize を含む)は、endpoint が提供する唯一の版を名指しした unsupported-protocol-version エラーで返る。
  • src/mcp.tsMcpAgent を継承した DO クラスから、リクエスト毎に MCP サーバーを組み立てる factory createRagMcpServer(env) へ。server.tool()server.registerTool() へ移行(schema は z.object() で包んだ、同一の 16 params)。
  • ユーザー同一性はリクエスト毎の OAuth props から取る。index.ts が従来どおり ctx.props を書き換え、handler がそれをリクエスト毎の auth context として再公開し、tool 側は getMcpAuthContext() で読む。this.props に相当するインスタンス状態は無くなった。
  • handler は env ごとに WeakMap で memo 化。factory が bindings を要るのに envfetch の中にしか無いため、module scope では作れない。
  • 退役した DO クラス(RagMcpAgent / RagMcpAgentV2)は src/retired-do.ts へ分離した。過去 migration が名指しするクラスはスクリプト内に存在せねばならないという Cloudflare の制約のため export だけ残す。撤去には deleted_classes migration が要るので別件。実データを持つ IssueStore は無変更(制約どおり)。
    • 分離は同時に src/mcp.ts から cloudflare:workers import を消し、node pool でのテストを可能にしている。

ブリッジ (mcp-server/)

  • 手書きハンドシェイク(getSessionId / initialize + mcp-session-id ヘッダ)を削除し、@modelcontextprotocol/client@2.0.0 を版 2026-07-28 に pin した client へ置換。Worker は他の版を拒否するので、探索しても成功し得ない分岐が増えるだけであり、pin が正しい。
  • クライアント面の構築とキャッシュを server/remote-client.js に分離した。index.js は import 時に stdio transport を繋いでしまうためテストから触れない。tools.js と同じ理由・同じ手当て。
  • Claude Desktop に対する面は SDK v1 / 2025 系のまま(制約どおり。移行は spec: decide the bridge stdio side when Claude Desktop ships 2026-07-28 #228)。
  • OAuth の一式(PKCE / localhost callback / token 保存 / 401 再認証)は既存のまま。transport の authProvider に繋ぎ直しただけ。

依存

検証

  • CI 相当を全部ローカルで通した: tsc --noEmit / root npm test (216) / check-schema-drift / mcp-server npm test (11) / wrangler deploy --dry-run
  • 新規: src/mcp-stateless-contract.test.ts ブリッジの実クライアント(remote-client.js)と Worker の実ハンドラ配線を in-process で接続し、次を検証する。
    • connect も含め全て POST、mcp-session-id ヘッダは一切無い
    • initialize を送らない(pin された modern endpoint への connect は server/discover で始まる)
    • 全 request が _metaio.modelcontextprotocol/protocolVersion: "2026-07-28" と clientCapabilities を載せている
    • 旧ブリッジ相当の initialize は 400 / -32022 / supported: ["2026-07-28"] で拒否される
    • search の 16 params が modern wire 越しに publish される(drift-check はソース文字列の比較なので、登録とシリアライズを実際に通す軸は別途要る)
  • 検証できていないのは tools/call の実行経路。Vectorize / Workers AI / D1 の binding に触れるため、デプロイ後の実機確認に回る。

リリース

minorrules/operations/release-version-rule.md の「構造変更 かつ user/system observable」に該当する(旧ブリッジが実際に壊れる)。README 注意書きは本 PR に含む。

破壊的変更の告知

README.md / README.ja.md / mcp-server/README.md に、この版から Worker が新仕様のみを提供すること、旧ブリッジは動作しないこと(落ち方が静かなことも)、Claude Desktop の再起動でブリッジ更新が要ること、版を pin していると再起動しても復旧しないことを明記した。mcp-server README の Troubleshooting にも同じ導線を足している。要求仕様(en/ja)には単レーンの決定とその理由、ステートレス化の帰結を記録した。

🤖 Generated with Claude Code

…er, bridge, deps, docs, tests]

Worker とブリッジのクライアント面を、MCP プロトコル版 2026-07-28
(ステートレスコア)へ同一 PR で切り替える。互換レーンは実装しない。

Worker side:
- `RagMcpAgentV2.serve("/mcp")` を agents の `createMcpHandler` へ置換し、
  `legacy: "reject"` を指定。旧版の request は unsupported-protocol-version
  エラーで返り、互換レーンは存在しない。
- `src/mcp.ts` は McpAgent 継承の DO クラスから、リクエスト毎に MCP サーバーを
  組み立てる factory `createRagMcpServer(env)` へ。ユーザー同一性は
  `getMcpAuthContext()` 経由でリクエスト毎の OAuth props から取る。
- 退役した DO クラス 2 つは `src/retired-do.ts` へ分離。過去 migration の
  制約で export だけ残す。実データを持つ `IssueStore` は無変更。

Bridge side (mcp-server/):
- 手書きハンドシェイク(`initialize` + `mcp-session-id`)を削除し、
  `@modelcontextprotocol/client@2.0.0` を版 2026-07-28 に pin した client へ
  置換。クライアント面の構築は `server/remote-client.js` に分離し、テスト
  可能にした。Claude Desktop に対する面は SDK v1 のまま(#228 の範囲)。

Deps:
- `agents` 0.19.0 -> 0.20.1、`@modelcontextprotocol/server` を 2.0.0 で exact
  pin(agents の非 optional peer が exact 2.0.0 のため)。
- Worker が SDK v1 を import しなくなったので、root の
  `@modelcontextprotocol/sdk` 依存宣言を削除。#227 が追っていた二重コピー問題は
  ここで消滅する。`@cloudflare/workers-types` の pin は lock 再生成後も
  4.20260404.1 のまま維持されることを確認済み。

Tests / docs:
- `src/mcp-stateless-contract.test.ts` を追加。ブリッジの実クライアントと
  Worker の実ハンドラを in-process で接続し、セッション不使用・envelope 付与・
  旧ブリッジの拒否・search スキーマの publish を検証する。
- README / mcp-server README / 要求仕様(en/ja)に破壊的変更の注意書きを追加。
  旧ブリッジは動作せず、Claude Desktop の再起動で追随が要る旨を明記。

Refs #224

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
✅ Deployment successful!
View logs
github-rag-mcp fe9f057 Aug 06 2026, 10:47 AM

@liplus-lin-lay liplus-lin-lay self-assigned this Aug 6, 2026

@liplus-lin-lay liplus-lin-lay left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AI self-review(親、execution_mode = auto)

head fe9f057 に対して実施。基準 = issue #224 本文 + PR diff + CI 結果。担当の報告は根拠に用いず、以下はすべて親が実読・実行して確認した。

受け入れ条件の照合

#224 の受け入れ条件 判定 親の確認方法
Worker が 2026-07-28 のみを提供し、旧仕様レーンを持たない pass src/index.ts:96legacy: "reject"。SDK 側の型定義を実読し意味を確認(下記)
ブリッジが新仕様で疎通し、Desktop に対しては従来どおり pass mcp-server/package.json は SDK v1 を保持、remote-client.js@modelcontextprotocol/client@2.0.02026-07-28 に pin
README に破壊的変更の注意書き pass README.md / README.ja.md / mcp-server/README.md の 3 本すべてに節を確認。版 pin 利用者は再起動でも復旧しない旨まで書かれている
CI green pass CI / test / Workers Builds すべて pass、mergeStateStatus: CLEAN

単レーン決定がコードの literal になっている点(本 PR の中核)

legacy オプションを SDK の型定義で実読した:

legacy?: 'stateless' | 'reject'
'reject' — modern-only strict: legacy-classified requests are rejected with
the unsupported-protocol-version error naming the endpoint's supported
revisions. **There is no 2025 serving in this mode.**

SDK は 2025 系フォールバックを提供する選択肢を持っており、本 PR はそれを明示的に断っている#224 決定 1(互換レーンを実装しない)が、コメントではなくオプション値として定着した形。後から「フォールバックを足し忘れた」ではなく「足さないと決めた」ことが読み取れる。

新規テストの評価

src/mcp-stateless-contract.test.ts はブリッジの実クライアントと Worker の実ハンドラをプロセス内で結線し、以下を assert している:

  • initialize が一度も送られない
  • 全リクエストの _metaprotocolVersion: "2026-07-28" を運ぶ
  • mcp-session-id ヘッダが存在しない
  • flip 前のブリッジが -32022 + supported: ["2026-07-28"] で拒否される

最後の 1 本が特に効く。本 PR の破壊的変更の中身そのものを、回帰として固定している。加えて 16 パラメータの search スキーマが新しい線上で生き残ることも検証しており、これは従来 drift-check がソース文字列比較しかしていなかった軸を埋めている。

scope 逸脱と、その判定

package.json から @modelcontextprotocol/sdk の宣言を削除した点は issue の対象ファイル記述を超えて見えるが、逸脱ではないと判定する。agents@0.20.1 が同パッケージを exactly 1.30.0 の必須 peer として要求するため、ルート側にレンジを残すと install が通らない。Worker はもう SDK v1 を import しないので、宣言を持たない状態が正しい。判断理由が package.json の comments に残されている点も可。

残件(親が別 issue として処理する。本 PR の阻却要因ではない)

  1. wrangler.tomlMCP_OBJECT バインディングが退役スタブ RagMcpAgentV2 を指したまま。deleted_classes migration を伴わない削除は不可のため、現状が安全側。整理は別 issue
  2. docs/0-requirements.md に、過去のリリースで削除済みのツールの記述が残存。本 PR 以前からの陳腐化
  3. npm audit high 5 件(すべて devDependency の toolchain)。本 PR 前は 13 件で、むしろ減っている

#227 の扱い

本 PR により package.json から SDK v1 のレンジ宣言が消えたため、#227^1.0.0 と agents の exact pin が偶然一致している状態)の前提が消滅した。#227 自身が制約に「SDK が v2 系へ移ると本問題は消滅する」と書いており、その到達点に達している。親が close する。

検証範囲の限界(記録)

担当の報告どおり、tools/call の実行経路(Vectorize / Workers AI / D1 バインディング)と mcp-server/ の実クライアント到達は、in-session では検証できていない。前者は merge 後のデプロイで実機確認が可能。後者は npm リリース + Claude Desktop の完全再起動を要する(webhook-mcp#247 の実測)。この PR の実機確認は Worker 半分までしか届かないことを明記しておく。

次の段階

auto モードにつき human gate なし。self-review pass -> merge。merge 後に Worker 側の実機確認を実施する。リリース版種は minor(構造変更かつ user/system observable = 旧ブリッジが実際に壊れる)。リリース実行は human gate。

@liplus-lin-lay
liplus-lin-lay merged commit 7e77474 into main Aug 6, 2026
3 checks passed
@liplus-lin-lay
liplus-lin-lay deleted the 224-spec-mcp-2026-07-28-migration-plan-single-lane-flip-no-dual-lane-fallback branch August 6, 2026 10:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

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

1 participant