Грешки на MCP Server

Как да се справяте с грешките, върнати от foura-mcp server.

Всеки отговор за грешка от който и да е от трите инструмента (foura_single, foura_proxy, foura_browser) е структуриран. LLM агентите могат да четат полето code за логика на повторен опит, без да анализират свободен текст.

Структура на обвивката

Всяка грешка (isError: true) съдържа structuredContent блок. Минимални полета за всяка грешка:

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

При upstream грешки с HTTP статус, присъства и status. При грешки за rate limit и капацитет, обвивката добавя retryAfter, current.{concurrency, rpm} и limits.{maxConcurrency, maxRpm}, в същия формат като базовите REST API грешки.

Стабилни стойности на code

Code HTTP Значение Безопасно за повторен опит?
ssrf_blocked n/a Целевият IP е в частен или резервиран диапазон (RFC 5735, RFC 6598, резервиран IPv6) Не, променете URL
upstream_non_json варира Upstream върна тяло, което не е валиден JSON Може би, проучете
output_validation_failed n/a Схемата outputSchema на MCP сървъра отхвърли upstream отговора (бъг в сървъра или неочаквана upstream структура) Може би, докладвайте
bad_request 400 Входната структура е отхвърлена от FourA API Не, коригирайте аргументите
auth_failed 401 Ключът липсва, е невалиден или деактивиран Не, коригирайте ключа
forbidden 403 Целта отхвърли заявката (anti-bot, гео-блокаж) Не, или преминете към foura_proxy
not_found 404 Целевият URL или endpoint не съществува Не
rate_limited 429 Достигнат е лимитът за RPM на ключ Да, изчакайте retryAfter секунди
at_capacity 503 Достигнат е лимитът за едновременни заявки (current.concurrency > limits.maxConcurrency) Да, изчакайте retryAfter секунди
service_disabled 503 Услугата е деактивирана за вашия акаунт (план или поддръжка) Свържете се с поддръжката
service_unavailable 503 Обща грешка 503 от upstream Да, кратко изчакване (backoff)
upstream_error 500+ Upstream 5xx Да, експоненциално изчакване (backoff)
upstream_client_error 4xx Друга грешка 4xx, непокрита по-горе Обикновено не
upstream_unknown други Защитно, не би трябвало да възниква на практика Проучете

Грешки на HTTP ниво от MCP сървъра

Някои отказа възникват на транспортния слой на MCP, преди да бъде извикан какъвто и да е инструмент. Те връщат сурови JSON-RPC грешки (без structuredContent):

HTTP Кога Какво виждате
400 Неподдържан 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 Липсващ или неправилно форматиран Authorization header JSON-RPC грешка + WWW-Authenticate: Bearer realm="foura-mcp", resource_metadata="https://foura.ai/docs/mcp/server#auth"
403 Неразрешен Origin или Host header (защита срещу DNS-rebinding, CVE-2025-66414) Origin <value> is not in the allowlist или Host <value> is not in the allowlist
405 GET или DELETE на /mcp (stateless режим) Method not allowed in stateless mode. Use POST /mcp.
413 Тяло на заявката > 256 KB Express по подразбиране 413

Списъците с разрешени адреси (allowlists) за 403 могат да се конфигурират чрез променливи на средата (env) за self-host потребители чрез FOURA_MCP_ALLOWED_HOSTS и FOURA_MCP_ALLOWED_ORIGINS.

Стратегия за повторен опит

Три категории:

  • Изчакване + повторен опит: rate_limited, at_capacity, service_unavailable, upstream_error. Съобразявайте се с retryAfter, когато е наличен (подсказка от сървъра, в секунди). Използвайте експоненциално изчакване (exponential backoff) с джитер (jitter), когато липсва.
  • Без повторен опит, коригирайте входа: bad_request, auth_failed, not_found, ssrf_blocked.
  • Смяна на инструмента: forbidden при foura_single → ескалирайте към foura_proxy. Ако страницата изисква и JavaScript, използвайте foura_browser. Ако foura_browser върне forbidden, свържете първо с foura_proxy и подайте върнатото proxy ID в foura_browser.proxy.

Пример за повторен опит (TypeScript, от страна на 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");
}

Свързани теми

  • MCP Server, трите инструмента и техните схеми
  • MCP Recipes, workflow подкани (prompts), доставени със сървъра
  • API грешки, същата обвивка на базовия слой на REST API
Обновено: 1 юли 2026 г.