How Plugsky MCP works in practice
Everything in this guide runs on Plugskyโs live MCP endpoint (https://plugsky.com/mcp) or the npm bridge (npx -y @plugsky/mcp). A client request flows: JSON-RPC over Streamable-HTTP → auth (API key or OAuth 2.1 + Dynamic Client Registration with fine-grained scopes) → tool router → the service you asked for. Model calls run behind a 7-tier provider failover chain; browsing renders with headless Chromium; transcripts come from real captions and Groq Whisper; images generate on FLUX; code runs in a sandbox with no network; memory persists in your account (Postgres-backed); and every tool call is metered per user on your dashboard.
Relevant live tools for this article: POST /oauth/register (DCR), GET /oauth/authorize (PKCE), POST /oauth/token โ scopes mcp.read/mcp.write/mcp.web/mcp.media/mcp.memory/mcp.compute.
OAuth 2.1 for MCP servers explained (the 2026 spec walkthrough)
Direct answer
OAuth 2.1 for MCP is the 2026 spec's mandated authorization pattern for remote (Streamable-HTTP) servers. It combines OAuth 2.1 + PKCE (RFC 6749/8252), Protected Resource Metadata (RFC 9728), Authorization Server Metadata (RFC 8414), and optional Dynamic Client Registration (RFC 7591). A well-implemented MCP server exposes three well-known endpoints, an authorization endpoint, a token endpoint, and (recommended) a registration endpoint โ the MCP client discovers everything automatically via a 401 challenge.
Key facts
| Governing spec | MCP 2026-07-28 authorization section |
| Underlying RFCs | 6749 (OAuth 2.0), 8252 (Native Apps), 7636 (PKCE), 9728 (Protected Resource Metadata), 8414 (AS Metadata), 7591 (DCR), 7592 (DCR Management) |
| Mandatory | OAuth 2.1 + PKCE for remote servers |
| Optional but recommended | Dynamic Client Registration (DCR) |
| Discovery entry point | 401 with WWW-Authenticate: Bearer resource_metadata="..." |
| Metadata paths | /.well-known/oauth-protected-resource, /.well-known/oauth-authorization-server |
| Required for | ChatGPT Business/Enterprise App directory, Claude Enterprise Connectors, Cloudflare MCP Catalog |
| Common scopes | chat.chat, chat.tools:run, chat.rag:read, chat.files:write, offline_access |
TL;DR
- MCP OAuth = OAuth 2.1 + PKCE with automatic discovery.
- Return 401 with
WWW-Authenticateon unauthed requests โ the client parses it to find the auth server. - Expose two well-known JSON files describing your resource and auth server.
- Support PKCE on
/authorize, standard exchange on/token, and (recommended) Dynamic Client Registration on/register. - Use scoped tokens per tool group; issue refresh tokens if you want long-lived agent access.
- Getting OAuth right unblocks ChatGPT App directory, Claude Enterprise, Cloudflare Catalog โ without it, you're capped at hobbyists.
How it works
The two well-known files
/.well-known/oauth-protected-resource
{
"resource": "https://plugsky.com/mcp",
"authorization_servers": ["https://plugsky.com/oauth"],
"scopes_supported": ["chat.chat","chat.tools:run","chat.rag:read","chat.files:write","offline_access"],
"bearer_methods_supported": ["header"],
"resource_documentation": "https://plugsky.com/mcp/docs"
}
/.well-known/oauth-authorization-server
{
"issuer": "https://plugsky.com/oauth",
"authorization_endpoint": "https://plugsky.com/oauth/authorize",
"token_endpoint": "https://plugsky.com/oauth/token",
"registration_endpoint": "https://plugsky.com/oauth/register",
"revocation_endpoint": "https://plugsky.com/oauth/revoke",
"scopes_supported": ["chat.chat","chat.tools:run","chat.rag:read","chat.files:write","offline_access"],
"response_types_supported": ["code"],
"grant_types_supported": ["authorization_code","refresh_token"],
"code_challenge_methods_supported": ["S256"],
"token_endpoint_auth_methods_supported": ["none","client_secret_basic","client_secret_post"]
}
PKCE โ non-negotiable
MCP clients are considered public clients. PKCE (RFC 7636) is mandatory to defend against interception attacks.
- Client generates a random
code_verifier(43โ128 chars). - Computes
code_challenge = BASE64URL(SHA256(code_verifier)). - Sends
code_challenge+code_challenge_method=S256on/authorize. - Sends
code_verifieron/token. - Server checks the SHA256 matches.
Dynamic Client Registration (DCR, RFC 7591)
DCR lets an MCP client bootstrap without a human first creating an OAuth app. The client POSTs client metadata to /register, the server returns client_id/client_secret. This is why a user can "add MCP URL to Claude" without touching a developer portal.
DCR is strongly recommended by the 2026 spec. Without it, every developer has to manually register your MCP as an OAuth app in their team โ killing adoption.
Scopes โ keep them fine-grained
Bad: one scope plugsky that grants everything.
Good: chat.chat, chat.models:read, chat.rag:read, chat.rag:write, chat.files:write, chat.tools:run, chat.web:read, chat.code:exec, chat.memory:read, chat.memory:write, offline_access.
With fine-grained scopes:
- ChatGPT users can grant read-only.
- Enterprise admins can restrict which teams get
chat.code:exec. - Audits show precisely what an agent was authorized to do.
Refresh tokens vs long-lived access tokens
- Refresh tokens โ required for long-running agents. Include
offline_accessscope. Rotate on every use (best practice). - Long-lived access tokens โ tempting but avoid; a leaked token is a full breach.
The 401 challenge โ the whole protocol hinges on this
When an unauthed request hits your MCP endpoint, return:
HTTP/1.1 401 Unauthorized WWW-Authenticate: Bearer resource_metadata="https://plugsky.com/.well-known/oauth-protected-resource"
That single header tells the MCP client where to find your metadata. Miss it and clients can't self-configure.
Common OAuth implementation mistakes
Forgetting WWW-Authenticate on 401 | Add the header โ clients can't discover you without it |
| Not supporting PKCE | Add S256 support |
| No DCR | Add /register โ huge friction reducer |
| Scopes too broad | Split into read/write/exec per tool group |
| Access tokens without expiry | Set 1h TTL, issue refresh tokens |
Skipping redirect_uri validation | Require exact match; reject wildcards |
| Storing refresh tokens in plaintext | Encrypt at rest |
| No revocation endpoint | Add /revoke per RFC 7009 |
Comparison โ Bearer vs OAuth 2.1 for MCP
| Setup for user | Paste key | Click login |
| Revocation | Manual regenerate | One-click on dashboard |
| Per-user scoping | โ | โ |
| Leak blast radius | Full account | Single client, single scope |
| Screenshots safe | โ | โ |
| ChatGPT App directory | โ | โ |
| Claude Enterprise | โ ๏ธ | โ |
| Cloudflare Catalog | โ | โ |
| Enterprise procurement | โ | โ |
FAQ
Q: Do I have to support OAuth 2.1 to publish an MCP server?
A: For local stdio, no. For remote (Streamable-HTTP), yes if you want listing in ChatGPT App directory, Claude Enterprise, or Cloudflare Catalog. Bearer works for hobbyists but blocks enterprise.
Q: What's Dynamic Client Registration and why do I need it?
A: DCR (RFC 7591) lets MCP clients auto-register themselves as OAuth apps, no manual dev-portal step. Without it, adoption dies at the friction of manual registration.
Q: How do refresh tokens interact with long-running agents?
A: Include the offline_access scope on your /authorize request; server issues a refresh token; agent silently exchanges it for a new access token when needed. Rotate on every use.
Q: What ports/URLs do I need to expose?
A: Just HTTPS on your usual domain. Add the two /.well-known/* files, /oauth/authorize, /oauth/token, optionally /oauth/register, /oauth/revoke. All standard REST.
Q: Can I use my existing OAuth server (Okta, Auth0, Entra) as the AS for MCP?
A: Yes โ as long as it advertises AS Metadata (RFC 8414) and supports PKCE. Most modern IdPs do.
Q: What about API keys for programmatic (headless) agents?
A: The client credentials grant is allowed. Issue service-account tokens with narrow scopes for headless use.
Trust & sources
- Author: Mustafa Hasan.
- Last updated: {DATE}.
- References: MCP authorization spec, RFC 9728, RFC 8414, RFC 7591, RFC 7636 PKCE.
- Related: [What is MCP](/blog/what-is-mcp) ยท [Publish your MCP to the Official Registry](/blog/publish-mcp-registry).
Plugsky (2026). “OAuth 2.1 for MCP servers explained (the 2026 spec walkthrough)”. Plugsky. Available at: https://plugsky.com/articles/oauth-2-1-mcp-servers-explained-2026 (last updated 2026-09-30).