Skip to content

OAuth Discovery fails when server is behind reverse proxy with path-based routing #249

@johnnyasantoss

Description

@johnnyasantoss

Problem

When using mcp-remote with --transport sse-only to connect to an MCP server exposed via Tailscale serve, the OAuth discovery phase fails because it looks for /.well-known/oauth at the root of the domain, not at the path where the MCP server is actually hosted.

SseError: SSE error: Non-200 status code (400)
Connection error: SseError: SSE error: Non-200 status code (400)
Discovering OAuth server configuration...

The MCP server itself works correctly. Direct HTTP POST to the endpoint with proper MCP session headers succeeds. The issue is specifically with mcp-remote's built-in OAuth discovery behavior.
This would happen to any reverse proxy with path based routing.

Use Case

Tailscale serve exposes a local service with a command like:

tailscale serve --bg --path /mcp 1234
This creates a private/public URL like https://example.tailnet.ts.net/mcp/some-other-path-maybe/.

The MCP server is correctly registered and responds to direct HTTP calls, but mcp-remote attempts OAuth discovery at https://example.tailnet.ts.net/.well-known/oauth instead of respecting the actual server path.

Expected Behavior

Users should be able to:

  1. Disable OAuth discovery entirely via a flag or environment variable
  2. Configure the discovery base URL separately from the MCP server URL

Suggested Solutions

  1. --no-oauth-discovery flag. Disables OAuth discovery entirely for cases where the server doesn't use OAuth
  2. --oauth-discovery-base-url <url> flag. Allows specifying a separate base URL for OAuth discovery
  3. OAUTH_DISCOVERY_BASE_URL env var alternative

Reproduction

# Expose via Tailscale serve with path
tailscale serve --bg --path /mcp 1234

# Try to connect with mcp-remote
npx -y mcp-remote@latest \
  "https://your-tailnet.ts.net/mcp/my_mcp_server" \
  --transport sse-only \
  --header "Authorization: Bearer x"

Notes

• The server does not use OAuth. the Bearer token is a placeholder to try to disable oauth discovery
• Direct JSON-RPC calls to the endpoint work correctly

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions