Con una cuenta desbloqueas el cuestionario, el foro de dudas y el tutor con IA de esta lección, además del registro de progreso y el certificado verificable al terminar «IA Agéntica: Agentes que Operan Sistemas Reales».
Sin un protocolo común, conectar agentes con sistemas es un problema cuadrático. Cada cliente agéntico necesita su propia integración con cada sistema: su forma de declarar herramientas, su autenticación, su manejo de errores. Con N sistemas y M clientes hacen falta N×M integraciones, y cada cambio en cualquier extremo obliga a tocar N o M piezas.
MCP (Model Context Protocol, protocolo de contexto de modelo) ataca exactamente eso: define un contrato único entre clientes y servidores, de modo que cada sistema implementa un servidor y cada cliente implementa un cliente. El problema pasa de N×M a N+M.
Ejemplo resuelto: el clúster CODE
Nuestro ecosistema tiene N=6 aplicaciones que exponen capacidades (dos gemelos digitales, la estación terrena, el hub, la suite de laboratorio y la plataforma de academia) y M=4 clientes que las consumen (dos copilotos, una consola de operaciones y un cliente de escritorio). Sin protocolo común:
Iadhoc=N×M=6×4=24 integraciones
Con MCP, cada aplicación escribe su servidor y cada cliente su cliente:
IMCP=N+M=6+4=10 implementaciones
La reducción es (24−10)/24≈0.583, un 58.3 % menos de superficie que mantener. Y crece a favor del protocolo: si mañana añadimos un quinto cliente, el modelo ad hoc suma 6 integraciones nuevas y el modelo MCP suma 1. Nuestros servidores MCP están escritos en biblioteca estándar pura, sin dependencias externas, precisamente porque su valor está en ser aburridos y estables: son plomería, no producto.
Arquitectura cliente-servidor
MCP separa tres roles que conviene no mezclar:
El host es la aplicación donde vive el agente (un IDE, una consola, un copiloto web).
El cliente MCP vive dentro del host y mantiene una conexión con un servidor.
El servidor MCP expone capacidades de un sistema: tools (funciones invocables), resources (datos legibles) y prompts (plantillas). En este curso nos centramos en tools.
El servidor traduce: recibe una llamada estructurada y la convierte en lo que el sistema real entienda — típicamente una petición a la API REST del sistema. Esa capa de traducción es también el lugar natural para aplicar validación y permisos, y por eso conviene que sea delgada y auditable.
JSON-RPC 2.0 sobre stdio
El transporte más común es asombrosamente simple: el host lanza el servidor como un subproceso y hablan por sus flujos estándar. Cada mensaje es un objeto JSON en una sola línea, terminado en salto de línea, siguiendo JSON-RPC 2.0. Peticiones y respuestas se emparejan por el campo id; los mensajes sin id son notificaciones y no esperan respuesta.
Que sea texto plano por stdio tiene dos virtudes operativas: se depura con tee y un editor, y el servidor hereda el aislamiento del proceso hijo (sin puerto abierto, sin superficie de red). El transporte HTTP existe para servidores remotos, con las implicaciones de autenticación que eso arrastra.
El handshake, transcrito
El orden importa y no es negociable: initialize → tools/list → tools/call. Una sesión real, recortada, se ve así (peticiones →, respuestas ←):
→ {"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"copiloto-orbiteye","version":"1.2.0"}}}
← {"jsonrpc":"2.0","id":1,"result":{"protocolVersion":"2025-06-18","capabilities":{"tools":{}},"serverInfo":{"name":"satdt-mcp","version":"0.9.0"}}}
→ {"jsonrpc":"2.0","method":"notifications/initialized"}
→ {"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}
← {"jsonrpc":"2.0","id":2,"result":{"tools":[
{"name":"satelite_info","description":"Datos de catálogo de un satélite. Úsala cuando necesites nombre, régimen orbital o estado operativo.","inputSchema":{"type":"object","properties":{"norad_id":{"type":"integer"}},"required":["norad_id"]}},
{"name":"proximos_pases","description":"Ventanas de visibilidad futuras desde una estación.","inputSchema":{"type":"object","properties":{"norad_id":{"type":"integer"},"estacion":{"type":"string"},"horas":{"type":"integer","minimum":1,"maximum":72}},"required":["norad_id","estacion"]}}
]}}
→ {"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"proximos_pases","arguments":{"norad_id":25544,"estacion":"orbiteye-mx","horas":24}}}
← {"jsonrpc":"2.0","id":3,"result":{"content":[{"type":"text","text":"3 pases: 03:14Z (elev 47°), 04:50Z (elev 12°), 22:07Z (elev 61°)"}],"isError":false}}
Tres detalles que se pagan caros si se ignoran:
tools/list devuelve el catálogo, no resultados: nombres, descripciones y inputSchema de cada herramienta. Es exactamente la ficha de la lección 2, y es lo que el host inyecta al contexto del modelo. Todo lo que aprendiste sobre descripciones y granularidad se aplica aquí sin cambios.
Los errores tienen dos capas. Un error de protocolo — argumentos que violan el inputSchema — es un error JSON-RPC con código -32602 (Invalid params) y no llega al modelo como resultado. Un error de dominio — "la estación está en mantenimiento" — viaja como result con isError: true, porque el modelo debe verlo para corregirse.
El orden se hace cumplir. Un tools/call antes de initialize debe fallar: sin negociar versión y capacidades no hay sesión. Lo comprobarás de primera mano en el laboratorio.
Versionado y federación
La versión del protocolo se negocia en initialize con una cadena de fecha (por ejemplo 2025-06-18). Si cliente y servidor no coinciden, se acuerda una versión común o la sesión no se establece — falla explícitamente en vez de degradar en silencio, que es la propiedad correcta para plomería que opera hardware.
La federación es la consecuencia arquitectónica más útil: un mismo host puede mantener varios clientes conectados a varios servidores a la vez, y el agente ve un catálogo unificado. En nuestro clúster eso significa que un copiloto puede, en un mismo episodio, consultar el gemelo del satélite, preguntar por la salud de la estación terrena y publicar un evento en el hub — tres servidores, tres procesos aislados, un solo lazo agéntico. El aislamiento es la ventaja de seguridad: cada servidor tiene sus propias credenciales y su propio alcance, así que comprometer uno no da acceso a los demás. Es el mismo argumento de mínimo privilegio que formalizaremos en la lección 7.
Comprueba el punto que más errores causa al implementar un servidor:
El cliente envía tools/call con horas: 200, pero el inputSchema declara maximum: 72. ¿Qué debe responder el servidor?
El laboratorio de esta lección es una consola MCP simulada: emitirás initialize, tools/list y tools/call contra un servidor con cuatro herramientas satelitales, verás la transcripción JSON-RPC cruda con formato legible y podrás provocar deliberadamente los dos errores que acabamos de distinguir — llamar antes del handshake, y violar el esquema de argumentos.
Laboratorio: Inspector MCP · Handshake y tools/call en JSON-RPC