Transport Layers en MCP: stdio, SSE y WebSocket — El Framework de Selección que el 80% Ignora

Transport Layers en MCP: stdio, SSE y WebSocket — El Framework de Selección que el 80% Ignora

Programming· 6 min read

El 80% de los Agentes MCP Usan el Transporte Equivocado

El 80% de los agentes MCP que he visto en producción usan stdio. No porque sea la mejor opción para su caso de uso. Sino porque viene por defecto.

Esto no es un problema técnico. Es un problema de diseño arquitectónico.

Elegir stdio sin auditar qué tipo de interacciones necesita tu agente significa renunciar a tres capacidades que diferencian un demo de un sistema productivo: streaming de resultados parciales, notificaciones del servidor, y estado compartido entre invocaciones.

El transporte que eliges no determina la simplicidad de tu implementación. Determina qué tipo de agente puedes construir.

En esta guía voy a mostraros cómo auditar vuestras herramientas MCP por patrón de interacción, qué transporte corresponde a cada patrón, y cómo migrar entre transportes sin reescribir todo el sistema.

El Fallo Oculto: Transport y Tool Schema No Son Independientes

La documentación actual de MCP trata el transporte como una decisión ortogonal al diseño de herramientas. Elige stdio, SSE, o WebSocket, y luego diseña tus schemas independientemente.

Esto es un error.

Un schema diseñado para stdio asume llamadas síncronas. El modelo invoca la herramienta, espera la respuesta, continúa. No necesita modelar estado entre invocaciones porque no hay estado que modelar.

Cuando migras ese mismo schema a SSE, el servidor puede empezar a devolver resultados parciales. La herramienta que antes era "buscar_usuario" y devolvía un objeto completo ahora puede devolver streaming de logs, actualizaciones progresivas, o notificaciones de progreso. Pero el schema no tiene dónde expresar eso.

Y cuando migras a WebSocket, la bidireccionalidad introduce conceptos que stdio no necesita: sessions, subscriptions, cancelaciones, notificaciones push. Tu schema carece de parámetros para modelarlos.

Diseño incorrecto: Elegir transporte → luego diseñar schemas

Diseño correcto: Auditar interacciones → elegir transporte → diseñar schemas para ese transporte desde el inicio

La decisión de transporte condiciona el diseño del schema desde el día uno. Postergar esta decisión no la hace más fácil. La hace más costosa.

La Auditoría de Herramientas: Tu Primer Paso Obligatorio

Antes de elegir transporte, necesitas saber qué patrones de interacción tienen tus herramientas. Esta auditoría tiene tres categorías.

Herramientas de Consulta (GET-like)

Devuelven datos. No modifican estado. Respuesta completa en una llamada. Ejemplos: buscar usuario, consultar precio, obtener configuración.

Estas herramientas no necesitan estado entre invocaciones. El modelo pregunta, la herramienta responde, fin.

Herramientas de Efecto (POST-like)

Modifican estado en el servidor. Una llamada, un efecto, una respuesta. Ejemplos: crear usuario, actualizar precio, enviar notificación.

Estas herramientas pueden funcionar en un modelo request-response simple, pero el servidor podría querer notificar cambios downstream que el agente necesita conocer.

Herramientas de Streaming (Observables)

Devuelven datos que llegan progresivamente. Logs, análisis, procesos largos. Ejemplos: streaming de logs, procesamiento de dataset, búsqueda con resultados parciales.

Estas herramientas rompen el modelo síncrono. Si el agente espera la respuesta completa, se bloquea. Necesitan un transporte que soporte streaming.

El Framework de Selección de Transporte

Después de auditar vuestras herramientas, aplicad este framework de tres capas para elegir el transporte correcto.

Capa 1: stdio para Consultas Síncronas Locales

Si todas vuestras herramientas son de consulta pura sin estado compartido, stdio es suficiente. No añadáis complejidad de red cuando no la necesitáis.

[@portabletext/react] Unknown block type "code", specify a component for it in the `components.types` prop

Este patrón funciona cuando servidor y cliente están en la misma máquina o contenedor. Sin overhead de red, sin autenticación de red, sin puertos abiertos.

