Commit 525b47

2026-03-13 18:23:12 Claude (MCP): [mcp] Update P1-9 task with completion status and fix details
Tasks/P1-9_MCP_OAuth_Routing.md ..
@@ 7,50 7,33 @@
# P1-9: Fix MCP OAuth Discovery Routing
+ **Status: COMPLETE** (2026-03-13)
+
## Problem
Claude.ai cannot connect to the dev.wikibot.io MCP server via OAuth because the `/.well-known/oauth-authorization-server` discovery endpoint is routed to the Otterwiki Lambda (`$default` catch-all) instead of the MCP Lambda. It returns an HTML wiki page instead of the OAuth JSON metadata document.
- The MCP endpoint itself (`POST /mcp`) works correctly (returns 405 on GET, as expected).
+ Additionally, `MCP_BASE_URL` was set to `https://dev.wikibot.io/mcp`, causing FastMCP to compute a doubled path (`/mcp/mcp`) for the protected resource URL.
## Root Cause
- In Pulumi `infra/__main__.py`, the API Gateway only routes `/mcp` and `/mcp/{proxy+}` to the MCP Lambda. All other paths (including `/.well-known/*`) fall through to Otterwiki's `$default` route.
-
- ## Deliverables
-
- 1. Add API Gateway routes for OAuth discovery endpoints so they reach the MCP Lambda:
- - `GET /.well-known/oauth-authorization-server`
- - `GET /.well-known/openid-configuration` (if needed by WorkOS)
- - Any other OAuth endpoints the MCP server handles (e.g., `/authorize`, `/token`, `/register`)
- 2. Verify the OAuth flow works end-to-end by testing each endpoint returns valid JSON (not HTML).
- 3. Do NOT break existing Otterwiki routes or the `/mcp` endpoint.
-
- ## Acceptance Criteria
-
- - `curl https://dev.wikibot.io/.well-known/oauth-authorization-server` returns JSON with `authorization_endpoint`, `token_endpoint`, etc.
- - `curl -X POST https://dev.wikibot.io/mcp` still returns 405 (MCP endpoint still works)
- - `curl https://dev.wikibot.io/Home` still returns the wiki HTML (Otterwiki still works)
- - The full OAuth flow works: Claude.ai can discover endpoints → register client → authorize → get token → call MCP tools
+ 1. API Gateway only routed `/mcp` and `/mcp/{proxy+}` to the MCP Lambda. All `/.well-known/*` paths fell through to Otterwiki's `$default` route.
+ 2. `MCP_BASE_URL` included the `/mcp` subpath, but FastMCP uses this as the base for constructing OAuth metadata URLs, resulting in doubled paths.
- ## Target
+ ## Fix
- - **Repo:** `wikibot-io` at `/Users/sderle/code/otterwiki/wikibot-io/`
- - **Files:** `infra/__main__.py` (Pulumi API Gateway routes)
- - **Branch:** Work on `main`
- - **Deploy:** `bash app/otterwiki/build.sh` is NOT needed (no otterwiki code changes). Only `bash infra/pulumi.sh up --yes` to update API Gateway routes.
+ Two infra changes, zero code changes:
- ## Context
+ 1. **`infra/__main__.py`** — Added API Gateway route `ANY /.well-known/{proxy+}` → MCP Lambda integration
+ 2. **`infra/Pulumi.dev.yaml`** — Changed `mcp_base_url` from `https://dev.wikibot.io/mcp` to `https://dev.wikibot.io`
- - MCP Lambda handler: `app/poc/mcp_package/mcp_server.py`
- - MCP Lambda uses Mangum ASGI adapter (unlike Otterwiki which uses apig-wsgi WSGI adapter)
- - WorkOS AuthKit config in `Pulumi.dev.yaml`: client_id, authkit_domain
- - MCP Lambda env vars set in `__main__.py` lines ~117-147
- - API Gateway routes for MCP defined in `__main__.py` lines ~153-185
- - The MCP server uses FastMCP's `AuthKitProvider` which serves the OAuth discovery and auth endpoints automatically
+ Commit: `e46ef4a` on `main`. Deployed via `pulumi up`.
- ## Notes
+ ## Verification
- - Need to figure out exactly which paths the MCP server handles for OAuth. Check `mcp_server.py` and FastMCP docs/source.
- - May need wildcard route `/.well-known/{proxy+}` or specific routes for each endpoint.
- - Be careful not to route non-OAuth `.well-known` paths away from Otterwiki (though it likely doesn't use any).
+ | Endpoint | Expected | Result |
+ |----------|----------|--------|
+ | `GET /.well-known/oauth-authorization-server` | WorkOS OAuth metadata JSON | PASS |
+ | `GET /.well-known/oauth-protected-resource/mcp` | Protected resource JSON | PASS |
+ | `POST /mcp` (with bearer token) | MCP initialize response | PASS |
+ | `GET /Home` | Otterwiki HTML | PASS (unchanged) |
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