Soluciona problemas de implementaciones de MCP en Apigee

Esta página se aplica a Apigee y Apigee Hybrid.

Consulta la documentación de Apigee Edge.

En esta página, se describe cómo solucionar problemas relacionados con la implementación de proxies de descubrimiento de MCP. Puedes usar esta página para comprender el ciclo de vida del aprovisionamiento asíncrono de las implementaciones de MCP, resolver códigos de error y verificar la conectividad del entorno de ejecución.

Comprende la implementación de MCP

La implementación de un proxy de descubrimiento de MCP es un proceso asíncrono de varios pasos que garantiza que la configuración se propague por completo en la infraestructura de Apigee y Google Cloud antes de que se complete la implementación del proxy.

Mientras se realizan estos pasos de aprovisionamiento descendente, la IU muestra el proxy en estado Aprovisionando. Cuando se complete el proceso, el estado cambiará a Implementado. Este estado confirma que todos los componentes downstream están completamente aprovisionados y que el proxy está listo para controlar el tráfico.

Soluciona problemas

En las siguientes secciones, se describen los errores y los problemas conocidos que puedes encontrar cuando usas MCP en Apigee.

Problema: Un backend lee un argumento de herramienta de una ubicación de solicitud (la cadena de consulta, un encabezado o una cookie), pero la especificación de OpenAPI declara el parámetro in en una ubicación diferente, por lo que el argumento llega a otro lugar en la solicitud del backend. La llamada falla o se comporta como si el argumento no estuviera presente.

Síntomas: La solicitud tools/call se realiza correctamente en la capa de MCP y el cliente de MCP proporciona el argumento, pero el backend responde como si faltara el valor, por ejemplo, un 400 para un valor obligatorio o un valor predeterminado que se aplica en lugar del valor enviado.

Causa: El parámetro se declara in: header o in: cookie en la especificación de OpenAPI, por lo que Apigee envía su valor como un encabezado de la solicitud o en el encabezado Cookie en lugar de en la cadena de consulta. Un backend que lee el valor solo de la cadena de consulta no lo ve. Consulta Ubicación del argumento de la herramienta en la solicitud de backend.

Solución: Decide a dónde pertenece el valor y haz que la especificación y el backend coincidan:

  • Para mantener el valor en la cadena de consulta, declara el parámetro in: query.
  • Para enviarlo como un encabezado o una cookie, deja la declaración como está y lee el valor de esa ubicación en tu backend.

Problema: Una cookie que llega en la solicitud HTTP que realiza el cliente de MCP (por ejemplo, una cookie de sesión de un cliente basado en un navegador) deja de llegar al backend en algunas llamadas a herramientas.

Síntomas: El backend se comporta como si el emisor no estuviera autenticado o no estuviera en sesión, y el comportamiento es incoherente: la misma operación funciona en algunas llamadas y no en otras.

Causa: La operación declara uno o más parámetros in: cookie, y las llamadas afectadas proporcionaron al menos uno de ellos. El encabezado Cookie se reescribe por completo en lugar de agregarse, por lo que, en esas llamadas, solo lleva los parámetros de cookie declarados y se descartan todas las demás cookies. Las llamadas que no proporcionaron ninguno de los parámetros de cookie pasan el encabezado sin modificar, por lo que solo fallan algunas llamadas. Consulta Cookies en la solicitud a tu backend.

Resolución: Declara cada cookie que el backend necesita como un parámetro in: cookie en cada operación que la requiera, de modo que su valor siempre se proporcione a través de la llamada a la herramienta en lugar de heredarse de la solicitud del cliente. No hay ningún parámetro de configuración que conserve una cookie no declarada.

Códigos de estado de respuesta de error para llamadas a herramientas y metadatos

Los extremos de MCP de Apigee devuelven códigos de estado HTTP que siguen la especificación del Protocolo de contexto del modelo (MCP) y los estándares de OAuth relacionados. Comprender este comportamiento te ayuda a controlar correctamente los errores en tu cliente de MCP o agente de IA.

