Arquitectura de un servidor MCP explicada con diagramas: del host a la llamada a una herramienta
Un servidor MCP se sitúa entre una aplicación de IA y los sistemas a los que necesita acceder. Este artículo recorre todo el camino con diagramas: host, cliente, servidor, transporte, handshake JSON-RPC, llamada a una herramienta, gestión de errores y seguridad, con un conector real de imagen y video como ejemplo práctico.
Tu asistente de IA puede redactar un contrato en segundos, pero no puede leer tu calendario, consultar tu base de datos ni redimensionar una foto por sí solo. El Model Context Protocol, abreviado MCP, cierra esa brecha con un contrato compartido entre las aplicaciones de IA y los sistemas que las rodean. Un servidor MCP es el pequeño programa al otro lado de ese contrato: anuncia lo que puede hacer, espera peticiones y devuelve resultados con una forma predecible. Este artículo desglosa esa arquitectura pieza a pieza. Cada diagrama es texto plano, así que se puede copiar y pegar en un README, un documento de diseño o una pull request sin problemas.
Por qué existe MCP
Antes de MCP, cada aplicación de IA que quería acceder a una base de datos, un calendario o un sistema de archivos necesitaba su propio conector a medida. Cada conector tenía su propia autenticación, su propio formato de errores y sus propios bugs. Tres apps y tres herramientas ya significaban nueve integraciones, y la cuadrícula crece con cada producto nuevo de cualquiera de los dos lados. MCP sustituye esa cuadrícula por un protocolo compartido, así que la cuenta pasa de apps por herramientas a apps más herramientas.
Before MCP: one custom connector for every pair
App A ──► Database App B ──► Database App C ──► Database
App A ──► Calendar App B ──► Calendar App C ──► Calendar
App A ──► Files App B ──► Files App C ──► Files
3 apps x 3 tools = 9 connectors to build and maintain
With MCP: one shared protocol in the middle
App A ──┐ ┌── Database server
App B ──┼──── MCP (JSON-RPC) ─────┼── Calendar server
App C ──┘ └── Files server
3 clients + 3 servers = 6 pieces
La palabra servidor induce a error. Un servidor MCP no es un modelo de lenguaje y no piensa. Es un programa común, escrito en TypeScript, Python o en cualquier lenguaje con una librería JSON, que envuelve una capacidad real y la describe en un formato que cualquier cliente compatible puede leer. El modelo nunca necesita saber cómo funciona el driver de tu base de datos. Solo necesita saber que existe una herramienta llamada run_query y qué argumentos acepta.
Los tres roles en un solo diagrama
MCP define tres roles, y confundirlos es la causa de la mayor parte de los malentendidos. Aquí tienes el panorama completo antes de entrar en detalles.
┌──────────── HOST (the AI application) ────────────┐
│ The LLM picks a tool, the host routes the call │
│ │
│ ┌────────────┐ ┌────────────┐ ┌────────────┐ │
│ │ client 1 │ │ client 2 │ │ client 3 │ │
│ └─────┬──────┘ └─────┬──────┘ └─────┬──────┘ │
└────────┬───────────────┬───────────────┬──────────┘
│ session │ session │ session
┌─────┴──────┐ ┌─────┴──────┐ ┌─────┴──────┐
│ Server A │ │ Server B │ │ Server C │
│ files │ │ GitHub │ │ image tool │
└────────────┘ └────────────┘ └────────────┘
El host controla la conversación
El host es la aplicación que una persona usa de verdad: una app de chat de escritorio, un asistente de IDE o un agente a medida. Ejecuta el modelo de lenguaje, decide a qué servidores conectarse y le muestra al usuario lo que está a punto de pasar. Modelos de razonamiento como Claude Sonnet 5, GPT 5.6 Sol y Gemini 3.1 Pro funcionan dentro del host, pero nunca hablan MCP directamente. El host traduce entre el formato de llamadas a herramientas del modelo y el protocolo, por eso un mismo servidor funciona con muchos modelos distintos.
El cliente mantiene una sesión
Dentro del host se crea un cliente MCP por cada servidor. Cada cliente mantiene una sesión con estado, uno a uno, con exactamente un servidor, recuerda las capacidades que ambas partes acordaron y enruta cada mensaje. Un host conectado a tres servidores ejecuta tres clientes, como muestra el diagrama. Si una sesión se cae, las otras dos siguen funcionando.
El servidor hace el trabajo
El servidor MCP envuelve un sistema real: una base de datos Postgres, una cuenta de GitHub, una carpeta de documentos o una API de imágenes. Se mantiene deliberadamente pequeño. Declara lo que ofrece, valida la entrada, ejecuta la acción y devuelve una salida estructurada. Nunca ve la conversación completa, solo las peticiones que se le envían, una decisión de diseño que protege la privacidad y mantiene los servidores reutilizables.
Un resumen rápido que puedes dejar pegado encima de tu escritorio:
Host: es el responsable del modelo, de la interfaz de usuario y de las solicitudes de consentimiento.
Cliente: uno por servidor, habla el protocolo y mantiene el estado de la sesión.
Servidor: expone capacidades, ejecuta la acción y devuelve resultados.
Qué expone un servidor
Un servidor ofrece tres bloques de construcción, llamados primitivas. Se diferencian en un detalle que marca todo el diseño: quién decide cuándo se usa cada una.
Primitiva
Controlada por
Uso típico
Métodos de ejemplo
Herramientas
El modelo
Ejecutar una acción o calcular un resultado
tools/list, tools/call
Recursos
La aplicación
Aportar contexto de solo lectura, como archivos o registros
resources/list, resources/read
Prompts
El usuario
Plantillas reutilizables, a menudo mostradas como comandos de barra
prompts/list, prompts/get
Las herramientas ejecutan acciones
Una herramienta tiene un nombre, una descripción en lenguaje natural y un inputSchema escrito en JSON Schema. El modelo lee la descripción para decidir si la herramienta encaja con la petición, y el esquema mantiene válidos los argumentos. Las descripciones merecen un esfuerzo real, porque una descripción vaga obliga al modelo a adivinar. Nombra las herramientas como verbos, mantén cada una estrecha y devuelve solo los campos que el modelo necesita. Una herramienta llamada search_orders con tres argumentos tipados es mejor que una única herramienta do_anything con un campo de texto libre. Los resultados de las herramientas no se limitan al texto: pueden incluir imágenes, audio o enlaces, y por eso los generadores de medios encajan tan bien en el protocolo. Una herramienta de imagen podría envolver Flux 2 Pro o Seedream 4.5, y una herramienta de video podría envolver Veo 3.1 o Kling v3 Video.
Los recursos aportan contexto
Los recursos son datos de solo lectura direccionados por URI, como file:///reports/q3.md o postgres://db/customers/schema. El host elige cuáles adjuntar al contexto del modelo, así que los recursos encajan con documentos, esquemas y registros. Después de que un cliente se suscribe, el servidor puede anunciar cambios con notifications/resources/updated.
Los prompts ofrecen plantillas
Los prompts son plantillas de mensajes parametrizadas que el usuario elige a propósito, normalmente desde un menú de comandos de barra. Un prompt como revisa esta pull request devuelve una lista de mensajes ya preparada, así que cada compañero del equipo parte de la misma redacción y de la misma lista de verificación.
El tráfico también fluye en sentido contrario. Los servidores pueden pedirle ayuda al cliente mediante sampling (solicitar una respuesta al modelo del host), roots (preguntar qué directorios están dentro del alcance) y elicitation (pedir al usuario datos que faltan). Los hosts deciden si permiten cada una.
💡 Regla general: si la acción cambia algo en el mundo, crea una herramienta. Si solo aporta información, empieza con un recurso.
Transportes: stdio o Streamable HTTP
El transporte decide cómo viajan los bytes entre cliente y servidor. Los mensajes son idénticos en cualquier caso: peticiones, respuestas y notificaciones JSON-RPC 2.0. Hay dos transportes estándar.
stdio para servidores locales
stdio: the host starts the server as a child process
┌────────┐ stdin: requests ┌───────────┐
│ Client │ ─────────────────────► │ Server │
│ │ ◄───────────────────── │ process │
└────────┘ stdout: responses └───────────┘
stderr: logs only
Con stdio, el host lanza el servidor como proceso hijo e intercambia mensajes JSON-RPC delimitados por saltos de línea a través de la entrada y salida estándar. La configuración es una sola línea de comandos, la latencia es mínima y las credenciales llegan por variables de entorno. Hay una regla que hace tropezar a muchos autores primerizos: el servidor nunca debe imprimir nada que no sea un mensaje de protocolo en stdout. Los registros van a stderr, o el flujo se corrompe y la sesión muere.
Streamable HTTP para servidores remotos
Streamable HTTP: one URL, many clients
┌──────────┐ POST /mcp ┌────────────┐
│ Client A │ ───────────────────► │ │
└──────────┘ ◄─────────────────── │ Server │
┌──────────┐ JSON or SSE reply │ (web app) │
│ Client B │ ───────────────────► │ │
└──────────┘ ◄─────────────────── └────────────┘
Streamable HTTP sirve a muchos clientes desde un único endpoint. El cliente envía cada mensaje como un POST de HTTP, y el servidor responde con JSON simple o abre un stream de Server-Sent Events cuando necesita enviar varios mensajes. Un identificador de sesión viaja en la cabecera Mcp-Session-Id. Este transporte sustituyó al antiguo diseño HTTP más SSE en la revisión 2025-03-26 de la especificación, y es la opción adecuada para servidores alojados, productos multiusuario y cualquier cosa detrás de un balanceador de carga. La autorización se basa en OAuth, así que un servidor puede responder 401 y apuntar al cliente hacia su servidor de autorización. Los servidores que todavía usan el diseño anterior pueden mantener la compatibilidad sirviendo ambos endpoints durante una migración, pero un proyecto nuevo debería empezar con Streamable HTTP.
Pregunta
stdio
Streamable HTTP
¿Dónde se ejecuta el servidor?
En la misma máquina que el host
En cualquier lugar accesible por URL
Usuarios por servidor
Uno
Muchos
Credenciales
Variables de entorno
OAuth o cabeceras HTTP
Mejor para
Herramientas de desarrollo, archivos locales
Productos alojados, servicios compartidos
Principal trampa
Salida no deseada por stdout
Gestión de sesiones detrás de proxies
Una división práctica: publica una versión stdio para los desarrolladores que quieran probar el servidor en un minuto, y una versión Streamable HTTP para el resto. El código de las herramientas es el mismo. Solo cambia el punto de entrada.
Una llamada a una herramienta, paso a paso
Esta es una única petición desde el momento en que el usuario escribe hasta que aparece la respuesta.
User Host + LLM MCP client MCP server
│ │ │ │
├─ asks for image ───► │ │
│ │ picks a tool │ │
│ ├─ tool request ────► │
│ │ ├─ tools/call ──────►
│ │ │ │ does the work
│ │ ◄─ text, isError ───┤
│ ◄─ result ──────────┤ │
◄─ answer + URL ─────┤ │ │
│ │ │ │
Paso 1: el handshake
Cada sesión empieza con initialize. El cliente envía la versión del protocolo que soporta junto con sus propias capacidades. El servidor responde con la versión que eligió y las capacidades que ofrece. Después, el cliente envía un mensaje notifications/initialized y empieza el tráfico normal. Si las versiones no se pueden conciliar, el cliente se desconecta en lugar de adivinar.
El cliente envía tools/list, el host pasa los esquemas al modelo y el modelo decide si llama a alguno. Cuando la lista de herramientas de un servidor cambia en tiempo de ejecución, envía notifications/tools/list_changed para que el cliente la actualice. Una llamada tiene este aspecto:
MCP separa dos tipos de fallo. Un error de protocolo es un objeto de error JSON-RPC, por ejemplo el código -32602 para parámetros no válidos o un nombre de herramienta desconocido. Un error de ejecución de la herramienta es un resultado normal con isError: true y un mensaje que el modelo puede leer. El segundo tipo es el más importante. Cuando una herramienta responde prompt demasiado largo, el modelo puede acortar el prompt y reintentar, pero solo si el error le llega como texto y no como una sesión caída. Cualquiera de los dos lados también puede enviar notifications/cancelled para abandonar una petición lenta.
Ejecuta el servidor con el MCP Inspector (npx @modelcontextprotocol/inspector) antes de que ningún modelo lo toque. El Inspector lista las herramientas, te deja lanzar llamadas a mano y muestra el tráfico JSON-RPC sin procesar, así puedes separar los bugs de protocolo de los bugs de prompt.
3 errores de diseño comunes
La mayoría de los problemas en producción se deben a las mismas tres decisiones:
Una herramienta gigante. Una herramienta llamada do_anything con un argumento de texto libre obliga al modelo a adivinar. Divídela en verbos estrechos como search_orders y refund_order, cada uno con argumentos tipados.
Resultados demasiado extensos. Devolver un bloque de 40.000 tokens consume la ventana de contexto del modelo. Devuelve los campos que necesita y enlaza a un recurso para el resto.
Estado oculto. Si una herramienta solo funciona después de que se haya ejecutado otra, indícalo en su descripción, o el modelo las llamará en el orden equivocado.
Un servidor real: herramientas de imagen y video
Un caso concreto muestra por qué importan las decisiones de arquitectura. PicassoIA ofrece un conector MCP cuyas herramientas generan y editan imágenes y videos en sus propias GPU. Los trabajos de imagen y video tardan de segundos a minutos, lo que rompe la imagen ingenua de llama a una herramienta y espera la respuesta. Los hosts y los SDK suelen imponer un tiempo límite por petición, así que un servidor que bloquea hasta que termina el render fallaría justo cuando el trabajo está casi listo.
Trabajos asíncronos detrás de una herramienta sencilla
El conector expone herramientas llamadas generate_image, edit_image, generate_video_picassoia, generate_video_seedance, get_generation, cancel_generation, list_models, list_generations y get_account. Una llamada de generación devuelve de inmediato un ID de predicción y un tiempo estimado. Después, el modelo llama a get_generation tras la espera sugerida, y de nuevo después de cada nueva pista, hasta que el estado indique succeeded o failed. La llamada a la herramienta se mantiene corta mientras el trabajo pesado se ejecuta como un proceso en segundo plano en un worker de GPU.
Un servidor que se sitúa delante de una cola de GPU tiene que protegerla. PicassoIA establece un máximo de cinco predicciones simultáneas por cuenta, compartidas entre las credenciales de API y las conexiones MCP. Un servidor bien construido convierte un límite así en un resultado de herramienta claro, como cinco trabajos en ejecución, reintenta en 30 segundos, en lugar de dejar que las peticiones se acumulen detrás. El modelo puede leer ese mensaje y esperar, lo que es mucho mejor que un timeout.
Cuatro hábitos hacen que un servidor asíncrono sea cómodo de usar desde un agente:
Responde rápido. Devuelve un ID en menos de un segundo y nunca bloquees durante minutos.
Indica la espera. Dile al modelo cuándo consultar de nuevo para que no sature la herramienta de estado.
Haz que el fallo sea definitivo. Un trabajo fallido se queda fallido, y el mensaje explica por qué.
Ofrece una herramienta de cancelación. Los usuarios cambian de opinión, y el trabajo en cola cuesta dinero.
Dónde encaja la seguridad
MCP traslada capacidad, así que también traslada riesgo. El protocolo define la forma de la conversación, pero el host y el servidor cargan con la responsabilidad. Seis comprobaciones detectan la mayoría de los problemas antes del lanzamiento:
Consentimiento del usuario. El host debería mostrar qué herramienta está a punto de ejecutarse y preguntar antes de cualquier acción con efectos secundarios.
Mínimo privilegio. Da a una herramienta de solo lectura una credencial de solo lectura y mantén las acciones potentes en un servidor aparte.
Validación de entradas. Trata cada argumento como no confiable. Valida también contra el esquema en el servidor, no solo en el cliente.
Inyección de prompts. El texto dentro del resultado de una herramienta o de un recurso puede contener instrucciones. El host debería tratarlo como datos, nunca como una orden del usuario.
Gestión de secretos. Nunca pongas credenciales en las descripciones ni en los resultados de las herramientas. Los servidores stdio las leen del entorno y los servidores HTTP usan OAuth.
Registros de auditoría. Escribe registros estructurados con un ID de solicitud en stderr o en un servicio de registros, para poder rastrear después cada llamada a una herramienta.
El despliegue sigue la misma lógica. Fija la versión del protocolo en tus pruebas, ejecuta el servidor con el Inspector en CI y pon los servidores remotos detrás de una pasarela que gestione TLS, límites de tasa y OAuth, para que el código de las herramientas se concentre en las herramientas.
Prueba tú mismo la generación de imágenes y video
Los diagramas se recuerdan mejor cuando puedes ver cómo una llamada a una herramienta produce algo real. Abre PicassoIA, escribe un prompt para una foto de tu propio escritorio, una sala de servidores o un boceto en una pizarra, y genéralo con Seedream 4.5 o GPT Image 2. Luego anima tu fotograma favorito con Veo 3.1 o Kling v3 Video. Si tu host admite conexiones MCP, añade el conector de PicassoIA y deja que tu asistente ejecute el trabajo mientras sigues los pasos de sondeo del diagrama de arriba.
Prueba tres prompts y cambia una sola cosa en cada uno: el ángulo de cámara, la dirección de la luz o la lente. Las diferencias muestran lo importante que es un prompt preciso, igual que importa una descripción de herramienta precisa para un modelo. Explora todos los modelos disponibles en picassoia.com/en/all-models y empieza tu primera generación hoy mismo.