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

Ошибки MCP Server

Как обрабатывать ошибки, возвращаемые foura-mcp server.

Каждый ответ с ошибкой от любого из четырех инструментов (foura_auto, foura_single, foura_proxy, foura_browser) является структурированным. LLM-агенты могут считывать поле code для логики повторных попыток без парсинга обычного текста.

Структура envelope

Каждая ошибка (isError: true) содержит блок structuredContent. Минимальный набор полей для каждой ошибки:

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

При ошибках upstream с HTTP-статусом также присутствует status. Если вызов отклоняется общей квотой платформы, конверт содержит retryAfter, current.{concurrency, rpm} и limits.{maxConcurrency, maxRpm} в том же формате, что и базовые ошибки REST API.

Когда вызов отклоняется из-за лимита вашего тарифного плана, кодом ошибки становится сам лимит: plan_limit_ с последующим credits, bandwidth, rate, concurrency, browser_daily, premium или feature. Поле retryAfter содержит время ожидания, если ожидание снимает ограничение, и отсутствует для лимитов, которые ожиданием не снимаются (например, недоступная в тарифе функция). plan_limit_browser_daily также не содержит retryAfter: сброс происходит в полночь по UTC.

На foura_auto лимит плана, достигнутый внутри очереди, возвращается как rate_limited или forbidden с кодом тарифа в reason.

Фиксированные значения code

Код HTTP Значение Можно повторять?
ssrf_blocked н/д Целевой адрес является приватным или зарезервированным (RFC 5735, RFC 6598, зарезервированные IPv6), URL не использует http(s), или имя хоста не удалось разрешить Нет, проверьте URL. Кратковременный сбой разрешения имени можно повторить
upstream_non_json разный Upstream вернул тело, которое не является валидным JSON Возможно, требуется анализ
output_validation_failed н/д outputSchema на стороне MCP server отклонил ответ upstream, или инструмент не смог выполнить вызов (не настроен API key, API недоступен) Возможно: проверьте настройки, затем отправьте отчет
bad_request 400 Формат входных данных отклонен FourA API Нет, исправьте аргументы
auth_failed 401 FourA API key отсутствует, недействителен или деактивирован; это не связано с учетными данными целевого сайта Нет, исправьте FourA key
forbidden 403 Целевой ресурс отклонил запрос (проверка сайта, ограничение по стране) Нет, или переключитесь на foura_proxy
not_found 404 Целевой URL или endpoint не существует Нет
rate_limited 429 Общий лимит платформы в минуту или 429 от целевого ресурса, отклоненный вашим validate. На foura_auto это также могут быть кредиты, трафик или rate limit вашего тарифа (см. reason) Да, подождите retryAfter при наличии, иначе используйте backoff
at_capacity 503 Достигнут лимит параллельных запросов (current.concurrency > limits.maxConcurrency) Да, подождите retryAfter секунд
service_disabled 503 Сервис отключен на обслуживание. Инструмент, не входящий в ваш тариф, возвращает plan_limit_feature Свяжитесь с поддержкой
service_unavailable 503 Общий 503 от upstream Да, короткий backoff
upstream_error 500+ или 0 Целевой ресурс вернул ошибку сервера, либо на foura_proxy, foura_browser и foura_auto не ответили Да, экспоненциальный backoff
upstream_client_error 4xx Другие 4xx, не указанные выше Обычно нет
upstream_unknown другое Запрос выполнен, но не дал принятого ответа: на foura_single целевой ресурс не ответил (таймаут, отказ в соединении), а в любом инструменте ваш validate отклонил ответ 2xx или 3xx. Смотрите status и error Требуется анализ
no_eligible_proxy н/д Ни один proxy не соответствует строгому списку разрешений exitCountries; details.exitCountries содержит нормализованный scope Повторите позже; меняйте scope только явно
plan_limit_credits 429 Ежемесячные кредиты вашего тарифа исчерпаны Да, после retryAfter, или смените тариф
plan_limit_bandwidth 429 Лимит трафика вашего тарифа исчерпан для этого расчетного периода Да, после retryAfter, или смените тариф
plan_limit_rate 429 Лимит запросов в минуту вашего тарифа для этого endpoint Да, после retryAfter
plan_limit_concurrency 429 Лимит параллельных запросов вашего тарифа для этого endpoint Да, после retryAfter
plan_limit_browser_daily 429 Дневной лимит Browser для вашего тарифа исчерпан Да, завтра, или используйте foura_single / foura_proxy
plan_limit_premium 403 Вы отправили exitClass: "premium" на тарифе, который не включает premium выходы Нет, уберите параметр или смените тариф
plan_limit_feature 403 Тариф не включает этот endpoint или эту возможность Нет, смените тариф

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

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

HTTP Когда Что вы видите
400 Неподдерживаемый заголовок 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 Вызов инструмента или чтение ресурса без ключа API. Получение списка инструментов и промптов работает без него Ошибка JSON-RPC + WWW-Authenticate: Bearer realm="foura-mcp"
403 Запрещенный заголовок 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 Тело запроса > 256 KB Стандартная 413 от Express

Разрешенные списки для 403 настраиваются через переменные окружения FOURA_MCP_ALLOWED_HOSTS и FOURA_MCP_ALLOWED_ORIGINS при самостоятельном хостинге.

Отклоненные профили браузера

Профиль браузера, который каталог не может предоставить, или профиль, переданный со значением false в unblocker, возвращается как сбой upstream с указанием причины в error, при этом запрос не покидает FourA. В сообщении перечислено, что доступно, поэтому повторите попытку с одной из указанных комбинаций вместо той же самой.

Это отказы, а не сбои в работе сервиса: повторение идентичного запроса не принесет успеха, и никакой другой браузер взамен использован не был.

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

Пять категорий:

  • Отказ со стороны вашего тарифного плана, а не целевого ресурса: любой код plan_limit_*. Та же операция через другой инструмент также будет отклонена, поэтому смена endpoint лишь тратит время. Дождитесь окончания retryAfter, если он есть; в противном случае необходимо изменить тарифный план. plan_limit_premium можно устранить самостоятельно, убрав exitClass.
  • Подождать и повторить попытку: rate_limited, at_capacity, service_unavailable, upstream_error. Учитывайте retryAfter при наличии. Используйте экспоненциальную задержку с джиттером (exponential backoff with jitter), если заголовок отсутствует. Не пытайтесь решить проблему одновременным повтором всех вызовов инструментов из очереди: вместо этого уменьшите количество параллельных запросов.
  • Сохранить область видимости и повторить позже: no_eligible_proxy. Не удаляйте exitCountries и не подменяйте страну скрытно. Изменяйте или расширяйте список разрешенных только тогда, когда пользователь явно меняет требования.
  • Не повторять попытку до исправления входных данных или учетных данных: bad_request, auth_failed, not_found, ssrf_blocked. Для auth_failed проверьте ключ API FourA, а не учетные данные целевого сайта.
  • Переключить инструмент, если этого требует контент: forbidden на foura_single может обосновать ограниченную попытку с foura_proxy. Используйте foura_browser, когда для получения нужного контента требуется JavaScript. После успешного выбора прокси передайте возвращенный 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: готовые промпты для воркфлоу, поставляемые с сервером
  • API Errors: тот же формат ответа на базовом уровне REST API
  • Rate Limits: лимиты аккаунта и платформы для rate_limited и at_capacity
Обновлено: 27 сентября 2026 г.