Skip to main content

Levante OAuth provider for FastMCP servers.

Project description

levante-mcp-sdk

OAuth provider for FastMCP servers deployed through Levante. It wraps your MCP server with a RemoteAuthProvider that validates Levante-issued tokens: it verifies the JWT locally against Levante's JWKS and confirms the grant/membership via Levante's introspection endpoint (/api/v1/mcp/introspect), with a short-lived in-memory cache.

Part of the sdks-levante repository. The TypeScript SDK (@levante/mcp-sdk) will live in packages/mcp-sdk/ of the same repo.

Install

pip install levante-mcp-sdk

Requires Python >=3.11 and fastmcp>=2.11.1.

Usage

from fastmcp import FastMCP
from fastmcp.server.dependencies import get_access_token
from levante_mcp_sdk import LevanteAuthProvider

mcp = FastMCP(name="crm-conquer", auth=LevanteAuthProvider.from_env())


@mcp.tool
def whoami() -> dict:
    token = get_access_token()
    if token is None:
        return {"error": "not_authenticated"}
    return {
        "user_id": token.claims.get("levante_user_id"),
        "org_id": token.claims.get("levante_org_id"),
        "mcp_slug": token.claims.get("levante_mcp_slug"),
    }

LevanteAuthProvider.from_env() reads its configuration from environment variables. When the MCP is deployed through Levante with a levante.yaml, these are injected automatically; you can also set them manually for local development.

Configuration (environment variables)

Variable Required Description
LEVANTE_MCP_BASE_URL yes Public base URL of this MCP server (the RemoteAuthProvider base URL, not the Levante platform URL).
LEVANTE_INTROSPECT_URL yes Levante introspection endpoint, e.g. https://platform.levanteapp.com/api/v1/mcp/introspect.
LEVANTE_API_KEY yes A real Levante API key (lv_sk_*) the MCP uses to authenticate against /introspect.
LEVANTE_ISSUER yes OAuth issuer / authorization server, e.g. https://platform.levanteapp.com.
LEVANTE_JWKS_URI yes JWKS URI, e.g. https://platform.levanteapp.com/.well-known/jwks.json.
LEVANTE_MCP_RESOURCE yes Resource/audience for this MCP.
LEVANTE_REQUIRE_ORG_MEMBERSHIP no (true) If true, denies tokens whose user is no longer an org member.
LEVANTE_FAIL_OPEN no (false) If true, allows requests when introspection is unreachable. Leave false in production.
LEVANTE_CACHE_TTL_SECONDS no (45) TTL of the in-memory introspection cache.

Example:

LEVANTE_MCP_BASE_URL=https://crm-conquer.example.run.app
LEVANTE_INTROSPECT_URL=https://platform.levanteapp.com/api/v1/mcp/introspect
LEVANTE_API_KEY=lv_sk_...
LEVANTE_ISSUER=https://platform.levanteapp.com
LEVANTE_JWKS_URI=https://platform.levanteapp.com/.well-known/jwks.json
LEVANTE_MCP_RESOURCE=https://crm-conquer.example.run.app
LEVANTE_REQUIRE_ORG_MEMBERSHIP=true
LEVANTE_FAIL_OPEN=false
LEVANTE_CACHE_TTL_SECONDS=45

LEVANTE_API_KEY must be a real key registered in Levante; it cannot be an arbitrary string.

How it works

  1. JWT verification (local, offline): the bearer token is verified against LEVANTE_JWKS_URI with the expected issuer and audience.
  2. Introspection (cached): the token is checked against LEVANTE_INTROSPECT_URL, which returns whether the grant is active and whether the user is still an org member.
  3. Membership gate: with LEVANTE_REQUIRE_ORG_MEMBERSHIP=true, a non-member is denied even if the JWT is otherwise valid.
  4. On success, Levante identity is attached to the token claims: levante_user_id, levante_org_id, levante_mcp_slug.

Revocations may take up to LEVANTE_CACHE_TTL_SECONDS to take effect on each running instance.

Build

pip install hatch
hatch build

Publishing to PyPI is automated via .github/workflows/publish-python.yml on GitHub release.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

levante_mcp_sdk-0.1.1.tar.gz (3.9 kB view details)

Uploaded Source

Built Distribution

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

levante_mcp_sdk-0.1.1-py3-none-any.whl (5.3 kB view details)

Uploaded Python 3

File details

Details for the file levante_mcp_sdk-0.1.1.tar.gz.

File metadata

  • Download URL: levante_mcp_sdk-0.1.1.tar.gz
  • Upload date:
  • Size: 3.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for levante_mcp_sdk-0.1.1.tar.gz
Algorithm Hash digest
SHA256 b45c4902fcb0bcc23b475f41575d707e835dd6030ca34cdf231b1a5a39739d29
MD5 885bf315ac84a0e651b9c1b7ac7b12ff
BLAKE2b-256 9fdef02644760dd2c775b4d831b0620838e0f69667fe9ea345e4f38474982055

See more details on using hashes here.

Provenance

The following attestation bundles were made for levante_mcp_sdk-0.1.1.tar.gz:

Publisher: publish-python.yml on levante-hub/SDKS-Levante

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

File details

Details for the file levante_mcp_sdk-0.1.1-py3-none-any.whl.

File metadata

File hashes

Hashes for levante_mcp_sdk-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 3475f0aaea0b8518d22c5ca7535f4d49ccf1737185da667df411d40309806651
MD5 b19349ff05a517709a7b3aa2ff9b5ed5
BLAKE2b-256 f322d6dd1171564766885c79a13ae592775946f790fbbed7e93e24f4c96a7757

See more details on using hashes here.

Provenance

The following attestation bundles were made for levante_mcp_sdk-0.1.1-py3-none-any.whl:

Publisher: publish-python.yml on levante-hub/SDKS-Levante

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 Pingdom Monitoring Sentry Error logging StatusPage Status page