workers-oauth-provider lets you secure your MCP Server (or any application) running on a Cloudflare Worker. The provider handles token management, client registration, and access token validation automatically.
redirect_uri validation
The workers-oauth-provider package handles this automatically. It validates that the redirect_uri in the authorization request matches one of the registered redirect URIs for the client. This prevents attackers from redirecting authorization codes to their own endpoints.
Consent dialog
When your MCP server acts as an OAuth proxy to third-party providers (like Google, GitHub, etc.), you must implement your own consent dialog before forwarding users to the upstream authorization server. This prevents the “confused deputy” problem where attackers could exploit cached consent from the third-party provider to gain unauthorized access. Your consent dialog should clearly identify the requesting MCP client by name and display the specific scopes being requested. Implementing this consent flow requires thinking about a few security concerns.CSRF Protection
Without CSRF protection, an attacker can trick users into approving malicious OAuth clients. Use a random token stored in a secure cookie and validate it on form submission.1
Generate CSRF token when showing consent form
2
Validate CSRF token when user approves
3
Implement helper functions
Input sanitization
User-controlled content (client names, logos, URIs) in your consent dialog can execute malicious scripts if not sanitized. Client registration is dynamic, so you must treat all client metadata as untrusted input.- Required protections
- Implementation
- Client names/descriptions: HTML-escape all text before rendering (escape
<,>,&,",') - Logo URLs: Validate URL scheme (allow only
http:andhttps:), rejectjavascript:,data:,file:schemes - Client URIs: Same as logo URLs - whitelist http/https only
- Scopes: Treat as text, HTML-escape before display
Content Security Policy (CSP)
CSP headers instruct browsers to block dangerous content and behaviors. They provide defence in depth from multiple attack vectors.Inline JavaScript
If your consent dialog needs inline JavaScript, use data attributes and nonces to prevent XSS attacks.- Data attributes store user-controlled data (like URLs) separately from JavaScript code, ensuring they are always treated as strings, never as executable code
- Nonces combined with the correct CSP headers (shown above) allow your specific inline script to execute while blocking any injected scripts
Handling State
Between the consent dialog and the callback there is a gap where the user could do something nasty. We need to make sure it is the same user that hits authorize and then reaches back to our callback. Use a random state token stored server-side in KV with a short expiration time.Approved client
MCP proxy servers must maintain a registry of approved client IDs per user and check this registry before initiating the third-party authorization flow. Store approved clients in a secure, cryptographically signed cookie with HMAC-SHA256.Cookies
Why __Host- prefix?
Throughout this document you will see cookies named with the __Host- prefix (like __Host-CSRF_TOKEN and __Host-APPROVED_CLIENTS). This is especially important for MCP servers running on *.workers.dev domains.
The __Host- prefix is a security feature that prevents subdomain attacks. When you set a cookie with this prefix:
- It must be set with the
Secureflag (HTTPS only) - It must have
Path=/ - It must not have a
Domainattribute
__Host-, an attacker controlling evil.workers.dev could set cookies for your mcp-server.workers.dev domain and potentially inject malicious CSRF tokens or approved client lists. The __Host- prefix prevents this by ensuring only your specific domain can set and read these cookies.
Multiple OAuth clients on the same host
If you are running multiple OAuth flows on the same domain (e.g., GitHub OAuth and Google OAuth on the same worker), namespace your cookies to prevent collisions.More info
MCP Authorization
Official MCP authorization specification
Security Best Practices
MCP security best practices guide
RFC 9700 - Redirect Flows
Protecting redirect-based OAuth flows
RFC 9700 - Best Practices
OAuth 2.1 best practices
Next Steps
Creating Servers
Build your own MCP server with the Agents SDK
Connecting Clients
Connect your agent to external MCP servers
Transports
Learn about different MCP transport options
Examples
View example implementations on GitHub