Skip to main content

mcp-auth-middleware

JWE authentication middleware for HTTP MCP servers. Encrypt user data end-to-end so that only your MCP server can read it.

What it does

mcp-auth-middleware gives your MCP server two things:

  1. A middleware that decrypts a JWE Bearer token, enforces configured JWT scopes, and exposes the authenticated user's claims via get_user().
  2. A CLI (mcp-auth-middleware) that generates RSA key pairs in JWKS format, outputs Kubernetes Secret YAML, and securely deletes local keys when you're done.

The middleware also publishes:

  • /.well-known/jwks.json for public key discovery
  • /.well-known/openid-configuration for OpenID discovery

Installation

pip install mcp-auth-middleware

Testing

python -m pip install -r requirements.txt
python -m pip install -e .
pytest --cov=mcp_auth_middleware --cov-report=term-missing --cov-fail-under=80

Quick start

1. Generate keys

mcp-auth-middleware generate

This writes:

.keys/mcp-private.json
.keys/mcp-public.json

2. Configure the private key

MCP_KEY_FILE_PATH=.keys/mcp-private.json

3. Add the middleware

import uvicorn
from fastmcp import FastMCP

from mcp_auth_middleware import JWKSAuthMiddleware, get_user

mcp = FastMCP("My Server")

required_scopes = [
    {"scope": "name"},
    {"scope": "email"},
]


@mcp.tool()
def whoami() -> str:
    user = get_user()
    return f"Hello, {user.name}!"


app = mcp.http_app()
app.add_middleware(JWKSAuthMiddleware, scopes=required_scopes)

if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=8000)

4. OpenID discovery

GET /.well-known/openid-configuration returns the issuer, JWKS URI, and configured scopes:

{
  "issuer": "http://localhost:8000",
  "jwks_uri": "http://localhost:8000/.well-known/jwks.json",
  "scopes_supported": ["name", "email"]
}

The endpoint is public and includes permissive CORS headers.

5. Missing scope response

If a verified token is missing one or more configured fields, the middleware rejects the request with 403 Forbidden:

{
  "error": "missing_scopes",
  "missing": [{ "scope": "email" }]
}

API reference

JWKSAuthMiddleware

Attach it to any Starlette-based MCP server app:

app.add_middleware(
    JWKSAuthMiddleware,
    scopes=[
        {"scope": "name"},
    ],
    verifier=None,
    jwks_path="/.well-known/jwks.json",
    openid_configuration_path="/.well-known/openid-configuration",
    issuer=None,
)

Rules:

  • scopes is required and must contain at least one scope.
  • Every configured scope is mandatory.
  • Scope names must match JWT field names.

get_user() -> AuthUser

Returns the authenticated user's claims for the current request.

user = get_user()
user.email
user["email"]

ScopeDefinition

Optional helper dataclass for typed configuration:

from mcp_auth_middleware import ScopeDefinition

scope = ScopeDefinition(
    scope="email",
)

JWETokenVerifier

Lower-level verifier if you need token verification outside the middleware:

from mcp_auth_middleware import JWETokenVerifier

verifier = JWETokenVerifier()
claims = await verifier.verify_token(token_string)
public_jwks = verifier.get_jwks()

verify_token() returns None when token decryption fails or when the decrypted payload is not a JSON object.

Browser access

/.well-known/openid-configuration already includes CORS headers.

If browser clients also need /.well-known/jwks.json, add CORS middleware after JWKSAuthMiddleware:

from starlette.middleware.cors import CORSMiddleware

app.add_middleware(JWKSAuthMiddleware, scopes=required_scopes)
app.add_middleware(CORSMiddleware, allow_origins=["*"])

Kubernetes deployment

Generate a Secret manifest:

mcp-auth-middleware k8s | kubectl apply -f -

Clean up local key material:

mcp-auth-middleware clean

Mount the generated private key and set:

MCP_KEY_FILE_PATH=/etc/mcp/secrets/key.json

A full example Deployment + Service is in examples/k8s-deployment.yaml.

Environment variables

Variable Required Description
MCP_KEY_FILE_PATH Yes Path to the private JWKS JSON file

License

MIT

Metadata

Release files for mcp-auth-middleware 0.1.8

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for mcp-auth-middleware 0.1.8
File Size Uploaded Provenance
mcp_auth_middleware-0.1.8.tar.gz 14.7 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for mcp-auth-middleware 0.1.8
File Interpreter ABI Platform
mcp_auth_middleware-0.1.8-py3-none-any.whl Python 3 none any Details

Total release size: 25.5 kB

Release files / mcp_auth_middleware-0.1.8.tar.gz

Download URL mcp_auth_middleware-0.1.8.tar.gz
Size 14.7 kB
Tags Source
SHA-256 checksum
How to use checksums
4a47ceba3ccfe07800521d69bd0d77a20d54044719367297d944128d2ad0a307
BLAKE2b-256 checksum
How to use checksums
bcae5c8c6b8f25f8e11dccccf08ecf353d22db6c7dcc3d978eb1f446de4717c5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Mar 22, 2026.

Transparency log

Release files / mcp_auth_middleware-0.1.8-py3-none-any.whl

Download URL mcp_auth_middleware-0.1.8-py3-none-any.whl
Size 10.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
efd8d663eb41e5d621b3c96ba50c36d7a258c559c5f22be3dab905a7f7c57bca
BLAKE2b-256 checksum
How to use checksums
a01ada2a72c5911e5c880deb675ca3da6222ee92c3cbaf5f9d46526e5496fe46
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Mar 22, 2026.

Transparency log

Security for mcp-auth-middleware 0.1.8

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.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for mcp_auth_middleware-0.1.8.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Mar 22, 2026.

Transparency log

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.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page