# `ExMCP.Authorization.ClientRegistration`
[🔗](https://github.com/azmaveth/ex_mcp/blob/v1.0.0/lib/ex_mcp/authorization/client_registration.ex#L1)

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

# `client_information`

```elixir
@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()
}
```

# `registration_request`

```elixir
@type registration_request() :: %{
  :registration_endpoint =&gt; String.t(),
  :client_name =&gt; String.t(),
  :application_type =&gt; String.t(),
  :redirect_uris =&gt; [String.t()],
  :grant_types =&gt; [String.t()],
  :response_types =&gt; [String.t()],
  :scope =&gt; String.t(),
  optional(:token_endpoint_auth_method) =&gt; String.t(),
  optional(:client_uri) =&gt; String.t() | nil,
  optional(:logo_uri) =&gt; String.t() | nil,
  optional(:contacts) =&gt; [String.t()] | nil,
  optional(:tos_uri) =&gt; String.t() | nil,
  optional(:policy_uri) =&gt; String.t() | nil,
  optional(:software_id) =&gt; String.t() | nil,
  optional(:software_version) =&gt; String.t() | nil
}
```

# `build_request`

```elixir
@spec build_request(registration_request()) :: {:ok, map()} | {:error, term()}
```

Validates a deprecated DCR request and builds its JSON payload.

# `get_client_information`

```elixir
@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.

# `register_client`

```elixir
@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.

# `update_client_information`

```elixir
@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.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
