Erreurs du serveur MCP

Erreurs du serveur MCP

Comment gérer les erreurs renvoyées par le serveur foura-mcp.

Chaque réponse d'erreur de l'un des quatre outils (foura_auto, foura_single, foura_proxy, foura_browser) est structurée. Les agents LLM peuvent lire le champ code pour la logique de nouvelle tentative sans analyser de texte.

Structure de l'enveloppe

Chaque erreur (isError: true) contient un bloc structuredContent. Champs minimums pour chaque erreur :

{
  "service": "auto | single | proxy | browser",
  "code": "rate_limited",
  "error": "Rate limit exceeded"
}

Pour les erreurs upstream avec un statut HTTP, status est également présent. Pour les erreurs de rate limit et de capacité, l'enveloppe ajoute retryAfter, current.{concurrency, rpm} et limits.{maxConcurrency, maxRpm}, avec la même structure que les erreurs de l'API REST sous-jacentes.

Valeurs code stables

Code HTTP Signification Réessai possible ?
ssrf_blocked n/a IP cible dans une plage privée ou réservée (RFC 5735, RFC 6598, IPv6 réservé) Non, modifiez l'URL
upstream_non_json variable L'upstream a renvoyé un body qui n'était pas un JSON valide Peut-être, à investiguer
output_validation_failed n/a Le outputSchema du serveur MCP a rejeté la réponse upstream (bug du serveur ou structure upstream inattendue) Peut-être, à signaler
bad_request 400 Structure d'entrée rejetée par l'API FourA Non, corrigez les arguments
auth_failed 401 La clé d'API FourA est manquante, invalide ou désactivée; il ne s'agit pas des identifiants du site cible Non, corrigez la clé FourA
forbidden 403 La cible a rejeté la request (anti-bot, blocage géographique) Non, ou passez à foura_proxy
not_found 404 L'URL cible ou l'endpoint n'existe pas Non
rate_limited 429 Limite de RPM par clé atteinte Oui, attendez retryAfter secondes
at_capacity 503 Limite de concurrence atteinte (current.concurrency > limits.maxConcurrency) Oui, attendez retryAfter secondes
service_disabled 503 Service désactivé pour votre compte (forfait ou maintenance) Contactez le support
service_unavailable 503 Erreur 503 générique de l'upstream Oui, backoff court
upstream_error 500+ Erreur 5xx de l'upstream Oui, backoff exponentiel
upstream_client_error 4xx Autre erreur 4xx non couverte ci-dessus Généralement non
upstream_unknown autre Défensif, ne devrait pas se produire en pratique À investiguer
no_eligible_proxy n/a Aucun proxy ne correspond à la liste d'autorisation stricte exitCountries; details.exitCountries contient le scope normalisé Réessayez plus tard, modifiez le scope uniquement de façon explicite

Erreurs de niveau HTTP provenant du serveur MCP

Certains échecs se produisent au niveau de la couche de transport MCP, avant l'appel d'un outil. Ceux-ci renvoient des erreurs JSON-RPC brutes (pas de structuredContent):

HTTP Quand Ce que vous voyez
400 Header MCP-Protocol-Version non pris en charge Unsupported MCP-Protocol-Version: <value>. Supported: 2025-11-25, 2025-06-18, 2025-03-26, 2024-11-05, 2024-10-07.
401 Header Authorization manquant ou malformé Erreur JSON-RPC + WWW-Authenticate: Bearer realm="foura-mcp", resource_metadata="https://foura.ai/docs/mcp/server#auth"
403 Header Origin ou Host non autorisé (défense contre le DNS-rebinding, CVE-2025-66414) Origin <value> is not in the allowlist ou Host <value> is not in the allowlist
405 GET ou DELETE sur /mcp (mode stateless) Method not allowed in stateless mode. Use POST /mcp.
413 Body de la request > 256 Ko Erreur 413 par défaut d'Express

Les listes d'autorisation pour 403 sont configurables par environnement pour les utilisateurs auto-hébergés via FOURA_MCP_ALLOWED_HOSTS et FOURA_MCP_ALLOWED_ORIGINS.

Profils de navigateur refusés

Un profil de navigateur que le catalogue ne peut pas présenter, ou un profil envoyé avec unblocker défini sur false, est renvoyé comme un échec en amont avec la raison dans error et la request ne quitte jamais FourA. Le message indique ce qui est disponible, réessayez donc avec l'une des combinaisons listées plutôt qu'avec la même.

Il s'agit de refus, pas de pannes : réessayer la même request ne peut pas aboutir, et aucun autre navigateur n'a été utilisé à sa place.

Stratégie de nouvelle tentative

Quatre catégories :

  • Attendre et réessayer : rate_limited, at_capacity, service_unavailable, upstream_error. Respectez retryAfter lorsqu'il est présent. Utilisez un backoff exponentiel avec jitter lorsqu'il est absent.
  • Conserver la portée et réessayer plus tard : no_eligible_proxy. Ne supprimez pas exitCountries et ne substituez pas un autre pays de manière silencieuse. Modifiez ou élargissez l'allowlist uniquement lorsque l'utilisateur modifie explicitement l'exigence.
  • Ne pas réessayer tant que l'entrée ou les informations d'identification ne sont pas corrigées : bad_request, auth_failed, not_found, ssrf_blocked. Pour auth_failed, vérifiez la clé API FourA, pas les informations d'identification du site cible.
  • Changer d'outil lorsque le contenu l'exige : forbidden sur foura_single peut justifier une tentative foura_proxy limitée. Utilisez foura_browser lorsque le contenu souhaité nécessite JavaScript. Après une sélection de proxy réussie, transmettez l'ID proxy retourné dans foura_browser.proxy au lieu de démarrer une nouvelle sélection.

Exemple de nouvelle tentative (TypeScript, côté 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");
}

Voir aussi

  • Serveur MCP, les quatre outils et leurs schémas
  • Recettes MCP, les prompts de workflow fournis avec le serveur
  • Erreurs API, la même enveloppe au niveau de la couche API REST sous-jacente
Mis à jour : 6 août 2026