feat: serve modern MCP with a stateless SDK v2 handler#176
Merged
Conversation
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.
Summary
2.0.0-beta.2to the latest published2.0.0-beta.4createMcpHandler(factory)directly from@modelcontextprotocol/server2026-07-28from a fresh server per request while retaining the SDK's default stateless 2025 compatibility pathEach authenticated request creates a TypeScript SDK handler whose factory closes over its validated
AuthProps, preserving the explicitprops -> createServer(props)data flow used before this migration. No Node ambient types,AsyncLocalStorage, or implicit global auth state is required.One response-shaping detail is intentional: ordinary modern requests return JSON under the SDK's
responseMode: "auto"; claimless stateless 2025 requests use the upstream SSE response shape. Both paths issue noMcp-Session-Id.Validation
npm cinpm run check— 17 test files / 289 testsnpm ls @modelcontextprotocol/server @modelcontextprotocol/client @modelcontextprotocol/core --depth=1npm audit --omit=dev— 0 vulnerabilitiesCoverage includes modern discovery/list/call, Code Mode and non-Code-Mode dispatch, concurrent auth and factory isolation, stateless 2025 fallback, GET/DELETE rejection, OAuth-issued tokens, Host/Origin rejection, and CORS preflights.
Production rollout
Deployed from runtime commit
ba95888:bca4d618-2eab-429b-a62a-71623c98c55e/mcpguard: pass (401)204)403)server/discover: pass, no session IDtools/list: pass, no session IDexecuteread (GET /user): passget_user: pass405)The Wrangler token was read in-memory for smoke tests and was not printed or persisted.