Skip to content

fix(server): set Allow: POST on stateless legacy 405 responses - #3002

Open
Hugo-DDT wants to merge 2 commits into
modelcontextprotocol:mainfrom
Hugo-DDT:fix/stateless-405-allow-header
Open

Hugo-DDT wants to merge 2 commits into
modelcontextprotocol:mainfrom
Hugo-DDT:fix/stateless-405-allow-header

Conversation

@Hugo-DDT

Copy link
Copy Markdown

Motivation and Context

Fixes #2970.

createMcpHandler's legacy stateless fallback answers non-POST requests with 405 Method not allowed but omits the Allow header. RFC 9110 §15.5.6 requires Allow on 405 responses. WebStandardStreamableHTTPServerTransport.handleUnsupportedRequest() already sets Allow: GET, POST, DELETE; the stateless fallback only accepts POST, so it should advertise Allow: POST.

How Has This Been Tested?

  • Extended the existing 405 cases in legacyStatelessFallback.test.ts and createMcpHandler.test.ts to assert Allow: POST.
  • Confirmed the new assertions fail on unmodified main and pass with this change.
  • Ran the full createMcpHandler + legacyStatelessFallback suites (61 tests).
  • pnpm --filter @modelcontextprotocol/server typecheck and lint passed.
  • Pre-push hook ran repo-wide build, typecheck, and lint successfully.

Breaking Changes

None. Adds a response header on an existing 405 path; status and JSON-RPC body are unchanged.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository style guidelines
  • New and existing tests pass locally
  • I have added tests that prove my fix is effective
  • I have checked my changes for security concerns including secrets and unsafe parsing

AI assistance

This change was prepared with AI assistance (Grok Bot). I reviewed the diff, ran the tests above, and take responsibility for the content.

createMcpHandler's legacy stateless fallback answered non-POST requests
with 405 without an Allow header. RFC 9110 §15.5.6 requires Allow on 405,
and WebStandardStreamableHTTPServerTransport.handleUnsupportedRequest
already sets it. Stateless serving only accepts POST, so advertise that.

Closes modelcontextprotocol#2970

Assisted-by: AI (Grok Bot)
@Hugo-DDT
Hugo-DDT requested a review from a team as a code owner October 11, 2026 12:33
Copilot AI balanced review requested due to automatic review settings October 11, 2026 12:33
@changeset-bot

changeset-bot Bot commented Oct 11, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 0a2a5d9

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 6 packages
Name Type
@modelcontextprotocol/server Patch
@modelcontextprotocol/client Patch
@modelcontextprotocol/codemod Patch
@modelcontextprotocol/core Patch
@modelcontextprotocol/server-legacy Patch
@modelcontextprotocol/core-internal Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@pkg-pr-new

pkg-pr-new Bot commented Oct 11, 2026 •

Copy link
Copy Markdown

Open in StackBlitz

@modelcontextprotocol/client

npm i https://pkg.pr.new/@modelcontextprotocol/client@3002

@modelcontextprotocol/codemod

npm i https://pkg.pr.new/@modelcontextprotocol/codemod@3002

@modelcontextprotocol/core

npm i https://pkg.pr.new/@modelcontextprotocol/core@3002

@modelcontextprotocol/server

npm i https://pkg.pr.new/@modelcontextprotocol/server@3002

@modelcontextprotocol/server-legacy

npm i https://pkg.pr.new/@modelcontextprotocol/server-legacy@3002

@modelcontextprotocol/express

npm i https://pkg.pr.new/@modelcontextprotocol/express@3002

@modelcontextprotocol/fastify

npm i https://pkg.pr.new/@modelcontextprotocol/fastify@3002

@modelcontextprotocol/hono

npm i https://pkg.pr.new/@modelcontextprotocol/hono@3002

@modelcontextprotocol/node

npm i https://pkg.pr.new/@modelcontextprotocol/node@3002

commit: 0a2a5d9

@0xamlab

0xamlab commented Oct 11, 2026

Copy link
Copy Markdown

Verified the fix: on main, a focused 405 test expects Allow: POST but receives null (2 failed). On this branch, the full server suite passes — 576 tests in 20.7s. The change adds the header in the non-POST branch at packages/server/src/server/createMcpHandler.ts:337-355, and the new assertions pin it at packages/server/test/server/legacyStatelessFallback.test.ts:90 and packages/server/test/server/createMcpHandler.test.ts:549. RFC 9110 compliance for the stateless fallback looks solid.

@claude claude Bot added the v2 Ideas, requests and plans for v2 of the SDK which will incorporate major changes and fixes label Oct 12, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

v2 Ideas, requests and plans for v2 of the SDK which will incorporate major changes and fixes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Stateless 405 response omits the Allow header

3 participants