Skip to content

Authentication

Custom MCP clients authenticate with OAuth 2.1 + PKCE (S256) as public clients — no client secret, ever.

Tokens last 30 days, with no refresh grant

This is the most important constraint to design for. When a token expires, the user must re-approve — build your client to expect that.

Endpoints

  • POST /api/oauth/registerDynamic Client Registration — returns your client_id
  • GET /api/oauth/authorizeConsent screen — user reviews scopes and approves
  • POST /api/oauth/tokenExchanges the authorization code for a 30-day access token

Flow

  1. Register your client with Dynamic Client Registration — authorization_code grant only, token_endpoint_auth_method: none.
  2. Send the user to the consent screen with a PKCE challenge.
  3. Exchange the returned code (plus verifier) for an access token.
  4. Call POST /mcp with the token as a Bearer header.
View example
Dynamic client registration
curl -X POST https://klaarin.com/api/oauth/register \
  -H "Content-Type: application/json" \
  -d '{
    "client_name": "My Klaarin Agent",
    "redirect_uris": ["https://myagent.dev/callback"],
    "grant_types": ["authorization_code"],
    "token_endpoint_auth_method": "none"
  }'
Token exchange
curl -X POST https://klaarin.com/api/oauth/token \
  -d grant_type=authorization_code \
  -d code=<authorization code> \
  -d code_verifier=<PKCE verifier> \
  -d client_id=<client id> \
  -d redirect_uri=https://myagent.dev/callback