MCP troubleshooting
This page covers common problems when using Casdoor’s built-in MCP server or when Casdoor is the OAuth provider for your own MCP server.
Common Errors
401 Unauthorized from MCP Server
Symptom: MCP server rejects requests with 401 Unauthorized status code.
Causes:
- Access token has expired
- Token's
aud(audience) claim doesn't match the MCP server's resource URI - Missing
Authorization: Bearerheader in requests - Token was issued for a different resource
Fix:
- Decode your token at jwt.io and check the
expclaim for expiration - Verify the
audclaim matches your MCP server's URI exactly (including scheme, host, and port) - Ensure requests include the header:
Authorization: Bearer YOUR_TOKEN - If using the
resourceparameter during OAuth, confirm it matches the MCP server URI
# Example: Check token claims
curl -X GET https://your-mcp-server.com/api/mcp \
-H "Authorization: Bearer YOUR_TOKEN"
# If 401, inspect token at jwt.io:
# - exp: 1735689600 (must be in future)
# - aud: "https://your-mcp-server.com" (must match server URI)
# - scope: "read:application" (must include required scopes)
CORS Errors in Browser
Symptom: Browser console shows CORS errors when MCP client attempts to connect to Casdoor.
Causes:
- Casdoor CORS settings don't include the MCP client's origin
- Preflight requests are being blocked
- Wildcard CORS is disabled for security
Fix:
- Log into Casdoor admin panel
- Navigate to your application configuration
- Add the MCP client's origin to the CORS Allowed Origins field
- Include the full origin:
https://client-domain.com(with scheme and port if non-standard) - For local development, add
http://localhost:PORT
# Example CORS configuration:
https://claude.ai
https://cursor.sh
http://localhost:3000
Redirect URI Mismatch
Symptom: OAuth flow fails with redirect_uri_mismatch error.
Causes:
- The
redirect_uriin the authorization request doesn't exactly match the application configuration - Scheme mismatch (
httpvshttps) - Port number missing or incorrect
- Trailing slash mismatch
Fix:
- Copy the exact
redirect_urifrom your authorization request - In Casdoor, edit the application configuration
- Add the exact URI to Redirect URLs field (must match character-for-character)
- Ensure scheme, host, port, and path all match exactly
# These are all different redirect URIs:
http://localhost:3000/callback
https://localhost:3000/callback # Different scheme
http://localhost:3000/callback/ # Trailing slash
http://localhost:3001/callback # Different port
Discovery Endpoint 404
Symptom: Attempting to fetch .well-known discovery document returns 404.
Causes:
- Using wrong discovery path for your use case
- Casdoor configuration doesn't expose discovery endpoints
- Application not configured as OIDC provider
Fix:
Try these discovery endpoints in order:
-
OAuth Authorization Server Metadata (RFC 8414):
curl https://your-casdoor.com/.well-known/oauth-authorization-server -
OpenID Connect Discovery:
curl https://your-casdoor.com/.well-known/openid-configuration -
OAuth Protected Resource Metadata (RFC 9470):
curl https://your-casdoor.com/.well-known/oauth-protected-resource
For MCP servers acting as resource servers, use the oauth-protected-resource endpoint to advertise OAuth requirements.
DCR Registration Rejected
Symptom: Dynamic Client Registration (DCR) request fails with error.
Causes:
- Organization has DCR disabled in settings
- Registration request missing required fields
- Software statement rejected or invalid
- Rate limiting on registration endpoint
Fix:
-
Navigate to your organization settings in Casdoor
-
Enable Dynamic Client Registration toggle
-
Configure Allowed Redirect URI Patterns to restrict client URIs
-
For registration requests, include all required metadata:
{
"client_name": "My MCP Client",
"redirect_uris": ["https://client.example.com/callback"],
"grant_types": ["authorization_code"],
"token_endpoint_auth_method": "client_secret_basic"
}
See Dynamic client registration for details.
Consent Screen Not Showing
Symptom: OAuth flow completes without showing user consent screen.
Causes:
- Application's Consent Policy is set to "Never"
- User has previously granted consent and policy is "Once"
- Session authentication bypasses consent
Fix:
- Edit your application in Casdoor admin panel
- Set Consent Policy to:
- Always: Show consent on every authorization request
- Once: Show consent only on first authorization (recommended)
- Save the application configuration
- Clear user's previous consent if testing (revoke application access)
The consent screen displays requested scopes with their display names and descriptions from your scope configuration.
insufficient_scope Error
Symptom: MCP tool calls fail with insufficient_scope JSON-RPC error.
Causes:
- Access token doesn't include the scope required by the tool
- Token was requested with incorrect scopes
- Scope names don't match server expectations
Fix:
-
Check the error response for
required_scopeandgranted_scopes:{
"error": {
"code": -32001,
"message": "insufficient_scope",
"data": {
"tool": "add_application",
"granted_scopes": ["read:application"],
"required_scope": "write:application"
}
}
} -
Request a new token with the required scope:
curl -X POST https://your-casdoor.com/api/login/oauth/access_token \
-d "grant_type=client_credentials" \
-d "client_id=YOUR_CLIENT_ID" \
-d "client_secret=YOUR_CLIENT_SECRET" \
-d "scope=read:application write:application"
See Authorization and scopes for the scope reference.
invalid_target / Resource Error
Symptom: Authorization request fails with invalid_target or invalid_resource error.
Causes:
resourceparameter is not a valid URI (RFC 8707)- Resource URI missing scheme (
http://orhttps://) - Resource parameter conflicts with token audience
Fix:
-
Ensure
resourceparameter is a full URL:# Correct:
resource=https://your-server.com
resource=https://api.example.com:8080
# Incorrect:
resource=your-server.com # Missing scheme
resource=localhost:3000 # Missing scheme -
The
resourcevalue becomes theaudclaim in the access token -
Resource must match the MCP server's expected audience exactly