Skip to main content

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.

PyPI version Python versions License: MIT CI Documentation MCP compatible

📖 Python API (Read the Docs): lime-mcp-server-sdk.readthedocs.io
📖 Platform HTTP docs: lime.pics/docs#guide-mcpServerSdk
📦 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(expected_domain=…) — domain-bound JWKS verify
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 + domain pin
4 Your server Use result.agent_id / result.domain 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

# Required: pin the hostname this RS serves (or set LIME_EXPECTED_DOMAIN).
verifier = TokenVerifier(expected_domain="autonomad.ai")


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:
        # Missing/invalid/mismatched domain, aud, exp, signature, …
        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(expected_domain="autonomad.ai")
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 — MCP Bearer JWT validation with mandatory domain binding
  • 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 / FastMCP
  • warmup() — prefetch OAuth metadata (RFC 8414) + Core JWKS at startup
  • Typed claimsMcpAccessTokenClaims TypedDict, 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 + domain pass
valid_claims McpAccessTokenClaims when valid (sub, domain, iss, aud, iat, exp, jti)
agent_id Alias for claims["sub"]
domain Bound RS hostname from JWT claim
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
LIME_EXPECTED_DOMAIN (required if not passed as kwarg) Hostname this RS serves; ports rejected

Domain errors (stable strings): Missing domain claim, Invalid domain claim, Domain mismatch.

Low-level helpers (tests / advanced): verify_mcp_access_token, normalize_mcp_domain, JwksCache, 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

lime_mcp_server_sdk-1.0.0.tar.gz (22.5 kB view details)

Uploaded Source

Built Distribution

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

lime_mcp_server_sdk-1.0.0-py3-none-any.whl (15.1 kB view details)

Uploaded Python 3

File details

Details for the file lime_mcp_server_sdk-1.0.0.tar.gz.

File metadata

  • Download URL: lime_mcp_server_sdk-1.0.0.tar.gz
  • Upload date:
  • Size: 22.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for lime_mcp_server_sdk-1.0.0.tar.gz
Algorithm Hash digest
SHA256 986332647ca071d8f5bef2c7e7492150ce10aec95184b80071267e0693635c43
MD5 825bd574cd698cc473fb7252fb0a3772
BLAKE2b-256 0f0fd63bd06fb3018e07c4594ffd65b4a4a5185775fa47177d4f3d4c7d84fbd3

See more details on using hashes here.

Provenance

The following attestation bundles were made for lime_mcp_server_sdk-1.0.0.tar.gz:

Publisher: publish.yml on Mawyxx/lime-mcp-server-sdk

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file lime_mcp_server_sdk-1.0.0-py3-none-any.whl.

File metadata

File hashes

Hashes for lime_mcp_server_sdk-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 19d6b439bf74ed0f6eba3ea8a00979a815e8713181e9e217d4a0a316eda901da
MD5 8d1768a9448e9303d86c309ce07b593e
BLAKE2b-256 2431a26e1228df3bb65d2f0207b4895d24f8a0c8a8deac2ee503f455581aaa7e

See more details on using hashes here.

Provenance

The following attestation bundles were made for lime_mcp_server_sdk-1.0.0-py3-none-any.whl:

Publisher: publish.yml on Mawyxx/lime-mcp-server-sdk

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

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