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

Manages 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

# `auth_method`

```elixir
@type auth_method() :: :client_secret | :private_key_jwt | :enterprise_idjag
```

# `t`

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

# `child_spec`

Returns a specification to start this module under a supervisor.

See `Supervisor`.

# `get_token`

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

# `get_token_info`

```elixir
@spec get_token_info(GenServer.server()) :: {:ok, map()} | {:error, atom()}
```

Gets full token information including metadata.

# `refresh_now`

```elixir
@spec refresh_now(GenServer.server()) :: {:ok, map()} | {:error, any()}
```

Forces an immediate token refresh.

# `set_token`

```elixir
@spec set_token(GenServer.server(), map()) :: :ok
```

Sets a new token in the manager.

# `start_link`

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

# `subscribe`

```elixir
@spec subscribe(GenServer.server()) :: :ok
```

Subscribes to token update notifications.

Subscribers receive `{:token_updated, manager, token_info}` messages.

# `unsubscribe`

```elixir
@spec unsubscribe(GenServer.server()) :: :ok
```

Unsubscribes from token update notifications.

# `upgrade_scopes`

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

---

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