Problemas al integrar un servidor MCP: protocolo, transporte, permisos y schema

Guía por capas para diagnosticar un servidor MCP: versión del protocolo, transporte, ejecución, autorización, schema de tools y una prueba segura con Inspector.

Si un servidor MCP no se conecta o una tool call falla, no cambie a la vez la configuración del cliente, el código del servidor y los permisos. Primero identifique la capa del fallo. Siga este orden: versión del protocolo → transporte → ejecución y entorno → permissions/auth → inputSchema → una llamada read-only.

A 23 de agosto de 2026, la versión vigente y verificada de la especificación MCP es 2026-07-28. Ya no exige el antiguo handshake obligatorio mediante initialize: el client puede usar server/discover, mientras que la versión del protocolo, los datos del client y sus capabilities se envían con las solicitudes en _meta. Las implementaciones legacy 2025-11-25 y anteriores siguen otra secuencia: initialize, respuesta del servidor y después notifications/initialized. No mezcle ambas épocas en un mismo intercambio.

Separe desde el principio MCP de la API del modelo. MCP conecta el client con tools y contexto; la llamada al modelo puede seguir otra ruta y usar otras credentials. Aísle la capa del modelo con la guía de BetterToken: una API Key propia y la interfaz OpenAI-compatible o Anthropic-compatible elegida ofrecen una ruta independiente y verificable, de modo que un error del modelo no se busque dentro de MCP. Esa Key no es una credential del servidor MCP, y BetterToken no es un MCP host ni un MCP transport.

Clasificación rápida del fallo

Antes de abrir Inspector, anote un síntoma y el último punto confirmado:

  • el proceso no arranca;
  • el proceso funciona, pero el client no recibe JSON-RPC;
  • el transporte responde, pero la versión o las capabilities no coinciden;
  • el servidor devuelve 401 o 403;
  • tools/list funciona, pero falta la tool esperada;
  • la tool aparece, pero tools/call rechaza sus arguments;
  • la llamada termina, pero no se puede verificar el resultado.

No guarde en las notas una API Key, un bearer token, una cookie, el prompt completo ni contenido de archivos privados. Para correlacionar basta con la hora, el nombre del servidor, el método, el id de JSON-RPC, el código de error y un mensaje depurado.

1. Determine la época del protocolo

Compruebe qué versión admiten el client, el server y el SDK. El mensaje Connected confirma el transporte y una parte del discovery, pero no demuestra por sí solo que exista acuerdo sobre 2026-07-28.

En una implementación moderna, verifique tres señales:

  1. El SDK o sus release notes declaran de forma explícita compatibilidad con 2026-07-28.
  2. La traza contiene server/discover u otra ruta de discovery prevista por el SDK.
  3. Las solicitudes incluyen un _meta correcto con versión, datos del client y capabilities.

No copie manualmente la forma de _meta desde otro SDK: el formato wire exacto debe generarlo un client compatible o el SDK oficial. Si el server espera initialize y el client envía solicitudes autocontenidas de 2026-07-28, hay una incompatibilidad de época, no un error en la tool schema.

initialize legacy: solo para 2025-11-25 y anteriores

Este es un request legacy mínimo. No lo añada a un flow moderno 2026-07-28 «por si acaso».

{ "jsonrpc": "2.0", "id": 1, "method": "initialize", "params": { "protocolVersion": "2025-11-25", "capabilities": {}, "clientInfo": { "name": "mcp-diagnostic-client", "version": "1.0.0" } } }

Tras una respuesta correcta, el legacy client envía notifications/initialized. Si este intercambio se interrumpe, compare primero las versiones y la lista de capabilities. Todavía no es momento de pasar a tools/list.

2. Pruebe el transporte separado de la semántica MCP

MCP define métodos y datos; el transporte se ocupa del arranque, el framing, la entrega y la cancelación de solicitudes. Cambiar de stdio a HTTP no corregirá un inputSchema inválido.

stdio

Con stdio, el client inicia el server como proceso hijo. Los mensajes circulan por stdin y stdout como documentos JSON-RPC UTF-8 separados por saltos de línea.

Compruebe:

  1. command existe y se ejecuta con el mismo usuario.
  2. Los argumentos se pasan como elementos separados, sin depender de aliases del shell.
  3. El directorio de trabajo contiene los archivos necesarios o las rutas son absolutas.
  4. Las variables necesarias están disponibles para el proceso hijo.
  5. stdout no contiene banners, líneas de depuración ni stack traces; los logs van a stderr.

