ExMCP.ConsentHandler behaviour (ex_mcp v0.9.2)

View Source

A behaviour for handling user consent for accessing external resources.

Summary

Types

The result of a consent request.

Context about the consent request.

The origin of the resource being accessed (e.g., "https://api.example.com").

The user identifier.

Callbacks

Checks if a valid consent already exists.

Requests user consent to access a resource.

Revokes any existing consent for a user and resource.

Types

consent_result()

@type consent_result() ::
  {:ok, expires_at :: non_neg_integer()} | {:error, :denied | :consent_required}

The result of a consent request.

  • {:ok, expires_at}: Consent granted, valid until the given monotonic time in seconds.
  • {:error, :denied}: Consent explicitly denied.
  • {:error, :consent_required}: Consent needs to be obtained through another channel (e.g., a web UI).

request_context()

@type request_context() :: map()

Context about the consent request.

resource_origin()

@type resource_origin() :: String.t()

The origin of the resource being accessed (e.g., "https://api.example.com").

user_id()

@type user_id() :: String.t() | atom()

The user identifier.

Callbacks

check_existing_consent(user_id, resource_origin)

@callback check_existing_consent(
  user_id :: user_id(),
  resource_origin :: resource_origin()
) :: {:ok, expires_at :: non_neg_integer()} | {:not_found} | {:expired}

Checks if a valid consent already exists.

This callback is primarily for handlers that might have their own persistent storage, separate from the global ConsentCache. Most handlers can simply return {:not_found} and rely on the cache.

request_consent(user_id, resource_origin, request_context)

@callback request_consent(
  user_id :: user_id(),
  resource_origin :: resource_origin(),
  request_context :: request_context()
) :: consent_result()

Requests user consent to access a resource.

The request_context map can contain transport-specific information and configuration like :consent_ttl.

revoke_consent(user_id, resource_origin)

@callback revoke_consent(user_id :: user_id(), resource_origin :: resource_origin()) ::
  :ok | {:error, String.t()}

Revokes any existing consent for a user and resource.