Implementación del Model Context Protocol (MCP) sobre HTTP
Clase 10 de 26 • Curso de MCP
El 70% del tráfico web mundial ya utiliza HTTP/2, una evolución que transforma radicalmente cómo los protocolos modernos como MCP pueden aprovechar la infraestructura web existente.
Hoy vamos a explorar cómo implementar el Model Context Protocol sobre HTTP, tanto en su versión 1.1 como en la 2.0. MCP es un protocolo de comunicación basado en JSON-RPC 2.0 que facilita la interacción entre un cliente, como una herramienta de desarrollo, y un servidor que maneja modelos de lenguaje o sistemas de IA. El objetivo principal es permitir que los modelos de lenguaje accedan a herramientas, contexto externo y datos estructurados mediante un sistema de comunicación organizado, seguro y rastreable.
¿Por qué HTTP como transporte? Porque cuando necesitas integraciones con servicios web o APIs remotas, HTTP proporciona un método familiar y establecido para esta comunicación. Imagina que estás desarrollando una aplicación web que necesita consultar a un modelo de lenguaje alojado en otro servidor. HTTP ya está ahí, probado, confiable.
Empecemos con lo fundamental: cómo funciona MCP sobre HTTP. El cliente MCP envía peticiones al servidor usando el formato JSON-RPC sobre HTTP. Estas peticiones viajan como mensajes HTTP estándar, aprovechando toda la infraestructura web existente. El servidor MCP recibe la petición, la procesa ejecutando herramientas, consultando datos o generando respuestas, y devuelve los resultados en formato JSON-RPC. La comunicación es asincrónica, lo que significa que el cliente puede seguir funcionando mientras espera la respuesta.
Un caso práctico: cuando un desarrollador usa Cursor y solicita ayuda para refactorizar código, Cursor actúa como cliente MCP y envía una petición HTTP al servidor, que puede ser Claude u Ollama. El servidor analiza el código, genera sugerencias y las devuelve al editor para mostrarlas al usuario.
Ahora, ¿cómo encapsulamos un mensaje JSON-RPC usando HTTP POST? Primero, creamos el mensaje JSON-RPC con esta estructura básica:
{ "jsonrpc": "2.0", "method": "nombre_del_método", "params": { "parámetro1": "valor1", "parámetro2": "valor2" }, "id": 1 }
Luego configuramos la solicitud HTTP. Usamos el método POST, apuntamos a la URL del servidor JSON-RPC, y establecemos las cabeceras críticas: Content-Type
con valor application/json
y Accept
también con application/json
. El mensaje JSON-RPC va en el cuerpo de la solicitud HTTP.
Mira este ejemplo práctico con JavaScript:
fetch('https://servidor-jsonrpc.com/api', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' }, body: JSON.stringify({ jsonrpc: '2.0', method: 'sumar', params: {a: 10, b: 5}, id: 1 }) }) .then(respuesta => respuesta.json()) .then(datos => console.log(datos));
El servidor responderá con un objeto JSON que incluye el resultado y el mismo ID que enviaste, permitiendo asociar respuestas con solicitudes específicas.
¿Por qué son tan importantes las cabeceras Content-Type y Accept? La cabecera Content-Type
indica al servidor qué tipo de datos está enviando el cliente. En MCP, basado en JSON-RPC, esta cabecera suele ser application/json
, lo que permite al servidor saber que debe interpretar el cuerpo de la solicitud como datos JSON. Cuando un cliente MCP como Cursor envía una solicitud al servidor MCP, necesita indicar que está enviando datos estructurados en formato JSON para que el servidor los procese correctamente.
La cabecera Accept
informa al servidor sobre qué tipos de datos puede procesar el cliente. Esto asegura que el servidor responda con un formato que el cliente pueda entender, normalmente también JSON en el caso de MCP. La correcta configuración de estas cabeceras garantiza comunicación sin errores entre cliente y servidor, interpretación adecuada de las solicitudes y respuestas, y compatibilidad entre diferentes implementaciones de MCP.
Veamos el flujo completo de una petición HTTP/1.1 en MCP. El cliente prepara un mensaje JSON-RPC que contiene un identificador único para la petición, el método que quiere invocar y los parámetros necesarios. Este mensaje se envía como el cuerpo de una petición HTTP POST al servidor MCP. El servidor procesa la solicitud y puede realizar acciones como consultar una base de datos, ejecutar una herramienta específica o interactuar con un modelo de lenguaje. Luego genera una respuesta JSON-RPC que incluye el mismo identificador de la petición original y los resultados obtenidos o un mensaje de error. Esta respuesta se devuelve en el cuerpo de la respuesta HTTP al cliente.
Si usamos Cursor como cliente MCP para pedir a Claude que busque información en una base de datos, el flujo sería: el usuario escribe su petición en Cursor, esta se convierte en un mensaje JSON-RPC, se envía por HTTP al servidor, Claude procesa la petición ejecutando la búsqueda, y finalmente devuelve los resultados empaquetados como JSON-RPC.
¿Y qué pasa cuando usamos HTTP/2? El proceso de respuesta en un servidor MCP usando HTTP/2 sigue un flujo estructurado basado en JSON-RPC. Cuando un servidor recibe una solicitud por HTTP/2, recibe los datos JSON enviados por el cliente MCP, analiza la solicitud JSON-RPC para identificar el método solicitado y los parámetros, evalúa el contexto necesario para procesar la solicitud, ejecuta la herramienta o acción solicitada según los parámetros recibidos, construye una respuesta en formato JSON-RPC 2.0 que contiene un identificador único que coincide con el de la solicitud, los resultados de la operación e información de estado o errores si los hubiera. Finalmente, envía esta respuesta al cliente a través del mismo canal HTTP/2.
La ventaja de usar HTTP/2 como transporte es que permite comunicación asíncrona, lo que resulta ideal para servicios web o cuando se necesitan integraciones remotas. Si un editor de código como Cursor solicita una refactorización de código, el servidor MCP recibe esta petición por HTTP/2, la procesa posiblemente consultando un LLM como Claude, y devuelve el código refactorizado empaquetado en formato JSON-RPC.
MCP es agnóstico al transporte, lo que significa que puede funcionar sobre diferentes protocolos de comunicación. Los transportes mencionados incluyen stdio para comunicación por entrada/salida estándar, útil en herramientas de línea de comandos, HTTP/1.1 y HTTP/2 para comunicación asincrónica en servicios web, y WebSockets propuesto para comunicación bidireccional persistente.
En general, HTTP/2 suele ser preferible a HTTP/1.1 en contextos donde se necesita mejor rendimiento en conexiones con alta latencia, se realizan múltiples solicitudes simultáneas gracias a la multiplexación, se transfiere gran cantidad de datos o se requiere priorización de recursos. Para MCP, HTTP/2 podría ser ventajoso cuando se implementan servicios de IA que manejan varias solicitudes concurrentes o cuando se necesita transferir grandes volúmenes de datos de contexto entre el cliente y el servidor.
La elección entre HTTP/1.1 y HTTP/2 para MCP dependerá de las necesidades específicas de cada implementación, considerando factores como el volumen de tráfico, la complejidad de las solicitudes y el entorno de despliegue.
Lo que hemos visto hoy es cómo MCP aprovecha HTTP como transporte confiable y familiar para conectar herramientas de desarrollo con modelos de lenguaje. Las cabeceras HTTP correctas son fundamentales para que la comunicación funcione sin problemas. HTTP/2 ofrece ventajas de rendimiento cuando trabajas con múltiples solicitudes concurrentes o grandes volúmenes de datos. Al final, la belleza de MCP radica en su flexibilidad: puedes elegir el transporte que mejor se adapte a tu caso de uso específico, sabiendo que el protocolo JSON-RPC subyacente mantendrá la comunicación estructurada y predecible.