Skip to content

Migrate to MCP SDK v2 with dual-era HTTP support - #208

Open
rgarcia wants to merge 3 commits into
mainfrom
hypeship/mcp-sdk-v2-migration
Open

rgarcia wants to merge 3 commits into
mainfrom
hypeship/mcp-sdk-v2-migration

Conversation

@rgarcia

@rgarcia rgarcia commented Sep 21, 2026

Copy link
Copy Markdown
Contributor

Summary

Depends on #211, which maps dev MCP discovery to the dev OAuth issuer. This PR contains only the SDK migration diff on top of that mapping.

Serve protocol revision 2026-07-28 and legacy 2025 Streamable HTTP clients at the same /mcp endpoint using the stock SDK v2 createMcpHandler (default stateless legacy fallback). No custom wire-compatibility layer or Tasks extension.

  • Pin @modelcontextprotocol/{server,core,client} to 2.0.0; migrate registration APIs, request contexts, and schemas to Zod 4. Preserve vault validation-error redaction through Standard Schema.
  • Replace mcp-handler with the SDK's Web Request/Response handler. Keep Clerk JWT verification, API-key validation, project scoping, entitlement checks, and OAuth challenges before passing verified authInfo to the SDK.
  • Remove @clerk/mcp-tools, used only for protected-resource metadata. Keep canonical discovery locally; use the same public origin for authorization metadata so v2 issuer validation works even when Next normalizes loopback URLs.
  • Preserve signed session/capability markers for legacy clients; use per-request capabilities and no session header for modern clients. Upgrade PostHog to 0.17.0, preserve the privacy allowlist, and disable newly default-on model/conversation parameters.

mcp-handler now has a v2 release, but the direct SDK handler avoids an unnecessary adapter. Clerk's latest MCP helper still depends on v1; removing its metadata-only use does not require replacing Clerk authentication. The v1 SDK remains a dev dependency only, for client interoperability tests.

Migration plan

  1. Move all tools, prompts, and resources to v2 registration/context APIs without changing their operations.
  2. Mount the stock dual-era handler behind existing authentication; separate legacy session metadata from modern per-request metadata.
  3. Verify both SDK client generations over HTTP, including OAuth, errors, capability isolation, and result envelopes; document intentional wire differences.

No server-initiated elicitation was found, so there is no MRTR flow to port. No tools declare an outputSchema; explicit content arrays, managed-auth structured content, and existing result formats are retained. The SDK supplies modern resultType rather than application code stamping it.

Behavior changes for legacy clients

Compatibility means usable clients, not identical wire bytes. The isolated SDK 1.26.0 → 2.0.0 HTTP probes recorded:

Case Before After
Unknown tool missing result: {content: [{type: "text", text: "MCP error -32602: Tool missing not found"}], isError: true} error: {code: -32602, message: "Tool missing not found"}
Invalid echo.text argument isError text with the MCP error -32602: prefix and serialized Zod issues isError text without that prefix, with a concise field-path message
Tool catalog Draft-07 schema representation and execution.taskSupport: "forbidden" JSON Schema 2020-12 representation, no obsolete execution field

Ordinary successful text-tool response bytes matched in that probe. The checked-in tests assert usable results/errors, not error wording: both clients handle unknown-tool JSON-RPC rejection and successfully call another tool afterward. Separate tests exercise 2025-03-26 and 2025-06-18 requests. The supported transport remains /mcp Streamable HTTP; the removed adapter's deprecated HTTP+SSE wiring is not retained.

Existing App consumer note: the managed-auth App handles both isError and rejected calls. Its wait loop retries rejected calls, whereas an isError stops it. If manage_auth_connections disappears during an open flow, an unknown-tool rejection therefore takes the existing retry path. The tool is always registered when the launcher is available. No unknown-tool special case was added.

Validation

  • Before migration: 660 existing tests passed. The four v1 HTTP/OAuth/App scenarios also passed against the original application checkout, with the original unknown-tool result expectation.
  • After migration: 679 tests passed, including v1 SDK and pinned-modern v2 SDK clients using the same running route. Covers API keys, discovery, registration, PKCE/state, token exchange/refresh, fixed-project scope, invalid credentials, real manage_projects calls, business/upstream/validation/unknown-tool errors, prompts, resources, Apps, and CORS/header validation.
  • bunx tsc --noEmit --incremental false, production bun run build with placeholder build-time client IDs and Clerk keys, managed-auth generated-bundle check, frozen install, and Prettier on changed TS/JSON files passed. Tests also passed with CI's Bun 1.3.3.
  • OAuth integration tests stub external Clerk services, Redis storage, and Kernel API responses; they run the real route/OAuth handlers and SDK clients, including locally signed JWT verification. A live hosted Clerk login was not performed.

Full diff self-reviewed and deslopped. Generated App assets are unchanged; unrelated lockfile version churn was removed.

@vercel

vercel Bot commented Sep 21, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
mcp Ready Ready Preview Sep 22, 2026 9:26pm UTC
mcp (staging) Ready Ready Preview Sep 22, 2026 9:26pm UTC

@socket-security

socket-security Bot commented Sep 21, 2026

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Added@​modelcontextprotocol/​client@​2.0.0951008490100
Added@​modelcontextprotocol/​server@​2.0.01001008591100
Added@​modelcontextprotocol/​core@​2.0.01001008590100
Addedzod@​4.3.610010010095100
Updated@​posthog/​mcp@​0.10.1 ⏵ 0.17.0100 +2110099 +1100 +1100

View full report

@rgarcia
rgarcia force-pushed the hypeship/mcp-sdk-v2-migration branch from 57a099c to 347062f Compare September 22, 2026 21:08
@rgarcia
rgarcia changed the base branch from main to hypeship/dev-mcp-oauth-discovery September 22, 2026 21:08
@rgarcia
rgarcia added this pull request to stack #212 September 22, 2026 21:08
Base automatically changed from hypeship/dev-mcp-oauth-discovery to main September 22, 2026 21:25

This branch was successfully deployed

2 active (1 outdated) deployments
staging cd572796 Deployed Sep 22, 2026 by vercel[bot]
Preview 57a099cb Deployed Sep 21, 2026 by vercel[bot]
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.

1 participant