Secure your MCP tools: verify LIME JWTs locally with JWKS, trust claims.sub as agent_id — no calls back to LIME per request.
| Role | Responsibility |
|---|---|
| Agent runtime | Gets MCP JWT from LIME, sends Bearer token to your server. |
| Your MCP resource server | Verify JWT, enforce aud=mcp, authorize by claims.sub. |
| LIME | Issues JWTs, publishes JWKS and OAuth metadata. |
Only what you implement in this role. No PoW, SSE, or token logic from the partner side — that is in a separate guide.
At startup you may fetch RFC 8414 metadata to learn issuer and JWKS URI. Hard-coding https://lime.pics is fine for LIME production.
# RFC 8414 metadata (raw JSON — read issuer, jwks_uri at top level)
curl -sS "https://lime.pics/api/v1/modules/oauth/.well-known/oauth-authorization-server"
# Also at issuer root (nginx alias):
# curl -sS "https://lime.pics/.well-known/oauth-authorization-server"
# Example response (full discovery document):
# {"issuer":"https://lime.pics","authorization_endpoint":"https://lime.pics/api/v1/modules/oauth/authorize","token_endpoint":"https://lime.pics/api/v1/modules/oauth/token","jwks_uri":"https://lime.pics/api/v1/core/.well-known/jwks.json","registration_endpoint":"https://lime.pics/api/v1/modules/oauth/register","grant_types_supported":["authorization_code","client_credentials"],"response_types_supported":["code"],"scopes_supported":["mcp"],"token_endpoint_auth_methods_supported":["none"],"code_challenge_methods_supported":["S256"],"lime_agent_token_header":"X-Agent-Token","lime_token_request_body":"grant_type","lime_default_audience":"mcp"}Read Authorization: Bearer <token> on each MCP invocation. Reject missing or malformed headers before running tool logic.
Validate with JWKS: iss must be https://lime.pics, aud must include mcp, exp in the future. Use claims.sub as the stable agent_id for ACLs.
# pip install lime-mcp-server-sdk
# https://github.com/Mawyxx/lime-mcp-server-sdk
# Full Python API: https://lime-mcp-server-sdk.readthedocs.io/
from lime_mcp_server import TokenVerifier
verifier = TokenVerifier() # LIME_BASE_URL, LIME_OAUTH_AUDIENCE from env
result = verifier.verify("{access_token_from_oauth_token_response}")
if result.is_valid:
print(result.agent_id) # alias for claims["sub"] (agent UUID)Map agent_id to allowed tools/namespaces. Return 403 when identity is valid but not permitted; 401 when token is invalid.
Tip: Never accept X-Agent-Token on MCP RS — that is LIME's opaque agent secret, not the MCP JWT.
Agents exchange agent_token for a short-lived MCP JWT at LIME, then send Authorization: Bearer to your server. You only verify — never issue tokens.
Every MCP request with a valid Bearer JWT is accepted; invalid/expired/wrong-audience tokens return 401; you log agent_id from claims.sub for audit.
The agent_id in MCP JWT is the same UUID users link on sites via Agent Binding and prove on Zero Human Auth:
Sites persist agent_id when users connect at /connect. Your ACL can allow or deny that UUID — one global identity namespace.
Zero Human Auth also ends with claims.sub on the site backend. Treat MCP JWT sub and site-login passport sub as the same agent_id.
# pip install lime-mcp-server-sdk
# https://github.com/Mawyxx/lime-mcp-server-sdk
# Full Python API: https://lime-mcp-server-sdk.readthedocs.io/
from lime_mcp_server import TokenVerifier
verifier = TokenVerifier()
result = verifier.verify("{bearer_mcp_jwt}")
if result.is_valid:
print(result.agent_id) # alias for claims["sub"]