Documentation
¶
Overview ¶
Package mcpauth has the discovery steps an MCP client needs before it can run OAuth against a protected server (MCP authorization, 2025-06-18 and later):
- a request gets 401 with WWW-Authenticate: Bearer resource_metadata="…" — ParseWWWAuthenticate / BearerChallenge;
- that URL (or, without one, the well-known URL derived from the server's own — ResourceMetadataURL) gives the protected-resource metadata, RFC 9728, which names the authorization servers — FetchResourceMetadata;
- each authorization server's metadata, RFC 8414 with the OpenID Connect fallback, gives the endpoints — FetchAuthServerMetadata.
What comes after — dynamic registration, the browser, PKCE, the token exchange, storing and refreshing the token — is the host's: it owns the user and the disk. Plug the result into mcpmgr.MCPConfig.Authorization and OnUnauthorized.
stdlib only, like mcpmgr.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func AuthServerMetadataURLs ¶
AuthServerMetadataURLs lists, in the order to try them, where an issuer's metadata may be (MCP 2025-11-25, "Authorization Server Metadata Discovery"). For an issuer with a path, https://as.example/tenant:
https://as.example/.well-known/oauth-authorization-server/tenant https://as.example/.well-known/openid-configuration/tenant https://as.example/tenant/.well-known/openid-configuration
and for one without, the first two without the path.
Types ¶
type AuthServerMetadata ¶
type AuthServerMetadata struct {
Issuer string `json:"issuer"`
AuthorizationEndpoint string `json:"authorization_endpoint,omitempty"`
TokenEndpoint string `json:"token_endpoint,omitempty"`
RegistrationEndpoint string `json:"registration_endpoint,omitempty"`
RevocationEndpoint string `json:"revocation_endpoint,omitempty"`
JWKSURI string `json:"jwks_uri,omitempty"`
ScopesSupported []string `json:"scopes_supported,omitempty"`
ResponseTypesSupported []string `json:"response_types_supported,omitempty"`
GrantTypesSupported []string `json:"grant_types_supported,omitempty"`
TokenEndpointAuthMethodsSupported []string `json:"token_endpoint_auth_methods_supported,omitempty"`
CodeChallengeMethodsSupported []string `json:"code_challenge_methods_supported,omitempty"`
ClientIDMetadataDocumentSupported bool `json:"client_id_metadata_document_supported,omitempty"`
}
AuthServerMetadata is RFC 8414 authorization-server metadata (which OpenID Connect discovery is a superset of). Only the fields an MCP client uses are decoded.
func FetchAuthServerMetadata ¶
func FetchAuthServerMetadata(ctx context.Context, hc *http.Client, issuer string) (*AuthServerMetadata, error)
FetchAuthServerMetadata tries AuthServerMetadataURLs(issuer) in order and returns the first document found. A non-200 moves on to the next URL; a transport error, a document that does not decode, or one whose issuer is not this issuer (RFC 8414 §3.3) stops the search. Issuers are compared exactly except for a trailing slash, which IdPs disagree about. A nil hc means http.DefaultClient.
type Challenge ¶
type Challenge struct {
Scheme string
Params map[string]string
Token68 string // the rare challenge that carries one instead of params
}
Challenge is one challenge of a WWW-Authenticate header (RFC 9110 §11.6.1). Scheme keeps the server's case; parameter names are lower-cased (they are case-insensitive) and values are unquoted.
func BearerChallenge ¶
BearerChallenge returns the first Bearer challenge in a WWW-Authenticate value. An MCP server's carries resource_metadata, and often scope, which is the scope to ask for (MCP 2025-11-25).
func ParseWWWAuthenticate ¶
ParseWWWAuthenticate parses a WWW-Authenticate value, which may hold several challenges ("Bearer realm=\"a\", Basic realm=\"b\""). Several header lines can be joined with ", " first. It is lenient: what it cannot parse ends the list rather than failing it.
type ResourceMetadata ¶
type ResourceMetadata struct {
Resource string `json:"resource"`
AuthorizationServers []string `json:"authorization_servers,omitempty"`
ScopesSupported []string `json:"scopes_supported,omitempty"`
BearerMethodsSupported []string `json:"bearer_methods_supported,omitempty"`
ResourceName string `json:"resource_name,omitempty"`
ResourceDocumentation string `json:"resource_documentation,omitempty"`
JWKSURI string `json:"jwks_uri,omitempty"`
}
ResourceMetadata is RFC 9728 protected-resource metadata. Only the fields an MCP client uses are decoded.
func FetchResourceMetadata ¶
func FetchResourceMetadata(ctx context.Context, hc *http.Client, metadataURL, resource string) (*ResourceMetadata, error)
FetchResourceMetadata GETs RFC 9728 metadata from metadataURL (the 401's resource_metadata, or ResourceMetadataURL). When resource is not empty the document's resource must equal it — RFC 9728 §3.3, the check that stops one server from pointing a client at another's authorization server. A nil hc means http.DefaultClient.