En la siguiente tabla, se resumen los códigos de estado que devuelven los extremos de MCP de Apigee:

Situación Código de estado HTTP Cuerpo de la respuesta
La ejecución de una herramienta falla en tools/call (por ejemplo, la API de backend devuelve un error 4xx o 5xx, como un error de validación o un campo obligatorio faltante). 200 OK Un CallToolResult con result.isError establecido en true y los detalles del error en content. Esto permite que el cliente de MCP y el agente de LLM lean el error y se recuperen (por ejemplo, volviendo a solicitar la entrada faltante y reintentando) en lugar de finalizar la sesión.
Los metadatos de recursos protegidos (PRM) de OAuth no están configurados o no se pueden encontrar en /.well-known/oauth-protected-resource/mcp. 404 Not Found Indica que no hay metadatos de recursos protegidos disponibles en la ubicación solicitada.
Falta el token de acceso, no es válido o venció. 401 Unauthorized Incluye un desafío WWW-Authenticate para impulsar el flujo de descubrimiento de OAuth.
El token de acceso tiene un permiso insuficiente. 403 Forbidden Incluye un desafío de WWW-Authenticate para impulsar el flujo de autorización de nivel superior.

Ejemplo: Cuerpo de la respuesta de error de ejecución de la herramienta

Cuando falla una llamada a una herramienta, el MCP de Apigee devuelve HTTP 200 OK y informa el error en el objeto JSON-RPC result, con isError establecido en true. El error original que muestra tu backend se conserva: el cuerpo de la respuesta del backend se coloca de forma textual (como una cadena) en result.content[].text. Por ejemplo, si el backend devuelve HTTP 404 con el cuerpo {"error":"User 42 not found"}, la respuesta de MCP es la siguiente:

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "{\"error\":\"User 42 not found\"}"
      }
    ],
    "isError": true
  }
}

El id coincide con el id de tu solicitud tools/call. Si el backend no devuelve un cuerpo de respuesta, text contiene un resumen generado, como Operation failed (HTTP 500).

Tu cliente de MCP debe inspeccionar result.isError (no el código de estado HTTP) para detectar una llamada a la herramienta con errores. Si tu código de cliente espera específicamente un estado HTTP 4xx o 5xx para indicar un error de ejecución de la herramienta, no detecta el error, porque la respuesta es HTTP 200 OK. Actualiza esos clientes para que lean result.isError y el array content.

Los errores a nivel del protocolo (por ejemplo, una solicitud JSON-RPC con formato incorrecto) son distintos de los errores de ejecución de la herramienta: se siguen devolviendo en el objeto error de JSON-RPC (por ejemplo, {"jsonrpc": "2.0", "error": {"code": -32700, ...}}) en lugar de en result.isError.

Recomendación: Los clientes de MCP que cumplen con los estándares controlan estos códigos de estado a través de su lógica predeterminada, por lo que no se requieren cambios. Si anteriormente agregaste una solución alternativa del cliente para controlar códigos de estado no estándar (por ejemplo, analizar un cuerpo de respuesta que no sea 2xx para errores tools/call o tratar una respuesta 500 del extremo de PRM como "metadatos no configurados"), te recomendamos que quites esa solución alternativa. De lo contrario, es posible que tu cliente siga usando la lógica de manejo obsoleta en lugar de procesar los códigos de estado corregidos con normalidad.

Política de CORS para llamadas de MCP basadas en el navegador

Se necesita una política de uso compartido de recursos de origen cruzado (CORS) cuando las llamadas al MCP de Apigee se realizan directamente desde un navegador (por ejemplo, cuando el inspector del MCP usa el parámetro de configuración "Directo" en lugar de "A través de un proxy"). La plantilla de proxy de descubrimiento de MCP incluye la política de CORS de Apigee en el PreFlow de solicitud del extremo del proxy del paquete de proxy de forma predeterminada para habilitar las llamadas basadas en el navegador.

