Passer au contenu principal

Dépannage MCP

Cette page couvre les problèmes liés au serveur MCP intégré de Casdoor ainsi qu'à vos propres serveurs MCP qui utilisent Casdoor comme fournisseur OAuth 2.0.

Problèmes courants​

Le serveur MCP répond avec une erreur HTTP 401​

Causes

  • Le jeton d'accès a expiré.
  • La revendication aud (audience) du jeton ne correspond pas à l'URI de la ressource du serveur MCP.
  • La requête n'a pas d'en-tête Authorization: Bearer.

Solution

  1. Décodez le jeton, par exemple sur jwt.io, et vérifiez la revendication exp.
  2. Vérifiez que la revendication aud correspond exactement à l'URI de votre serveur MCP, y compris le schéma, l'hôte et le port.
  3. Vérifiez que la requête porte l'en-tête Authorization: Bearer <access-token>.
  4. Si votre client envoie le paramètre resource dans le flux OAuth 2.0, vérifiez qu'il s'agit bien de l'URI du serveur MCP.
# 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)

Le navigateur signale une erreur CORS​

Cause

L'origine du client MCP n'est pas une origine approuvée par Casdoor. Casdoor autorise les requêtes inter-origines provenant des origines listées dans les Redirect URLs de vos applications.

Solution

  1. Dans la console d'administration Casdoor, ouvrez la page d'édition de l'application.
  2. Ajoutez une URL contenant l'origine du client MCP, y compris le schéma et un port non standard, dans Redirect URLs. Pour le développement local, ajoutez http://localhost:<port>.

Consultez Appeler l'API depuis un navigateur.

L'URL de redirection ne correspond pas​

Causes

  • Le redirect_uri de la demande d'autorisation n'est pas présent dans les Redirect URLs de l'application.
  • Le schéma (http ou https), le port ou une barre oblique finale diffèrent.

Solution

  1. Copiez exactement le redirect_uri de la demande d'autorisation.
  2. Ajoutez-le aux Redirect URLs de l'application.

Les URL suivantes sont toutes différentes :

# 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

Un point de terminaison de découverte renvoie HTTP 404​

Cause

Le client demande un chemin de découverte qui ne correspond pas à son rôle.

Solution

Demandez le point de terminaison correspondant à votre cas d'utilisation :

  1. Métadonnées du serveur d'autorisation OAuth 2.0 (RFC 8414) :

    curl https://your-casdoor.com/.well-known/oauth-authorization-server
  2. Découverte OpenID Connect :

    curl https://your-casdoor.com/.well-known/openid-configuration
  3. Métadonnées des ressources protégées OAuth 2.0 (RFC 9728) :

    curl https://your-casdoor.com/.well-known/oauth-protected-resource

Un serveur MCP qui est un serveur de ressources publie le document oauth-protected-resource pour annoncer son serveur d'autorisation.

L'enregistrement dynamique des clients est rejeté​

Causes

  • L'enregistrement dynamique des clients (DCR) est désactivé pour l'organisation.
  • La demande d'enregistrement manque de champs obligatoires.

Solution

  1. Dans la console d'administration Casdoor, ouvrez la page d'édition de l'organisation et activez Enable dynamic client registration. Un client s'enregistre dans l'organisation built-in sauf si l'URL d'enregistrement contient un paramètre organization.

  2. Envoyez toutes les métadonnées requises dans la demande d'enregistrement :

    {
    "client_name": "My MCP Client",
    "redirect_uris": ["https://client.example.com/callback"],
    "grant_types": ["authorization_code"],
    "token_endpoint_auth_method": "client_secret_basic"
    }

Voir Enregistrement dynamique des clients.

Causes

  • L'application n'a pas de portée personnalisée. Casdoor demande un consentement uniquement pour les portées personnalisées.
  • Le client ne demande pas de portée personnalisée.
  • The user has already granted or declined the requested scopes for the application. Casdoor doesn't ask again, and the token carries only the granted scopes.

Solution

  1. Vérifiez que l'application définit les portées et que le client les demande. Voir Portées personnalisées.
  2. Pour tester à nouveau l'écran de consentement, révoquez l'autorisation précédente sur la page Consents.

Un appel d'outil échoue avec insufficient_scope​

Cause

Le jeton d'accès ne contient pas la portée requise par l'outil.

Solution

  1. Lisez required_scope et granted_scopes dans l'erreur :

    {
    "error": {
    "code": -32001,
    "message": "insufficient_scope",
    "data": {
    "tool": "add_application",
    "granted_scopes": ["read:application"],
    "required_scope": "write:application"
    }
    }
    }
  2. Demandez un nouveau jeton avec la portée requise :

    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"

Voir la référence des portées.

La demande d'autorisation échoue avec invalid_target​

Causes

  • Le paramètre resource n'est pas un URI absolu, comme l'exige la RFC 8707.
  • L'URI de la ressource ne comporte pas de schéma.

Solution

  1. Envoyez une URL complète dans resource :

    # Correct:
    resource=https://your-server.com
    resource=https://api.example.com:8080

    # Incorrect:
    resource=your-server.com # Missing scheme
    resource=localhost:3000 # Missing scheme
  2. N'oubliez pas que la valeur de resource devient la revendication aud du jeton d'accès. Elle doit correspondre exactement à l'audience attendue par le serveur MCP.

