Storage¶
Token storage abstractions and implementations.
PostgresTokenStorage is importable from this module but loaded lazily
so that asyncpg is only required when actually used. Install the
postgres extra to enable it: pip install mcp-authflow[postgres]
TokenStorage¶
TokenStorage
¶
Bases: ABC
Abstract interface for MCP token storage.
initialize
abstractmethod
async
¶
close
abstractmethod
async
¶
store_token
abstractmethod
async
¶
store_token(
token: str,
client_id: str,
scopes: list[str],
expires_at: int,
resource: str | None = None,
user_id: UserId | None = None,
) -> None
Store an access token.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
token
|
str
|
The access token string |
required |
client_id
|
str
|
OAuth client ID |
required |
scopes
|
list[str]
|
List of granted scopes |
required |
expires_at
|
int
|
Unix timestamp when token expires |
required |
resource
|
str | None
|
Optional RFC 8707 resource binding |
None
|
user_id
|
UserId | None
|
Optional ID of the user who authorized the token. May be an
int or a str so it can match the consumer's user primary key
(see :data: |
None
|
Source code in mcp_authflow/storage/base.py
load_token
abstractmethod
async
¶
Load an access token.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
token
|
str
|
The access token string to look up |
required |
Returns:
| Type | Description |
|---|---|
dict[str, Any] | None
|
Token data dict if found and not expired, None otherwise |
Source code in mcp_authflow/storage/base.py
delete_token
abstractmethod
async
¶
Delete a token.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
token
|
str
|
The access token string to delete |
required |
store_refresh_token
abstractmethod
async
¶
store_refresh_token(
refresh_token: str,
client_id: str,
scopes: list[str],
expires_at: int,
resource: str | None = None,
user_id: UserId | None = None,
) -> None
Store a refresh token.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
refresh_token
|
str
|
The refresh token string |
required |
client_id
|
str
|
OAuth client ID |
required |
scopes
|
list[str]
|
List of granted scopes |
required |
expires_at
|
int
|
Unix timestamp when token expires |
required |
resource
|
str | None
|
Optional RFC 8707 resource binding |
None
|
user_id
|
UserId | None
|
Optional ID of the user who authorized the token. May be an
int or a str so it can match the consumer's user primary key
(see :data: |
None
|
Source code in mcp_authflow/storage/base.py
load_refresh_token
abstractmethod
async
¶
Load a refresh token.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
refresh_token
|
str
|
The refresh token string to look up |
required |
Returns:
| Type | Description |
|---|---|
dict[str, Any] | None
|
Token data dict if found and not expired, None otherwise |
Source code in mcp_authflow/storage/base.py
delete_refresh_token
abstractmethod
async
¶
Delete a refresh token.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
refresh_token
|
str
|
The refresh token string to delete |
required |
revoke_client_tokens
abstractmethod
async
¶
Revoke every access and refresh token issued to a client.
Implementations should remove both token types atomically when their storage backend supports transactions.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
client_id
|
str
|
OAuth client ID whose tokens should be revoked |
required |
Returns:
| Type | Description |
|---|---|
int
|
Total number of access and refresh tokens removed |
Source code in mcp_authflow/storage/base.py
cleanup_expired_tokens
abstractmethod
async
¶
Remove all expired access tokens.
Returns:
| Type | Description |
|---|---|
int
|
Number of tokens removed |
cleanup_expired_refresh_tokens
abstractmethod
async
¶
Remove all expired refresh tokens.
Returns:
| Type | Description |
|---|---|
int
|
Number of tokens removed |
get_token_count
abstractmethod
async
¶
Get the total number of access tokens in storage.
Returns:
| Type | Description |
|---|---|
int
|
Number of tokens stored |
get_refresh_token_count
abstractmethod
async
¶
Get the total number of refresh tokens in storage.
Returns:
| Type | Description |
|---|---|
int
|
Number of refresh tokens stored |
MemoryTokenStorage¶
MemoryTokenStorage
¶
Bases: TokenStorage
In-memory token storage for testing and development.
This implementation stores tokens in memory and does not persist them across restarts. Suitable for testing and development only.
Initialize in-memory token storage.
Source code in mcp_authflow/storage/memory.py
initialize
async
¶
close
async
¶
Close the storage and clear all tokens.
store_token
async
¶
store_token(
token: str,
client_id: str,
scopes: list[str],
expires_at: int,
resource: str | None = None,
user_id: UserId | None = None,
) -> None
Store an access token in memory.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
token
|
str
|
The access token string |
required |
client_id
|
str
|
OAuth client ID |
required |
scopes
|
list[str]
|
List of granted scopes |
required |
expires_at
|
int
|
Unix timestamp when token expires |
required |
resource
|
str | None
|
Optional RFC 8707 resource binding |
None
|
user_id
|
UserId | None
|
Optional ID of the user who authorized the token. May be an
int or a str so it can match the consumer's user primary key
(see :data: |
None
|
Source code in mcp_authflow/storage/memory.py
load_token
async
¶
Load an access token from memory.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
token
|
str
|
The access token string to look up |
required |
Returns:
| Type | Description |
|---|---|
dict[str, Any] | None
|
Token data dict if found and not expired, None otherwise |
Source code in mcp_authflow/storage/memory.py
delete_token
async
¶
Delete a token from memory.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
token
|
str
|
The access token string to delete |
required |
cleanup_expired_tokens
async
¶
Remove all expired access tokens from memory.
Returns:
| Type | Description |
|---|---|
int
|
Number of tokens removed |
get_token_count
async
¶
Get the total number of access tokens in storage.
Returns:
| Type | Description |
|---|---|
int
|
Number of tokens stored |
store_refresh_token
async
¶
store_refresh_token(
refresh_token: str,
client_id: str,
scopes: list[str],
expires_at: int,
resource: str | None = None,
user_id: UserId | None = None,
) -> None
Store a refresh token in memory.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
refresh_token
|
str
|
The refresh token string |
required |
client_id
|
str
|
OAuth client ID |
required |
scopes
|
list[str]
|
List of granted scopes |
required |
expires_at
|
int
|
Unix timestamp when token expires |
required |
resource
|
str | None
|
Optional RFC 8707 resource binding |
None
|
user_id
|
UserId | None
|
Optional ID of the user who authorized the token. May be an
int or a str so it can match the consumer's user primary key
(see :data: |
None
|
Source code in mcp_authflow/storage/memory.py
load_refresh_token
async
¶
Load a refresh token from memory.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
refresh_token
|
str
|
The refresh token string to look up |
required |
Returns:
| Type | Description |
|---|---|
dict[str, Any] | None
|
Token data dict if found and not expired, None otherwise |
Source code in mcp_authflow/storage/memory.py
delete_refresh_token
async
¶
Delete a refresh token from memory.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
refresh_token
|
str
|
The refresh token string to delete |
required |
Source code in mcp_authflow/storage/memory.py
revoke_client_tokens
async
¶
Revoke every access and refresh token issued to a client.
Source code in mcp_authflow/storage/memory.py
cleanup_expired_refresh_tokens
async
¶
Remove all expired refresh tokens from memory.
Returns:
| Type | Description |
|---|---|
int
|
Number of tokens removed |
get_refresh_token_count
async
¶
Get the total number of refresh tokens in storage.
Returns:
| Type | Description |
|---|---|
int
|
Number of refresh tokens stored |
PostgresTokenStorage¶
PostgresTokenStorage
¶
Bases: TokenStorage
Database-backed storage for MCP access tokens using PostgreSQL.
Initialize token storage.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
database_url
|
str | None
|
PostgreSQL connection URL. If not provided, will be read from DATABASE_URL environment variable. |
None
|
Source code in mcp_authflow/storage/postgres.py
initialize
async
¶
Initialize the database connection pool.
Source code in mcp_authflow/storage/postgres.py
close
async
¶
store_token
async
¶
store_token(
token: str,
client_id: str,
scopes: list[str],
expires_at: int,
resource: str | None = None,
user_id: UserId | None = None,
) -> None
Store an access token in the database.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
token
|
str
|
The access token string |
required |
client_id
|
str
|
OAuth client ID |
required |
scopes
|
list[str]
|
List of granted scopes |
required |
expires_at
|
int
|
Unix timestamp when token expires |
required |
resource
|
str | None
|
Optional RFC 8707 resource binding |
None
|
user_id
|
UserId | None
|
Optional ID of the user who authorized the token. May be an
int or a str so it can match the consumer's user primary key
(see :data: |
None
|
Source code in mcp_authflow/storage/postgres.py
load_token
async
¶
Load an access token from the database.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
token
|
str
|
The access token string to look up |
required |
Returns:
| Type | Description |
|---|---|
dict[str, Any] | None
|
Token data dict if found and not expired, None otherwise |
Source code in mcp_authflow/storage/postgres.py
delete_token
async
¶
Delete a token from the database.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
token
|
str
|
The access token string to delete |
required |
cleanup_expired_tokens
async
¶
Remove all expired tokens from the database.
Returns:
| Type | Description |
|---|---|
int
|
Number of tokens removed |
get_token_count
async
¶
Get the total number of tokens in storage.
Returns:
| Type | Description |
|---|---|
int
|
Number of tokens stored |
Source code in mcp_authflow/storage/postgres.py
store_refresh_token
async
¶
store_refresh_token(
refresh_token: str,
client_id: str,
scopes: list[str],
expires_at: int,
resource: str | None = None,
user_id: UserId | None = None,
) -> None
Store a refresh token in the database.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
refresh_token
|
str
|
The refresh token string |
required |
client_id
|
str
|
OAuth client ID |
required |
scopes
|
list[str]
|
List of granted scopes |
required |
expires_at
|
int
|
Unix timestamp when token expires |
required |
resource
|
str | None
|
Optional RFC 8707 resource binding |
None
|
user_id
|
UserId | None
|
Optional ID of the user who authorized the token. May be an
int or a str so it can match the consumer's user primary key
(see :data: |
None
|
Source code in mcp_authflow/storage/postgres.py
load_refresh_token
async
¶
Load a refresh token from the database.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
refresh_token
|
str
|
The refresh token string to look up |
required |
Returns:
| Type | Description |
|---|---|
dict[str, Any] | None
|
Token data dict if found and not expired, None otherwise |
Source code in mcp_authflow/storage/postgres.py
delete_refresh_token
async
¶
Delete a refresh token from the database.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
refresh_token
|
str
|
The refresh token string to delete |
required |
Source code in mcp_authflow/storage/postgres.py
revoke_client_tokens
async
¶
Atomically revoke every access and refresh token issued to a client.
Source code in mcp_authflow/storage/postgres.py
cleanup_expired_refresh_tokens
async
¶
Remove all expired refresh tokens from the database.
Returns:
| Type | Description |
|---|---|
int
|
Number of tokens removed |
get_refresh_token_count
async
¶
Get the total number of refresh tokens in storage.
Returns:
| Type | Description |
|---|---|
int
|
Number of refresh tokens stored |
Source code in mcp_authflow/storage/postgres.py
UserId¶
UserId
module-attribute
¶
Identifier of the user who authorized a token.
Deliberately not narrowed to int: consuming applications key users on
anything from a SERIAL/BIGINT counter to a UUID or an external
subject string. Storage backends pass the value straight through, so the type
you hand in has to match the user_id column type in your DDL (see the README
"Choosing a user_id column type" section for the BIGINT/UUID/TEXT
variants). Pass UUIDs in their string form.