Si tienes problemas relacionados con CORS cuando realizas llamadas directamente desde un navegador, es posible que debas ajustar la configuración de la política de CORS en el flujo previo de solicitud del extremo del proxy de tu paquete de proxy de MCP Discovery.

Error de análisis de JSON cuando se envía una solicitud al extremo de MCP

Es posible que recibas un mensaje de error similar al siguiente (o con un código de error y un mensaje diferentes) cuando envíes una solicitud a tu extremo de MCP:

{
  "error": {
    "code": -32700,
    "message": "JSON parse error"
  },
  "id": null,
  "jsonrpc": "2.0"
}

En ese caso, te recomendamos que confirmes la siguiente información:

  • Ingresaste la URL de extremo de MCP correcta.
  • Tu solicitud tiene el formato correcto.
  • Estás accediendo a un método compatible.
  • Habilitaste y configuraste tu proxy de descubrimiento de MCP en una región admitida. Para obtener una lista de las regiones que pueden tener límites de capacidad, consulta fallas de implementación.

Fallas de Deployment

Si la implementación de tu proxy de descubrimiento de MCP falla con el estado Fallido en la IU, consulta el mensaje de error para obtener más detalles. Entre las fallas comunes, se incluyen las siguientes:

  • Error en la configuración de red o Esquema no compatible en OAS: Estos errores suelen indicar un problema con la especificación de OpenAPI. Asegúrate de que tu especificación sea válida y use una versión compatible.
  • Límites de capacidad de la región (solo Apigee): Si ves un error relacionado con una falla de aprovisionamiento del balanceador de cargas o el estado de aprovisionamiento nunca cambia a Implementado, es posible que se deba a límites de capacidad de infraestructura temporales en una de las siguientes regiones:
    • asia-east2
    • asia-northeast3
    • asia-southeast2
    • australia-southeast1
    • europe-central2
    • europe-west12
    • europe-west9
    • me-central2
    • us-central2

    Para resolver el error, intenta implementar el proxy en un entorno de otra región. Este modo de falla no se aplica a Apigee Hybrid, en el que la infraestructura del entorno de ejecución es tu propio clúster.

  • MCP no habilitado en el clúster (solo Apigee Hybrid): Si la implementación del proxy de MCP permanece en el estado Aprovisionando de forma indefinida y nunca alcanza el estado Implementado, verifica que MCP esté habilitado en el clúster. Consulta Diagnóstico del lado del clúster a continuación.

Diagnóstico del lado del clúster (solo Apigee Hybrid)

Debido a que el plano de datos de MCP de Apigee Hybrid se ejecuta dentro de tu propio clúster de Kubernetes, los modos de falla dentro del clúster se diagnostican con kubectl en el clúster. Revisa la siguiente lista de tareas de diagnóstico en orden.

Paso 1: Verifica que MCP esté habilitado en el clúster

MCP se implementa como un recurso personalizado de ApigeeDeployment (administrado por el operador de Apigee), no como un Deployment de Kubernetes básico. Verifica el MCP ApigeeDeployment:

kubectl -n APIGEE_NAMESPACE get apigeedeployment -l app=apigee-mcp-server

Resultado esperado (los nombres de los recursos incluyen un sufijo derivado de la organización, que se muestra aquí como ORG_CR_SUFFIX):

NAME                                     STATE     NESTEDSTATE   AGE
apigee-mcp-server-default-ORG_CR_SUFFIX       running                 1h

Si el comando devuelve No resources found in APIGEE_NAMESPACE namespace., MCP no está habilitado. Regresa a Habilita MCP en Apigee Hybrid y verifica que enableMcpServer: true esté configurada como una clave de nivel superior en tu overrides.yaml y que hayas actualizado la versión de Helm apigee-operator antes de la versión apigee-org. Consulta el paso 3 y el paso 4 del procedimiento de habilitación para conocer los comandos de helm correctos.

Paso 2: Verifica que los Pods de MCP se estén ejecutando

