Deprecated Dynamic Client Registration for OAuth 2.1.
Implements RFC 7591 (OAuth 2.0 Dynamic Client Registration Protocol) to allow MCP clients to register themselves with authorization servers at runtime.
MCP 2026-07-28 deprecates this mechanism in favor of Client ID Metadata
Documents. Keep DCR only as a compatibility fallback for authorization
servers that advertise registration_endpoint but not a usable CIMD path.
Example
# Register a new client
{:ok, client_info} = ExMCP.Authorization.ClientRegistration.register_client(%{
registration_endpoint: "https://auth.example.com/register",
client_name: "My MCP Client",
application_type: "native",
redirect_uris: ["https://localhost:8080/callback"],
grant_types: ["authorization_code"],
response_types: ["code"],
scope: "mcp:read mcp:write"
})
# Use the returned client_id and client_secret for authorization flows
Summary
Functions
Validates a deprecated DCR request and builds its JSON payload.
Retrieves client information using a registration access token.
Registers a new client with the authorization server.
Updates client information using a registration access token.
Types
@type client_information() :: %{ client_id: String.t(), client_secret: String.t() | nil, client_secret_expires_at: integer() | nil, registration_access_token: String.t() | nil, registration_client_uri: String.t() | nil, client_name: String.t(), redirect_uris: [String.t()], grant_types: [String.t()], response_types: [String.t()], scope: String.t() }
@type registration_request() :: %{ :registration_endpoint => String.t(), :client_name => String.t(), :application_type => String.t(), :redirect_uris => [String.t()], :grant_types => [String.t()], :response_types => [String.t()], :scope => String.t(), optional(:token_endpoint_auth_method) => String.t(), optional(:client_uri) => String.t() | nil, optional(:logo_uri) => String.t() | nil, optional(:contacts) => [String.t()] | nil, optional(:tos_uri) => String.t() | nil, optional(:policy_uri) => String.t() | nil, optional(:software_id) => String.t() | nil, optional(:software_version) => String.t() | nil }
Functions
@spec build_request(registration_request()) :: {:ok, map()} | {:error, term()}
Validates a deprecated DCR request and builds its JSON payload.
@spec get_client_information(String.t(), String.t()) :: {:ok, client_information()} | {:error, term()}
Retrieves client information using a registration access token.
This allows clients to read their current registration information from the authorization server.
@spec register_client(registration_request()) :: {:ok, client_information()} | {:error, term()}
Registers a new client with the authorization server.
Dynamic Client Registration is deprecated by MCP 2026-07-28. New clients should use a pre-registered client or Client ID Metadata Document.
This implements the client registration flow from RFC 7591, sending client metadata to the registration endpoint and receiving client credentials in response.
@spec update_client_information(String.t(), String.t(), map()) :: {:ok, client_information()} | {:error, term()}
Updates client information using a registration access token.
This allows clients to modify their registration information at the authorization server.