Inteligencia Artificial

MCP por dentro: cómo funciona el protocolo que conecta agentes y herramientas

Autorangel cruz
Publicado
Lectura6 min de lectura
MCP por dentro: cómo funciona el protocolo que conecta agentes y herramientas

Le conectas un servidor MCP a Claude Code y, de pronto, el agente consulta tu base de datos o lee tus docs. Parece magia, pero no lo es. Por debajo hay un protocolo sorprendentemente simple: mensajes JSON-RPC 2.0 que viajan por un transporte, después de un handshake donde cliente y servidor negocian qué sabe hacer cada uno. Si todavía no lo tienes claro, empieza por qué es MCP; esto es el nivel de abajo. Todo lo que sigue sale de la especificación oficial.

Dos capas: datos y transporte

MCP se divide en dos capas, y entenderlas separadas aclara casi todo lo demás:

  • Capa de datos: el protocolo JSON-RPC 2.0. Define los mensajes, el ciclo de vida de la conexión y las primitivas (tools, resources, prompts).
  • Capa de transporte: cómo viajan esos mensajes (por procesos locales o por HTTP).

La capa de datos es la interna; la de transporte, la externa. La ventaja de separarlas: el mismo formato de mensaje funciona igual sin importar el transporte. Cambias de local a remoto y el JSON-RPC no cambia.

Los participantes: host, cliente y servidor

MCP sigue una arquitectura cliente-servidor con tres roles:

  • Host: la aplicación de IA que coordina todo (Claude Code, Claude Desktop, VS Code).
  • Cliente: por cada servidor que conectas, el host crea un cliente con una conexión dedicada.
  • Servidor: el programa que entrega el contexto (tus tools, resources y prompts).

El detalle que casi nadie menciona: la relación es uno a uno. Si conectas tres servidores, el host levanta tres clientes, cada uno con su conexión aislada. Eso importa (lo retomo al final).

El transporte: local contra remoto

La spec define dos transportes, y la elección determina si el servidor es "local" o "remoto":

  • stdio: comunicación por entrada/salida estándar entre procesos en la misma máquina. Sin red, sin sobrecarga. Un servidor local con stdio suele servir a un solo cliente. Es lo que usa, por ejemplo, el servidor de filesystem que Claude Desktop lanza en tu equipo.
  • Streamable HTTP: POST para los mensajes cliente a servidor, con Server-Sent Events opcionales para streaming. Es para servidores remotos que atienden a muchos clientes, con autenticación por bearer token o API key (la spec recomienda OAuth). Es lo que usa un servidor alojado como el de Sentry.

El handshake: negociar capacidades

Toda conexión arranca con un initialize. El cliente se presenta, dice qué versión del protocolo habla y qué sabe hacer:

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

El servidor responde con su propia versión y sus capacidades:

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "protocolVersion": "2025-11-25",
    "capabilities": {
      "tools": { "listChanged": true },
      "resources": {}
    },
    "serverInfo": { "name": "example-server", "version": "1.0.0" }
  }
}

Y el cliente cierra el handshake con una notificación de que está listo:

{ "jsonrpc": "2.0", "method": "notifications/initialized" }

Ese intercambio hace tres cosas: negocia una versión compatible del protocolo (el campo protocolVersion, una cadena de texto con la fecha), descubre capacidades (cada lado declara qué primitivas soporta, para no intentar operaciones que el otro no entiende) e intercambia identidad (nombre y versión, para depurar). Si no hay una versión compatible, la conexión se corta.

El ciclo de una herramienta: descubrir y ejecutar

Con la conexión lista, el cliente descubre las tools con tools/list:

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

La respuesta trae un array donde cada tool tiene name (identificador único), description y un inputSchema en JSON Schema (los parámetros que espera). Con eso, el host arma un registro unificado de tools de todos los servidores y se lo ofrece al modelo.

Cuando el modelo decide usar una, el cliente la ejecuta con tools/call:

{
  "jsonrpc": "2.0",
  "id": 3,
  "method": "tools/call",
  "params": {
    "name": "weather_current",
    "arguments": { "location": "San Francisco", "units": "imperial" }
  }
}

