modelcontextprotocol / modelcontextprotocol/typescript-sdk

OAuth token exchange crashes on gzip-compressed token response (JSON.parse on undecompressed bytes)

Open
#2,408 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

auth bug needs repro v1 v2
Dominant language
TypeScript
Stars
13.4k
Forks
2.2k
Avg merge
3d 15h
Merged PRs (30d)
4

Description

Summary

When completing the OAuth flow against a server whose /oauth/token-request endpoint returns a gzip-compressed token response, mcp-remote crashes while parsing that response. The raw compressed bytes appear to be passed to JSON.parse without being decompressed first.

Environment

  • mcp-remote: 0.1.37 and 0.1.38 (both fail)
  • Node: v26.2.0
  • OS: Windows 11 Enterprise 23H2 (build 22631.7219)
  • Auth server: Snowflake MCP endpoint; /oauth/token-request returns gzip-encoded responses (not on every call)

Error

Authorization error during finishAuth
SyntaxError: Unexpected token '\u001f', "\u001f \b\u0000\u0000\u0000\u0000\u0000\u0000\u0003"... is not valid JSON
at JSON.parse ()
at parseJSONFromBytes (node:internal/deps/undici/undici:4292:19)
at successSteps (node:internal/deps/undici/undici:6907:27)
at readAllBytes (node:internal/deps/undici/undici:5754:13)

The leading bytes 1F 8B 08 00 00 00 00 00 03 are the gzip magic header, confirming the body being parsed is still gzip-compressed.

Diagnosis

  • A plain curl to the endpoint returns uncompressed JSON (7B 0A ...), so the server only gzips when the client advertises gzip support.
  • Node's own fetch() decompresses correctly: a direct fetch() with Accept-Encoding: gzip, reading arrayBuffer(), returns decompressed JSON (is gzip: false).
  • This points to the token-exchange code path reading the raw response body without gzip decompression, rather than a Node bug.

Expected

The token response should be decompressed (or fetch() allowed to handle Content-Encoding) before JSON.parse, so gzip-encoded token responses parse successfully.

Actual

Raw gzip bytes are passed to JSON.parse, throwing SyntaxError and aborting the OAuth flow, so the connection never completes against this endpoint.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at the finishAuth OAuth flow and the /oauth/token-request exchange, then trace where the response body reaches JSON.parse. Compare that path with Node fetch() handling of gzip-encoded responses. Done means gzip-compressed token responses are decompressed or handled by fetch before parsing, and the OAuth connection completes successfully.

Written by the indexing model from the issue text.

Assessment

Tech stack
node.js, typescript
Domain
api, authentication
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.