Skip to content

fix: handle URL-encoded token responses from OAuth providers#1599

Open
giulio-leone wants to merge 2 commits intomodelcontextprotocol:v1.xfrom
giulio-leone:fix/oauth-url-encoded-token-response
Open

fix: handle URL-encoded token responses from OAuth providers#1599
giulio-leone wants to merge 2 commits intomodelcontextprotocol:v1.xfrom
giulio-leone:fix/oauth-url-encoded-token-response

Conversation

@giulio-leone
Copy link

Summary

Some OAuth providers (e.g. GitHub) return token endpoint responses in application/x-www-form-urlencoded format instead of JSON. The SDK calls response.json() unconditionally, causing a SyntaxError when the response is URL-encoded.

Root Cause

In executeTokenRequest(), line 1246:

return OAuthTokensSchema.parse(await response.json());

While the SDK already sends Accept: application/json (which handles compliant servers like GitHub), some OAuth providers may still return URL-encoded responses regardless of the Accept header.

Fix

Added parseTokenResponse() helper that checks the response Content-Type header:

  • application/x-www-form-urlencoded: Parses with URLSearchParams and converts to a plain object
  • Everything else (including application/json and missing header): Falls through to response.json() (existing behavior, fully backward-compatible)

The OAuthTokensSchema uses z.coerce.number() for expires_in, so string values from URL-encoded responses are automatically coerced to numbers.

Tests

Added 3 new tests in exchangeAuthorization:

  • URL-encoded response with content-type: application/x-www-form-urlencoded
  • URL-encoded response with expires_in as string (coerced to number)
  • JSON response with explicit content-type: application/json (regression test)

Verification

2 consecutive clean test runs: 1550/1550 tests passed, 0 failures.

Fixes #759

@changeset-bot
Copy link

changeset-bot bot commented Feb 27, 2026

🦋 Changeset detected

Latest commit: f465500

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

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
Copy link

pkg-pr-new bot commented Feb 27, 2026

Open in StackBlitz

npm i https://pkg.pr.new/@modelcontextprotocol/sdk@1599

commit: 1340923

g97iulio1609 added 2 commits February 28, 2026 15:50
Some OAuth providers (e.g. GitHub) return token responses in
application/x-www-form-urlencoded format instead of JSON. The SDK
already sends Accept: application/json, but non-compliant servers
may still return URL-encoded responses.

This adds Content-Type-aware parsing in executeTokenRequest:
- If Content-Type is application/x-www-form-urlencoded, parse with
  URLSearchParams
- Otherwise, default to response.json() (existing behavior)

Fixes modelcontextprotocol#759
@giulio-leone
Copy link
Author

All CI checks pass. Ready for review.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant