lime-mcp-server-sdk — MCP OAuth JWT Verification (JWKS + RS256)
lime-mcp-server-sdk is the official Python server SDK for LIME MCP resource servers — verify MCP OAuth Bearer JWTs issued by LIME with JWKS + RS256, in-process caching, and zero-config defaults for production. Built for the Anthropic MCP ecosystem: agents authenticate with lime-agents-sdk; your server validates Authorization: Bearer tokens without hand-rolled PyJWT or metadata fetches on every request.
Use this package when you operate an external MCP resource server (FastMCP, custom HTTP /mcp, etc.). Not for site login passports (aud=lime-site-login) — use lime-sites-sdk on site backends.
📖 Platform API docs: https://lime.pics/docs
📦 This SDK: github.com/Mawyxx/lime-mcp-server-sdk
🌐 Platform: https://lime.pics
Why lime-mcp-server-sdk?
| Problem | SDK solution |
|---|---|
| Manual JWKS fetch + PyJWT setup | TokenVerifier() — metadata-driven issuer + cached JWKS |
| Per-request network to LIME | In-memory JWKS cache (TTL, kid refresh, stale fallback) |
| Blocking verify in async servers | verify_async() via asyncio.to_thread |
| Framework lock-in | Core wheel only — bring your own FastMCP / Starlette middleware |
MCP OAuth JWT flow (this SDK)
| Step | Who | What happens |
|---|---|---|
| 1 | Agent (lime-agents-sdk) |
POST /api/v1/modules/oauth/token with X-Agent-Token → MCP JWT (~5 min TTL) |
| 2 | Agent | Calls your MCP RS with Authorization: Bearer <jwt> |
| 3 | Your server (this SDK) | TokenVerifier.verify(token) → RS256 + aud=mcp + issuer |
| 4 | Your server | Use result.agent_id (sub claim) for authorization |
| Artifact | Audience | Verified by |
|---|---|---|
| MCP access JWT | External MCP resource servers | lime-mcp-server-sdk (TokenVerifier) |
| Site passport JWT | Site backends (aud=lime-site-login) |
lime-sites-sdk — different token, different SDK |
Security: MCP JWTs are rejected on LIME HTTP APIs. This SDK is for your MCP server only.
Installation
pip install lime-mcp-server-sdk
Latest from GitHub:
pip install git+https://github.com/Mawyxx/lime-mcp-server-sdk.git
Requirements: Python 3.10+ · import: lime_mcp_server · deps: PyJWT, cryptography, httpx
Quick start
Scenario A — Sync verify (middleware / request handler)
Story: Extract the Bearer token from an incoming MCP request and verify it before executing tools.
from lime_mcp_server import TokenVerifier
verifier = TokenVerifier() # LIME_BASE_URL=https://lime.pics, LIME_OAUTH_AUDIENCE=mcp
def authorize_mcp_request(authorization_header: str | None) -> str | None:
if not authorization_header:
return None
token = authorization_header.removeprefix("Bearer ").strip()
if not token:
return None
result = verifier.verify(token)
if not result.is_valid:
# result.error explains invalid signature, aud, exp, forbidden claims, etc.
return None
return result.agent_id # alias for claims["sub"] — agent UUID
MCP OAuth identity is claim sub (UUID). There is no separate agent_id JWT claim.
Scenario B — Async FastMCP + JWKS warmup (production)
Story: Warm JWKS at startup so verification stays fast; use async verify in your MCP auth hook.
from contextlib import asynccontextmanager
from fastmcp import FastMCP
from lime_mcp_server import TokenVerifier
verifier = TokenVerifier()
mcp = FastMCP("my-tools")
@asynccontextmanager
async def lifespan(app):
if not verifier.warmup(raise_on_failure=True):
raise RuntimeError("JWKS warmup failed")
yield
async def verify_bearer(authorization: str) -> str | None:
token = authorization.removeprefix("Bearer ").strip()
if not token:
return None
result = await verifier.verify_async(token)
if not result.is_valid:
# log result.error in production (invalid aud, expired, bad signature, …)
return None
return result.agent_id
# Wire verify_bearer into your MCP server's auth layer.
# Monorepo reference: github.com/Mawyxx/Lime — scripts/verify/lime_mcp_rs_auth.py
JwksCache.fetch_count tracks successful metadata + JWKS network fetches (ops/debug).
Features
TokenVerifier— single entry point for MCP Bearer JWT validation- JWKS caching — TTL (default 3600s),
kid-mismatch refresh, min refresh interval, stale fallback on network errors - Fast path after warmup — verify uses cached keys; no metadata round-trip per request
- RS256 — PyJWT +
cryptography; rejects forbidden site-login claims (user_id,request_id, …) verify_async()— non-blocking verify for ASGI / FastMCPwarmup()— prefetch OAuth metadata (RFC 8414) + Core JWKS at startup- Typed claims —
McpAccessTokenClaimsTypedDict,py.typed, mypy strict
API reference (summary)
TokenVerifier
| Method / property | Description |
|---|---|
verify(token) |
Sync RS256 verify → TokenValidationResult |
await verify_async(token) |
Same, non-blocking |
warmup(raise_on_failure=False) |
Prefetch metadata + JWKS |
refresh_cache() / invalidate_cache() |
Force refresh or clear cache |
.cache |
JwksCache (incl. fetch_count) |
.config |
Resolved LimeConfig |
TokenValidationResult
| Field / property | Description |
|---|---|
is_valid |
True when signature + iss + aud + exp pass |
valid_claims |
McpAccessTokenClaims when valid (sub, iss, aud, iat, exp, jti) |
agent_id |
Alias for claims["sub"] |
error |
Human-readable reason when invalid |
Environment variables
| Variable | Default | Description |
|---|---|---|
LIME_BASE_URL |
https://lime.pics |
LIME origin for OAuth metadata + JWKS |
LIME_OAUTH_AUDIENCE |
mcp |
Expected JWT aud |
LIME_JWKS_CACHE_TTL_SECONDS |
3600 |
Metadata + JWKS cache TTL |
LIME_JWT_VERIFY_LEEWAY_SECONDS |
120 |
Clock skew leeway |
LIME_JWKS_MIN_REFRESH_SECONDS |
60 |
Min interval between forced JWKS refresh |
Low-level helpers (tests / advanced): verify_mcp_access_token, JwksCache, unwrap_lime_data, FORBIDDEN_MCP_CLAIMS.
Related packages
| Package | Role |
|---|---|
lime-agents-sdk |
Agent worker: issue MCP JWT + MCP client (list_tools, call_tool) |
lime-sites-sdk |
Site backend: site passport JWT via SSE (not MCP tokens) |
Contributing
Issues and pull requests: github.com/Mawyxx/lime-mcp-server-sdk
git clone https://github.com/Mawyxx/lime-mcp-server-sdk.git
cd lime-mcp-server-sdk
pip install -e ".[dev]"
ruff check src tests
mypy src/lime_mcp_server
pytest --cov=lime_mcp_server --cov-fail-under=100
CI runs on Python 3.10–3.13 with 100% line coverage on src/lime_mcp_server.
Live integration (optional):
LIME_MCP_SERVER_INTEGRATION=1 LIME_AGENT_TOKEN=at_... pytest tests/integration/ -v
License
MIT — see LICENSE.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file lime_mcp_server_sdk-0.4.4.tar.gz.
File metadata
- Download URL: lime_mcp_server_sdk-0.4.4.tar.gz
- Upload date:
- Size: 13.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2a06bd14029195e7b9014f3345c7b1738bc15795d89c0ba6fc2fa683bccf0b9c
|
|
| MD5 |
53838567a21c09f090256f8bce2ff628
|
|
| BLAKE2b-256 |
9a1bb9ef1e47b33a7b358c9e181a504a854aae9a8f5a101121e38e4716984f45
|
Provenance
The following attestation bundles were made for lime_mcp_server_sdk-0.4.4.tar.gz:
Publisher:
publish.yml on Mawyxx/lime-mcp-server-sdk
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
lime_mcp_server_sdk-0.4.4.tar.gz -
Subject digest:
2a06bd14029195e7b9014f3345c7b1738bc15795d89c0ba6fc2fa683bccf0b9c - Sigstore transparency entry: 2061704815
- Sigstore integration time:
-
Permalink:
Mawyxx/lime-mcp-server-sdk@9cc05e596b3ed80c404ac642c474b59c9aab7d77 -
Branch / Tag:
refs/tags/v0.4.4 - Owner: https://github.com/Mawyxx
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@9cc05e596b3ed80c404ac642c474b59c9aab7d77 -
Trigger Event:
push
-
Statement type:
File details
Details for the file lime_mcp_server_sdk-0.4.4-py3-none-any.whl.
File metadata
- Download URL: lime_mcp_server_sdk-0.4.4-py3-none-any.whl
- Upload date:
- Size: 12.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e5a1fc00ff3c60e4f9332764000c2510917059bff68abc8b0337ae1ce0940c69
|
|
| MD5 |
cb2b26fb4a85e6856be8b0c8ed916b6f
|
|
| BLAKE2b-256 |
52444559158e438ea22b28ec7f714f89357c2d9d0c86bb8251cd68b353fcd7b3
|
Provenance
The following attestation bundles were made for lime_mcp_server_sdk-0.4.4-py3-none-any.whl:
Publisher:
publish.yml on Mawyxx/lime-mcp-server-sdk
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
lime_mcp_server_sdk-0.4.4-py3-none-any.whl -
Subject digest:
e5a1fc00ff3c60e4f9332764000c2510917059bff68abc8b0337ae1ce0940c69 - Sigstore transparency entry: 2061705002
- Sigstore integration time:
-
Permalink:
Mawyxx/lime-mcp-server-sdk@9cc05e596b3ed80c404ac642c474b59c9aab7d77 -
Branch / Tag:
refs/tags/v0.4.4 - Owner: https://github.com/Mawyxx
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@9cc05e596b3ed80c404ac642c474b59c9aab7d77 -
Trigger Event:
push
-
Statement type: