Skip to content

Quick start

Single source of truth: this page is rendered directly from the README. Edit the README to update both.

Quick start

Step 1 — Declare current_user

The library is wired together through a single ContextVar that you create and own. Declare it once at module level in your server file and pass it to everything:

from contextvars import ContextVar

# You create this. The middleware writes it; providers read it.
current_user: ContextVar[dict | None] = ContextVar("current_user", default=None)

Python scopes ContextVar per async task automatically, so concurrent requests never interfere.

Step 2 — Add the JWT middleware (Leg 1)

from mcpauthkit.auth_middleware import JwtAuthMiddleware
from mcpauthkit.auth_routes import oauth_meta_router

app.include_router(oauth_meta_router(
    server_base_url=SERVER_URL,
    issuer_url=ISSUER_URL,
    client_id=CLIENT_ID,
))

app.add_middleware(
    JwtAuthMiddleware,
    issuer_url=ISSUER_URL,
    current_user=current_user,
    server_base_url=SERVER_URL,
    open_paths=("/.well-known", "/health", "/register"),
)

Step 3 — Gate a tool behind a third-party OAuth token (Leg 2a)

from mcpauthkit import OAuthProvider

provider = OAuthProvider.from_standard_oauth2(
    name="github",
    authorization_url="https://github.com/login/oauth/authorize",
    token_url="https://github.com/login/oauth/access_token",
    client_id=os.environ["GITHUB_CLIENT_ID"],
    client_secret=os.environ["GITHUB_CLIENT_SECRET"],
    scope="read:user repo",
    redirect_uri=f"{SERVER_URL}/github/callback",
    user_context=current_user,
)
provider.register(app)

@mcp.tool()
@provider.require_token()
async def list_prs(ctx: Context, repo: str) -> str:
    token = provider.get_token()
    ...

Step 4 — Gate a tool behind a PAT / API key form (Leg 2b)

from mcpauthkit import CredentialsProvider

creds = CredentialsProvider(
    name="confluence",
    variables={"pat": {"label": "Personal Access Token", "type": "password"}},
    user_context=current_user,
    server_base_url=SERVER_URL,
)
creds.register(app)

@mcp.tool()
@creds.require_credentials()
async def list_pages(ctx: Context, space: str) -> str:
    pat = creds.get_credentials()["pat"]
    ...