Ensure proper MCP URL OAuth Discovery for API/V4/MCP

What does this MR do and why?

Our dynamic OAuth discovery for the api/v4/mcp endpoint is broken because the .well-known/oauth-authorization-server prepends api/v4/mcp per the MCP service discovery(https://modelcontextprotocol.io/specification/draft/basic/authorization#server-metadata-discovery)specification. The issue is that we don't handle the routing properly with prepending api/v4/mcp as the tenant.

When MCP clients connect to GitLab endpoints with path components (e.g., https://gitlab.example.com/api/v4/mcp), they attempt OAuth discovery using path insertion according to the MCP spec:

  1. https://gitlab.example.com/.well-known/oauth-authorization-server/api/v4/mcp
  2. https://gitlab.example.com/.well-known/openid-configuration/api/v4/mcp

Since the endpoint doesn't exist in our config/routes.rb. When the https://gitlab.com/.well-known/oauth-authorization-server/api/v4/mcp <-- redirects to a login screen (this is the issue), it's given an HTML page instead of a valid token

Example of error trace

[84436] Fatal error: SyntaxError: Unexpected token '<', "<!-- BEGIN"... is not valid JSON
    at JSON.parse (<anonymous>)
    at parseJSONFromBytes (node:internal/deps/undici/undici:5738:19)
    at successSteps (node:internal/deps/undici/undici:5719:27)
    at fullyReadBody (node:internal/deps/undici/undici:4609:9)
    at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
    at async consumeBody (node:internal/deps/undici/undici:5728:7)
    at async discoverAuthorizationServerMetadata (file:///Users/terrichu/.npm/_npx/1a3c4333f3a90708/node_modules/mcp-remote/dist/chunk-AKJME7CQ.js:12475:40)
    at async authInternal (file:///Users/terrichu/.npm/_npx/1a3c4333f3a90708/node_modules/mcp-remote/dist/chunk-AKJME7CQ.js:12261:20)
    at async auth (file:///Users/terrichu/.npm/_npx/1a3c4333f3a90708/node_modules/mcp-remote/dist/chunk-AKJME7CQ.js:12235:12)
    at async StreamableHTTPClientTransport.send (file:///Users/terrichu/.npm/_npx/1a3c4333f3a90708/node_modules/mcp-remote/dist/chunk-AKJME7CQ.js:13454:26)
[2025-09-12T20:03:09.745Z][84436] Fatal error: SyntaxError: Unexpected token '<', "<!-- BEGIN"... is not valid JSON

Why this is happening now:

The TypeScript SDK backing mcp-remote was updated 19 days ago to support path insertion for discovery in version 0.1.19 (TypeScript SDK PR #652), which was then integrated into mcp-remote ~2 weeks ago (mcp-remote PR #143). During our MCP development, the dynamic OAuth registration hardcoded the path discovery without accounting for this change.

Initial MR: !197644 (merged)

References

#570064 (closed)

Screenshots or screen recordings

Screenshot_2025-09-15_at_1.22.17_PM

Screenshot_2025-09-17_at_1.19.40_PM Caption: Tested on Cursor

Screenshot_2025-09-17_at_1.29.21_PM Caption: Tested on Claude Desktop

How to set up and validate locally

  1. Start your GitLab development environment
  2. Test the original endpoint still works:
   curl -H "Accept: application/json" https://gdk.test:3443/.well-known/oauth-authorization-server/api/v4/mcp
   curl -H "Accept: application/json" https://gdk.test:3443/.well-known/openid-configuration/api/v4/mcp
  1. Create a MCP server entry in Client claude-mcp-desktop.json
    "GitLab-GDK": {
      "command": "npx",
      "args": [
        "mcp-remote@latest",
        "https://gdk.test:3443/api/v4/mcp",
        "--debug",
        "--static-oauth-client-metadata",
        "{\"scope\": \"mcp\"}"   
      ],
      "env": {
        "NODE_TLS_REJECT_UNAUTHORIZED": "0"
      }
    }

**Ensure MCP related feature flags of mcp_server and oauth_dynamic_client_registration are enabled **

MR acceptance checklist

Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

Edited by Nathan Weinshenker

Merge request reports

Loading