ExMCP.Authorization.TokenManager (ex_mcp v1.0.0-rc.0)
View SourceManages OAuth tokens with automatic refresh and expiration tracking.
This GenServer maintains tokens, monitors their expiration, and automatically refreshes them before they expire, following MCP authorization best practices.
Features
- Automatic token refresh before expiration
- Thread-safe token storage
- Configurable refresh window
- Token rotation support
Summary
Functions
Returns a specification to start this module under a supervisor.
Gets the current valid access token.
Gets full token information including metadata.
Forces an immediate token refresh.
Sets a new token in the manager.
Starts a token manager process.
Subscribes to token update notifications.
Unsubscribes from token update notifications.
Upgrades the token's scopes by merging additional scopes with the current ones.
Types
@type auth_method() :: :client_secret | :private_key_jwt | :enterprise_idjag
@type t() :: %ExMCP.Authorization.TokenManager{ access_token: String.t() | nil, auth_config: map(), auth_method: auth_method() | nil, expires_at: DateTime.t() | nil, refresh_timer: reference() | nil, refresh_token: String.t() | nil, scope: String.t() | nil, subscribers: MapSet.t(pid()), token_type: String.t() }
Functions
Returns a specification to start this module under a supervisor.
See Supervisor.
@spec get_token(GenServer.server()) :: {:ok, String.t()} | {:error, atom()}
Gets the current valid access token.
Returns {:ok, token} or {:error, reason} if token is expired/missing.
@spec get_token_info(GenServer.server()) :: {:ok, map()} | {:error, atom()}
Gets full token information including metadata.
@spec refresh_now(GenServer.server()) :: {:ok, map()} | {:error, any()}
Forces an immediate token refresh.
@spec set_token(GenServer.server(), map()) :: :ok
Sets a new token in the manager.
@spec start_link(keyword()) :: GenServer.on_start()
Starts a token manager process.
Options:
:auth_config- Authorization configuration (client_id, client_secret, token_endpoint, etc.):refresh_window- Seconds before expiration to refresh (default: 300):name- Optional process name
@spec subscribe(GenServer.server()) :: :ok
Subscribes to token update notifications.
Subscribers receive {:token_updated, manager, token_info} messages.
@spec unsubscribe(GenServer.server()) :: :ok
Unsubscribes from token update notifications.
@spec upgrade_scopes(GenServer.server(), [String.t()], keyword()) :: {:ok, map()} | {:error, atom() | {atom(), [String.t()]}}
Upgrades the token's scopes by merging additional scopes with the current ones.
If a refresh token is available, attempts to refresh with the expanded scope set.
If no refresh token is available, returns {:error, :reauthorization_required}
with the combined scope list so the caller can initiate a full re-authorization.
Options
:timeout- Call timeout in milliseconds (default: 30_000)