Capa 2: SSE para Streaming y Resultados Parciales

Cuando tengáis herramientas que devuelven streams largos,迁移 a SSE. El modelo puede procesar resultados parciales sin bloquearse.

[@portabletext/react] Unknown block type "code", specify a component for it in the `components.types` prop

El servidor envía eventos Server-Sent Events que el cliente recibe progresivamente. El modelo no espera a que termine el procesamiento completo para empezar a trabajar con los resultados parciales.

Capa 3: WebSocket para Estado Compartido y Bidireccionalidad

Cuando necesitéis que el servidor notifique al agente sin que el agente lo haya solicitado, WebSocket es la opción. Sesiones de usuario, carritos de compra, workflows donde múltiples herramientas comparten estado.

[@portabletext/react] Unknown block type "code", specify a component for it in the `components.types` prop

El Selector Automático de Transporte

Para sistemas con herramientas de múltiples tipos, este wrapper selecciona el transporte según el patrón de interacción:

[@portabletext/react] Unknown block type "code", specify a component for it in the `components.types` prop

El Punto Ciego: Negociación de Capacidades

Hay un problema en la especificación actual de MCP que la mayoría ignora: no existe un estándar para que cliente y servidor negocien qué transportes soporta cada uno.

Implementar un cliente que soporte múltiples transportes requiere lógica ad-hoc:

[@portabletext/react] Unknown block type "code", specify a component for it in the `components.types` prop

Esto no está estandarizado. No hay header X-MCP-Transport-Capabilities en el handshake inicial. No hay negociación formal de capacidades.

Los primeros en proponer convenciones para esta negociación ganarán ventaja. Es un gap real en el ecosistema MCP que necesita una solución comunitaria.

Migración Gradual: No Todo a la Vez

La迁移 a nuevos transportes no tiene que ser un big bang. Seguid esta progresión:

Paso 1: Auditoría completa

Clasificad cada herramienta existente en query, streaming, o shared-state.

Paso 2: Grupo A — stdio para todo

Confirmad que las herramientas de consulta funcionan correctamente en stdio. Este es vuestro baseline.

Paso 3: Grupo B — Migrad streaming a SSE

Identificad las herramientas que más se benefician del streaming. Procesamiento de datos largos, logs, análisis progresivos. Migrad una a SSE, medid latencia percibida, comparar con stdio.

Paso 4: Grupo C — WebSocket solo cuando sea necesario

Solo cuando necesitéis notificaciones push del servidor o sesiones compartidas entre herramientas. No antes.

No migréis todo a WebSocket porque "es más moderno" o "escala mejor". Usadlo cuando el caso de uso lo requiera naturalmente.

Comparativa: Cuándo Usar Cada Transporte

| Aspecto | stdio | SSE | WebSocket |

|---------|-------|-----|-----------|

| Latencia | Mínima (local) | Media (red) | Baja (persistente) |

| Streaming | ❌ No | ✅ Sí | ✅ Sí |

| Bidireccionalidad | ❌ No | ❌ No | ✅ Sí |

| Complejidad | Baja | Media | Alta |

| Estado entre llamadas | ❌ No | ⚠️ Limitado | ✅ Sí |

| Notificaciones push | ❌ No | ❌ No | ✅ Sí |

Conclusión: Decisión Explícita, No Por Defecto

La próxima vez que configuréis un cliente MCP, no uséis stdio porque viene por defecto. Haced la auditoría. Clasificad vuestras herramientas. Elegid el transporte que corresponde a cada patrón.

stdio no es "más simple y por tanto mejor". Es suficiente para consultas síncronas locales. Cuando necesitéis streaming, elegid SSE. Cuando necesitéis bidireccionalidad y estado compartido, elegid WebSocket.

El transporte no es una decisión técnica neutral. Determina qué tipo de agente puedes construir.

Haced la auditoría. Tomad la decisión conscientemente.

Artículos relacionados

---

¿Quieres recibir contenido como este cada semana? Suscríbete a mi newsletter

Brian Mena

Brian Mena

Software engineer building profitable digital products: SaaS, directories and AI agents. All from scratch, all in production.

LinkedIn