Грешки на MCP сървъра
Грешки на MCP Server
Как да обработвате грешки, върнати от foura-mcp server.
Всеки отговор за грешка от всеки от четирите инструмента (foura_auto, foura_single, foura_proxy, foura_browser) е структуриран. LLM агентите могат да четат полето code за логика на повторен опит, без да анализират свободен текст.
Формат на обграждащия обект
Всяка грешка (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 |
n/a | Целта е частен или резервиран адрес (RFC 5735, RFC 6598, IPv6 reserved), URL адресът не е http(s), или неговият host name не можа да бъде резолвнат | Не, проверете URL адреса. Търсене, което е неуспешно за кратко, може да бъде повторено |
upstream_non_json |
варира | Upstream върна тяло, което не е валиден JSON | Може би, разследвайте |
output_validation_failed |
n/a | outputSchema на MCP сървъра отхвърли отговора от upstream, или инструментът не успя да завърши извикването изобщо (няма конфигуриран API ключ, API е недостъпен) |
Може би: проверете конфигурацията, след това докладвайте |
bad_request |
400 | Форматът на входните данни беше отхвърлен от FourA API | Не, коригирайте аргументите |
auth_failed |
401 | FourA API ключът липсва, невалиден е или е деактивиран; това не се отнася за идентификационни данни на целевия сайт | Не, коригирайте FourA ключа |
forbidden |
403 | Целта отхвърли заявката (проверка на сайта, ограничение по държава) | Не, или превключете на foura_proxy |
not_found |
404 | Целевият URL или endpoint не съществува | Не |
rate_limited |
429 | Споделеният лимит за минута на платформата или 429 от целта, който вашият validate отхвърли. В foura_auto това може също да са кредити, трафик или rate limit на вашия план (вижте reason) |
Да, изчакайте retryAfter, когато е наличен, в противен случай изчакайте (back off) |
at_capacity |
503 | Достигнат е лимитът за едновременни заявки (current.concurrency > limits.maxConcurrency) |
Да, изчакайте retryAfter секунди |
service_disabled |
503 | Услугата е изключена за поддръжка. Инструмент, който планът ви не включва, се връща като plan_limit_feature |
Свържете се с поддръжката |
service_unavailable |
503 | Обща грешка 503 от upstream | Да, кратко изчакване (short backoff) |
upstream_error |
500+ или 0 | Целта отговори със сървърна грешка, или при foura_proxy, foura_browser и foura_auto така и не отговориха |
Да, експоненциално изчакване (exponential backoff) |
upstream_client_error |
4xx | Друг 4xx код, непокрит по-горе | Обикновено не |
upstream_unknown |
друго | Заявката се изпълни, но не върна приет отговор: при foura_single целта така и не отговори (timeout, отказана връзка), а при всеки друг инструмент вашият validate отхвърли 2xx или 3xx отговор. Прочетете status и error |
Разследвайте |
no_eligible_proxy |
n/a | Няма proxy, което да съответства на стриктния exitCountries allowlist; 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 exits |
Не, премахнете параметъра или сменете плана |
plan_limit_feature |
403 | Планът не съдържа този endpoint или тази възможност | Не, сменете плана |
Грешки на 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 | Извикване на инструмент или четене на ресурс без API key. Извеждането на инструменти и промптове работи без такъв | JSON-RPC грешка + WWW-Authenticate: Bearer realm="foura-mcp" |
| 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 | Request body > 256 KB | Express default 413 |
Списъците с разрешени адреси (allowlists) за 403 могат да се конфигурират чрез променливи на средата при self-hosting през FOURA_MCP_ALLOWED_HOSTS и FOURA_MCP_ALLOWED_ORIGINS.
Отказани браузърни профили
Браузърен профил, който каталогът не може да предостави, или профил, изпратен с unblocker, зададен на false, се връща като грешка от upstream със съответната причина в error, като заявката изобщо не напуска FourA. Съобщението посочва какво е налично, затова опитайте отново с някоя от изброените комбинации, вместо със същата.
Това са откази, а не сривове в системата: повторният опит с идентична заявка не може да успее, като друг браузър не е бил използван на нейно място.
Стратегия за повторни опити (retry)
Пет категории:
- Вашият собствен план го отказа, а не целевият сайт: всеки
plan_limit_*код. Същата задача през друг инструмент също ще бъде отказана, така че смяната на endpoint-и само губи време. ИзчакайтеretryAfter, когато има такъв; в противен случай планът трябва да се промени.plan_limit_premiumе грешката, която можете да изчистите сами, като премахнетеexitClass. - Изчакайте и опитайте отново:
rate_limited,at_capacity,service_unavailable,upstream_error. СпазвайтеretryAfter, когато е наличен. Използвайте експоненциално отлагане (exponential backoff) с вариация (jitter), когато липсва. Не реагирайте, като изпратите наново всички извиквания на инструменти наведнъж: вместо това намалете броя на паралелно изпълняваните. - Запазете обхвата и опитайте отново по-късно:
no_eligible_proxy. Не премахвайтеexitCountriesи не заменяйте държавата тихо с друга. Променяйте или разширявайте списъка с разрешени стойности само когато потребителят изрично промени изискването. - Не опитвайте отново, докато входните данни или идентификационните данни не бъдат коригирани:
bad_request,auth_failed,not_found,ssrf_blocked. Заauth_failedпроверете FourA API key, а не идентификационните данни за целевия сайт. - Сменете инструмента, когато съдържанието го изисква:
forbiddenприfoura_singleможе да оправдае ограниченfoura_proxyопит. Използвайтеfoura_browser, когато желаното съдържание изисква JavaScript. След успешно избиране на proxy подайте върнатияproxyID към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, същият envelope в базовия REST API слой
- Rate Limits, лимитите за акаунта и платформата зад
rate_limitedиat_capacity