MCP Server Errors

MCP Server 错误

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

来自四个工具(foura_auto、foura_single、foura_proxy、foura_browser)中的每个错误 response 均采用结构化格式。LLM agent 可直接读取 code 字段以实现重试逻辑,无需解析文本。

Envelope 结构

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

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

在带有 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 保留地址),URL 不是 http(s),或其主机名无法解析 否,请检查 URL。短暂失败的解析可以重试
upstream_non_json 各异 上游返回了非有效 JSON 的响应体 可能可以,请排查原因
output_validation_failed n/a MCP 服务器的 outputSchema 拒绝了上游响应,或者工具根本无法完成调用(未配置 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 上,也可能是套餐的积分、流量或速率限制(参见 reason) 是,存在 retryAfter 时请等待该时长,否则执行退避重试
at_capacity 503 达到并发上限(current.concurrency > limits.maxConcurrency) 是,等待 retryAfter 秒
service_disabled 503 服务因维护而关闭。套餐中未包含的工具会返回 plan_limit_feature 请联系支持团队
service_unavailable 503 来自上游的通用 503 是,短暂退避后重试
upstream_error 500+ 或 0 目标返回了服务器错误,或者在 foura_proxy 上,foura_browser 和 foura_auto 从未响应 是,指数退避重试
upstream_client_error 4xx 上述未涵盖的其他 4xx 错误 通常不可重试
upstream_unknown 其他 请求已执行但未产生被接受的响应:在 foura_single 上目标从未响应(超时、连接被拒绝),以及在任何工具上您的 validate 拒绝了 2xx 或 3xx 响应。请查阅 status 和 error 请排查原因
no_eligible_proxy n/a 没有 proxy 符合严格的 exitCountries 允许列表;details.exitCountries 包含规范化后的范围 稍后重试;仅在明确需要时更改范围
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" 否,移除该参数或更改套餐
plan_limit_feature 403 套餐不包含该 endpoint 或该功能 否,更改套餐

来自 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 无 API key 调用工具或读取资源。列出工具和 prompt 在没有 key 的情况下可用 JSON-RPC 错误 + WWW-Authenticate: Bearer realm="foura-mcp"
403 未被允许的 Origin 或 Host header(DNS 重新绑定防御,CVE-2025-66414) Origin <value> is not in the allowlist 或 Host <value> is not in the allowlist
405 在 /mcp(无状态模式)上使用 GET 或 DELETE Method not allowed in stateless mode. Use POST /mcp.
413 request body > 256 KB Express 默认 413

403 的白名单可供自托管用户通过环境变量 FOURA_MCP_ALLOWED_HOSTS 和 FOURA_MCP_ALLOWED_ORIGINS 进行配置。

拒绝的浏览器 profile

目录中无法提供的浏览器 profile,或将 unblocker 设置为 false 发送的 profile,会作为上游故障返回并在 error 中指明原因,request 绝不会离开 FourA。错误消息中会列出可用项,因此请改用列出的组合之一重试,而非使用相同的组合。

这些属于拒绝而非服务中断:重试完全相同的 request 无法成功,且系统未替换使用任何其他浏览器。

重试策略

分为五类:

  • 被你自己的计划拒绝,而非目标站点:任何 plan_limit_* 状态码。通过其他工具执行相同的操作也会被拒绝,因此切换 endpoint 只会浪费时间。如果存在 retryAfter,请等待其超时;否则必须修改计划。plan_limit_premium 是唯一可自行解决的错误,只需移除 exitClass 即可。
  • 等待并重试:rate_limited、at_capacity、service_unavailable、upstream_error。若存在 retryAfter,请遵循其要求。若不存在,请使用带抖动的指数退避。切勿通过一次性重新发起所有排队的工具调用来响应,而应减少并发运行的数量。
  • 保留作用域并稍后重试:no_eligible_proxy。请勿移除 exitCountries 或静默替换为其他国家。仅当用户明确更改需求时,才修改或放宽白名单。
  • 在修复输入或凭据前不要重试:bad_request、auth_failed、not_found、ssrf_blocked。对于 auth_failed,请验证 FourA API key,而非目标站点的凭据。
  • 内容需要时切换工具: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");
}

相关内容

  • MCP Server:4 个工具及其模式规范
  • MCP Recipes:随服务器提供的完整工作流提示词
  • API Errors:底层 REST API 层的相同响应封包
  • Rate Limits:rate_limited 与 at_capacity 背后的账户及平台限制
更新于: 2026年9月27日