MCP 服务器

MCP Server

在任意 Model Context Protocol 客户端(Claude Desktop、Claude Code、Cursor、Windsurf、VS Code)中以 4 个原生工具和 6 个工作流 prompt 的形式使用 FourA。无需集成代码,无需自定义 HTTP 客户端。

已在 GitHub 开源;npm 包为 @fouradata/mcp。当前版本:0.7.3。

快速开始:本地 stdio(推荐用于 Claude Desktop)

在 foura.ai/dashboard#api-keys 获取 Key(一键生成,创建时仅显示一次,格式为 pk_live_...)。将其填入 MCP 客户端的配置中:

{
  "mcpServers": {
    "foura": {
      "command": "npx",
      "args": ["-y", "@fouradata/mcp"],
      "env": { "FOURA_API_KEY": "pk_live_..." }
    }
  }
}

Claude Desktop 注意事项:在编辑配置文件之前,请彻底退出 Claude Desktop(macOS 上使用 Cmd+Q)。如果应用仍在运行,它会在退出时用内存中的配置覆盖您的修改。

npx 命令会在首次启动时下载 @fouradata/mcp,并将其作为 MCP 客户端的子进程运行。无需全局安装。

客户端 配置文件位置
Claude Desktop (macOS) ~/Library/Application Support/Claude/claude_desktop_config.json
Claude Desktop (Windows) %APPDATA%\Claude\claude_desktop_config.json
Claude Code claude mcp add foura -- npx -y @fouradata/mcp(请先在环境中设置 FOURA_API_KEY)
Cursor ~/.cursor/mcp.json
Windsurf ~/.codeium/windsurf/mcp_config.json
VS Code (MCP 扩展) .vscode/mcp.json

重启客户端。工具(foura_auto、foura_single、foura_proxy、foura_browser)和六个 prompt 将显示在您的工具列表中。

快速开始:托管版 (Streamable HTTP)

对于支持 Streamable HTTP 传输的客户端(Cursor、Windsurf、VS Code 以及带有 --transport http 的 Claude Code),可直接指向托管 endpoint,而无需运行本地子进程:

{
  "mcpServers": {
    "foura": {
      "url": "https://mcp.foura.ai/mcp",
      "headers": {
        "Authorization": "Bearer pk_live_..."
      }
    }
  }
}

对于 Claude Desktop,请使用上方的 stdio 配置,或通过 mcp-remote 桥接托管 endpoint:

{
  "mcpServers": {
    "foura": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "https://mcp.foura.ai/mcp", "--header", "Authorization: Bearer pk_live_..."]
    }
  }
}

托管 endpoint 参考

属性 值
URL https://mcp.foura.ai/mcp
传输方式 可流式传输的 HTTP (POST /mcp, SSE 响应)
身份验证 每次请求需提供 Authorization: Bearer pk_live_...
MCP-Protocol-Version 遵循 @modelcontextprotocol/sdk (当前为 2025-11-25, 2025-06-18, 2025-03-26, 2024-11-05, 2024-10-07)
401 challenge WWW-Authenticate: Bearer realm="foura-mcp"

401 challenge 特意不包含 RFC 9728 resource_metadata 参数。声明该参数会使支持 OAuth 的客户端启动此服务器未实现的流程。将你的 pk_live_ 密钥作为 Bearer token 发送即可消除 401。

托管服务器是无状态的。每个请求自带密钥,服务器会将其作为 X-API-Key 转发至 FourA API。一个密钥可解锁全部四个工具。

为防范 DNS 重新绑定 (CVE-2025-66414),服务器会验证 Host 请求头 (必须为 mcp.foura.ai 或 localhost) 以及 Origin 请求头 (存在时,白名单:mcp.foura.ai, claude.ai, app.cursor.sh, app.cursor.com)。服务器间调用者 (curl, stdio 桥接模式下的 MCP 客户端) 不发送 Origin,直接通过。

工具

根据 MCP 2025-06-18 规范,所有四个工具均已标注 readOnlyHint: true 和 openWorldHint: true。自动批准受信任只读工具的客户端无需每次请求弹出确认框即可直接调用。

foura_auto 是智能默认项:传入 URL 即可返回内容,自动为你选择抓取方式。另外三个是其编排的底层原语,需要显式控制时可直接使用。

foura_auto

需要 FourA 自行选择请求方式时,传入 URL。它会在可用的 HTTP、proxy 和浏览器路径中进行有上限的尝试。在受保护的目标上传入 validate,以确保响应包含标识真实页面的内容。如果没有一次尝试满足验证条件,工具将返回错误,而不是将 challenge 页面作为成功结果返回。

