keycardai-fastmcp
FastMCP integration for Keycard OAuth: protect FastMCP servers with Keycard authentication and run delegated OAuth 2.0 token exchange (RFC 8693) for downstream APIs.
This is the canonical home for the integration. The old name,
keycardai-mcp-fastmcp, is retired; its final release (0.21.0) remains on
PyPI so existing pins keep resolving.
Installation
pip install keycardai-fastmcp
Quick Start
from fastmcp import FastMCP
from keycardai.fastmcp import AccessContext, AuthProvider
auth_provider = AuthProvider(
zone_id="abc1234",
mcp_server_name="My Server",
mcp_base_url="http://localhost:8000",
)
mcp = FastMCP("My Server", auth=auth_provider.get_remote_auth_provider())
@mcp.tool()
async def call_external_api(
query: str,
access: AccessContext = auth_provider.grant("https://api.example.com"),
):
token = access.access("https://api.example.com").access_token
return f"Results for {query} (token starts with {token[:8]})"
Declaring the grant as a typed parameter default injects the populated
AccessContext per request; the parameter never appears in the tool's input
schema. Exchange failures are recorded on the AccessContext (check
access.has_errors() / access.get_errors()), never raised. Granting
multiple resources is all-or-nothing: if any exchange fails, the context
carries that resource's error and no tokens.
If you lint with flake8-bugbear or Ruff's B008 rule (function call in
argument default), exempt your tool modules: the call-in-default is the
intended spelling here, the same pattern as FastAPI's Depends. In
pyproject.toml:
[tool.ruff.lint.per-file-ignores]
"src/my_server/tools/*.py" = ["B008"]
Migrating from the decorator form
The decorator form (@auth_provider.grant(...) above the tool) still works
from the same object. Reading the result via ctx.get_state("keycardai") is
deprecated and emits a DeprecationWarning; helpers that only hold the
FastMCP Context can use await AccessContext.from_context(ctx) instead.
The warning fires once per tool, at decoration time (module import). If your
test or CI setup escalates warnings to errors (-W error,
filterwarnings = ["error"] in pytest config), importing a server module
that still uses the old form will raise instead of warn. Either migrate the
tools to the injected-parameter form, or allow this warning explicitly:
filterwarnings = ["error", 'default:Tool .* uses the grant decorator:DeprecationWarning']
Testing
Fake delegated access without patching internals:
from keycardai.fastmcp.testing import mock_access_context
with mock_access_context(access_token="fake_token"):
... # grants resolve to an AccessContext serving fake_token
The bare access_token form serves the token for any resource, so it will
not catch a mistyped resource URL in an access(...) call. Pass
resource_tokens={...} when the test should enforce which resources the
tool reads; resources outside the dict raise ResourceAccessError, matching
production.
Migration from keycardai-mcp-fastmcp
The keycardai-mcp-fastmcp package is retired. Its final release, 0.21.0,
stays on PyPI so existing pins keep resolving: from keycardai.mcp.integrations.fastmcp import AuthProvider emits a
DeprecationWarning pointing here and returns the same class. New code
should depend on keycardai-fastmcp and import from keycardai.fastmcp.
Release files for keycardai-fastmcp 0.6.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 | |
|---|---|---|---|
| keycardai_fastmcp-0.6.0.tar.gz | 161.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| keycardai_fastmcp-0.6.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 182.9 kB
Release files / keycardai_fastmcp-0.6.0.tar.gz
| Download URL | keycardai_fastmcp-0.6.0.tar.gz |
|---|---|
| Size | 161.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
a51a43a534f2ba4c65080015dd272f1e6383e6d8665f731622f00aa06d3d5deb
|
|
BLAKE2b-256 checksum How to use checksums |
46214f74871c76a0e603cd90d51dacba4e6c5ad077ca49087f909fddc34b0220
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.7 {"installer":{"name":"uv","version":"0.12.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / keycardai_fastmcp-0.6.0-py3-none-any.whl
| Download URL | keycardai_fastmcp-0.6.0-py3-none-any.whl |
|---|---|
| Size | 21.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
b9280a378faac84c199952c54df8be7d134cb552d235d13884993a33c78c099a
|
|
BLAKE2b-256 checksum How to use checksums |
7c88abbbeb08284321e3328b0af07338d1417efb6fe0a4b48802164e63243219
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.7 {"installer":{"name":"uv","version":"0.12.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|