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 选择成功后,将返回的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:4 个工具及其模式规范
- MCP Recipes:随服务器提供的完整工作流提示词
- API Errors:底层 REST API 层的相同响应封包
- Rate Limits:
rate_limited与at_capacity背后的账户及平台限制