fastmcp-creds
Pluggable credential management for FastMCP servers — supply API tokens or username/password credentials for the backend services they connect to, from environment variables, OS keychain, or HTTP headers, with automatic fallback through a priority chain.
The framework-neutral parts — the chain and the environment and keychain providers — live in credchain and are re-exported here unchanged, so existing imports keep working. This package adds the providers that read FastMCP's HTTP request headers.
Installation
pip install fastmcp-creds
# or, with uv:
uv add fastmcp-creds
The KeyringCredentialsProvider requires the optional keyring extra:
pip install fastmcp-creds[keyring]
# or, with uv:
uv add fastmcp-creds[keyring]
Requires Python 3.10+.
Usage
Credential provider chain
Compose providers in priority order. The chain tries each in sequence and returns the first result where both username and password (or token) are non-empty.
from fastmcp_creds import (
CredentialsProviderChain,
BasicAuthCredentialsProvider,
EnvironmentCredentialsProvider,
)
from fastmcp_creds.keyring import KeyringCredentialsProvider # optional dep
chain = CredentialsProviderChain([
KeyringCredentialsProvider("my-service"),
BasicAuthCredentialsProvider(),
EnvironmentCredentialsProvider("MY_USERNAME", "MY_PASSWORD"),
])
username, password = chain.get_credentials()
Environment variables
Read username and password from two environment variables:
from fastmcp_creds import EnvironmentCredentialsProvider
provider = EnvironmentCredentialsProvider("MY_USERNAME", "MY_PASSWORD")
username, password = provider.get_credentials()
For a single token variable:
provider = EnvironmentCredentialsProvider.for_token("MY_API_TOKEN")
token, _ = provider.get_credentials()
HTTP Basic Auth header
Decode credentials from the standard Authorization: Basic <base64> header.
Also accepts the non-compliant Bearer Basic <base64> variant emitted by MCP
Inspector, and raw base64 without a scheme prefix.
from fastmcp_creds import BasicAuthCredentialsProvider
provider = BasicAuthCredentialsProvider()
username, password = provider.get_credentials()
Optionally check a custom header first before falling back to Authorization:
provider = BasicAuthCredentialsProvider(custom_header_name="X-My-Auth")
Custom HTTP headers
Read credentials from two plain-text HTTP headers:
from fastmcp_creds import CustomHeaderCredentialsProvider
provider = CustomHeaderCredentialsProvider("X-Username", "X-Password")
username, password = provider.get_credentials()
For a single token header:
provider = CustomHeaderCredentialsProvider.for_token("X-Api-Token")
token, _ = provider.get_credentials()
OS keychain
Read credentials stored in the OS keychain via
keyring. Requires fastmcp-creds[keyring].
from fastmcp_creds.keyring import KeyringCredentialsProvider
# Two-key mode: reads "username" and "password" entries under the service name
provider = KeyringCredentialsProvider("my-service")
username, password = provider.get_credentials()
# Token mode: reads a single "token" entry
provider = KeyringCredentialsProvider.for_token("my-service")
token, _ = provider.get_credentials()
# Custom key names
provider = KeyringCredentialsProvider("my-service", username_key="user", password_key="secret")
provider = KeyringCredentialsProvider.for_token("my-service", token_key="jwt")
# Custom lookup timeout in seconds (default 5), or None to wait indefinitely
provider = KeyringCredentialsProvider("my-service", timeout=10)
The keychain lookup is bounded by a timeout, so a locked or unresponsive
keychain (e.g. one waiting for an unlock prompt in a headless session) cannot
stall server startup. On timeout, a warning is logged and (None, None) is
returned, so a CredentialsProviderChain falls through to its next provider.
API Reference
CredentialsProvider
CredentialsProvider is a Protocol — any object with a
get_credentials() -> tuple[str | None, str | None] method satisfies it.
CredentialsProviderChain
CredentialsProviderChain(providers) — tries each provider in order and
returns the first result where both values are non-empty. Returns
(None, None) if no provider succeeds.
| Method | Description |
|---|---|
get_credentials() |
Returns tuple[str | None, str | None] — (username, password) or (token, token) |
EnvironmentCredentialsProvider
EnvironmentCredentialsProvider(username_env_var_name, password_env_var_name)
— reads two environment variables.
EnvironmentCredentialsProvider.for_token(token_env_var_name) — reads a
single environment variable; returns it as both elements of the tuple.
| Method | Description |
|---|---|
get_credentials() |
Returns tuple[str | None, str | None] |
BasicAuthCredentialsProvider
BasicAuthCredentialsProvider(custom_header_name=None) — extracts credentials
from an HTTP Basic Auth header. Checks custom_header_name first if provided,
then falls back to the standard Authorization header. Silently ignores
unresolved MCP client placeholders (e.g. ${MY_VAR}).
| Method | Description |
|---|---|
get_credentials() |
Returns tuple[str | None, str | None]; raises BasicAuthError on malformed headers |
CustomHeaderCredentialsProvider
CustomHeaderCredentialsProvider(username_header_name, password_header_name)
— reads credentials from two plain-text HTTP headers. Ignores unresolved
placeholders.
CustomHeaderCredentialsProvider.for_token(token_header_name) — reads a
single header; returns it as both elements of the tuple.
| Method | Description |
|---|---|
get_credentials() |
Returns tuple[str | None, str | None] |
KeyringCredentialsProvider
KeyringCredentialsProvider(service, username_key="username", password_key="password", timeout=5.0)
— reads credentials stored in the OS keychain under the given service name.
Returns (None, None) if the keychain does not answer within timeout seconds
(None waits indefinitely). Requires fastmcp-creds[keyring].
KeyringCredentialsProvider.for_token(service, token_key="token", timeout=5.0)
— reads a single keychain entry.
| Method | Description |
|---|---|
get_credentials() |
Returns tuple[str | None, str | None] |
BasicAuthError
BasicAuthError(message, header_name) — raised by BasicAuthCredentialsProvider
when a header is present but malformed (bad base64, unsupported scheme, missing
colon separator, empty username or password).
| Field | Type | Description |
|---|---|---|
header_name |
str |
Name of the header that caused the error |
is_unresolved_placeholder_value
is_unresolved_placeholder_value(value: str) -> bool — returns True when a
header value is an unresolved MCP client placeholder such as ${MY_VAR} or
Basic ${MY_VAR}. Used internally by BasicAuthCredentialsProvider and
CustomHeaderCredentialsProvider; exposed for custom provider implementations.
Contributing
See CONTRIBUTING.md for development setup and guidelines.
License
MIT — see LICENSE.
Metadata
Release files for fastmcp-creds 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| fastmcp_creds-0.1.0.tar.gz | 146.7 kB | Without provenance | Details for fastmcp_creds-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| fastmcp_creds-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for fastmcp_creds-0.1.0-py3-none-any.whl |
Total release size: 156.0 kB
Release files / fastmcp_creds-0.1.0.tar.gz
| Download URL | fastmcp_creds-0.1.0.tar.gz |
|---|---|
| Size | 146.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
7ce5d90e220a09260fc22e42267a2dea3660f367a68d909df730691ad99c7987
|
|
BLAKE2b-256 checksum How to use checksums |
f864702bf4e54ae6d07fe7f9ac121d421bcb731e7adbec1896b3ab63c31a010d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.13.7 {"installer":{"name":"uv","version":"0.13.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / fastmcp_creds-0.1.0-py3-none-any.whl
| Download URL | fastmcp_creds-0.1.0-py3-none-any.whl |
|---|---|
| Size | 9.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
baf9b5585b566711d5609b5407e512c9b04151485ac8dfc9ef7142930c654614
|
|
BLAKE2b-256 checksum How to use checksums |
491c6f8ea21fb6347a386ab95c9d01a35ac12df455795d0ceb93b16e53cef449
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.13.7 {"installer":{"name":"uv","version":"0.13.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Security for fastmcp-creds 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.