MCP servers increasingly need real authorization — not just 'anyone with the URL can call'. The 2025 spec added OAuth 2.1 authorization. Production MCP deployments need to handle authorization correctly to avoid the obvious 'agent exfiltrates user data' attack.
Why OAuth, not API keys
API keys are static, hard to scope per-user. OAuth lets the MCP server confirm 'agent X is acting for user Y with scope Z'. Same model as third-party app access to GitHub, Google APIs. Battle-tested.
The flow
Client (agent runtime) initiates OAuth flow with MCP server. User authenticates and grants scope. Server returns access token. Agent attaches token to MCP calls. Server validates token + scope per tool call.
Scope per tool
Different tools require different scopes. Read documents: docs:read. Delete: docs:write. Sensitive op: docs:admin. Token scope checked against tool's required scope on each invocation. Default-deny.
Token refresh
Long-running agent sessions: short-lived access tokens, refresh tokens with rotation. Agent runtime handles refresh transparently. MCP server doesn't need to know about user passwords ever.
Common mistakes
Treating MCP server as 'internal' and skipping auth (then an agent shares a tool with another user). Bearer tokens in URLs (logged everywhere). Long-lived tokens (large blast radius if leaked). Missing scope check on the actual tool execution path.