Qué cambia cuando tu servidor sale de tu laptop
Un servidor MCP de prototipo vive en condiciones ideales. Lo lanza tu propio Claude Desktop como subproceso, lo usa una sola persona (tú), los datos son de prueba y si algo falla lo reinicias. Nada de eso es cierto en producción. En esta lección conoces el caso que vamos a trabajar todo el curso, haces la lista de lo que cambia y revisas qué trae la versión actual de la especificación de MCP, porque cambió justo en los puntos que más importan para producción.
Al terminar podrás:
- describir las diferencias entre un servidor MCP local y uno de producción en seis dimensiones concretas;
- explicar los cambios principales de la revisión 2026-07-28 de MCP y por qué te conviene diseñar ya con ellos;
- ubicar cada tema del curso en el camino del prototipo al servicio;
- montar el servidor base del caso con
MCPServerdel SDK de Python 2.
El caso: Logística Cerro de la Silla
Logística Cerro de la Silla (LCS, para los cuates) es una paquetería regional con almacén en Apodaca, Nuevo León. Reparte en Monterrey, San Pedro Garza García, Apodaca y Saltillo. Tiene unos 60 operadores, un centro de atención a clientes con ocho personas y tres coordinadores de ruta.
Mariana Treviño es la líder de plataforma. Hace unas semanas armó un servidor MCP en su laptop para consultar envíos desde Claude: le das un número de guía y te dice destino, estado y fecha de entrega. Lo presentó en la junta del lunes y salió muy bien. Tan bien que el gerente de operaciones pidió lo obvio: "quiero que lo use todo el centro de atención y que los coordinadores puedan reprogramar entregas desde ahí".
Esa frase convierte un prototipo en un proyecto de producción. Este es el servidor que tiene Mariana hoy:
"""Prototipo del servidor MCP de Logística Cerro de la Silla."""
import logging
from typing import Annotated
from pydantic import Field
from mcp.server import MCPServer
from mcp.server.mcpserver.exceptions import ToolError
from mcp.types import ToolAnnotations
log = logging.getLogger("lcs")
mcp = MCPServer(
"lcs-operaciones",
version="0.1.0",
instructions="Rastreo de envíos de Logística Cerro de la Silla. Fechas en formato AAAA-MM-DD.",
)
Guia = Annotated[str, Field(pattern=r"^LCS-\d{8}$", description="Número de guía, por ejemplo LCS-10000001")]
ENVIOS: dict[str, dict] = {
"LCS-10000001": {"destino": "Saltillo, Coah.", "estado": "en_ruta", "entrega": "2026-10-14"},
"LCS-10000002": {"destino": "San Pedro Garza García, N. L.", "estado": "en_almacen", "entrega": "2026-10-13"},
}
@mcp.tool(annotations=ToolAnnotations(read_only_hint=True))
def rastrear_envio(guia: Guia) -> dict:
"""Devuelve destino, estado y fecha de entrega de un envío a partir de su guía."""
envio = ENVIOS.get(guia)
if envio is None:
raise ToolError(f"No existe la guía {guia}. Revisa que tenga el formato LCS- y ocho dígitos.")
log.info("Consulta de guía %s", guia)
return {"guia": guia, **envio}
if __name__ == "__main__":
mcp.run() # stdio por defecto
Nada de esto es nuevo para ti si hiciste nuestro curso Agentes de IA y MCP: MCPServer, el decorador @mcp.tool(), tipos con Annotated y Field, ToolError para errores que el modelo debe leer y logging en lugar de print. Fíjate en un detalle que ya es de producción: la guía se valida con un patrón (^LCS-\d{8}$). Si el modelo manda "la del cliente de Saltillo", el SDK rechaza la llamada antes de ejecutar tu función.
Seis cosas que cambian en producción
Mariana hizo una lista en el pizarrón. Es buena idea que hagas la tuya con tu propio servidor, pero estas seis dimensiones casi siempre aparecen.
1. Dónde corre y cómo llega el tráfico
En el prototipo, el host (Claude Desktop, Claude Code) lanza tu archivo como subproceso y le habla por stdin y stdout. En producción, el servidor corre en otra máquina, normalmente en un contenedor, y los clientes se conectan por red con el transporte Streamable HTTP. Eso trae un endpoint público, TLS, un proxy enfrente y una lista de hosts permitidos. Lo ves en la lección 1.2 y en la 4.1.
2. Quién puede usarlo
Por stdio, la frontera de seguridad es la máquina: si puedes lanzar el proceso, puedes usarlo. Por HTTP, cualquiera que llegue a la URL puede intentarlo. La especificación define cómo proteger un servidor MCP con OAuth 2.1: tu servidor actúa como servidor de recursos y verifica un token en cada solicitud. Para stdio, en cambio, la especificación indica que no se use ese flujo y que las credenciales vengan del entorno. Es la lección 2.1.
3. Qué puede hacer cada quien
El centro de atención solo debe consultar. Los coordinadores también reprogramar. Nadie debe poder leer archivos fuera de la carpeta de manifiestos. Esto se resuelve con alcances (scopes) por herramienta, validación estricta de entradas y credenciales de mínimo privilegio hacia tus sistemas internos (lecciones 2.1, 2.2 y 3.3).
4. Qué pasa con el estado
El prototipo guarda los envíos en un diccionario. En cuanto corres dos réplicas detrás de un balanceador, cada una tiene su propio diccionario y los cambios de una no se ven en la otra. La revisión actual de MCP además eliminó las sesiones del protocolo, así que no puedes apoyarte en "la conexión" para guardar nada. Lo resolvemos en las lecciones 1.2 y 4.1.
5. Cómo se comporta con tareas largas y acciones delicadas
Generar el reporte de cierre de una ruta tarda. Reprogramar una entrega cambia datos de un cliente real. En producción necesitas avisar del progreso, permitir que el usuario cancele y pedir confirmación antes de modificar. Para eso existen las notificaciones de progreso y la elicitation (lecciones 3.1 y 3.2).
6. Cómo sabes qué está pasando
En tu laptop ves los errores en la terminal. En producción necesitas registros, trazas, pruebas automáticas que corran antes de cada despliegue y una política de versiones para no romperle nada a los clientes. Es la lección 4.2.
La revisión 2026-07-28: el protocolo cambió
La especificación de MCP tiene versiones con fecha. La vigente al escribir este curso es la 2026-07-28, y su registro de cambios trae modificaciones de fondo. Estas son las que afectan directamente tu servidor de producción:
- Sin sesiones ni saludo inicial. Desaparecen el intercambio
initializey el encabezadoMcp-Session-Id. Cada solicitud lleva en su_metala versión del protocolo y las capacidades del cliente. Un servidor que necesita estado entre llamadas emite identificadores explícitos que el cliente manda de vuelta como argumentos normales. - Nuevo método
server/discover. Los servidores deben implementarlo para anunciar versiones soportadas, capacidades e identidad. El cliente puede llamarlo antes de cualquier otra cosa. - El servidor ya no le hace solicitudes al cliente. En lugar de abrir su propia solicitud para pedir una confirmación o una respuesta de un modelo, el servidor devuelve un resultado
InputRequiredResultcon lo que necesita, y el cliente reintenta la llamada original con las respuestas. La especificación llama a esto Multi Round-Trip Requests (solicitudes de varias vueltas). - Roots, muestreo (sampling) y logging del protocolo quedan obsoletos. Siguen funcionando durante un periodo mínimo de doce meses, pero las implementaciones nuevas no deberían adoptarlos. Las rutas recomendadas: pasar carpetas por parámetros o configuración, integrar directamente la API de tu proveedor de modelos y registrar en stderr o con OpenTelemetry.
- Avisos de cambios por
subscriptions/listen. Un solo flujo de larga duración, por POST, reemplaza el endpoint GET y la suscripción por recurso. - Autorización más estricta. Se recomiendan los Client ID Metadata Documents para registrar clientes y el registro dinámico de clientes queda obsoleto.
¿Y los clientes que todavía hablan la versión 2025-11-25? El SDK de Python 2 atiende ambas épocas en el mismo endpoint. La documentación del SDK las llama era "legacy" (con saludo) y era moderna (con server/discover). Diseñarás para la moderna y verás en cada lección qué cambia para los clientes antiguos.
Por qué importa para ti: casi todo lo que encuentras en blogs y videos sobre "MCP en producción" se escribió para la versión anterior: sesiones pegajosas, muestreo,
ctx.log(). Si copias esas recetas hoy, construyes sobre piezas obsoletas.
El camino del curso
| Lección | Qué le agregamos al servidor de LCS |
|---|---|
| 1.2 | Transporte Streamable HTTP y lista de hosts permitidos |
| 2.1 | Verificación de tokens OAuth y alcances por herramienta |
| 2.2 | Validación estricta, identificadores ligados al usuario y defensa contra inyección |
| 3.1 | Progreso y cancelación en el reporte de ruta |
| 3.2 | Confirmación antes de reprogramar una entrega |
| 3.3 | Lectura de manifiestos limitada a una carpeta |
| 4.1 | Contenedor, varios workers y estado compartido |
| 4.2 | Trazas, pruebas con pytest y versionado |
| 4.3 | Todo junto, con rúbrica |
Prepara tu entorno
Necesitas Python 3.10 o superior y el SDK oficial en su versión 2. Con uv:
uv init lcs-operaciones
cd lcs-operaciones
uv add "mcp[cli]"
uv run mcp version
El último comando debe mostrar una versión 2.x. Guarda el prototipo de arriba como servidor.py y pruébalo con el Inspector:
uv run mcp dev servidor.py
Llama rastrear_envio con LCS-10000001 y luego con 12345. La segunda llamada debe fallar por el patrón antes de llegar a tu código.
Práctica
Dedica 30 minutos.
- Instala el SDK 2 y ejecuta el prototipo de LCS con el Inspector.
- Toma un servidor MCP tuyo (o el de LCS) y llena una tabla con las seis dimensiones de esta lección: cómo está hoy y qué necesitaría en producción.
- Busca en tu código usos de
ctx.log(),ctx.info(), muestreo o roots. Anótalos: son candidatos a migrar en las lecciones 3.1 a 3.3. - Agrega a
ENVIOSdos guías más con destinos reales del área metropolitana (por ejemplo Guadalupe o Santa Catarina) y verifica que el patrón las acepte.
Resumen
- Un servidor de producción cambia en seis dimensiones: dónde corre, quién lo usa, qué puede hacer cada quien, dónde vive el estado, cómo maneja tareas largas y acciones delicadas, y cómo lo observas.
- La revisión 2026-07-28 de MCP elimina sesiones y el saludo
initialize, agregaserver/discovery reemplaza las solicitudes del servidor al cliente por solicitudes de varias vueltas. - Roots, muestreo y logging del protocolo están obsoletos: siguen funcionando, pero no son base para diseños nuevos.
- El SDK de Python 2 atiende clientes modernos y antiguos en el mismo endpoint.
- Validar entradas con patrones y tipos desde el prototipo te ahorra trabajo cuando el servidor sale a producción.