How a client learns where a remote MCP server's authorization lives, the way the MCP authorization spec says:
GETthe MCP URL with no credential. A conforming server answers401withWWW-Authenticate: Bearer resource_metadata="…"naming its protected-resource metadata (RFC 9728). A server that names none is tried at the well-known path for its URL, then at the origin's.- That document's
authorization_serversnames the issuer; its RFC 8414 metadata (/.well-known/oauth-authorization-server, with the OpenID/.well-known/openid-configurationas the fallback) carries the authorize, token, revocation and registration endpoints. register/3: RFC 7591 dynamic client registration atregistration_endpoint, so the tenant types no client id anywhere. The server picks the client's auth method; a public client comes back with no secret andtoken_endpoint_auth_method: none.
Every URL, including the ones the server sent back, passes
Managoat.McpAuth.UrlGuard before it is fetched: a malicious
resource document that points discovery at the metadata service is the
obvious trick. Each fetch has a timeout and the chain follows no
redirects.
Summary
Functions
The merged metadata for an MCP server URL: resource, issuer,
authorization_endpoint, token_endpoint, revocation_endpoint,
registration_endpoint, scopes, code_challenge_methods_supported,
token_endpoint_auth_methods_supported, plus the raw documents under
resource_metadata and authorization_server_metadata.
Register a client at the authorization server (RFC 7591) and return the
provider attributes it yields: client_id, client_secret (absent for
a public client), token_endpoint_auth and client_source: "dcr".
Types
Functions
The merged metadata for an MCP server URL: resource, issuer,
authorization_endpoint, token_endpoint, revocation_endpoint,
registration_endpoint, scopes, code_challenge_methods_supported,
token_endpoint_auth_methods_supported, plus the raw documents under
resource_metadata and authorization_server_metadata.
@spec register(metadata(), String.t(), client_name: String.t(), client_uri: String.t() ) :: {:ok, map()} | {:error, term()}
Register a client at the authorization server (RFC 7591) and return the
provider attributes it yields: client_id, client_secret (absent for
a public client), token_endpoint_auth and client_source: "dcr".
:client_name and :client_uri are required options. Omitting either is a
programming error and raises rather than sending an incomplete registration.