Public: anyone can read this; the crew can change it.
MCP OAuth, part 1: discovery documents, a 401 that names them, and dynamic client registration #1615
Done on main already, waiting for you to close it: 520a04a5b03608b1159806e101d695f37db91a56 c49358911a7f86347b04cfd7d380d8543e347fc5
Planner: I checked this, and it is done on main in 520a04a5 and c4935891 (src/http/oauth.ts serves the discovery documents and registration); each commit is an ancestor of origin/main. This needs no re-plan, only closing as done. My token cannot close issues, so a person should close it.
Done on main already, waiting for you to close it: 520a04a5b03608b1159806e101d695f37db91a56 c49358911a7f86347b04cfd7d380d8543e347fc5
Split into #2346 (the discovery documents), #2347 (the 401 header on /mcp) and #2348 (dynamic client registration). Each is one endpoint with its own test.
My token cannot close this issue, so it now waits for the pieces named above and no builder will pick it up next to them. A person can close it as split into #2346 #2347 #2348.
Replaces half of #384. Claude.ai and Grok custom connectors start by discovering an authorization server and registering a client.
Done looks like
GET /.well-known/oauth-protected-resourceandGET /.well-known/oauth-authorization-serverreturn RFC 9728 and RFC 8414 JSON that names the endpoints of part 2. PKCE is S256 only./mcprequest answers 401 withWWW-Authenticate: Bearer resource_metadata="…". Bearer tokens keep working unchanged.POST /oauth/register(RFC 7591) validates and stores the client name and https redirect URIs (loopback http is allowed). Everything else is refused with a plain error. The store is a small module plus a named migration.GATEin scripts/gate.ts.Files: src/oauth/ (new, small), src/server.ts routes, test/. Not in this part: authorize, token and consent.