kubectl -n APIGEE_NAMESPACE get pods -l app=apigee-mcp-server

Resultado esperado (los sufijos de los Pods serán diferentes):

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

Los nombres de los Pods siguen la plantilla apigee-mcp-server-default-ORG_CR_SUFFIX-REV-POD_HASH, en la que REV es la revisión de la versión híbrida de cuatro dígitos (por ejemplo, 1170 para la versión híbrida 1.17.0) y POD_HASH es un sufijo alfanumérico de ocho caracteres que es diferente para cada Pod.

Cada Pod debe mostrar 2/2 en la columna READY y Running en la columna STATUS. Si los Pods no están en estado Running, kubectl -n APIGEE_NAMESPACE describe pod POD_NAME muestra el motivo. Las causas comunes son las fallas de extracción de imágenes (verifica la salida de tu clúster al registro de imágenes configurado en tu overrides.yaml) y el margen de CPU o memoria insuficiente (aumenta mcpServer.resources.requests en overrides.yaml).

Paso 3: Verifica el estado de extracción de la configuración del archivo adicional

El contenedor sidecar apigee-mcp-server-config en cada Pod de MCP extrae de forma periódica la configuración de MCP del plano de control de Apigee. Cada extracción recupera la referencia de configuración actual de apigee.googleapis.com y, luego, recupera el paquete de configuración al que se hace referencia desde Cloud Storage. El plano de datos de MCP comienza a entregar tráfico de herramientas de MCP en https://mcp.apigee.internal/mcp una vez que se completa correctamente una extracción con una configuración válida.

Antes de esa primera extracción exitosa con una configuración válida (ya sea porque aún no se implementó ningún proxy de descubrimiento de MCP para tu organización o porque el archivo adicional no puede alcanzar el plano de control), los Pods de MCP permanecen en estado Ready, pero las solicitudes a https://mcp.apigee.internal/mcp fallan con el mensaje conexión rechazada.

Inspecciona los registros de sidecar para determinar en qué caso te encuentras:

kubectl -n APIGEE_NAMESPACE logs -l app=apigee-mcp-server -c apigee-mcp-server-config --tail=100
  • Línea info repetida que indica que no hay configuración de MCP desde el plano de control:
    {"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"}
    El plano de control de Apigee devolvió una respuesta correcta, pero aún no se implementó ningún proxy de descubrimiento de MCP para tu organización. Este es el estado estable esperado durante la incorporación. Para que el plano de datos de MCP pase al estado de entrega, implementa un proxy de descubrimiento de MCP según la guía de inicio rápido de MCP.
  • Línea error con un contador consecutive_failures:
    {"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>"}
    Los registros de sidecar son JSON estructurados. Cuando veas "level":"error" con un contador consecutive_failures en aumento, el archivo adicional no pudo completar una extracción de configuración. El archivo de tareas secundarias vuelve a intentarlo automáticamente con una retirada y restablece el contador a 0 en la siguiente extracción correcta.

    Estas son las causas raíz comunes que debes verificar cuando este contador sigue aumentando:

    • La cuenta de servicio de Google Cloud apigee-watcher no está en la lista watcher_identities del recurso controlPlaneAccess de tu organización de Apigee. Consulta el Paso 2: Otorga a la identidad del observador acceso a la configuración de MCP en el plano de control en el procedimiento de habilitación para agregar el otorgamiento y verificar que se haya aplicado.
    • La salida de tu clúster a apigee.googleapis.com o storage.googleapis.com está bloqueada. Se debe poder acceder a ambos extremos desde los Pods de MCP (consulta Requisitos de red saliente en el procedimiento de habilitación).
    • La cuenta de servicio apigee-watcher no puede obtener tokens de acceso de Google Cloud desde este clúster. Si los componentes existentes de Apigee Hybrid en el mismo espacio de nombres también informan fallas de autenticación, primero soluciona el problema de autenticación compartido.
    • Un error transitorio del plano de control de Apigee o de Cloud Storage. Si el contador sigue aumentando durante un período prolongado después de descartar las causas anteriores, comunícate con el equipo de asistencia de Apigee.

