Skip to content

fix(server): omit invalid_token when a bearer challenge has no credentials - #3139

Open
Anandumv wants to merge 1 commit into
modelcontextprotocol:mainfrom
Anandumv:cursor/fix-3124-bearer-challenge-c081
Open

Anandumv wants to merge 1 commit into
modelcontextprotocol:mainfrom
Anandumv:cursor/fix-3124-bearer-challenge-c081

Conversation

@Anandumv

Copy link
Copy Markdown

Closes #3124.

Summary

requireBearerAuth answered a request with no Authorization header as 401 invalid_token. RFC 6750 §3.1 says a resource server should not include an error code when the request has no authentication information.

The challenge now omits error and error_description when scope or resource_metadata is already present, and the JSON body is {} so it matches the header. The Express adapter sends that same body. A presented token that fails verification is unchanged. When neither scope nor resource_metadata is configured, the challenge still includes invalid_token, so it is never a bare Bearer.

Tests

  • Unit coverage in @modelcontextprotocol/server and @modelcontextprotocol/express for scope only, resource_metadata only, both, neither, a rejected token, and a malformed Authorization header.
  • hosting:auth:missing-401 and hosting:auth:query-token-ignored expect the credential-less challenge.
  • pnpm lint:all, pnpm build:all, and pnpm test:all pass. The bearer-auth and bearer-auth-web examples pass on the modern and legacy HTTP legs.

RFC 6750 §3.1 says a challenge for a request with no authentication
information should not include an error code. requireBearerAuth now
drops error and error_description when scope or resource_metadata is
already present, and the Express adapter sends that same body. A
rejected token still returns invalid_token, and a challenge with
neither parameter keeps the error code.

Fixes modelcontextprotocol#3124

Co-authored-by: Anandu Mv <Anandumv@users.noreply.github.com>
@Anandumv
Anandumv requested a review from a team as a code owner October 31, 2026 10:03
@changeset-bot

changeset-bot Bot commented Oct 31, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 1584c28

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

This PR includes changesets to release 7 packages
Name Type
@modelcontextprotocol/server Patch
@modelcontextprotocol/express 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

@pkg-pr-new

pkg-pr-new Bot commented Oct 31, 2026

Copy link
Copy Markdown

Open in StackBlitz

@modelcontextprotocol/client

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

@modelcontextprotocol/codemod

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

@modelcontextprotocol/core

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

@modelcontextprotocol/server

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

@modelcontextprotocol/server-legacy

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

@modelcontextprotocol/express

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

@modelcontextprotocol/fastify

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

@modelcontextprotocol/hono

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

@modelcontextprotocol/node

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

commit: 1584c28

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

@JosephDoUrden JosephDoUrden left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

pulled the branch and ran it.

packages/server bearerAuth.test.ts 37/37, packages/middleware/express resourceServer.test.ts 16/16, test/e2e hosting-express.test.ts 25/25. merge against upstream/main clean, one commit behind (#3115). client side only branches on 403 insufficient_scope and use_dpop_nonce, so a 401 with no error param still starts the oauth flow.

one gap. rfc 6750 §3.1 names two no-error cases: no auth info at all, and "attempted using an unsupported authentication method". the pr covers the first only.

packages/server/src/server/middleware/bearerAuth.ts:168-170 still throws plain InvalidToken for a non-bearer scheme. probe with resource_metadata set: no header gives Bearer resource_metadata="..." and an empty body. Basic dXNlcjpwYXNz gives Bearer error="invalid_token", error_description="Invalid Authorization header format..." and an error body. Digest behaves like Basic.

a client sending Basic has not presented a bearer token, so telling it the token is invalid is the same mismatch #3124 is about. Bearer with an empty token is arguably malformed and can keep the error. suggest the scheme-mismatch branch throws MissingAuthorizationError too, plus one test.

otherwise the shape looks right: the error is only dropped when scope or resource_metadata keeps the challenge non-empty, and the express adapter now reuses the core body. fine to land after that tweak.

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.

[v2] requireBearerAuth: drop error="invalid_token" when no credentials were sent and resource_metadata is set (RFC 6750 §3.1)

3 participants