MCP-Server-Fehler

MCP-Server-Fehler

So behandelst du Fehler, die vom foura-mcp server zurückgegeben werden.

Jede Fehler-Response von einem der vier Tools (foura_auto, foura_single, foura_proxy, foura_browser) ist strukturiert. LLM-Agents können das code-Feld für Retry-Logik auslesen, ohne Fließtext parsen zu müssen.

Envelope-Struktur

Jeder Fehler (isError: true) enthält einen structuredContent-Block. Mindestfelder bei jedem Fehler:

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

Bei Upstream-Fehlern mit HTTP-Status ist status ebenfalls vorhanden. Wenn das geteilte Kontingent der Plattform einen Aufruf ablehnt, enthält der Envelope zusätzlich retryAfter, current.{concurrency, rpm} und limits.{maxConcurrency, maxRpm}, im selben Format wie die zugrundeliegenden REST-API-Fehler.

Wenn eines der Limits deines eigenen Tarifs einen Aufruf ablehnt, entspricht der Code genau diesem Limit: plan_limit_ gefolgt von credits, bandwidth, rate, concurrency, browser_daily, premium oder feature. retryAfter enthält die Wartezeit, sofern Warten das Problem behebt, und fehlt bei Limits, die sich nicht durch Warten lösen lassen, wie etwa ein im Tarif nicht enthaltenes Feature. plan_limit_browser_daily enthält ebenfalls kein retryAfter: Es wird um Mitternacht UTC zurückgesetzt.

Bei foura_auto wird ein Tariflimit innerhalb seiner Stufe als rate_limited oder forbidden zurückgegeben, mit dem Tarif-Code in reason.

Stabile code-Werte

Code HTTP Bedeutung Retry sicher?
ssrf_blocked k. A. Das Ziel ist eine private oder reservierte Adresse (RFC 5735, RFC 6598, IPv6-reserviert), die URL ist nicht http(s) oder ihr Hostname konnte nicht aufgelöst werden Nein, prüfe die URL. Ein kurzzeitig fehlgeschlagener Lookup kann wiederholt werden
upstream_non_json variiert Upstream hat einen Body zurückgegeben, der kein gültiges JSON war Vielleicht, analysieren
output_validation_failed k. A. Der outputSchema des MCP-Servers hat die Upstream-Response abgelehnt oder das Tool konnte den Aufruf gar nicht abschließen (kein API-Key konfiguriert, API nicht erreichbar) Vielleicht: Setup prüfen, dann melden
bad_request 400 Eingabeformat von der FourA-API abgelehnt Nein, Argumente korrigieren
auth_failed 401 Der FourA-API-Key fehlt, ist ungültig oder deaktiviert; dies betrifft nicht die Zugangsdaten der Zielseite Nein, FourA-Key korrigieren
forbidden 403 Ziel hat den Request abgelehnt (Site-Check, Länderbeschränkung) Nein, oder zu foura_proxy wechseln
not_found 404 Ziel-URL oder Endpoint existiert nicht Nein
rate_limited 429 Geteiltes Minutenkontingent der Plattform oder ein 429 vom Ziel, das dein validate abgelehnt hat. Bei foura_auto können es auch Credits, Traffic oder Rate-Limits deines Tarifs sein (siehe reason) Ja, warte retryAfter ab, falls vorhanden, sonst Backoff nutzen
at_capacity 503 Concurrency-Limit erreicht (current.concurrency > limits.maxConcurrency) Ja, warte retryAfter Sekunden
service_disabled 503 Der Dienst ist wegen Wartungsarbeiten deaktiviert. Ein Tool, das dein Tarif nicht enthält, wird als plan_limit_feature zurückgegeben Support kontaktieren
service_unavailable 503 Generischer 503 vom Upstream Ja, kurzer Backoff
upstream_error 500+ oder 0 Das Ziel hat mit einem Serverfehler geantwortet, oder bei foura_proxy haben foura_browser und foura_auto nie geantwortet Ja, exponentieller Backoff
upstream_client_error 4xx Sonstige 4xx, die oben nicht abgedeckt sind Meistens nein
upstream_unknown sonstige Request lief, ergab aber keine akzeptierte Antwort: Bei foura_single hat das Ziel nie geantwortet (Timeout, Verbindung abgelehnt), und bei jedem Tool hat dein validate eine 2xx- oder 3xx-Response abgelehnt. Lies status und error Analysieren
no_eligible_proxy k. A. Kein Proxy entspricht der strikten exitCountries-Allowlist; details.exitCountries enthält den normalisierten Scope Später erneut versuchen; Scope nur explizit ändern
plan_limit_credits 429 Die monatlichen Credits deines Tarifs sind aufgebraucht Ja, nach retryAfter, oder Tarif wechseln
plan_limit_bandwidth 429 Das Traffic-Kontingent deines Tarifs ist für diesen Abrechnungszeitraum aufgebraucht Ja, nach retryAfter, oder Tarif wechseln
plan_limit_rate 429 Requests pro Minute deines Tarifs für diesen Endpoint Ja, nach retryAfter
plan_limit_concurrency 429 Parallele Requests deines Tarifs für diesen Endpoint Ja, nach retryAfter
plan_limit_browser_daily 429 Tägliches Browser-Kontingent deines Tarifs ist aufgebraucht Ja, morgen, oder foura_single / foura_proxy nutzen
plan_limit_premium 403 Du hast exitClass: "premium" in einem Tarif gesendet, der keine Premium-Exits enthält Nein, Parameter weglassen oder Tarif wechseln
plan_limit_feature 403 Der Tarif enthält diesen Endpoint oder dieses Feature nicht Nein, Tarif wechseln