Paso 4: Verifica que se hayan insertado los hostAliases del Message Processor

Cuando habilitas el MCP, el operador de Apigee inserta una entrada hostAliases en la especificación del Pod del Message Processor (MP). La entrada contiene una IP (la ClusterIP del servicio de MCP) y dos nombres de host: mcp.apigee.internal y ORG_NAME.mcp.apigee.internal en minúsculas. Verifica que la inserción se haya realizado correctamente:

kubectl -n APIGEE_NAMESPACE get pods -l app=apigee-runtime \
  -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.hostAliases}{"\n"}{end}'

Cada Pod de MP de la lista debe tener una entrada hostAliases que contenga mcp.apigee.internal y ORG_NAME.mcp.apigee.internal en minúsculas que apunten a la ClusterIP del Service de MCP. Cualquier Pod de MP que muestre una entrada vacía o faltante se creó antes de que se habilitara MCP. Borra el Pod de MP afectado para que el controlador de ApigeeDeployment lo vuelva a crear a partir de la especificación del Pod actual (que incluye la entrada hostAliases insertada):

kubectl -n APIGEE_NAMESPACE delete pod -l app=apigee-runtime

Paso 5: Verificación de extremo a extremo

Para realizar una prueba de extremo a extremo que envíe una solicitud de initialize de MCP real a través del plano de datos de MCP, implementa un proxy de descubrimiento de MCP y sigue la guía de inicio rápido de MCP. Antes de que se implemente un proxy de descubrimiento de MCP para tu organización, las solicitudes a https://mcp.apigee.internal/mcp fallan con el mensaje conexión rechazada, independientemente de si el Message Processor puede alcanzar los Pods de MCP (consulta el paso 3).

Casos de asistencia

Si abres un caso de asistencia que involucra el plano de datos de MCP de Apigee Hybrid, adjunta el siguiente resultado para acelerar el diagnóstico:

  • kubectl -n APIGEE_NAMESPACE logs -l app=apigee-mcp-server --all-containers --tail=1000
  • kubectl -n APIGEE_NAMESPACE describe pod -l app=apigee-mcp-server
  • kubectl -n APIGEE_NAMESPACE get pods -l app=apigee-mcp-server -o wide y kubectl -n APIGEE_NAMESPACE get svc -l app=apigee-mcp-server.
  • Resultado reciente de overrides.yaml y helm history APIGEE_ORG_RELEASE_NAME -n APIGEE_NAMESPACE (en el que APIGEE_ORG_RELEASE_NAME es el nombre de la versión de Helm para el gráfico de apigee-org; encuéntralo con helm list -n APIGEE_NAMESPACE | grep apigee-org). Antes de compartir overrides.yaml, oculta el material secreto, incluido lo siguiente:
    • Cualquier clave de cuenta de servicio intercalada en gcp.workloadIdentity, envs[].serviceAccountPaths o mcpServer.serviceAccountPath.
    • Cualquier certificado TLS o clave privada en virtualhosts.
    • Los campos de contraseña de cassandra.auth
    • Son las credenciales intercaladas que tus anulaciones pasan al operador.
  • El comando curl completo y la respuesta que reproduce el problema.

No se puede cambiar el estilo de la API a MCP en el concentrador de APIs

Si ya existe un recurso de API con operaciones de API en el centro de APIs de Apigee, no puedes cambiar el atributo Estilo de API de ese recurso a MCP. Para registrar una API en el centro de APIs de Apigee como una API de MCP, debes seleccionar el estilo MCP cuando registres la API por primera vez o asegurarte de que no haya operaciones presentes en el recurso de la API antes de cambiar el estilo a MCP.

Si tienes algún otro problema, consulta Usa la depuración para obtener información detallada sobre cómo usar la herramienta de depuración en la consola de Google Cloud para analizar las solicitudes y respuestas hacia y desde tu proxy de descubrimiento de MCP.