响应在 meta 中包含完成详情,并在默认情况下提供包含 proxy、cookies 和 userAgent 的可复用 session。如需进行常规后续请求,调用 foura_single 时将 session.proxy 设置为 proxy,将 cookie 序列化为 Cookie 请求头,并将 session.userAgent 作为 User-Agent 请求头发送。如需 JavaScript 渲染,请将会话值传递给对应的 foura_browser 字段。

foura_single

单次 HTTP 请求并返回响应。与 POST /api/single/ 一一对应。

适用于静态页面、JSON API、服务端渲染的 HTML。

选择所模拟的浏览器

请求默认模拟最新的 Google Chrome。当目标站点接受某种浏览器而拒绝另一种时,设置 browser (Chrome, Edge, Safari, Firefox, 或 Tor)、os (Windows, macOS, Android, 或 iOS)、version,或者传入精确的 profile id:

{
  "method": "GET",
  "url": "https://example.com",
  "browser": "Firefox",
  "os": "Windows"
}

当多个配置匹配时,优先使用最新版本。不存在的组合会返回错误并列出可用项,因此绝不会使用您未选择的浏览器发送 request。选择功能需要 unblocker,该选项默认开启。目录发布在 GET /api/profiles,无需 API key。

相同的四个字段位于 foura_proxy 的 request 对象中。

foura_proxy

通过轮换 proxy 路由单个 HTTP request,并支持自动重试。当 foura_single 被阻止或目标需要特定出口国家时使用。

将 exitCountries 设置为由用户或目标需求提供的严格两位字母国家代码白名单:

{
  "maxTries": 5,
  "exitCountries": ["CZ", "GB"],
  "request": {
    "method": "GET",
    "url": "https://example.com/pricing",
    "browser": "Chrome",
    "os": "Windows"
  }
}

值会被去除首尾空格、转为大写并去重。出口未知的 proxy 会被排除,且 request 绝不会回退到未请求的国家。选择使用最新的目标可见国家元数据(通常在十分钟内更新),而非 request 期间的实时地理位置查询。请勿根据 proxy 主机地址推断服务国家。

指定范围的成功响应会返回 exitCountry 以及可复用的 proxy ID。请检查 exitCountry 是否属于请求的 allowlist。如果当前池中没有匹配项,工具将返回 code: "no_eligible_proxy",并在 details.exitCountries 中附带规范化的范围。请保留该范围并在稍后重试。仅在用户明确更改要求时才更改或放宽该范围。国家范围限定功能包含在 Startup 及以上方案中。在不包含该功能的方案中,发送 exitCountries 的调用会被拒绝,并返回 403 和 X-FourA-Limit: plan_limit_feature。

如果选定的页面后续需要 JavaScript,请将返回的 proxy ID 传递给 foura_browser.proxy,以便浏览器复用相同的出口。

针对标准池无论尝试多少出口都无法访问的目标,设置 exitClass: "premium"。这是一个许可,而非强制指令:标准池仍会竞速响应并通常获胜,在尝试任何 premium 出口之前由其响应的 request 不消耗 premium 流量。premium 尝试即使失败也会计入其承载的流量。响应会返回 exitClass(premium 或 standard),以便您查看每个 request 具体由哪个类别提供服务。当方案包含的 premium 流量用尽时,standard 也是返回的结果,这属于正常结果而非错误。exitClass: "standard" 会直接禁止升级。在没有 premium 出口的方案中设置 exitClass: "premium" 会被拒绝并返回 code: "plan_limit_premium"。请参阅 exitClass。

当轮换必须切换到另一个浏览器家族才能获取响应时,成功的响应会携带包含最终所选家族的 profile。请使用它重放,否则下一次调用将重复失败的版本。

失败的轮换会在错误旁携带 attemptReport:一个 summary 句子,以及分别统计从未响应的出口(noResponse)、Bot 验证拒绝的出口(defense,厂商见 vendors)、已送达但仅被您自己的 validate.data 拒绝的页面(contentRejected)、statusRejected 和 other 的计数。profilesTried 按首次使用顺序列出任务发送的浏览器,其中 default 表示 request 完全按原样发出。contentRejected 偏高意味着 FourA 交付了真实页面,但被您自己的规则丢弃了。请参阅 Why a Proxy Request Ran Out of Tries。

foura_browser

完整浏览器会话。JavaScript 会执行,DOM 会渲染,cookies 会返回。对应 POST /api/browser/。

适用于单页应用、懒加载内容,或包含需要真实浏览器才能完成的验证的页面。

关于各工具的输入结构、默认值和验证规则,请参阅 REST endpoint 参考。工具 schema 与 REST API 字段完全一致,外加仅限 MCP 的 offload_large 选项(见下文)。

