fix: restore globalThis.Response after lazy-loading MCP SDK#148
Open
br-schneider wants to merge 1 commit intovercel:mainfrom
Open
fix: restore globalThis.Response after lazy-loading MCP SDK#148br-schneider wants to merge 1 commit intovercel:mainfrom
br-schneider wants to merge 1 commit intovercel:mainfrom
Conversation
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. Lazy-loading alone (as proposed in vercel#141) only delays the problem. Once the MCP endpoint is hit, the global Response is replaced and all subsequent requests to any route handler fail. This fix: - Converts eager SDK imports to type-only imports - Adds a loadSdk() function that dynamically imports SDK modules - Saves globalThis.Response before import, restores it after - Defers StreamableHTTPServerTransport creation to first request - Calls loadSdk() at the start of mcpApiHandler Fixes vercel#140
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The
@modelcontextprotocol/sdkhas transitive dependencies (via undici) that replaceglobalThis.Responsewhen imported. This breaks Next.js App Router route handlers which validate responses withinstanceof 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.Responseis permanently replaced. All subsequent requests to any route handler in the same Node.js process then fail theinstanceof Responsecheck.We verified this on Vercel production:
Fix
This PR:
McpServer,SSEServerTransport,StreamableHTTPServerTransport) to type-only importsloadSdk()function that dynamically imports SDK modules at first useglobalThis.Responsebefore the import and restores it after, so that other route handlers continue to pass Next.js'sinstanceof ResponsevalidationStreamableHTTPServerTransportcreation to first request (instead of module load time)loadSdk()at the start ofmcpApiHandlerKey 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
should read server capabilitiesis unrelated to this change)Fixes #140