Грешки на 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и подайте върнатото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, workflow подкани (prompts), доставени със сървъра
- API грешки, същата обвивка на базовия слой на REST API