Las herramientas MCP congelan a los agentes de IA cuando las APIs externas son lentas, causando errores 424. El patrón handleId asíncrono devuelve inmediatamente un ID de trabajo y consulta los resultados sin bloquear.
El timeout de herramienta MCP ocurre cuando un agente de IA llama a una herramienta del Protocolo de Contexto de Modelo (MCP) que depende de una API externa lenta. La herramienta bloquea al agente indefinidamente en lugar de devolver un error. El resultado es un error 424 (Failed Dependency) o un flujo de trabajo congelado sin retroalimentación al usuario. Este post muestra el problema con escenarios reales y cómo el patrón handleId asíncrono proporciona respuestas inmediatas.
Esta demo usa Strands Agents con MCP (Model Context Protocol). El patrón asíncrono es independiente del framework y aplica a cualquier agente que llame APIs externas a través de MCP.
Código funcional: github.com/aws-samples/sample-why-agents-fail
Serie: Por Qué Fallan los Agentes de IA
- Desbordamiento de Ventana de Contexto — Patrón de Puntero de Memoria para datos grandes
- Herramientas MCP Que Nunca Responden (este post) — Patrón asíncrono para APIs externas lentas
- Loops de Razonamiento en Agentes de IA — Detectar y bloquear llamadas repetidas a herramientas
El Problema: Herramientas MCP Que Nunca Responden
El Protocolo de Contexto de Modelo (MCP) permite a los agentes de IA llamar herramientas externas. Pero cuando esas herramientas dependen de APIs lentas, todo el flujo de trabajo del agente se congela. El agente espera. El usuario espera. No pasa nada.
Una observación comunitaria de Octopus (Resilient AI Agents With MCP, 2025) identifica el problema central: a medida que aumentan las integraciones de sistemas externos, también aumenta la probabilidad de fallo. Los sistemas dejan de estar disponibles, responden lentamente o devuelven errores. Los agentes no tienen una estrategia incorporada para manejar esto.
Los reportes de OpenAI Community confirman el impacto del mundo real:
- Errores 424 cuando las herramientas MCP tardan demasiado
- Estados sin respuesta donde las solicitudes ni tienen éxito ni fallan
- Herramientas que pasan la validación de handshake pero hacen timeout durante la ejecución
Por Qué Sucede Esto
MCP espera que las herramientas respondan rápidamente. Cuando una herramienta llama a una API externa lenta.
El protocolo MCP tiene expectativas de timeout implícitas. Si la herramienta no responde dentro de ~7-10 segundos, la conexión puede caerse con un error 424 (Failed Dependency). El agente recibe un error en lugar de datos, y el usuario no obtiene una respuesta útil.
Tres modos de fallo:
- API lenta — La herramienta espera 15+ segundos, UX pobre pero eventualmente responde
- API fallida — Servicio externo no disponible, error 424 después del timeout
- Estado sin respuesta — Solicitud aceptada pero nunca devuelve, requiere reinicio de sesión
La Demo: Simulando Escenarios Reales de Timeout
Construimos un servidor MCP que simula estos escenarios del mundo real:
from mcp.server import FastMCP
import asyncio
# FastMCP es un framework ligero de servidor MCP — las herramientas se registran con @mcp.tool()
mcp = FastMCP("Timeout Demo Server")
# Línea base: responde en 1s, bien dentro del umbral de timeout implícito de MCP (~7-10s)
@mcp.tool(description="Fast API - responds in 1 second")
async def fast_api(query: str) -> str:
await asyncio.sleep(1)
return f"Fast result for: {query}"
# Caso problema: retraso de 15s excede timeout de MCP — el agente se congela esperando esto
@mcp.tool(description="Slow API - responds in 15 seconds")
async def slow_api(query: str) -> str:
await asyncio.sleep(15) # Simula un servicio externo lento (pipeline de datos, trabajo por lotes)
return f"Slow result for: {query}"
# Caso de fallo: retraso de 7s activa el timeout, luego lanza Failed Dependency (424)
@mcp.tool(description="Failing API - returns 424 after delay")
async def failing_api(query: str) -> str:
await asyncio.sleep(7)
raise Exception("Failed Dependency: External service unavailable")
La Solución Async HandleId
En lugar de esperar operaciones lentas, devuelve inmediatamente con un ID de seguimiento:
import uuid
# Almacén de trabajos en memoria: mapea job_id → {status, query, result}
# Para producción, reemplazar con un almacén persistente (Redis, DynamoDB) para durabilidad entre reinicios
JOBS = {}
# El patrón handleId: devuelve un ID de seguimiento inmediatamente en lugar de bloquear
@mcp.tool(description="Start a long-running job, returns immediately with job ID")
async def start_async_job(query: str) -> str:
job_id = str(uuid.uuid4())[:8] # ID corto que el LLM puede pasar en llamadas de seguimiento
JOBS[job_id] = {"status": "processing", "query": query}
# Fire-and-forget: el trabajo lento se ejecuta en segundo plano, la herramienta devuelve antes de que termine
asyncio.create_task(do_work(job_id, query))
# El agente recibe esto en < 1s — sin timeout, sin UI congelada
return f"Job started: {job_id}. Use check_job_status to poll for results."
# Endpoint de consulta: el agente llama a esto repetidamente hasta que el estado es "completed"
@mcp.tool(description="Check status of a running job")
async def check_job_status(job_id: str) -> str:
job = JOBS.get(job_id)
if not job:
return f"Job {job_id} not found"
if job["status"] == "completed":
return f"COMPLETED: {job['result']}" # Devuelve el resultado real al agente
return f"PROCESSING: Job {job_id} still running" # El agente consulta de nuevo después de una breve espera
Resultados de la Demo
Probamos los cuatro escenarios con un Strands Agent conectado al servidor MCP:
| Escenario | Tiempo de Respuesta | Experiencia de Usuario | Hallazgo de Investigación |
|---|---|---|---|
| Fast API (retraso 1s) | 3.2s total | ✅ Buen UX | Línea base |
| Slow API (retraso 15s) | 17.8s total | ❌ UX pobre — agente espera | Octopus: "el agente espera indefinidamente" |
| Failing API (424) | 7.7s total | ❌ Error después de esperar | OpenAI Community: errores 424 |
| Patrón asíncrono (handleId) | 3.7s total | ✅ Respuesta inmediata | Solución: "responder ASAP con handleId" |
El patrón asíncrono transforma una espera de 17.8s en una respuesta inmediata de 3.7s. El agente le dice al usuario "trabajo iniciado" y puede verificar el estado más tarde, sin UI congelada y sin errores de timeout.
¿Por Qué Strands Agents para Integración MCP?
El MCPClient se conecta a cualquier servidor MCP en dos líneas. El agente descubre herramientas disponibles en tiempo de ejecución a través de list_tools_sync(), así que no mantienes una lista de herramientas codificada. Cuando el servidor MCP implementa el patrón handleId asíncrono, el agente consulta automáticamente sin código de orquestación adicional.
Strands soporta múltiples proveedores de modelos (OpenAI, Amazon Bedrock, Anthropic, Ollama). Los patrones de timeout de MCP mostrados aquí funcionan idénticamente en todos los proveedores.
Cuándo Usar Cada Patrón
Llamada directa (herramientas rápidas < 5s):
- Búsquedas, cálculos, llamadas pequeñas a API
- Sin riesgo de timeout
HandleId asíncrono (herramientas lentas > 5s):
- Llamadas a API externas con latencia impredecible
- Procesamiento de datos, generación de reportes
- Cualquier operación que pueda exceder el timeout de MCP
Reintento con backoff (fallos intermitentes):
- Servicios que ocasionalmente fallan pero se recuperan
- Operaciones dependientes de red
Pruébalo Tú Mismo
Necesitas Python 3.9+, uv, y una clave API de OpenAI. El servidor MCP se ejecuta localmente como un subproceso, así que no se necesitan servicios externos.
git clone https://github.com/aws-samples/sample-why-agents-fail
cd sample-why-agents-fail/stop-ai-agents-wasting-tokens/02-mcp-timeout-demo
uv venv && uv pip install -r requirements.txt
export OPENAI_API_KEY="tu-clave-aquí"
uv run python test_mcp_timeout.py # Ejecuta los 4 escenarios
O abre test_mcp_timeout.ipynb en Jupyter, JupyterLab, VS Code, o tu entorno de notebook preferido.
Conclusiones Clave
- Las herramientas MCP hacen timeout silenciosamente — errores 424 sin recuperación
- Las APIs lentas congelan todo el agente — espera de 17.8s sin retroalimentación
- El patrón handleId asíncrono lo soluciona — respuesta inmediata, consultar por resultados
- Diseña para el fallo — cada llamada externa puede hacer timeout, planifica en consecuencia
Preguntas Frecuentes
¿Qué causa errores 424 en llamadas a herramientas MCP?
Un error 424 (Failed Dependency) ocurre cuando una herramienta MCP tarda más que el umbral de timeout implícito (típicamente 7-10 segundos) en responder. El protocolo MCP espera que las herramientas devuelvan resultados rápidamente. Cuando una API externa bloquea la herramienta más allá de este umbral, la conexión se cae y el agente recibe un error 424 en lugar de datos.
¿Cuándo debo usar el patrón handleId asíncrono en lugar de una llamada directa a herramienta MCP?
Usa el patrón handleId asíncrono para cualquier herramienta que llame a una API externa con latencia impredecible: procesamiento de datos, generación de reportes, llamadas a servicios de terceros, o cualquier operación que pueda exceder 5 segundos. Para búsquedas rápidas, cálculos y llamadas pequeñas a API por debajo de 5 segundos, las llamadas directas funcionan bien.
¿El patrón handleId asíncrono funciona con cualquier servidor MCP, no solo Strands?
Sí. El patrón handleId asíncrono es un patrón de diseño de servidor MCP, no una característica de framework. Cualquier agente compatible con MCP puede llamar herramientas start_long_job y check_job_status. El patrón funciona con OpenAI Agents, integraciones MCP de LangChain, y cualquier cliente que soporte el Protocolo de Contexto de Modelo.
Referencias
Investigación
- Resilient AI Agents With MCP: Timeout And Retry Strategies — Octopus blog (observación comunitaria), May 2025
- Call remote MCP server tool timed out, error 424 — OpenAI Community (foro comunitario)
- Handling Timeouts with Long-Running MCP Connectors — OpenAI Community (foro comunitario), Dec 2025
- Build Timeout-Proof MCP Tools — Arsturn (observación comunitaria)
Implementación
- Strands MCP Tools — Connect any MCP server
- Strands Model Providers — Swap to Amazon Bedrock, Anthropic, Ollama
Gracias!



Top comments (0)