feat(mcp): upgrade generated servers to SDK v2

TH
6d ago
+4770-1462

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, and mount entrypoints.
  • 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 --check passed.
  • 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.json and src/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.