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:
- A middleware that decrypts a JWE Bearer token, enforces configured JWT scopes, and exposes the authenticated user's claims via
get_user(). - 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.jsonfor public key discovery/.well-known/openid-configurationfor 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:
scopesis 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)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| mcp_auth_middleware-0.1.8.tar.gz | 14.7 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| 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 logRelease 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 logSecurity 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.
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 logA 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.