Un solo console.log() accidental en stdout puede romper el framing antes de que el client vea una respuesta JSON-RPC.

Streamable HTTP

Con Streamable HTTP, el client envía mensajes POST a un único endpoint MCP. La respuesta puede ser JSON normal o SSE limitado a la solicitud. Verifique la URL exacta, el método HTTP, Content-Type, TLS, redirects, proxy y método de autenticación.

Haga la prueba de transporte en loopback o en un entorno de pruebas aislado. No escanee un endpoint público de producción sin permiso. Si POST devuelve el HTML de inicio de sesión, un 301/302 hacia otro host o una respuesta del reverse proxy, aún no ha llegado a MCP.

3. Reproduzca el arranque en el mismo entorno

Para stdio, ejecute primero el comando del server directamente desde el mismo directorio y con el mismo usuario que el MCP client. No lo sustituya por una ejecución desde el IDE: pueden variar PATH, cwd, runtime y permisos.

Compruebe:

node --version pwd node ./dist/server.js

pwd no revela un secret por sí mismo, pero no publique la ruta si contiene un nombre de usuario o el nombre de un proyecto privado. El comando del server debe esperar JSON-RPC en stdin o terminar con un error claro en stderr. Una salida inmediata sin mensaje suele indicar un entrypoint incorrecto, una dependencia ausente o un error de arranque capturado sin log.

La documentación oficial de Inspector CLI, verificada el 23 de agosto de 2026, requiere Node.js 22.19.0 o posterior. Si la versión es inferior, deténgase y cambie de runtime antes de continuar.

4. Separe permissions y authentication

El código de respuesta indica la siguiente comprobación:

  • 401 Unauthorized: falta la credential, ha caducado o no se acepta;
  • 403 Forbidden: la identity se reconoce, pero no tiene el permission o scope necesario;
  • 404: suele señalar un endpoint o una ruta incorrectos, no permisos insuficientes;
  • timeout: el server, proxy o tool no terminó a tiempo; no prueba un error de auth.

No desactive permissions para un smoke test. Cree una identity de prueba independiente con el scope mínimo y elija una tool read-only sin efectos externos. El client debe permitir que una persona rechace la llamada; las annotations de la tool son datos no confiables y no sustituyen la policy.

En los logs conserve la decisión de auth (allowed/denied), el nombre del scope y el correlation ID. Elimine o enmascare la credential, el header Authorization y las cookies.

5. Valide la capability y inputSchema

El server debe declarar la capability tools antes de atender tools/list. Cada tool necesita un nombre único y un objeto JSON Schema válido en inputSchema. Los arguments de tools/call deben ajustarse a esa schema.

Declaración mínima de una tool read-only:

{ "name": "echo", "description": "Devuelve el texto recibido sin cambios", "inputSchema": { "type": "object", "properties": { "text": { "type": "string" } }, "required": ["text"], "additionalProperties": false } }

Los errores habituales son simples: falta el type: object raíz, un campo obligatorio no aparece en properties, el client envía un número en vez de una cadena, cambia el uso de mayúsculas en el nombre de un argument o el server anuncia dos tools con el mismo nombre.

Cuando versión y transporte coincidan, pruebe el método con este payload JSON-RPC:

{ "jsonrpc": "2.0", "id": 2, "method": "tools/list", "params": {} }

Después invoque exactamente una tool:

{ "jsonrpc": "2.0", "id": 3, "method": "tools/call", "params": { "name": "echo", "arguments": { "text": "MCP_OK_2026" } } }

Estos fragmentos muestran el payload de los métodos, no el bootstrap completo de la conexión. En el flow 2026-07-28, un client compatible añade en _meta los metadatos requeridos por la solicitud; en el legacy flow, primero se ejecuta initialize. No envíe manualmente estos JSON a un endpoint de producción sin permiso.

6. Ejecute una prueba segura con MCP Inspector CLI

Primero instale Inspector como dependencia del proyecto fijada en un lockfile confiable. La opción --no-install siguiente evita descargar una versión actual arbitraria durante el diagnóstico.

Lista de tools de un server stdio local:

npx --no-install @modelcontextprotocol/inspector --cli node ./dist/server.js --method tools/list

Una llamada a echo:

npx --no-install @modelcontextprotocol/inspector --cli node ./dist/server.js \ --method tools/call \ --tool-name echo \ --tool-arg text=MCP_OK_2026

