Key Takeaways
- MCP OAuth replaces static keys with short-lived tokens.
- Claude Code users should use an MCP gateway to centralize OAuth, avoid token sprawl, and prevent mid-task failures.
The Problem: Static API Keys Are a Credential Leak Waiting to Happen

You've been there. You paste a GitHub personal access token into your claude_desktop_config.json or an environment variable, and it just sits there—long-lived, broad-scoped, and one git push away from being leaked.
MCP's answer is OAuth 2.1. Instead of a permanent key in a config file, the agent runs an authorization code flow to get a short-lived, scoped access token. Cleaner, safer, and the right direction.
But here's the catch: if you're running Claude Code (and maybe Cursor or Codex too), each client does its own OAuth dance. You authorize the same server multiple times. Tokens scatter across machines. And when a token expires mid-task, your agent just fails silently.
What Changed — MCP OAuth Is Now Production-Ready
The Model Context Protocol authorization spec (built on OAuth 2.1) is now the recommended way to connect Claude Code to remote MCP servers. The flow:
- Claude Code calls the server → gets a
401with metadata pointing to the authorization server - Client registers itself (often via dynamic client registration—no manual client ID needed)
- User grants consent through the authorization server
- Claude Code exchanges the code for a scoped access token, refreshing it as it expires
Your agent ends up holding a short-lived token scoped to specific permissions, not a permanent key to everything.
What It Means For You — The Token Lifecycle Problem
For a single Claude Code instance against a single server, OAuth is a clear improvement. But at scale—multiple developers, multiple machines, multiple clients—it gets messy:
- Every client redoes it. Claude Code, Cursor, and Codex each run their own OAuth dance and store tokens their own way. You authorize the same server several times.
- Tokens scatter. Access and refresh tokens land in per-client local storage across every machine. No single place to see what's authorized or to cut it off.
- Refresh and revocation are nobody's job. When a token expires mid-task, your agent fails. When someone leaves, their tokens persist wherever their clients cached them.
- No central policy. A valid OAuth token authorizes the agent against the server, but says nothing about which tools or arguments are allowed. OAuth scopes are coarse and server-defined.
OAuth solves the static-key problem and hands you a token-lifecycle problem in its place.
Try It Now — Centralize OAuth with an MCP Gateway
An MCP gateway runs the OAuth flow once, centrally, and keeps the tokens off every client. Here's how you set it up with Claude Code:
- Deploy or use an MCP gateway (like PolicyLayer or a self-hosted solution) that handles the upstream OAuth flow
- The gateway holds the GitHub (or other service) OAuth tokens, refreshes them as they expire
- Claude Code authenticates to the gateway with a simple grant token—never touching the upstream OAuth tokens
Your claude_desktop_config.json becomes:
{
"mcpServers": {
"github": {
"url": "https://your-gateway.com/mcp/<server-uuid>/",
"headers": { "Authorization": "Bearer <grant-token>" }
}
}
}
That's it. One authorization flow instead of one per client. One place to revoke. And because the call still passes through policy on the way out, an OAuth-authorized agent is governed by per-tool, per-argument rules—not just whatever broad scope the server granted.
Why This Matters for Your Team
If you're the only one using Claude Code, you can probably get away with a single OAuth flow. But if you're managing a fleet of agents or multiple developers, the gateway approach is non-negotiable:
- No more mid-task failures from expired tokens—the gateway handles refresh
- Single revocation point when someone leaves or a credential is compromised
- Fine-grained authorization on top of OAuth—control which tools and arguments are allowed
- One config for all Claude Code instances
Short-lived tokens, centrally managed, with real authorization on top. That's what MCP OAuth was reaching for.
Source: dev.to









