Lỗi MCP Server

Cách xử lý các lỗi do foura-mcp server trả về.

Mỗi response lỗi từ bất kỳ công cụ nào trong ba công cụ (foura_single, foura_proxy, foura_browser) đều được cấu trúc. Các LLM agent có thể đọc trường code để thực hiện logic thử lại (retry) mà không cần phân tích cú pháp văn bản.

Cấu trúc envelope

Mỗi lỗi (isError: true) đều đi kèm một block structuredContent. Các trường tối thiểu trên mỗi lỗi:

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

Đối với các lỗi upstream có HTTP status, trường status cũng sẽ xuất hiện. Đối với các lỗi rate-limit và dung lượng (capacity), envelope sẽ bổ sung retryAfter, current.{concurrency, rpm}, và limits.{maxConcurrency, maxRpm}, cùng cấu trúc với các REST API errors bên dưới.

Các giá trị code ổn định

Code HTTP Ý nghĩa Thử lại an toàn?
ssrf_blocked n/a IP đích nằm trong dải riêng tư hoặc được bảo lưu (RFC 5735, RFC 6598, IPv6 bảo lưu) Không, hãy thay đổi URL
upstream_non_json thay đổi Upstream trả về body không phải là JSON hợp lệ Có thể, hãy kiểm tra
output_validation_failed n/a outputSchema của MCP server đã từ chối response từ upstream (lỗi server hoặc cấu trúc upstream không mong muốn) Có thể, hãy báo cáo
bad_request 400 Cấu trúc đầu vào bị từ chối bởi FourA API Không, hãy sửa các đối số
auth_failed 401 Key bị thiếu, không hợp lệ hoặc đã bị vô hiệu hóa Không, hãy sửa key
forbidden 403 Đích từ chối request (chống bot, chặn địa lý) Không, hoặc chuyển sang foura_proxy
not_found 404 URL hoặc endpoint đích không tồn tại Không
rate_limited 429 Đạt giới hạn RPM của mỗi key Có, đợi retryAfter giây
at_capacity 503 Đạt giới hạn concurrency (current.concurrency > limits.maxConcurrency) Có, đợi retryAfter giây
service_disabled 503 Dịch vụ bị vô hiệu hóa cho tài khoản của bạn (gói dịch vụ hoặc bảo trì) Liên hệ hỗ trợ
service_unavailable 503 Lỗi 503 chung từ upstream Có, backoff ngắn
upstream_error 500+ Lỗi 5xx từ upstream Có, exponential backoff
upstream_client_error 4xx Lỗi 4xx khác không được đề cập ở trên Thường là không
upstream_unknown khác Phòng thủ, không nên xảy ra trong thực tế Kiểm tra

Các lỗi cấp độ HTTP từ MCP server

Một số lỗi xảy ra ở tầng transport của MCP, trước khi bất kỳ công cụ nào được gọi. Những lỗi này trả về lỗi JSON-RPC thô (không có structuredContent):

HTTP Khi nào Những gì bạn thấy
400 Header MCP-Protocol-Version không được hỗ trợ Unsupported MCP-Protocol-Version: <value>. Supported: 2025-11-25, 2025-06-18, 2025-03-26, 2024-11-05, 2024-10-07.
401 Header Authorization bị thiếu hoặc sai định dạng JSON-RPC error + WWW-Authenticate: Bearer realm="foura-mcp", resource_metadata="https://foura.ai/docs/mcp/server#auth"
403 Header Origin hoặc Host không được phép (phòng thủ DNS-rebinding, CVE-2025-66414) Origin <value> is not in the allowlist hoặc Host <value> is not in the allowlist
405 GET hoặc DELETE trên /mcp (chế độ stateless) Method not allowed in stateless mode. Use POST /mcp.
413 Request body > 256 KB Lỗi 413 mặc định của Express

Các allowlist cho lỗi 403 có thể cấu hình qua biến môi trường cho những người tự host (self-host) thông qua FOURA_MCP_ALLOWED_HOSTSFOURA_MCP_ALLOWED_ORIGINS.

Chiến lược thử lại (retry)

Ba nhóm chính:

  • Chờ + thử lại: rate_limited, at_capacity, service_unavailable, upstream_error. Tuân thủ retryAfter khi có sẵn (gợi ý từ server, tính bằng giây). Sử dụng exponential backoff kèm jitter khi không có.
  • Không thử lại, sửa đầu vào: bad_request, auth_failed, not_found, ssrf_blocked.
  • Chuyển đổi công cụ: forbidden trên foura_single → chuyển tiếp lên foura_proxy. Nếu trang cũng cần JavaScript, sử dụng foura_browser. Nếu foura_browser báo lỗi forbidden, hãy kết hợp với foura_proxy trước và truyền ID proxy nhận được vào foura_browser.proxy.

Ví dụ thử lại (TypeScript, phía 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");
}

Tài liệu liên quan

  • MCP Server, ba công cụ và schema của chúng
  • MCP Recipes, các workflow prompt đi kèm với server
  • API Errors, cùng cấu trúc envelope ở tầng REST API bên dưới
Cập nhật: 1 tháng 7, 2026