Protect a FastMCP App
Use caracalai-mcp-fastmcp when a Python FastMCP app should reject invalid, expired, insufficient, or revoked Caracal mandates.
Install
Section titled “Install”pip install "caracalai-mcp-fastmcp[fastmcp]" caracalai-revocationUse caracalai-revocation-redis for shared production revocation. The in-memory store is only for local development and tests.
Create an authenticator
Section titled “Create an authenticator”from caracalai_mcp_fastmcp import CaracalAuthfrom caracalai_revocation import InMemoryRevocationStore
auth = CaracalAuth( issuer="https://sts.example.com", audience="https://mcp.example.com", expected_zone_id="zone_prod", required_scopes=["mcp:tool:call"], required_targets=["https://mcp.example.com"], revocations=InMemoryRevocationStore(), require_agent=True,)
async def startup(): await auth.warmup()Verify before running a tool
Section titled “Verify before running a tool”from caracalai_mcp_fastmcp import CaracalAuthError
async def handle_tool_call(token: str, payload: dict): try: claims = await auth(token) except CaracalAuthError as err: return {"error": err.code, "error_description": err.description, "error_hint": err.hint}
return { "subject": claims.sub, "result": await run_tool(payload), }Wire this check into the FastMCP auth or request hook used by your server. The important boundary is that the mandate is verified before the tool handler performs work.
Validate
Section titled “Validate”| Test | Expected result |
|---|---|
| Missing bearer token | missing_token or framework 401. |
| Wrong audience | invalid_token. |
| Missing scope | insufficient_scope. |
| Revoked session | session_revoked. |
Non-agent token with require_agent=True | agent_required. |
Related pages: Protect an MCP Server and Step-Up Re-Authentication.

