About Example Python
Example Python is an MCP server in the Search category: this example demonstrates a minimal FastMCP application with integrated JWT-based authentication middleware.
Install
git clone https://github.com/systemiq-ai/mcp-example-pythonThis server has no ConduID identity, so agent calls to it are not receipted. Pin the version you install and review the source before granting it credentials.
Ask AI
Ask AI about Example Python
Powered by Claude · Grounded in docs
Security checks
- ✓README presentThe repository ships documentation.
5 checks have not been run yet.
README
MCP Example with Auth Integration
This repo shows how to run a Model Context Protocol (MCP) server over streamable HTTP and protect it with JWT-based authentication.
Authentication happens in a lightweight ASGI middleware that validates the incoming Authorization: Bearer <token> header and exposes the decoded payload to MCP tools safely via ContextVars (isolated per request).
- Secure MCP over HTTP: Every MCP request must provide a valid bearer token
- Tools: Example
greetandextensiontools that can read the token payload - Concurrency-safe auth: Token & payload are stored in ContextVars (no cross-request leakage)
- Host protection: FastMCP transport security only allows local hosts such as
host.docker.internal,localhost, and127.0.0.1
Requirements
-
Python 3.13+
-
A valid RS256 JWT (must include:
client_idinCLIENT_IDSscopesincluding"client_super")
-
Env vars:
PUBLIC_KEY(PEM string for RS256)CLIENT_IDS(comma-separated IDs, e.g.1,2,3)
Setup
Install dependencies:
pip install -r requirements.txt
Export environment variables:
export PUBLIC_KEY="-----BEGIN PUBLIC KEY-----
...your RS256 public key...
-----END PUBLIC KEY-----"
export CLIENT_IDS="1,2,3"
Run
You can run either way:
# direct
python main.py
# or with uvicorn (dev hot-reload)
ENVIRONMENT=development uvicorn main:app --reload
The app serves a streamable HTTP MCP endpoint:
POST /mcp– JSON-RPC requests for MCPGET /mcp– optional long-lived stream / notifications when supported by the client library
All MCP HTTP requests are protected by the JWT middleware.
How Authentication Works
-
A custom ASGI middleware validates the
Authorization: Bearer <token>header:- Verifies RS256 signature using
PUBLIC_KEY - Checks
client_id∈CLIENT_IDS - Requires
"client_super"inscopes
- Verifies RS256 signature using
-
On success, it stores the raw token and decoded payload in ContextVars:
auth_token: ContextVar[str | None]auth_payload: ContextVar[dict]
-
In your MCP tools, you read these without touching HTTP/Starlette objects:
- This is safe under concurrency: ContextVars are isolated per request.
Example Tools
from mcp.server.fastmcp import FastMCP
from auth import auth_token, auth_payload # ContextVars set by middleware
mcp = FastMCP("My Tool Server")
@mcp.tool()
def greet(name: str) -> str:
token = auth_token.get()
payload = auth_payload.get()
# Use payload as needed (e.g., enforce scopes, log client_id, etc.)
return f"Hello, {name}!"
@mcp.tool()
def extension(config: object, data: list, action: str) -> bool:
token = auth_token.get()
payload = auth_payload.get()
return True
Note: We do not rely on HTTP request objects in the tools; they remain transport-agnostic.
Docker
A Dockerfile is included.
Build
docker build -t mcp-example .
Run
docker run --rm \
-e PUBLIC_KEY="-----BEGIN PUBLIC KEY-----\n...\n-----END PUBLIC KEY-----" \
-e CLIENT_IDS="1" \
-p 8000:8000 \
mcp-example
Notes & Guarantees
- Isolation: ContextVars ensure each request sees only its own
token/payload. - No framework coupling: Tools don’t need direct access to HTTP request objects.
- Scopes: By default, the middleware requires
"client_super"; adapt as needed. - Host validation: FastMCP rejects unexpected
Hostheaders unless they are listed inallowed_hosts.
Further Information
You can also find extended documentation at Model Context Protocol.
License
MIT © systemiq.ai
README copy captured when this server was indexed; it may lag the repository. The original is authoritative.