Serve MCP protocol revision 2026-07-28 only, single lane [worker, bridge, deps, docs, tests] - #229
Conversation
…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>
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
github-rag-mcp | fe9f057 | Aug 06 2026, 10:47 AM |
liplus-lin-lay
left a comment
There was a problem hiding this comment.
AI self-review(親、execution_mode = auto)
head fe9f057 に対して実施。基準 = issue #224 本文 + PR diff + CI 結果。担当の報告は根拠に用いず、以下はすべて親が実読・実行して確認した。
受け入れ条件の照合
| #224 の受け入れ条件 | 判定 | 親の確認方法 |
|---|---|---|
| Worker が 2026-07-28 のみを提供し、旧仕様レーンを持たない | pass | src/index.ts:96 の legacy: "reject"。SDK 側の型定義を実読し意味を確認(下記) |
| ブリッジが新仕様で疎通し、Desktop に対しては従来どおり | pass | mcp-server/package.json は SDK v1 を保持、remote-client.js が @modelcontextprotocol/client@2.0.0 を 2026-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が一度も送られない- 全リクエストの
_metaがprotocolVersion: "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 の阻却要因ではない)
wrangler.tomlのMCP_OBJECTバインディングが退役スタブRagMcpAgentV2を指したまま。deleted_classesmigration を伴わない削除は不可のため、現状が安全側。整理は別 issuedocs/0-requirements.mdに、過去のリリースで削除済みのツールの記述が残存。本 PR 以前からの陳腐化npm audithigh 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。
Closes #224
何をしたか
Worker とブリッジのクライアント面を、MCP プロトコル版 2026-07-28(ステートレスコア)へ同一 PR で切り替えた。互換レーンは実装していない(決定 1)。
Worker (
src/)RagMcpAgentV2.serve("/mcp")をagents/mcp/serverのcreateMcpHandlerへ置換。legacy: "reject"を指定しており、単レーンという決定がそのままコードの literal になっている。2025 系の request(initializeを含む)は、endpoint が提供する唯一の版を名指しした unsupported-protocol-version エラーで返る。src/mcp.tsはMcpAgentを継承した DO クラスから、リクエスト毎に MCP サーバーを組み立てる factorycreateRagMcpServer(env)へ。server.tool()はserver.registerTool()へ移行(schema はz.object()で包んだ、同一の 16 params)。index.tsが従来どおりctx.propsを書き換え、handler がそれをリクエスト毎の auth context として再公開し、tool 側はgetMcpAuthContext()で読む。this.propsに相当するインスタンス状態は無くなった。envごとに WeakMap で memo 化。factory が bindings を要るのにenvはfetchの中にしか無いため、module scope では作れない。RagMcpAgent/RagMcpAgentV2)はsrc/retired-do.tsへ分離した。過去 migration が名指しするクラスはスクリプト内に存在せねばならないという Cloudflare の制約のため export だけ残す。撤去にはdeleted_classesmigration が要るので別件。実データを持つIssueStoreは無変更(制約どおり)。src/mcp.tsからcloudflare:workersimport を消し、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と同じ理由・同じ手当て。authProviderに繋ぎ直しただけ。依存
agents0.19.0 → 0.20.1、@modelcontextprotocol/serverを exact2.0.0で追加。agents が非 optional peer として exact 2.0.0 を要求するため、caret にすると spec(deps): decide version alignment policy for @modelcontextprotocol/sdk #227 が問題にしていた二重コピーを再現してしまう。exact なら agents の bump が install 時に失敗する(= tsc まで持ち越さない)。@modelcontextprotocol/client/server2.0.0 の本番投入は決定 3(2026-08-06 go-sign)に基づく。agents 0.20.x はこの 2 つを静的 import するので、入れずに 0.20.x を採る道は無い。@modelcontextprotocol/sdk依存宣言を削除した。Worker はもう SDK v1 を一切 import しない。agents の必須 peer として npm が入れるが、こちら側にレンジが無いので agents の exact pin と食い違いようがない。spec(deps): decide version alignment policy for @modelcontextprotocol/sdk #227 が「spec: MCP 2026-07-28 migration plan - single-lane flip, no dual-lane fallback #224 で消滅する」と書いていた状態にそのまま到達している — spec(deps): decide version alignment policy for @modelcontextprotocol/sdk #227 を閉じるかは親の判断に委ねる。@modelcontextprotocol/sdkを保持したまま、@modelcontextprotocol/clientを追加。@cloudflare/workers-typesの pin は lockfile の実測で確認した。作業前4.20260404.1→node_modulesと lock を捨ててnpm installで再生成した後も4.20260404.1。spec(deps): decide version alignment policy for @modelcontextprotocol/sdk #227 が懸念していた「lock 再生成で崩れる」経路を実際に通して確認している。検証
tsc --noEmit/ rootnpm test(216) /check-schema-drift/ mcp-servernpm test(11) /wrangler deploy --dry-run。src/mcp-stateless-contract.test.ts。 ブリッジの実クライアント(remote-client.js)と Worker の実ハンドラ配線を in-process で接続し、次を検証する。mcp-session-idヘッダは一切無いinitializeを送らない(pin された modern endpoint への connect はserver/discoverで始まる)_metaにio.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 に触れるため、デプロイ後の実機確認に回る。リリース
minor。
rules/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