VS Code extension's MCP OAuth flow sends malformed resource parameter (double-encoded, params leak into outer URL)

Open 💬 1 comment Opened Jun 20, 2026 by LNBelo

Summary

When authenticating an HTTP-transport MCP server (Supabase MCP, https://mcp.supabase.com/mcp?project_ref=...&features=...) from the VS Code extension's "MCP servers" panel, the generated OAuth authorize URL has a malformed resource parameter. The authorization server rejects it with {"message":"resource: Resource must be a valid MCP endpoint"}.

The same MCP server authenticates successfully when run from the terminal CLI (claude mcp list / /mcp), using the same Claude Code version. This points to a separate/divergent OAuth URL-construction code path in the VS Code extension vs. the CLI.

Environment

  • Claude Code CLI version: 2.1.183
  • Claude Code VS Code extension version: anthropic.claude-code@2.1.183 (latest available via marketplace at time of report)
  • OS: Windows 11
  • MCP server config (.mcp.json):
{
  "mcpServers": {
    "supabase": {
      "type": "http",
      "url": "https://mcp.supabase.com/mcp?project_ref=<redacted>&features=docs%2Caccount%2Cdatabase%2Cdebugging%2Cdevelopment%2Cfunctions%2Cbranching%2Cstorage"
    }
  }
}

Steps to reproduce

  1. Add an HTTP MCP server whose URL itself contains a query string (e.g. Supabase's remote MCP endpoint, which requires project_ref and optionally features as query params).
  2. Open the "MCP servers" panel in the VS Code extension, select the server, click Authenticate.
  3. Inspect the generated authorize URL.

Actual result

The resource parameter is malformed — the embedded ? is double-encoded (%253F instead of %3F), and the rest of the embedded query string (project_ref, features) is not encoded at all, so it leaks out as sibling top-level query parameters on the outer authorize URL instead of staying part of the resource value:

...&resource=https://mcp.supabase.com/mcp%253Fproject_ref=<redacted>&features=docs%252Caccount%252Cdatabase%252Cdebugging%252Cdevelopment%252Cfunctions%252Cbranching%252Cstorage

Supabase's OAuth server rejects this with:

{"message":"resource: Resource must be a valid MCP endpoint"}

This was reproduced consistently across multiple authentication attempts from the VS Code panel (different client_id/code_challenge each time, same malformed structure).

Expected result

The resource parameter should be the full MCP server URL, properly URL-encoded as a single value, matching the behavior already correct in the terminal/CLI flow:

...&resource=https%3A%2F%2Fmcp.supabase.com%2Fmcp%3Fproject_ref%3D<redacted>%26features%3Ddocs%252Caccount%252Cdatabase%252Cdebugging%252Cdevelopment%252Cfunctions%252Cbranching%252Cstorage

(Note: commas in features are double-encoded as %252C here because they're already percent-encoded as %2C in the source URL — that part is correct. Only the embedded ?, &, and = need single-encoding to %3F, %26, %3D; they are currently either double-encoded or not encoded at all, inconsistently.)

Workaround

Two workarounds were confirmed:

  1. Authenticate via the terminal (claude mcp list or /mcp from an interactive CLI session) instead of the VS Code panel — the CLI builds the resource parameter correctly. However, the resulting token does not appear to be shared with the VS Code panel's own connection state — the panel still shows "Needs Auth" even after a successful terminal auth for the same server URL.
  2. Manually correcting the malformed resource parameter in the browser's address bar before submitting the authorize request (re-encoding the embedded MCP URL as a single properly-escaped value, keeping client_id/code_challenge/state/redirect_uri unchanged) also completes authentication successfully, confirming the bug is purely in how the panel constructs the resource value client-side, not a server-side rejection issue.

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