RFC7591 Dynamic Client Registration Implementation
Overview
This document explains the RFC7591 (OAuth 2.0 Dynamic Client Registration Protocol) implementation added to resolve OpenAI MCP server integration issues.
Problem
When using a Cloudflare tunnel to expose your MCP server, OpenAI attempts to dynamically register itself as an OAuth client using RFC7591. Without this endpoint, OpenAI returns an error stating the server doesn’t support RFC7591.
Solution
Added full RFC7591 Dynamic Client Registration support to the MCP server.
Changes Made
1. Settings Configuration (src/corpusiq/settings.py)
Added new configuration options:
oauth_registration_endpoint: The URL where clients can register (default:https://your-domain.com/register)allow_dynamic_client_registration: Boolean flag to enable/disable dynamic registration (default:True)
2. OAuth Metadata Updates (src/corpusiq/app.py)
Updated /.well-known/oauth-authorization-server endpoint to include:
registration_endpoint: Advertises the RFC7591 registration endpointtoken_endpoint_auth_methods_supported: Lists supported authentication methods
3. Client Registration Endpoint (src/corpusiq/app.py)
Implemented POST /register endpoint that:
- Accepts client registration requests per RFC7591 specification
- Validates required fields (redirect_uris, client_name, etc.)
- Generates client credentials (client_id and client_secret if needed)
- Returns RFC7591-compliant registration response with:
client_id: Unique identifier for the clientclient_secret: Secret for client authentication (if applicable)client_id_issued_at: Unix timestamp of registrationclient_secret_expires_at: Expiration time (90 days)- All other client metadata
How It Works
Registration Flow
- OpenAI discovers the registration endpoint via
/.well-known/oauth-authorization-server - OpenAI sends a POST request to
/registerwith:{ "client_name": "OpenAI ChatGPT", "redirect_uris": ["https://chat.openai.com/callback"], "grant_types": ["authorization_code"], "response_types": ["code"], "token_endpoint_auth_method": "client_secret_basic" } - Server validates the request and generates credentials
- Server responds with client credentials:
{ "client_id": "client_abc123...", "client_secret": "secret_xyz789...", "client_name": "OpenAI ChatGPT", "redirect_uris": ["https://chat.openai.com/callback"], "grant_types": ["authorization_code"], "response_types": ["code"], "token_endpoint_auth_method": "client_secret_basic", "scope": "corpus:read corpus:search", "client_id_issued_at": 1704240000, "client_secret_expires_at": 1711996800 }
Environment Configuration
For Cloudflare Tunnel Setup
Update your .env file or environment variables:
# Your Cloudflare tunnel URL
CORPUSIQ_OAUTH_RESOURCE_URL=https://your-tunnel.trycloudflare.com
# Registration endpoint (usually the same as resource URL + /register)
CORPUSIQ_OAUTH_REGISTRATION_ENDPOINT=https://your-tunnel.trycloudflare.com/register
# OAuth issuer (can be the same as resource URL for self-contained servers)
CORPUSIQ_OAUTH_ISSUER=https://your-tunnel.trycloudflare.com
# OAuth endpoints (customize based on your auth provider)
CORPUSIQ_OAUTH_AUTHORIZATION_ENDPOINT=https://your-tunnel.trycloudflare.com/authorize
CORPUSIQ_OAUTH_TOKEN_ENDPOINT=https://your-tunnel.trycloudflare.com/token
CORPUSIQ_OAUTH_JWKS_URI=https://your-tunnel.trycloudflare.com/.well-known/jwks.json
# Enable dynamic client registration
CORPUSIQ_ALLOW_DYNAMIC_CLIENT_REGISTRATION=true
# CORS - allow OpenAI to access your server
CORPUSIQ_CORS_ALLOW_ORIGINS_CSV=https://chat.openai.com,https://chatgpt.com
Testing the Implementation
1. Test OAuth Metadata Discovery
curl https://your-tunnel.trycloudflare.com/.well-known/oauth-authorization-server
Should return JSON including:
{
"registration_endpoint": "https://your-tunnel.trycloudflare.com/register",
...
}
2. Test Client Registration
curl -X POST https://your-tunnel.trycloudflare.com/register \
-H "Content-Type: application/json" \
-d '{
"client_name": "Test Client",
"redirect_uris": ["https://example.com/callback"],
"grant_types": ["authorization_code"],
"response_types": ["code"]
}'
Should return 201 Created with client credentials.
3. Monitor Server Logs
When OpenAI connects, you should see log entries like:
Client registration request received: OpenAI ChatGPT
Client registered successfully: client_abc123... (OpenAI ChatGPT)
Client redirect URIs: ['https://chat.openai.com/callback']
Production Considerations
⚠️ Important: Client Storage
The current implementation generates credentials but does not persist them. For production:
- Add a database or key-value store to persist client credentials
- Implement client lookup during token exchange
- Add client secret validation in your token endpoint
- Consider using a proper OAuth provider like Auth0, Keycloak, or similar
Example Storage Implementation
# In production, replace the TODO comment with actual storage:
# Store in database
await db.clients.insert_one({
"client_id": client_id,
"client_secret": hashed_secret, # Use bcrypt or similar
"client_name": client_name,
"redirect_uris": redirect_uris,
"created_at": datetime.utcnow(),
"expires_at": datetime.utcnow() + timedelta(days=90)
})
Security Notes
- Client secrets should be hashed before storage (use bcrypt, argon2, etc.)
- Validate redirect URIs strictly to prevent authorization code interception
- Use HTTPS only for all OAuth endpoints (enforced by Cloudflare tunnel)
- Rate limit the registration endpoint to prevent abuse (already included via RateLimitMiddleware)
- Consider requiring authentication for client registration in production
- Log all registration attempts for security auditing (already implemented)
Troubleshooting
OpenAI Still Reports RFC7591 Error
- Verify the metadata endpoint is accessible:
/.well-known/oauth-authorization-server - Check that
registration_endpointis present in the response - Ensure your Cloudflare tunnel is properly forwarding requests
- Check server logs for any registration errors
403 Forbidden on /register
- Verify
CORPUSIQ_ALLOW_DYNAMIC_CLIENT_REGISTRATION=trueis set - Check that the environment variable is being loaded correctly
400 Invalid Redirect URI
- Ensure the client is sending at least one
redirect_uriin the registration request - Validate that redirect URIs are properly formatted URLs