Cette page s'applique à Apigee et à Apigee hybrid.
Consultez la documentation d'
Apigee Edge.
Cette page explique comment résoudre les problèmes liés au déploiement des proxys de découverte MCP. Cette page vous permet de comprendre le cycle de vie du provisionnement asynchrone des déploiements MCP, de résoudre les codes d'erreur et de vérifier la connectivité d'exécution.
Comprendre le déploiement de MCP
Le déploiement d'un proxy de découverte MCP est un processus asynchrone en plusieurs étapes qui garantit que la configuration est entièrement propagée dans l'infrastructure Apigee et Google Cloud avant la fin du déploiement du proxy.
Pendant que ces étapes de provisionnement en aval sont en cours, l'UI affiche l'état Provisionnement pour le proxy. Une fois le processus terminé, l'état passe à Déployé. Cet état confirme que tous les composants en aval sont entièrement provisionnés et que le proxy est prêt à gérer le trafic.
Dépannage
Les sections suivantes décrivent les erreurs et les problèmes connus que vous pouvez rencontrer lorsque vous utilisez MCP dans Apigee.
Le backend ne reçoit pas d'argument d'outil à l'emplacement attendu
Problème : un backend lit un argument d'outil à partir d'un emplacement de requête (chaîne de requête, en-tête ou cookie), mais la spécification OpenAPI déclare le paramètre in à un autre emplacement. L'argument arrive donc ailleurs dans la requête du backend. L'appel échoue ou se comporte comme si l'argument était absent.
Symptômes : La requête tools/call aboutit au niveau de la couche MCP et le client MCP fournit l'argument, mais le backend répond comme si la valeur était manquante (par exemple, un 400 pour une valeur requise ou une valeur par défaut appliquée à la place de la valeur envoyée).
Cause : Le paramètre est déclaré in: header ou in: cookie dans la spécification OpenAPI. Apigee envoie donc sa valeur en tant qu'en-tête de requête ou dans l'en-tête Cookie plutôt que dans la chaîne de requête. Un backend qui lit la valeur uniquement à partir de la chaîne de requête ne la voit pas. Consultez Emplacement des arguments de l'outil dans la requête de backend.
Résolution : déterminez l'emplacement de la valeur et faites en sorte que la spécification et le backend concordent :
- Pour conserver la valeur dans la chaîne de requête, déclarez le paramètre
in: query. - Pour l'envoyer en tant qu'en-tête ou cookie, laissez la déclaration telle quelle et lisez la valeur à partir de cet emplacement dans votre backend.
Le backend ne reçoit plus le cookie transporté par la requête du client MCP.
Problème : un cookie qui arrive sur la requête HTTP effectuée par le client MCP (un cookie de session d'un client basé sur un navigateur, par exemple) n'atteint plus le backend lors de certains appels d'outils.
Symptômes : le backend se comporte comme si l'appelant n'était pas authentifié ou n'était pas en session, et le comportement est incohérent : la même opération fonctionne sur certains appels et pas sur d'autres.
Cause : l'opération déclare un ou plusieurs paramètres in: cookie, et les appels concernés ont fourni au moins l'un d'entre eux. L'en-tête Cookie est réécrit dans son intégralité plutôt que d'être ajouté. Par conséquent, lors de ces appels, il ne contient que les paramètres de cookie déclarés et tous les autres cookies sont supprimés. Les appels qui n'ont fourni aucun des paramètres de cookie transmettent l'en-tête sans modification, ce qui explique pourquoi seuls certains appels échouent. Consultez Cookies sur la requête envoyée à votre backend.
Résolution : Déclarez chaque cookie dont le backend a besoin en tant que paramètre in: cookie sur chaque opération qui en a besoin, afin que sa valeur soit toujours fournie par l'appel d'outil plutôt qu'héritée de la requête du client. Aucun paramètre ne permet de conserver un cookie non déclaré.
Codes d'état des réponses d'erreur pour les appels d'outils et les métadonnées
Les points de terminaison MCP Apigee renvoient des codes d'état HTTP conformes à la spécification MCP (Model Context Protocol) et aux normes OAuth associées. Comprendre ce comportement vous aide à gérer correctement les erreurs dans votre client MCP ou votre agent IA.
Le tableau suivant récapitule les codes d'état renvoyés par les points de terminaison MCP Apigee :
| Scénario | Code d'état HTTP | Corps de la réponse |
|---|---|---|
L'exécution d'un outil échoue sur tools/call (par exemple, l'API backend renvoie une erreur 4xx ou 5xx, telle qu'une erreur de validation ou un champ obligatoire manquant). |
200 OK |
Un CallToolResult avec result.isError défini sur true et les détails de l'erreur dans content. Cela permet au client MCP et à l'agent LLM de lire l'erreur et de la corriger (par exemple, en demandant à nouveau l'entrée manquante et en réessayant) au lieu de mettre fin à la session. |
Les métadonnées de la ressource protégée par OAuth (PRM) ne sont pas configurées ou sont introuvables à l'adresse /.well-known/oauth-protected-resource/mcp. |
404 Not Found |
Indique qu'aucune métadonnée de ressource protégée n'est disponible à l'emplacement demandé. |
| Le jeton d'accès est manquant, non valide ou a expiré. | 401 Unauthorized |
Inclut un test WWW-Authenticate pour piloter le flux de découverte OAuth. |
| Le niveau du jeton d'accès est insuffisant. | 403 Forbidden |
Inclut un test WWW-Authenticate pour piloter le flux d'autorisation de l'authentification renforcée. |
Exemple : Corps de la réponse d'erreur d'exécution de l'outil
Lorsqu'un appel d'outil échoue, Apigee MCP renvoie HTTP 200 OK et signale l'échec dans l'objet JSON-RPC result, avec isError défini sur true. L'erreur d'origine renvoyée par votre backend est conservée : le corps de la réponse du backend est placé textuellement (sous forme de chaîne) dans result.content[].text. Par exemple, si le backend renvoie HTTP 404 avec le corps {"error":"User 42 not found"}, la réponse MCP est la suivante :
{ "jsonrpc": "2.0", "id": 1, "result": { "content": [ { "type": "text", "text": "{\"error\":\"User 42 not found\"}" } ], "isError": true } }
Le id correspond au id de votre requête tools/call.
Si le backend ne renvoie aucun corps de réponse, text contient un résumé généré à la place, tel que Operation failed (HTTP 500)..
Votre client MCP doit inspecter result.isError (et non le code d'état HTTP) pour détecter un échec d'appel d'outil. Si votre code client attend spécifiquement un état HTTP 4xx ou 5xx pour signaler une erreur d'exécution de l'outil, il ne détecte pas l'erreur, car la réponse est HTTP 200 OK. Mettez à jour ces clients pour lire result.isError et le tableau content.
Les erreurs au niveau du protocole (par exemple, une requête JSON-RPC incorrecte) sont distinctes des erreurs d'exécution de l'outil : elles continuent d'être renvoyées dans l'objet JSON-RPC error (par exemple, {"jsonrpc": "2.0", "error": {"code": -32700, ...}}) plutôt que dans result.isError.
Recommandation : Les clients MCP conformes aux normes gèrent ces codes d'état via leur logique par défaut. Aucune modification n'est donc requise. Si vous avez déjà ajouté une solution de contournement côté client pour gérer les codes d'état non standards (par exemple, en analysant un corps de réponse non-2xx pour les erreurs tools/call ou en traitant une réponse 500 du point de terminaison PRM comme "métadonnées non configurées"), nous vous recommandons de supprimer cette solution de contournement. Sinon, votre client risque de continuer à utiliser une logique de traitement obsolète au lieu de traiter normalement les codes d'état corrigés.
Règle CORS pour les appels MCP basés sur un navigateur
Une règle CORS (Cross-Origin Resource Sharing) est nécessaire lorsque les appels MCP Apigee sont effectués directement depuis un navigateur (par exemple, lorsque l'inspecteur MCP utilise le paramètre "Direct" au lieu de "Via un proxy"). Le modèle de proxy de découverte MCP inclut par défaut la règle CORS Apigee dans le PreFlow de requête du point de terminaison du proxy du bundle de proxy pour activer les appels basés sur un navigateur.
Si vous rencontrez des problèmes liés à CORS lorsque vous effectuez des appels directement depuis un navigateur, vous devrez peut-être ajuster les paramètres de la règle CORS dans le PreFlow de requête du point de terminaison du proxy de votre bundle de proxy MCP Discovery.
Erreur d'analyse JSON lors de l'envoi de la requête au point de terminaison MCP
Vous pouvez recevoir un message d'erreur semblable à celui-ci (ou avec un code d'erreur et un message différents) lorsque vous envoyez une requête à votre point de terminaison MCP :
{
"error": {
"code": -32700,
"message": "JSON parse error"
},
"id": null,
"jsonrpc": "2.0"
}Dans ce cas, nous vous recommandons de confirmer les informations suivantes :
- Vous avez saisi l'URL de point de terminaison MCP correcte.
- Votre requête est correctement formatée.
- Vous accédez à une méthode compatible.
- Vous avez activé et configuré votre proxy de découverte MCP dans une région prise en charge. Pour obtenir la liste des régions susceptibles d'avoir des limites de capacité, consultez Échecs de déploiement.
Échecs de déploiement
Si le déploiement de votre proxy de découverte MCP échoue avec l'état Échec dans l'interface utilisateur, consultez le message d'erreur pour en savoir plus. Voici quelques échecs courants :
- Échec de la configuration réseau ou Schéma non compatible dans OAS : ces erreurs indiquent généralement un problème avec votre spécification OpenAPI. Assurez-vous que votre spécification est valide et qu'elle utilise une version compatible.
- Limites de capacité des régions (Apigee uniquement) : si vous voyez une erreur liée à l'échec du provisionnement de l'équilibreur de charge ou si l'état du provisionnement ne passe jamais à Déployé, cela peut être dû à des limites de capacité d'infrastructure temporaires dans l'une des régions suivantes :
asia-east2asia-northeast3asia-southeast2australia-southeast1europe-central2europe-west12europe-west9me-central2us-central2
Pour résoudre l'erreur, essayez de déployer le proxy dans un environnement d'une autre région. Ce mode d'échec ne s'applique pas à Apigee hybrid, où l'infrastructure d'exécution est votre propre cluster.
- MCP non activé dans le cluster (Apigee hybrid uniquement) : si le déploiement de votre proxy MCP reste indéfiniment à l'état Provisionnement et n'atteint jamais l'état Déployé, vérifiez que MCP est activé dans votre cluster. Consultez la section Diagnostic côté cluster ci-dessous.
Diagnostic côté cluster (Apigee hybrid uniquement)
Étant donné que le plan de données MCP Apigee hybrid s'exécute dans votre propre cluster Kubernetes, les modes de défaillance au sein du cluster sont diagnostiqués avec kubectl sur le cluster.
Suivez la checklist de diagnostic suivante dans l'ordre.
Étape 1 : Vérifier que MCP est activé dans le cluster
MCP est déployé en tant que ressource personnalisée ApigeeDeployment (gérée par l'opérateur Apigee), et non en tant que Deployment Kubernetes standard. Recherchez le ApigeeDeployment MCP :
kubectl -n APIGEE_NAMESPACE get apigeedeployment -l app=apigee-mcp-server
Résultat attendu (les noms des ressources incluent un suffixe dérivé de l'organisation, indiqué ici par ORG_CR_SUFFIX) :
NAME STATE NESTEDSTATE AGE apigee-mcp-server-default-ORG_CR_SUFFIX running 1h
Si la commande renvoie No resources found in APIGEE_NAMESPACE namespace., MCP n'est pas activé. Revenez à Activer MCP dans Apigee hybrid et vérifiez que enableMcpServer: true est défini comme clé de premier niveau dans votre overrides.yaml, et que vous avez mis à niveau la version Helm apigee-operator avant la version apigee-org. Consultez les étapes 3 et 4 de la procédure d'activation pour connaître les commandes helm appropriées.
Étape 2 : Vérifier que les pods MCP sont en cours d'exécution
kubectl -n APIGEE_NAMESPACE get pods -l app=apigee-mcp-server
Résultat attendu (les suffixes des pods seront différents) :
NAME READY STATUS RESTARTS AGE apigee-mcp-server-default-ORG_CR_SUFFIX-1170-abcd1234 2/2 Running 0 1h apigee-mcp-server-default-ORG_CR_SUFFIX-1170-efgh5678 2/2 Running 0 1h
Les noms des pods suivent le modèle apigee-mcp-server-default-ORG_CR_SUFFIX-REV-POD_HASH, où REV correspond à la révision de la version hybride à quatre chiffres (par exemple, 1170 pour la version hybride 1.17.0) et POD_HASH est un suffixe alphanumérique de huit caractères qui diffère pour chaque pod.
Chaque pod doit afficher 2/2 dans la colonne READY et Running dans la colonne STATUS. Si les pods ne sont pas Running, kubectl -n APIGEE_NAMESPACE describe pod POD_NAME indique la raison. Les causes courantes sont les échecs d'extraction d'image (vérifiez la sortie de votre cluster vers le registre d'images configuré dans votre overrides.yaml) et une marge de manœuvre insuffisante du processeur ou de la mémoire (augmentez mcpServer.resources.requests dans overrides.yaml).
Étape 3 : Vérifiez l'état d'extraction de la configuration du side-car
Le conteneur side-car apigee-mcp-server-config de chaque pod MCP extrait régulièrement la configuration MCP du plan de contrôle Apigee. Chaque extraction récupère la référence de configuration actuelle à partir de apigee.googleapis.com, puis extrait le bundle de configuration référencé à partir de Cloud Storage. Le plan de données MCP commence à diffuser le trafic des outils MCP sur https://mcp.apigee.internal/mcp une fois qu'une extraction s'est terminée avec succès avec une configuration valide.
Avant la première extraction réussie avec une configuration valide (soit parce qu'aucun proxy de découverte MCP n'a encore été déployé pour votre organisation, soit parce que le side-car ne peut pas atteindre le plan de contrôle), les pods MCP restent Ready, mais les requêtes adressées à https://mcp.apigee.internal/mcp échouent avec l'erreur connexion refusée.
Inspectez les journaux du side-car pour déterminer dans quel cas vous vous trouvez :
kubectl -n APIGEE_NAMESPACE logs -l app=apigee-mcp-server -c apigee-mcp-server-config --tail=100
- Ligne
inforépétée indiquant l'absence de configuration MCP à partir du plan de contrôle : Le plan de contrôle Apigee a renvoyé une réponse positive, mais aucun proxy de découverte MCP n'a encore été déployé pour votre organisation. Il s'agit de l'état stable attendu lors de l'intégration. Pour faire passer le plan de données MCP à l'état de diffusion, déployez un proxy de découverte MCP conformément au guide de démarrage rapide MCP.{"level":"info","ts":1787582542.68,"caller":"mcpsidecar/sidecar.go:397","msg":"mcpsidecar: no MCP config from CP yet; skipping tick, pod stays Ready via seed","org":"YOUR_ORG","mcp_server_id":"default"} - Ligne
erroravec un compteurconsecutive_failures: Les journaux du side-car sont au format JSON structuré. Lorsque vous voyez{"level":"error","ts":1787613247.74,"caller":"mcpsidecar/sidecar.go:...","msg":"mcpsidecar: ...","org":"YOUR_ORG","mcp_server_id":"default","consecutive_failures":185,"error":"<wrapped error text>"}"level":"error"avec un compteurconsecutive_failurescroissant, cela signifie que le side-car n'a pas pu effectuer une extraction de configuration. Le side-car effectue automatiquement une nouvelle tentative avec intervalle exponentiel entre les tentatives et réinitialise le compteur à 0 lors de la prochaine extraction réussie.Causes courantes à vérifier lorsque ce compteur continue d'augmenter :
- Le compte de service Google Cloud
apigee-watcherne figure pas dans la listewatcher_identitiesde la ressourcecontrolPlaneAccessde votre organisation Apigee. Consultez l'étape 2 : Accordez à l'identité de l'observateur l'accès à la configuration MCP sur le plan de contrôle dans la procédure d'activation pour ajouter l'autorisation et vérifier qu'elle a été appliquée. - La sortie de votre cluster vers
apigee.googleapis.comoustorage.googleapis.comest bloquée. Les deux points de terminaison doivent être accessibles depuis les pods MCP (voir Exigences du réseau sortant dans la procédure d'activation). - Le compte de service
apigee-watcherne peut pas obtenir de jetons d'accès Google Cloud à partir de ce cluster. Si des composants Apigee hybrid existants dans le même espace de noms signalent également des échecs d'authentification, résolvez d'abord le problème d'authentification partagé. - Erreur temporaire du plan de contrôle Apigee ou de Cloud Storage. Si le compteur continue d'augmenter pendant une période prolongée après avoir exclu les causes ci-dessus, contactez l'assistance Apigee.
- Le compte de service Google Cloud
Étape 4 : Vérifier que les hostAliases du processeur de messages ont été injectés
Lorsque vous activez MCP, l'opérateur Apigee injecte une entrée hostAliases dans la spécification du pod du processeur de messages (MP). L'entrée contient une adresse IP (ClusterIP du service MCP) et deux noms d'hôte : mcp.apigee.internal et ORG_NAME.mcp.apigee.internal en minuscules. Vérifiez que l'injection a réussi :
kubectl -n APIGEE_NAMESPACE get pods -l app=apigee-runtime \ -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.hostAliases}{"\n"}{end}'
Chaque pod MP listé doit comporter une entrée hostAliases contenant à la fois mcp.apigee.internal et ORG_NAME.mcp.apigee.internal en minuscules pointant vers l'adresse ClusterIP du service MCP. Tout pod MP qui affiche une entrée vide ou manquante a été créé avant l'activation de MCP. Supprimez le pod MP concerné afin que le contrôleur ApigeeDeployment le recrée à partir de la spécification de pod actuelle (qui inclut l'entrée hostAliases injectée) :
kubectl -n APIGEE_NAMESPACE delete pod -l app=apigee-runtime
Étape 5 : Validation de bout en bout
Pour un test de bout en bout qui envoie une véritable requête MCP initialize via le plan de données MCP, déployez un proxy de découverte MCP et suivez le guide de démarrage rapide MCP.
Avant qu'un proxy de découverte MCP ne soit déployé pour votre organisation, les requêtes adressées à https://mcp.apigee.internal/mcp échouent avec l'erreur connexion refusée, que le processeur de messages puisse ou non atteindre les pods MCP (voir l'étape 3).
Demandes d'assistance
Si vous ouvrez une demande d'assistance impliquant le plan de données MCP Apigee hybrid, joignez le résultat suivant pour accélérer le diagnostic :
kubectl -n APIGEE_NAMESPACE logs -l app=apigee-mcp-server --all-containers --tail=1000kubectl -n APIGEE_NAMESPACE describe pod -l app=apigee-mcp-serverkubectl -n APIGEE_NAMESPACE get pods -l app=apigee-mcp-server -o wideetkubectl -n APIGEE_NAMESPACE get svc -l app=apigee-mcp-server.- Sortie récente de
overrides.yamlethelm history APIGEE_ORG_RELEASE_NAME -n APIGEE_NAMESPACE(oùAPIGEE_ORG_RELEASE_NAMEest le nom de la version Helm pour le graphiqueapigee-org; recherchez-le avechelm list -n APIGEE_NAMESPACE | grep apigee-org). Avant de partageroverrides.yaml, masquez les éléments secrets, y compris :- Toutes les clés de compte de service intégrées sous
gcp.workloadIdentity,envs[].serviceAccountPathsoumcpServer.serviceAccountPath. - Tous les certificats TLS ou clés privées sous
virtualhosts. - Les champs de mot de passe
cassandra.auth. - Toutes les identifiants intégrés que vos remplacements transmettent à l'opérateur.
- Toutes les clés de compte de service intégrées sous
- La commande
curlcomplète et la réponse reproduisant le problème.
Impossible de remplacer le style d'API par MCP dans le hub d'API
Si une ressource d'API avec des opérations d'API existantes est déjà présente dans le hub d'API Apigee, vous ne pouvez pas remplacer l'attribut Style d'API de cette ressource par MCP. Pour enregistrer une API auprès du hub d'API Apigee en tant qu'API MCP, vous devez sélectionner le style MCP lors du premier enregistrement de l'API ou vous assurer qu'aucune opération n'est présente sur la ressource d'API avant de remplacer le style par MCP.
Si vous rencontrez d'autres problèmes, consultez Utiliser le débogage pour obtenir des informations détaillées sur l'utilisation de l'outil de débogage dans la console Google Cloud afin d'analyser les requêtes et les réponses vers et depuis votre proxy de découverte MCP.