MCPizy
MarketplaceRecipesGuidesPricingDocs
Log inGet Started
All guides
Guide · EN
11 min read
April 24, 2026

MCP Auth in Production: OAuth 2.1, PKCE, and Scoped Tokens

Authentication patterns for MCP servers past the prototype stage: OAuth 2.1 + PKCE for clients, scoped tokens per tool, machine-to-machine, and token rotation.

mcpauthoauthsecuritytokens

MCP servers that expose any privileged data need real auth. Static bearer tokens in the manifest JSON are fine for localhost dev; they are not fine for production. This guide covers the three auth patterns we deploy in production MCP servers.

The three patterns

  1. OAuth 2.1 + PKCE — when a human is on the other end (Claude Desktop, Cursor with your login).
  2. Machine-to-machine (M2M) — when an agent process calls your MCP server (no user present).
  3. Per-tool scoped tokens — when different tools need different permissions.

Pattern 1: OAuth 2.1 + PKCE for Claude Desktop / Cursor

The MCP spec (since late 2025) supports OAuth via the oauth field in the server manifest. Client performs PKCE, stores the token in the OS keychain, includes it in every tool call.

{
  "name": "stripe-read",
  "oauth": {
    "authorization_url": "https://auth.mycorp.io/oauth/authorize",
    "token_url": "https://auth.mycorp.io/oauth/token",
    "scopes": ["stripe.read"],
    "client_id": "mcp-stripe-read"
  }
}

Server validates the access token on each request. Any OAuth 2.1-compliant provider works: Clerk, Auth0, Okta, Keycloak.

Pattern 2: M2M tokens for agent-to-server

When an automated agent (not a human) calls your MCP server, OAuth 2.1 client_credentials flow works.

POST /oauth/token
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials
&client_id=agent-backfill
&client_secret=***
&scope=catalog.read

Agent caches the token until 60s before expiry, refreshes proactively. Server validates signature + expiry + scope on each request.

Pattern 3: Per-tool scoped tokens

One MCP server can expose multiple tools with different risk levels. Read tools should not need write credentials.

{
  "tools": [
    { "name": "search_orders", "scopes_required": ["orders.read"] },
    { "name": "refund_order",  "scopes_required": ["orders.write", "refund.admin"] }
  ]
}

Server checks scopes on each call, not just at session init. Prevents scope-creep once the token is issued.

Token rotation strategy

  • Access tokens: 15 min expiry, in-memory only.
  • Refresh tokens: 30 days rolling, stored in the OS keychain (Claude Desktop) or Vault / AWS Secrets Manager (servers).
  • Rotation on refresh: one-time-use refresh tokens. Each use invalidates the old one. Catches token theft within 15 min.
  • Client secrets: rotate every 90 days. Automate.

What to log (for audit, not for leak)

  • ✅ Token JTI (unique ID), timestamp, client ID, scopes used.
  • ✅ Tool name called, duration, outcome (ok / unauthorized / forbidden).
  • ❌ Never the token itself, raw or hashed.
  • ❌ Never the client secret.

Common mistakes

  • Shared token across tools. Read tool with write scope "just in case" = incident waiting to happen.
  • No revocation endpoint. User leaves, token works until expiry. Needs /oauth/revoke.
  • Client secrets in git. Scan with gitleaks before every commit.
  • No rate limit per token. A leaked token + no rate limit = bill explosion + data exfil.

Recommended stack

  • Auth provider: Clerk (fast setup) or Keycloak (self-hosted).
  • Authorization layer: Casbin or Oso inside the MCP server.
  • Rate limiting: Upstash Redis with sliding-window counters per-token.
  • Audit log: structured JSON shipped to Loki, correlated by token JTI.

Ship secure MCP servers on MCPizy → /pricing

Running MCP in production?

Centralised auth, cost analytics, and the APC optimization layer — free tier included.

Try MCPizy
All guidesPricing →
MCPizy— The MCP Platform
MarketplaceDocsPrivacyTermsCookiesMentions légalesContact

© 2026 MCPizy. All rights reserved.