Skip to content

Quickstart

One docker run. A working OAuth 2.1 + MCP authorization server in under a minute. All you need installed is Docker.

  1. Generate the two secrets

    Terminal window
    export AUTHPLANE_ADMIN_API_KEY="$(openssl rand -hex 32)"
    export AUTHPLANE_SESSION_SECRET="$(openssl rand -hex 32)"
    echo "Save this — it's your Admin UI login: $AUTHPLANE_ADMIN_API_KEY"

    AUTHPLANE_ADMIN_API_KEY is your login for the Admin UI and the admin REST API. AUTHPLANE_SESSION_SECRET secures user login sessions.

  2. Start AuthPlane

    Terminal window
    docker run --name authserver -p 9000:9000 -p 9001:9001 \
    -e AUTHPLANE_ADMIN_API_KEY \
    -e AUTHPLANE_SESSION_SECRET \
    -e AUTHPLANE_CLIENT_CREDENTIALS_ENABLED=true \
    -e AUTHPLANE_DPOP_ENABLED=true \
    -e AUTHPLANE_TOKEN_EXCHANGE_ENABLED=true \
    -v authserver-data:/data \
    authplane/authserver:latest serve

    The public OAuth endpoints are on http://localhost:9000; the admin API and Admin UI are on http://localhost:9001. State — the default SQLite database and the auto-generated signing keys — persists in the authserver-data volume.

    The authorization-code + refresh-token flow is always on. The other grants are off by default; the three flags enable them:

    • AUTHPLANE_CLIENT_CREDENTIALS_ENABLED — machine-to-machine tokens, the simplest MCP-server path.
    • AUTHPLANE_DPOP_ENABLED — DPoP sender-constrained tokens (RFC 9449).
    • AUTHPLANE_TOKEN_EXCHANGE_ENABLED — RFC 8693, needed for agent-to-agent delegation and Broker upstreams.
  3. Log in to the Admin UI

    Open http://localhost:9001/admin/ui/ and paste the API key you printed in step 1. The dashboard shows server stats, registered clients, users, and scopes — every administrative operation is available from the web UI, and each one is also exposed via the admin REST API.

  4. Register your first MCP server

    AuthPlane calls each protected MCP server a resource. Scopes are declared on the resource they belong to. Register one with backend kind mint (AuthPlane signs the tokens your server validates):

    In the Admin UI at http://localhost:9001/admin/ui/, open the Resources section and create a resource with the same fields as the API call: slug my-mcp-server, backend kind mint, URI http://localhost:8080/mcp, and its scopes (mcp:echo, mcp:add).

  5. Verify discovery

    Terminal window
    curl -s http://localhost:9000/.well-known/oauth-authorization-server \
    | jq '{issuer, grant_types_supported, scopes_supported}'

    The response is the OAuth 2.0 Authorization Server Metadata (RFC 8414). Spot-check three things:

    • issuer matches http://localhost:9000.
    • grant_types_supported contains client_credentials and urn:ietf:params:oauth:grant-type:token-exchange. If you only see ["authorization_code", "refresh_token"], the flags didn’t apply — re-check the AUTHPLANE_*_ENABLED variables and restart the container.
    • scopes_supported contains the scopes you declared on the resource (mcp:echo, mcp:add).
  6. Connect your MCP server

    Drop the AuthPlane SDK adapter into your MCP server — about 5 lines of integration code. It validates JWTs against the JWKS (signature, audience, scope), serves the RFC 9728 discovery document, and returns the 401 + WWW-Authenticate response that tells agents where to authenticate.

    Each example ships make run and a make verify that mints a token and calls the protected tool end to end. Adding auth to an MCP server you already have? Use the before/after retrofit examples — Python · TypeScript · Go.

    Then point an MCP client at your server — AuthPlane is tested against Claude Code, Claude Desktop, and MCP Inspector.

The setup above is for local development. Before deploying:

  1. Set the issuer to your public HTTPS URL (server.issuer: https://auth.example.com).
  2. Set a session secret (session.secret or AUTHPLANE_SESSION_SECRET).
  3. Set an admin API key (admin.api_key or AUTHPLANE_ADMIN_API_KEY).
  4. Enable secure cookies (session.secure: true — enforced automatically for non-localhost issuers).
  5. Consider PostgreSQL for multi-instance deployments (storage.driver: postgres).

See the configuration guide and the field-by-field schema reference.

Going deeper, in the upstream docs: Connect an MCP server · Admin CLI & API · OIDC federation · Upstream provider connections · Drive the whole flow by hand with curl