v0.4.0 — the PontifexMCP facade
PontifexMCP — a governed MCP server in a few lines
PontifexMCP is a drop-in subclass of the MCP SDK's FastMCP: swap the import and your tools keep working. The difference is what you can turn on. The floor needs no database, no Redis, and no auth — an anonymous caller, audit to stdout, stdio or localhost HTTP. You graduate to the full governance stack one keyword at a time.
from pontifex_mcp import PontifexMCP, ApiKeyAuth
mcp = PontifexMCP("payments", auth=ApiKeyAuth(), audit="audit.db")
@mcp.tool(scope="refunds:execute")
async def issue_refund(charge_id: str, amount: int, idempotency_key: str) -> dict:
...
mcp.run(http=True)What's new
- Zero-infra floor → opt-in ceiling.
auth=ApiKeyAuth()/JwtAuth()turn on Bearer auth and scope enforcement;@tool(scope="resource:action")is advisory until then. No auth → HTTP binds127.0.0.1; exposing it publicly is an explicitauth="none". - Pluggable audit sinks.
audit=is stdout by default, a path/URL for durable rows, or a list to tee. Audit needs no infrastructure to stay visible. - SQLite alongside Postgres. Point any datastore at a
sqlite:///file path for local dev or apostgresql+asyncpg://…URL for production; the dialect is detected from the connection string. Postgres keeps its schema-per-domain isolation. mcp.cacheandmcp.add_openapi(...). A Redis cache exposed to your tools, and one-line generation of governed tools from an OpenAPI spec — each authenticated, scope-checked, and audited like a hand-written one.
Compatibility
Backward-compatible. create_mcp_http_app, run_mcp_stdio, and tool_runtime are unchanged — now the lower-level path beneath the facade.
Full Changelog: v0.3.0...v0.4.0