HTTP-Fehler vom MCP-Server

Manche Fehler treten auf der MCP-Transportschicht auf, bevor ein Tool aufgerufen wird. Diese geben reine JSON-RPC-Fehler zurück (kein structuredContent):

HTTP Wann Was du siehst
400 Nicht unterstützter MCP-Protocol-Version Header Unsupported MCP-Protocol-Version: <value>. Supported: 2025-11-25, 2025-06-18, 2025-03-26, 2024-11-05, 2024-10-07.
401 Ein Tool-Aufruf oder Ressourcen-Lesevorgang ohne API key. Das Auflisten von Tools und Prompts funktioniert ohne Key JSON-RPC-Fehler + WWW-Authenticate: Bearer realm="foura-mcp"
403 Unzulässiger Origin oder Host Header (DNS-Rebinding-Schutz, CVE-2025-66414) Origin <value> is not in the allowlist oder Host <value> is not in the allowlist
405 GET oder DELETE auf /mcp (stateless Modus) Method not allowed in stateless mode. Use POST /mcp.
413 Request Body > 256 KB Express Default 413

Die Allowlists für 403 sind für Self-Hoster über FOURA_MCP_ALLOWED_HOSTS und FOURA_MCP_ALLOWED_ORIGINS per Umgebungsvariable konfigurierbar.

Abgelehnte Browser-Profile

Ein Browser-Profil, das der Katalog nicht bereitstellen kann, oder ein Profil, das mit unblocker auf false gesendet wurde, wird als Upstream-Fehler mit dem Grund in error zurückgegeben und der Request verlässt FourA nie. Die Meldung nennt verfügbare Optionen. Wiederhole den Versuch mit einer der aufgelisteten Kombinationen statt mit derselben.

Dies sind Ablehnungen, keine Ausfälle: Ein erneuter identischer Request kann nicht erfolgreich sein, und es wurde kein anderer Browser als Ersatz verwendet.

Retry-Strategie

Fünf Kategorien:

  • Dein eigener Plan hat abgelehnt, nicht das Ziel: Jeder plan_limit_* Code. Dieselbe Aktion über ein anderes Tool wird ebenfalls abgelehnt, ein Wechsel der Endpoints kostet also nur Zeit. Warte retryAfter ab, falls vorhanden; andernfalls muss der Plan geändert werden. plan_limit_premium kannst du selbst beheben, indem du exitClass entfernst.
  • Warten und wiederholen: rate_limited, at_capacity, service_unavailable, upstream_error. Beachte retryAfter, falls vorhanden. Nutze Exponential Backoff mit Jitter, wenn kein Wert vorliegt. Reagiere nicht damit, alle anstehenden Tool-Aufrufe sofort erneut zu senden: Reduziere stattdessen die Anzahl paralleler Requests.
  • Scope beibehalten und später wiederholen: no_eligible_proxy. Entferne exitCountries nicht und ersetze Länder nicht stillschweigend. Ändere oder erweitere die Allowlist nur, wenn der Nutzer die Anforderung explizit anpasst.
  • Nicht wiederholen, bis Input oder Zugangsdaten korrigiert sind: bad_request, auth_failed, not_found, ssrf_blocked. Prüfe bei auth_failed den FourA API key, nicht die Zugangsdaten der Zielseite.
  • Tool wechseln, wenn der Inhalt es erfordert: forbidden auf foura_single kann einen begrenzten Versuch mit foura_proxy rechtfertigen. Nutze foura_browser, wenn der gewünschte Inhalt JavaScript benötigt. Übergib nach erfolgreicher Proxy-Auswahl die zurückgegebene proxy ID an foura_browser.proxy, statt eine neue Auswahl zu starten.

Retry-Beispiel (TypeScript, MCP-seitig)

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");
}

Verwandte Themen

  • MCP Server, die vier Tools und ihre Schemas
  • MCP Recipes, mit dem Server ausgelieferte Workflow-Prompts
  • API Errors, dieselbe Envelope auf der zugrunde liegenden REST-API-Ebene
  • Rate Limits, die Account- und Plattform-Limits hinter rate_limited und at_capacity
Aktualisiert: 27. September 2026