El servidor devuelve un array content (texto, imágenes, recursos) que el host inyecta de vuelta en la conversación. Ese patrón de listar y luego llamar es lo que permite catálogos dinámicos: el cliente no necesita saber de antemano qué tools existen.

Notificaciones: cambios en tiempo real

MCP no es solo pregunta-respuesta. Un servidor puede avisar cuando sus tools cambian:

{ "jsonrpc": "2.0", "method": "notifications/tools/list_changed" }

Fíjate que no tiene id: es una notificación JSON-RPC, no espera respuesta. Y solo la envían los servidores que declararon "listChanged": true en el handshake. Al recibirla, el cliente vuelve a pedir tools/list y actualiza lo que el modelo tiene disponible. Por eso las herramientas pueden aparecer o desaparecer en vivo, sin reiniciar nada.

No solo el servidor habla: primitivas del cliente

La spec también define primitivas que expone el cliente, y son las que permiten servidores más ricos:

  • Sampling: el servidor puede pedirle al host una completion del modelo (sampling/createMessage). Así el autor del servidor usa un LLM sin meter el SDK de ningún proveedor: se mantiene independiente del modelo.
  • Elicitation: el servidor pide información o confirmación al usuario (elicitation/create).

Por qué esto te importa en la práctica

Saber cómo funciona por dentro te cambia la forma de depurar:

  • Un cliente por servidor, con conexión dedicada: un servidor que se cae no tumba a los demás. Los aíslas mentalmente.
  • El handshake de capacidades explica el bug más común: si una tool "no aparece", muchas veces es que no se declaró o no se negoció en el initialize.
  • stdio contra HTTP explica por qué los servidores locales son instantáneos y los remotos necesitan autenticación y toleran latencia de red.
  • El ciclo listar/llamar dinámico es lo que permite que los mejores servidores MCP cambien sus tools sobre la marcha.

Cuando escribes el tuyo con la guía para crear un servidor MCP, el SDK te esconde casi todo esto. Pero cuando algo no conecta, saber qué mensaje falta es la diferencia entre adivinar y arreglarlo.

Preguntas frecuentes

¿Qué protocolo usa MCP por debajo?

JSON-RPC 2.0. Cliente y servidor se mandan requests (con id), responses y notifications (sin id, no esperan respuesta). Ese mismo formato viaja igual por cualquier transporte.

¿Cuál es la diferencia entre los transportes stdio y HTTP?

stdio comunica procesos locales por entrada/salida estándar, sin red, y suele servir a un cliente (servidor "local"). Streamable HTTP usa POST más SSE opcional, sirve a muchos clientes y soporta autenticación (servidor "remoto"). La spec recomienda OAuth para los remotos.

¿Qué se negocia en el handshake de MCP?

En el initialize se negocian tres cosas: la versión del protocolo (para que sean compatibles), las capacidades (qué primitivas soporta cada lado) y la identidad de cliente y servidor. Si no hay versión común, la conexión se cierra.

¿Cómo sabe el agente qué herramientas tiene un servidor?

Las descubre con tools/list, que devuelve el nombre, la descripción y el esquema de entrada de cada tool. Luego las ejecuta con tools/call. Si las tools cambian, el servidor puede avisar con una notificación y el cliente vuelve a listar.

¿MCP depende de un modelo de IA concreto?

No. MCP solo define el protocolo de intercambio de contexto; no dicta qué modelo usa la aplicación ni cómo. Gracias a la primitiva de sampling, incluso un servidor puede pedir completions sin acoplarse a ningún proveedor.

Cierre

MCP no es magia: es JSON-RPC 2.0 sobre un transporte, con un handshake que negocia qué sabe hacer cada lado y unas pocas primitivas bien definidas. Esa simpleza es justo lo que lo hace universal. Si quieres el panorama de entrada, lee qué es MCP; si quieres pasar del concepto al código, sigue con cómo crear tu primer servidor MCP.

Fuente