当目标执行 Bot 检查时

当目标在返回 body 的过程中执行了 bot 检查时,foura_single 和 foura_proxy 会返回 defense。defense.solved: true 表示通过了检查且 data 是真实页面;false 表示 body 可能是质询页面。请使用不同的浏览器、操作系统或版本重试,或升级至 foura_proxy 或 foura_browser,而不是直接将质询页面作为内容处理。

类型化响应

每个工具的响应均包含 content(可读文本摘要)和 structuredContent(针对工具 outputSchema 验证过的类型化 JSON)。每个工具都有其独特的结构:

  • foura_auto: 单请求结构的 { status, headers, data },外加 meta({ rung, solved, attempts, credits },始终存在,其中 rung 为 cache、probe、proxy、browser、warmup、fail 之一),以及默认包含的 session({ proxy, cookies, userAgent }),用于通过更底层的工具进行重放。无 total_time。
  • foura_single: { status, headers, data, total_time, ... }(headers 是一个数组,每个重定向跳步对应一项)
  • foura_proxy: 与 single 相同,外加 { proxy, total };限定作用域的成功请求还会包含 exitCountry,指定了 class 的请求包含 exitClass,更改了浏览器家族的轮换包含 profile,失败则包含 attemptReport
  • foura_browser: 独立结构 { status, headers: object, body, cookies, userAgent }(注意: body 可能是字符串或对象,取决于 content-type)

每个工具还会根据 API 的响应 headers 报告该次调用的费用以及如何进行追踪:

  • credits - 本次调用消耗的积分。失败时也会显示,因为无论结果如何工作都已执行。我们仅对成功的调用计费,因此失败调用虽在此处显示积分,但不会扣除费用。
  • request_id - FourA 为该调用分配的 ID。在提交支持请求时请引用此 ID。
  • exitClass - 当由高级出口处理调用时为 premium。在 foura_single 和 foura_browser 上,当 proxy 重放了 foura_proxy 找到的出口时会发生这种情况。

如果 API 未报告任何内容,则各字段均会缺省,因此针对早期版本编写的客户端可以继续正常工作。相同的值记录在 Response Headers 中。

支持 structuredContent 的客户端可以直接将类型化对象传递给 LLM,而无需让其从文本中解析 JSON。

多值响应 Headers

多次出现的 Headers(Set-Cookie、Link、WWW-Authenticate)会以数组形式返回:

{
  "headers": [
    {
      "result": { "version": "HTTP/2", "code": 200, "reason": "" },
      "content-type": "text/html",
      "set-cookie": ["a=1; Path=/", "b=2; Path=/"]
    }
  ]
}

这对于在单次 response 中同时设置会话、追踪和许可 cookie 的网站(大多数电商网站)非常重要。

大响应处理:offload_large(默认:inline)

默认情况下(自 v0.2.0 起),无论大小如何,完整 response body 都会在 structuredContent 中内联返回。这在所有 MCP client 中均可开箱即用。

如果你的 client 支持 MCP resources/read 并且你希望在大型页面上节省 token,可以在每次 tool 调用时传递 offload_large: true。大于等于 50 KB 的 response 将写入磁盘,并作为 resource_link 返回,你的 client 仅在实际需要时才获取 body。在托管服务器上,缓存的 payload 会在 1 小时后过期。在私有实例上,系统不会自动删除存储的 payload:请自行从 payload 目录中清理超过一小时的文件。

{
  "method": "GET",
  "url": "https://en.wikipedia.org/wiki/Web_scraping",
  "offload_large": true
}
客户端 offload_large: true
Claude Desktop 暂不支持,保留默认 false
Claude Code, Cursor, Windsurf 已支持
VS Code MCP 扩展 已支持

租户隔离:每个 API key 拥有独立的命名空间 (sha256(apiKey)[:16])。只有存储 payload 的 key 才能回读该数据。跨租户读取返回 Payload not found,且不会泄露资源存在性。

内置 Prompt

六个工作流模板在任意 MCP 客户端中均可通过 /prompts 访问。每个模板接收命名参数,并返回编排一个或多个工具的模板化用户消息。

Prompt 参数 功能说明
smart_fetch url, 可选 must_contain, extract 自动抓取(选择方法,处理 Bot 防护),然后返回或提取内容
scrape_product_page url 浏览器抓取,然后提取商品标题、价格、图片、库存、SKU 为 JSON
extract_article url 单次请求带 proxy 回退,然后去除导航/广告并返回纯净文章 JSON
monitor_pricing url, 可选 target_price Proxy 抓取,提取当前价格并与目标价格比对
check_endpoint_health url, 可选 expected_text 严格验证单次请求,返回可达性与响应耗时
bulk_fetch_urls urls(逗号分隔) 并行单次请求,按 URL 自动回退至 proxy,仅返回元数据