Claude Desktop ou Cursor ne peuvent pas se connecter à votre propre serveur MCP​

Causes

  • Votre serveur MCP ne renvoie pas de métadonnées de ressource protégée valides.
  • L'en-tête WWW-Authenticate est manquant ou mal formé.
  • Le client ne peut pas atteindre les points de terminaison de découverte.
  • Votre serveur MCP ne parvient pas à valider le jeton.

Solution

  1. Vérifiez que le point de terminaison des métadonnées renvoie un JSON valide :

    curl https://your-mcp-server.com/.well-known/oauth-protected-resource

    Réponse attendue :

    {
    "resource": "https://your-mcp-server.com",
    "authorization_servers": [
    "https://your-casdoor.com"
    ]
    }
  2. Vérifiez l'en-tête WWW-Authenticate d'une demande non authentifiée :

    curl -v https://your-mcp-server.com/api/mcp

    En-tête attendu :

    WWW-Authenticate: Bearer realm="mcp-server",
    authorization_uri="https://your-casdoor.com/login/oauth/authorize",
    scope="read:application write:application"
  3. Exécutez manuellement le flux OAuth 2.0 :

    # 1. Get authorization code (requires browser)
    # 2. Exchange for token
    curl -X POST https://your-casdoor.com/api/login/oauth/access_token \
    -d "grant_type=authorization_code" \
    -d "code=AUTH_CODE" \
    -d "redirect_uri=YOUR_REDIRECT_URI" \
    -d "client_id=YOUR_CLIENT_ID" \
    -d "client_secret=YOUR_CLIENT_SECRET"

    # 3. Test MCP endpoint with token
    curl https://your-mcp-server.com/api/mcp \
    -H "Authorization: Bearer ACCESS_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

Outils de débogage​

MCP Inspector​

Le MCP Inspector officiel permet de tester une connexion MCP de manière interactive. Il parcourt et appelle les outils, affiche les demandes et réponses JSON-RPC, et exécute le flux OAuth 2.0.

npx @modelcontextprotocol/inspector

Points de terminaison de découverte​

Vérifiez que chaque point de terminaison de découverte renvoie un JSON valide :

# OAuth Authorization Server
curl -s https://your-casdoor.com/.well-known/oauth-authorization-server | jq

# OIDC Configuration
curl -s https://your-casdoor.com/.well-known/openid-configuration | jq

# Protected Resource (for MCP resource servers)
curl -s https://your-mcp-server.com/.well-known/oauth-protected-resource | jq

Revendications du jeton​

Décodez le jeton d'accès sur jwt.io, ou en ligne de commande :

# Alternative: Decode token with jq
echo "YOUR_JWT_TOKEN" | cut -d. -f2 | base64 -d | jq
ClaimCheck
audMatches the URI of the MCP server
scopeContains the scopes that the tools require
expIs in the future. The value is a Unix timestamp
issIs the URL of Casdoor
subIs the ID of the user
client_idIs the application that received the token

Introspection du jeton​

Demandez à Casdoor si un jeton est valide et ce qu'il contient (RFC 7662) :

curl -X POST https://your-casdoor.com/api/login/oauth/introspect \
-H "Content-Type: application/x-www-form-urlencoded" \
-u "CLIENT_ID:CLIENT_SECRET" \
-d "token=ACCESS_TOKEN"

La réponse :

{
"active": true,
"scope": "read:application write:application",
"client_id": "your-client-id",
"username": "admin",
"exp": 1735689600,
"iat": 1735603200,
"aud": "https://your-mcp-server.com"
}

Flux OAuth 2.0 avec curl​

# 1. Test authorization endpoint (requires browser)
# Open in browser:
https://your-casdoor.com/login/oauth/authorize?
client_id=YOUR_CLIENT_ID&
redirect_uri=http://localhost:8080/callback&
response_type=code&
scope=read:application&
state=random-state

# 2. Exchange authorization code for token
curl -X POST https://your-casdoor.com/api/login/oauth/access_token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=authorization_code" \
-d "code=AUTHORIZATION_CODE" \
-d "redirect_uri=http://localhost:8080/callback" \
-d "client_id=YOUR_CLIENT_ID" \
-d "client_secret=YOUR_CLIENT_SECRET"

# 3. Use access token with MCP server
curl https://your-mcp-server.com/api/mcp \
-H "Authorization: Bearer ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

Journaux et traces réseau​

  • Client MCP : Activez le mode debug ou verbose, et consultez le journal pour la redirection, l'échange de jetons et les appels d'outils.

  • Serveur MCP : Journalisez chaque demande entrante, le résultat de la validation du jeton avec la raison de l'échec, ainsi que les vérifications de portée.

  • Navigateur : Ouvrez les outils de développement. L'onglet réseau affiche les redirections et les appels API, tandis que la console affiche les erreurs JavaScript.

  • Clients CLI : Acheminez le client via mitmproxy pour voir ses requêtes :

    mitmproxy -p 8080
    # Configure client to use proxy: http://localhost:8080

Voir aussi​