Para un endpoint Streamable HTTP de prueba en loopback:

npx --no-install @modelcontextprotocol/inspector --cli \ http://127.0.0.1:3000/mcp \ --transport http \ --method tools/list

No introduzca un token en el historial del shell, la URL o el artículo. Si el endpoint exige auth, configure la credential mediante el mecanismo normal de Inspector en el entorno local, o detenga la prueba y solicite una identity de prueba al propietario del server. Los comandos anteriores no incluyen ninguna Key real de forma intencionada.

Síntoma → comprobación → corrección

SíntomaQué comprobar primeroCorrección mínima
spawn ENOENT o proceso no encontradoRuta absoluta de command, runtime y PATH del proceso clientIndicar un executable existente o corregir el entorno de ejecución
El proceso termina de inmediatocwd, entrypoint, dependencias y error en stderrEjecutar desde el directorio correcto y devolver un non-zero exit claro
El client informa de JSON parse errorSalida adicional en stdout, UTF-8 y salto de líneaDejar solo JSON-RPC en stdout y enviar los logs a stderr
HTTP devuelve HTML o redirectURL MCP, proxy, TLS y ruta POSTUsar un único endpoint MCP correcto y corregir la regla del proxy
Error de versión antes de tools/listÉpoca del protocolo y compatibilidad del SDKActualizar el lado incompatible o mantener explícitamente la ruta legacy; no mezclar handshakes
401 UnauthorizedPresencia y vencimiento de la credentialObtener una credential de prueba independiente por el procedimiento autorizado
403 ForbiddenScope, resource policy e identityConceder solo el scope necesario a la identity de prueba
tools/list → error de método/capabilitySi se declaró la capability toolsCorregir la declaración antes de registrar tools
La tool no apareceNombre único y registro realRegistrar una tool y reiniciar el server
tools/call rechaza argumentsinputSchema, tipos, required y mayúsculas de los nombresAjustar los arguments a la schema; no relajarla a un objeto arbitrario
La llamada queda bloqueadaTimeout, cancellation y dependencia externa de la toolSustituir la prueba por un echo local read-only y comprobar después la dependencia

Criterios de aceptación

La integración supera la aceptación mínima cuando se cumplen las cinco condiciones:

  1. Los logs o la telemetry muestran la versión esperada y negociada del protocolo.
  2. El transporte conserva el framing: stdio no tiene contenido extra en stdout y HTTP responde desde el endpoint MCP.
  3. tools/list devuelve una tool esperada con un inputSchema válido.
  4. tools/call se invoca realmente con text=MCP_OK_2026 y devuelve MCP_OK_2026 sin cambios.
  5. La prueba no desactivó permissions, no expuso credentials y no provocó efectos externos.

Ver MCP_OK_2026 en una respuesta del modelo no basta. Hace falta una tool call registrada con el id JSON-RPC correspondiente, o un registro de Inspector junto con el log depurado del server.

Condiciones de parada

Detenga el diagnóstico y no pase a la capa siguiente si:

  • se desconoce la época del protocolo compatible con alguna de las partes;
  • Inspector propone instalar una versión no fijada del paquete sin revisarla;
  • la prueba exige una credential de producción, desactivar auth o ampliar el scope;
  • la única tool disponible escribe en una base de datos, envía un mensaje, modifica un archivo o ejecuta un comando;
  • el endpoint HTTP pertenece a un tercero y no se ha confirmado el permiso de prueba;
  • aparecen en los logs una Key, un token, una cookie, datos personales o contenido de un recurso privado;
  • tools/list es inestable o devuelve schemas diferentes en ejecuciones repetidas;
  • el server falla antes de generar una respuesta JSON-RPC válida.

En estos casos, conserve el síntoma depurado, las versiones de client/server/SDK, el transporte, el correlation ID y un fragmento mínimo del error. Basta para entregar el problema al responsable de la capa correcta sin repartir permisos ni secretos innecesarios.

Fuentes

La versión de la especificación, el transporte y la versión mínima de Node.js se verificaron el 23 de agosto de 2026. Consulte de nuevo la documentación oficial antes de repetir el diagnóstico después de actualizar el client, server, SDK o Inspector.

¿Quieres optimizar tu flujo de trabajo con LLM?

Conecta modelos mediante una API, gestiona claves y controla el gasto en IA.