feat(mcp): upgrade generated servers to SDK v2
TH
6d ago+4770+4770+0123456789012345678901234567890123456789-1462-1462-0123456789012345678901234567890123456789
Why
Upgrade generated MCP servers to the stable v2 SDK while preserving existing clients, legacy transports, and extension entrypoints.
What changed
- Use MCP server/client/server-legacy 2.3.1 and Node adapter 2.1.1. Require Node.js 20, or 22.18 for Gram-enabled servers, while preserving stricter custom engine constraints.
- Keep Node and Cloudflare SSE available. Cloudflare retains stateful legacy Streamable HTTP sessions alongside modern HTTP, including its Durable Object bindings and
serve,serveSSE, andmountentrypoints. - Allow both compatible Worker-types major versions so clean installs resolve the current Wrangler peer dependency.
- Preserve session-opening credentials for legacy clients, isolate concurrent request credentials, and keep authenticated Worker props authoritative.
- Preserve standalone and optional TypeScript extension callback aliases such as
extra.signal, v1 resource-template registration, and cancellation guards. Retain SDK 1.32.1 for existing extension imports alongside the v2 server packages. Keep optional MCP SDKs on root Zod 3 while the v2 dependencies use their own Zod 4. - Preserve schema defaults, transforms, validation, prompt completions, and Gram/eval integrations. Distinguish schema input and output types, honor JSON Schema dialects, and preserve tuple and recursive-reference constraints. Fix transport-specific setup links, authentication headers, and supported Node HTTP parameter overrides while retaining legacy SSE header aliases, authentication defaults, DELETE preflights, and graceful HTTP shutdown.
- Keep package metadata, tool declarations, and stdio options compatible with custom edits during regeneration. Create fresh stdio servers when modern discovery falls back to legacy initialization.
- Add regression coverage, regenerate the MCP review SDK, and include major changesets for the Node runtime requirement.
Testing
- Standalone MCP primary suite: 336 passed.
- Optional TypeScript MCP tertiary suite: 414 passed, one skipped.
- Schema/extension scratch matrix: 185 passed; generated CLI cases also pass in the permanent suite.
- Real stdio and HTTP clients using legacy and modern protocols, concurrent calls, cancellation, malformed input, and recovery. Both HTTP protocol eras pass the in-flight shutdown regression.
- Miniflare legacy SSE/session, authentication isolation, and custom Worker entrypoint checks; Node 20 transport checks; Node 22 Gram/eval checks.
- Clean Cloudflare dependency install and type-check with Wrangler 4.148.0 and Worker types 5.20261007.1.
- Wrangler deployment dry-run and Gram packaging checks. No deployment performed; physical Worker disconnect behavior still requires deployed verification.
- Neutral three-way merge checks preserve custom package metadata, tool annotations, and stdio options. Both generated CLIs cover modern discovery followed by legacy initialization; custom stdio options and startup hooks survive the regeneration merge.
- Full repository lint and
git diff --checkpassed. - Generated MCP and TypeScript snapshot outputs reviewed; no unrelated production model or SDK method changes were found. Earlier package metadata, tool annotation, Zod, and stdio regeneration regressions now pass their snapshots.
- One customized snapshot retains explicit SDK dependency pins and an adjacent custom import that conflict with this upgrade. That snapshot requires manual reconciliation in
package.jsonandsrc/mcp-server/cli/serve/impl.ts; aggregate CI success does not establish compile success for it. Isolated copies pass type-checking, lint, bundling, stdio initialization/tool discovery, HTTP initialization, and the custom route after resolving only those conflict blocks. Existing baseline failures were checked against their actual diagnostics. A separate stale running indicator was verified as a successful compile/lint from the job log.
Public-safety check
- This change contains no credentials, customer documents, private repository URLs, private filesystem paths, or unredacted private logs.
- Title, body, comments, and commit messages name no customers or customer-derived identifiers, private paths or trackers, or workflow provenance, and are understandable without private context (
.claude/skills/public-repo-communication/SKILL.md). - Generated fixtures and review SDK changes are public-safe.
- I reviewed
git diff --check.