mcpauth

package
v0.18.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 1, 2026 License: MIT Imports: 7 Imported by: 0

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):

  1. a request gets 401 with WWW-Authenticate: Bearer resource_metadata="…" — ParseWWWAuthenticate / BearerChallenge;
  2. 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;
  3. 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

func AuthServerMetadataURLs(issuer string) ([]string, error)

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.

func ResourceMetadataURL

func ResourceMetadataURL(resource string) (string, error)

ResourceMetadataURL is where RFC 9728 puts a resource's metadata when the 401 named none: /.well-known/oauth-protected-resource inserted before the resource URL's 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

func BearerChallenge(header string) (Challenge, bool)

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

func ParseWWWAuthenticate(header string) []Challenge

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL