Properties
category: reference
tags:
  - P1
  - infrastructure
  - oauth
  - mcp
last_updated: 2026-03-13

P1-9: Fix MCP OAuth Discovery Routing

Problem

Claude.ai needs to discover OAuth endpoints via /.well-known/oauth-authorization-server to initiate the OAuth flow with the MCP server. Two issues prevented this:

  1. Missing API Gateway route: /.well-known/* paths hit the Otterwiki Lambda ($default catch-all) instead of the MCP Lambda, returning HTML instead of OAuth metadata JSON.

  2. Double path in resource URL: MCP_BASE_URL was set to https://dev.wikibot.io/mcp, but FastMCP's _get_resource_url() appends the mcp_path parameter (/mcp) to the base URL, producing https://dev.wikibot.io/mcp/mcp.

Solution

Two infrastructure changes, no code changes:

  1. Added API Gateway route ANY /.well-known/{proxy+} pointing to the MCP Lambda integration. This routes OAuth discovery requests to the correct Lambda.

  2. Changed MCP_BASE_URL from https://dev.wikibot.io/mcp to https://dev.wikibot.io. FastMCP now computes the correct resource URL https://dev.wikibot.io/mcp via _get_resource_url("/mcp").

Verification

All endpoints tested after deploy:

Endpoint Expected Actual
GET /.well-known/oauth-authorization-server WorkOS OAuth metadata JSON Pass
GET /.well-known/oauth-protected-resource/mcp Protected resource metadata JSON Pass
POST /mcp (with bearer token) MCP initialize response (200) Pass
POST /mcp (no auth) 401 Unauthorized Pass
GET /Home Otterwiki HTML Pass

Files Changed

  • infra/Pulumi.dev.yamlmcp_base_url value
  • infra/__main__.py — new mcp-route-well-known API Gateway route

How It Works

Client → GET /.well-known/oauth-authorization-server
       → API Gateway route: ANY /.well-known/{proxy+}
       → MCP Lambda
       → Starlette route: /.well-known/oauth-authorization-server
       → AuthKitProvider forwards WorkOS metadata

Client → GET /.well-known/oauth-protected-resource/mcp
       → API Gateway route: ANY /.well-known/{proxy+}
       → MCP Lambda
       → Starlette route: /.well-known/oauth-protected-resource/mcp
       → Returns resource metadata with authorization_servers

Client → POST /mcp (MCP protocol)
       → API Gateway route: ANY /mcp
       → MCP Lambda
       → Starlette route: /mcp
       → StreamableHTTP handler

Commit

e46ef4a on main branch (not pushed)

0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9