Ошибки MCP-сервера

Как обрабатывать ошибки, возвращаемые 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 варьируется Вышестоящий сервер вернул тело, не являющееся валидным JSON Возможно, требуется анализ
output_validation_failed n/a Схема outputSchema MCP-сервера отклонила ответ вышестоящего сервера (баг сервера или неожиданный формат ответа) Возможно, сообщите об ошибке
bad_request 400 Формат входных данных отклонен FourA API Нет, исправьте аргументы
auth_failed 401 Ключ отсутствует, недействителен или деактивирован Нет, исправьте ключ
forbidden 403 Целевой ресурс отклонил запрос (антибот, геоблокировка) Нет, или переключитесь на 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_error 500+ Ошибка 5xx вышестоящего сервера Да, с экспоненциальной задержкой
upstream_client_error 4xx Другие ошибки 4xx, не описанные выше Обычно нет
upstream_unknown другое Резервный код, на практике возникать не должен Требуется анализ

Ошибки HTTP-уровня от MCP-сервера

Некоторые сбои происходят на транспортном уровне MCP до вызова какого-либо инструмента. В этих случаях возвращаются необработанные ошибки JSON-RPC (без structuredContent):

HTTP Когда Что вы видите
400 Неподдерживаемый header MCP-Protocol-Version Unsupported MCP-Protocol-Version: <value>. Supported: 2025-11-25, 2025-06-18, 2025-03-26, 2024-11-05, 2024-10-07.
401 Отсутствующий или некорректный header Authorization JSON-RPC ошибка + WWW-Authenticate: Bearer realm="foura-mcp", resource_metadata="https://foura.ai/docs/mcp/server#auth"
403 Запрещенный header Origin или Host (защита от 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 Тело request > 256 КБ Стандартная ошибка 413 от Express

Разрешенные списки (allowlists) для ошибки 403 могут быть настроены через переменные окружения для self-host решений с помощью FOURA_MCP_ALLOWED_HOSTS и FOURA_MCP_ALLOWED_ORIGINS.

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

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

  • Ожидание и повтор: rate_limited, at_capacity, service_unavailable, upstream_error. Учитывайте значение retryAfter, если оно указано (подсказка сервера в секундах). В противном случае используйте экспоненциальную задержку со случайным отклонением (jitter).
  • Без повтора, исправьте входные данные: bad_request, auth_failed, not_found, ssrf_blocked.
  • Смена инструмента: forbidden в foura_single (переключитесь на foura_proxy). Если для страницы также требуется JavaScript, используйте foura_browser. Если foura_browser возвращает forbidden, сначала выполните цепочку с foura_proxy и передайте полученный ID proxy в 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, шаблоны рабочих процессов (prompts), поставляемые с сервером
  • API Errors, аналогичная структура на уровне базового REST API
Обновлено: 1 июля 2026 г.