Prompt 在空闲时不消耗 token。只有被调用的 Prompt 才会进入 LLM 上下文。

完整文本及手动回退 Prompt:MCP 配方。

错误封装格式

每个错误 (isError: true) 都包含一个 structuredContent 封装对象。每个错误的最小字段集如下:

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

发生带有 HTTP 状态的上游错误时,status 也会存在。发生 rate-limit 和容量错误时,上游封包会添加 retryAfter、current.{concurrency, rpm} 和 limits.{maxConcurrency, maxRpm}。有关底层 REST 结构,请参阅 API Errors。

稳定的 code 值:

错误代码 HTTP 含义 是否可重试?
ssrf_blocked 不适用 目标是私有或保留地址(RFC 5735、6598、IPv6 保留地址),URL 不是 http(s),或其主机名无法解析 否,请检查 URL。短暂失败的解析可以重试
upstream_non_json 视情况而定 上游返回了格式错误的响应体 可能可以,请排查原因
output_validation_failed 不适用 MCP 服务器的 outputSchema 拒绝了上游响应,或者工具根本无法完成调用(未配置 API key,API 无法访问) 可能可以:请检查配置,然后上报
bad_request 400 输入格式被拒绝 否,请修复参数
auth_failed 401 Key 缺失、无效或已停用 否,请修复 key
forbidden 403 目标返回了 403,并且您的 validate 拒绝了它(站点检查、国家/地区限制) 否,或者切换到 foura_proxy
not_found 404 目标或 endpoint 不存在 否
rate_limited 429 达到 RPM 上限 是,请等待 retryAfter
at_capacity 503 达到并发上限 是,请等待 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 其他 request 已执行但未生成可接受的应答:在 foura_single 上目标从未应答(超时、拒绝连接),而在任何工具上您的 validate 拒绝了 2xx 或 3xx 响应。请查看 status 和 error 请排查原因
no_eligible_proxy 不适用 没有符合严格 exitCountries 范围的 proxy 稍后重试;仅在明确需要时更改范围
plan_limit_* 403 或 429 您的套餐限额之一拒绝了调用:plan_limit_ 后跟 feature、premium、concurrency、rate、browser_daily、credits 或 bandwidth。请参阅 MCP Server Errors 存在 retryAfter 时请等待;否则直到限额重置或套餐变更前都不可重试

LLM agent 可以直接读取 code 以执行重试逻辑,无需解析文本说明。认证操作指引:Authentication。

Limits

  • 默认使用内联 body。启用 offload_large: true 时,>= 50 KB 的 response 将写入磁盘并返回 resource_link (按租户隔离,1 小时 TTL)。
  • 私有目标地址会在 MCP 层被拒绝 (RFC 5735、RFC 6598、IPv6 保留网段)。仅转发公共 host。
  • 传入 /mcp request 的 request body 大小上限为 256 KB (实际 MCP 载荷 < 4 KB)。
  • rate limit 由 FourA API 按服务强制执行。请参见 Rate Limits。

Self-Hosting

完整的服务端源码已在 GitHub 上以 @fouradata/mcp 开源。克隆仓库,运行 npm install、npm run build,并执行 node dist/http.js 即可启动自有实例。可在任意负载均衡器后以单个无状态容器运行。

可配置的环境变量:

Variable Default Purpose
PORT 3076 HTTP 监听端口
FOURA_API_BASE https://api.foura.ai/api 上游 FourA REST 基础 URL
FOURA_MCP_PAYLOADS_DIR 系统临时目录中的 foura-mcp-payloads 文件夹 (自带的 Docker Compose 文件设置为 /data/payloads) >= 50 KB response 的磁盘缓存位置 (搭配 offload_large: true)
FOURA_MCP_ALLOWED_HOSTS mcp.foura.ai,localhost,127.0.0.1,[::1] Host header 的主机名白名单 (DNS 重绑定防御)
FOURA_MCP_ALLOWED_ORIGINS https://mcp.foura.ai,https://claude.ai,https://app.cursor.sh,https://app.cursor.com 浏览器调用方的 Origin 白名单

官方容器以 uid 1001 (非 root) 运行。/data/payloads 主机绑定挂载目录必须对该 UID 可写。

可在任意负载均衡器后进行水平扩展。客户端在每次 request 中提供其 key,因此无需粘性会话。

更新于: 2026年9月27日