Skip to main content

mcp-authz (Python)

Authorization for servers built with the official MCP Python SDK v2. It uses the SDK's MCPServer, TokenVerifier, AccessToken, AuthSettings, and server-middleware interfaces rather than replacing the protocol stack.

pip install mcp-authz
from mcp.server.auth.settings import AuthSettings
from mcp_authz import AuthorizedMCPServer, JwtVerifier, current_principal, define_policy

policy = define_policy({
    "roles": {
        "reader": ["cases:read"],
        "editor": ["cases:read", "cases:write"],
    },
    "rules": [
        {"match": {"domain": "acme.com"}, "role": "reader"},
        {"match": {"email": "alice@acme.com"}, "role": "editor"},
    ],
})

server = AuthorizedMCPServer(
    "cases",
    policy=policy,
    token_verifier=JwtVerifier(
        issuer="https://auth.acme.com",
        jwks_uri="https://auth.acme.com/.well-known/jwks.json",
        resource="https://mcp.acme.com/mcp",
    ),
    auth=AuthSettings(
        issuer_url="https://auth.acme.com",
        resource_server_url="https://mcp.acme.com/mcp",
        required_scopes=["mcp"],
    ),
)

@server.tool(permission="cases:read")
def get_case(case_id: str) -> dict[str, str]:
    return {"id": case_id}

app = server.streamable_http_app(stateless_http=True)

The verifier checks signature, issuer, resource audience, expiry, stable subject, and verified email. Stable identities are (issuer, sub), and email or domain policy rules match only verified email identities. Policy is deny-by-default; matching deny rules override grants. Unauthorized tools, prompts, and resources are filtered from discovery and rejected if called directly.

Tools, prompts, and resources are first-class MCP capabilities:

@server.prompt(permission="reports:generate")
def release_report(version: str) -> str: ...

@server.resource("case://{case_id}", permission="cases:read")
def case(case_id: str) -> str: ...

Inside a handler, current_principal() exposes the authorization context for tenant and row-level decisions. The package performs the declared capability permission check; the application uses the resulting principal to constrain its own domain query.

The official Python SDK currently exposes only global HTTP scope requirements. AuthSettings.required_scopes therefore enforces the baseline scope, while per-capability permissions control discovery and invocation. The shared routing and scope helpers pin the intended step-up behavior, but this package does not double-verify tokens or patch private SDK routes to manufacture transport-level per-capability challenges.

The package runs the same language-neutral policy, scope, and routing fixtures as mcp-authz, preventing the two implementations from drifting.

Development

uv sync --all-extras
uv run ruff check src tests
uv run mypy src tests
uv run pytest
uv build

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mcp_authz-0.1.0.tar.gz (85.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mcp_authz-0.1.0-py3-none-any.whl (12.2 kB view details)

Uploaded Python 3

File details

Details for the file mcp_authz-0.1.0.tar.gz.

File metadata

  • Download URL: mcp_authz-0.1.0.tar.gz
  • Upload date:
  • Size: 85.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.5.6

File hashes

Hashes for mcp_authz-0.1.0.tar.gz
Algorithm Hash digest
SHA256 a5628bd8e74f271584682e749d86fd703ab1fb4c366ea225459cabbbaff29f81
MD5 9c4342beb2a03b1185ff436fb04bd39a
BLAKE2b-256 6e834ac3fcb4119a74610b913496e2f1d3120b6db341bd02762e47ad9af52e76

See more details on using hashes here.

File details

Details for the file mcp_authz-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: mcp_authz-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 12.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.5.6

File hashes

Hashes for mcp_authz-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 00eb148703a62bfe59f31b87269fa5673f6986a0e4b76de512169219638b6a8e
MD5 9b2206315f7b588d22964b007bbea094
BLAKE2b-256 0064201316ea2178395ff3bd25c06f413701588a19bcf920bb275b34b03b5427

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page