Errores del servidor MCP
Errores del servidor de MCP
Cómo manejar los errores devueltos por el servidor foura-mcp.
Cada respuesta de error de cualquiera de las cuatro herramientas (foura_auto, foura_single, foura_proxy, foura_browser) está estructurada. Los agentes LLM pueden leer el campo code para la lógica de reintento sin analizar el texto.
Estructura del envoltorio
Cada error (isError: true) lleva un bloque structuredContent. Campos mínimos en cada error:
{
"service": "auto | single | proxy | browser",
"code": "rate_limited",
"error": "Rate limit exceeded"
}
En errores del upstream con estado HTTP, status también está presente. En errores de rate limit y capacidad, la envoltura añade retryAfter, current.{concurrency, rpm} y limits.{maxConcurrency, maxRpm}, con la misma estructura que los errores subyacentes de la API REST.
Valores code estables
| Código | HTTP | Significado | ¿Es seguro reintentar? |
|---|---|---|---|
ssrf_blocked |
n/a | IP de destino en un rango privado o reservado (RFC 5735, RFC 6598, IPv6 reservado) | No, cambia la URL |
upstream_non_json |
varía | El upstream devolvió un cuerpo que no era un JSON válido | Quizás, investiga |
output_validation_failed |
n/a | El outputSchema del servidor MCP rechazó la respuesta del upstream (error del servidor o estructura inesperada del upstream) |
Quizás, repórtalo |
bad_request |
400 | Estructura de entrada rechazada por la API de FourA | No, corrige los argumentos |
auth_failed |
401 | La clave API de FourA falta, es inválida o está desactivada (no se trata de credenciales del sitio de destino) | No, corrige la clave de FourA |
forbidden |
403 | El destino rechazó la request (antibot, geobloqueo) | No, o cambia a foura_proxy |
not_found |
404 | La URL o el endpoint de destino no existe | No |
rate_limited |
429 | Límite de RPM por clave alcanzado | Sí, espera retryAfter segundos |
at_capacity |
503 | Límite de concurrencia alcanzado (current.concurrency > limits.maxConcurrency) |
Sí, espera retryAfter segundos |
service_disabled |
503 | Servicio deshabilitado para tu cuenta (plan o mantenimiento) | Contacta a soporte |
service_unavailable |
503 | 503 genérico del upstream | Sí, backoff corto |
upstream_error |
500+ | 5xx del upstream | Sí, backoff exponencial |
upstream_client_error |
4xx | Otro 4xx no cubierto arriba | Normalmente no |
upstream_unknown |
otro | Defensivo, no debería ocurrir en la práctica | Investiga |
no_eligible_proxy |
n/a | Ningún proxy coincide con la estricta allowlist exitCountries; details.exitCountries contiene el scope normalizado |
Reintenta más tarde, cambia el scope solo explícitamente |
Errores a nivel HTTP del servidor MCP
Algunos fallos ocurren en la capa de transporte del MCP, antes de que se llame a cualquier herramienta. Estos devuelven errores JSON-RPC crudos (sin structuredContent):
| HTTP | Cuándo | Qué ves |
|---|---|---|
| 400 | Header MCP-Protocol-Version no soportado |
Unsupported MCP-Protocol-Version: <value>. Supported: 2025-11-25, 2025-06-18, 2025-03-26, 2024-11-05, 2024-10-07. |
| 401 | Header Authorization ausente o mal formado |
Error JSON-RPC + WWW-Authenticate: Bearer realm="foura-mcp", resource_metadata="https://foura.ai/docs/mcp/server#auth" |
| 403 | Header Origin o Host no permitido (defensa contra DNS rebinding, CVE-2025-66414) |
Origin <value> is not in the allowlist o Host <value> is not in the allowlist |
| 405 | GET o DELETE en /mcp (modo stateless) |
Method not allowed in stateless mode. Use POST /mcp. |
| 413 | Request body > 256 KB | 413 por defecto de Express |
Las allowlists para 403 se pueden configurar por variables de entorno para hostings propios vía FOURA_MCP_ALLOWED_HOSTS y FOURA_MCP_ALLOWED_ORIGINS.
Perfiles de navegador rechazados
Un perfil de navegador que el catálogo no puede presentar, o un perfil enviado con unblocker establecido en false, vuelve como un fallo upstream con el motivo en error y la request nunca abandona FourA. El mensaje nombra lo que está disponible, así que reintenta con una de las combinaciones listadas en lugar de usar la misma.
Estos son rechazos, no cortes de servicio: reintentar la request idéntica no puede tener éxito, y no se usó ningún otro navegador en su lugar.
Estrategia de reintentos
Cuatro categorías:
- Esperar y reintentar:
rate_limited,at_capacity,service_unavailable,upstream_error. RespetaretryAftercuando esté presente. Usa retroceso exponencial (exponential backoff) con jitter cuando esté ausente. - Preservar el scope y reintentar más tarde:
no_eligible_proxy. No eliminesexitCountriesni sustituyas otro país de forma silenciosa. Cambia o amplía la allowlist solo cuando el usuario cambie explícitamente el requisito. - No reintentar hasta que se corrija el input o la credencial:
bad_request,auth_failed,not_found,ssrf_blocked. Paraauth_failed, verifica la API key de FourA, no las credenciales del sitio de destino. - Cambiar de herramienta cuando el contenido lo requiera:
forbiddenenfoura_singlepuede justificar un intento limitado defoura_proxy. Usafoura_browsercuando el contenido deseado necesite JavaScript. Después de una selección de proxy exitosa, pasa el ID deproxydevuelto afoura_browser.proxyen lugar de iniciar una nueva selección.
Ejemplo de reintento (TypeScript, lado del MCP)
async function callWithRetry(call: () => Promise<any>, maxAttempts = 3) {
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
const r = await call();
if (!r.isError) return r;
const code = r.structuredContent?.code;
const wait = r.structuredContent?.retryAfter ?? Math.min(2 ** attempt, 30);
if (["rate_limited", "at_capacity", "service_unavailable", "upstream_error"].includes(code)) {
await new Promise((res) => setTimeout(res, wait * 1000));
continue;
}
// Non-retryable, surface to caller
throw new Error(`${code}: ${r.structuredContent?.error}`);
}
throw new Error("max retries exceeded");
}
Relacionado
- Servidor MCP, las cuatro herramientas y sus esquemas
- Recetas de MCP, prompts de flujo de trabajo incluidos con el servidor
- Errores de la API, mismo sobre en la capa subyacente de la API REST