// Package oauth implements a minimal OAuth 2.0 client_credentials flow // for the brain MCP server. Designed for claude.ai's custom MCP integration // UI, which only supports OAuth (no static-Bearer field). The flow trades // a registered client_id + client_secret for the existing BRAIN_MCP_TOKEN — // no JWTs, no expiry, no refresh — so the rest of the auth middleware is // unchanged. package oauth import ( "encoding/json" "net/http" "strings" ) // MetadataHandler serves RFC 8414 authorization-server metadata at // GET /.well-known/oauth-authorization-server. issuer must be the public // origin of the brain MCP (e.g. https://brain-mcp.d-ma.be); the handler // derives the token endpoint from it. // // Mount with no auth — discovery must be reachable to anonymous callers. func MetadataHandler(issuer string) http.HandlerFunc { issuer = strings.TrimRight(issuer, "/") body, _ := json.Marshal(struct { Issuer string `json:"issuer"` TokenEndpoint string `json:"token_endpoint"` GrantTypes []string `json:"grant_types_supported"` TokenEndpointAuthMeth []string `json:"token_endpoint_auth_methods_supported"` }{ Issuer: issuer, TokenEndpoint: issuer + "/oauth/token", GrantTypes: []string{"client_credentials"}, TokenEndpointAuthMeth: []string{"client_secret_post", "client_secret_basic"}, }) return func(w http.ResponseWriter, _ *http.Request) { w.Header().Set("Content-Type", "application/json") _, _ = w.Write(body) } }