Problem
The @modelcontextprotocol/sdk has transitive dependencies (via undici) that replace globalThis.Response when imported. This breaks Next.js App Router route handlers which validate responses with instanceof Response, causing "No response is returned from route handler" errors for all routes in the same process — not just the MCP endpoint.
Why lazy-loading alone isn't enough
PR #141 proposed lazy-loading the SDK, which delays the import until the first MCP request. However, once the MCP endpoint is hit and the SDK loads, globalThis.Response is permanently replaced. All subsequent requests to any route handler in the same Node.js process then fail the instanceof Response check.
We verified this on Vercel production:
# Before MCP route is hit — works fine
curl /api/deployment-status → 200 ✓
# Hit MCP route — triggers SDK load
curl /api/connect/sse → 200 ✓
# After MCP SDK loaded — broken!
curl /api/deployment-status → 500 ✗ "No response is returned"Fix
This PR:
- Converts eager SDK value imports (
McpServer,SSEServerTransport,StreamableHTTPServerTransport) to type-only imports - Adds a
loadSdk()function that dynamically imports SDK modules at first use - Saves
globalThis.Responsebefore the import and restores it after, so that other route handlers continue to pass Next.js'sinstanceof Responsevalidation - Defers
StreamableHTTPServerTransportcreation to first request (instead of module load time) - Calls
loadSdk()at the start ofmcpApiHandler
Key insight
The critical difference from #141 is step 3 — saving and restoring globalThis.Response. Without this, the SDK's side effect persists across the entire process.
Testing
- All existing tests pass (29/30 — the 1 pre-existing failure in
should read server capabilitiesis unrelated to this change) - Verified on Vercel production that routes return correct responses both before and after the MCP endpoint is called
Fixes #140