MCP Server Errors

MCP Server 错误

如何处理 foura-mcp server 返回的错误。

这四个工具 (foura_auto, foura_single, foura_proxy, foura_browser) 的每个错误响应都是结构化的。LLM agent 可以读取 code 字段来执行重试逻辑,而无需解析自然语言文本。

Envelope 结构

每个错误 (isError: true) 都包含一个 structuredContent 块。每个错误包含的最少字段:

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

出现带 HTTP 状态的上游错误时,也会提供 status。对于速率限制和容量错误,封装中会添加 retryAftercurrent.{concurrency, rpm}limits.{maxConcurrency, maxRpm},结构与底层的 REST API 错误相同。

稳定的 code

代码 HTTP 含义 可安全重试?
ssrf_blocked n/a 目标 IP 位于私有或保留范围内(RFC 5735,RFC 6598,IPv6 保留) 否,请更改 URL
upstream_non_json 不一 上游返回的正文不是有效的 JSON 可能,需调查
output_validation_failed n/a MCP 服务器的 outputSchema 拒绝了上游响应(服务器错误或非预期的上游结构) 可能,请报告
bad_request 400 输入结构被 FourA API 拒绝 否,请修复参数
auth_failed 401 FourA API 密钥缺失、无效或已停用;这与目标站点的凭据无关 否,请修复 FourA 密钥
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 其他 防御性,在实践中不应发生 需调查
no_eligible_proxy n/a 没有 proxy 匹配严格的 exitCountries 允许列表;details.exitCountries 包含标准化范围 稍后重试;仅可显式更改范围

来自 MCP 服务器的 HTTP 级别错误

某些故障发生在 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 不允许的 OriginHost header(DNS 重新绑定防御,CVE-2025-66414) Origin <value> is not in the allowlistHost <value> is not in the allowlist
405 /mcp 上的 GETDELETE(无状态模式) Method not allowed in stateless mode. Use POST /mcp.
413 Request body > 256 KB Express 默认 413

自托管者可以通过 FOURA_MCP_ALLOWED_HOSTSFOURA_MCP_ALLOWED_ORIGINS 对 403 的允许列表进行环境变量配置。

拒绝的浏览器配置文件

如果 catalogue 无法提供某个浏览器配置文件,或者发送配置文件的 unblocker 设置为 false,则会作为 upstream 故障返回,原因包含在 error 中,并且 request 永远不会离开 FourA。该消息会列出可用的选项,因此请使用列出的组合之一重试,而不是使用相同的组合。

这些是拒绝,而不是中断:重试完全相同的 request 无法成功,并且没有使用其他浏览器代替。

重试策略

分为四类:

  • 等待并重试rate_limited, at_capacity, service_unavailable, upstream_error。存在时遵循 retryAfter。不存在时使用带抖动的指数退避算法。
  • 保留作用域并稍后重试no_eligible_proxy。不要静默移除 exitCountries 或替换为另一个国家。仅当用户明确更改要求时,才更改或放宽 allowlist。
  • 在修复输入或凭据之前不要重试bad_request, auth_failed, not_found, ssrf_blocked。对于 auth_failed,请验证 FourA API 密钥,而不是目标站点的凭据。
  • 根据内容需求切换工具foura_single 上的 forbidden 可以作为进行有界 foura_proxy 尝试的理由。当所需内容需要 JavaScript 时,请使用 foura_browser。成功选择 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");
}

相关

更新于: 2026年8月6日