跳到正文

CrawlForge Team工程团队

阅读时长 12 分钟

CrawlForge v5.0.0:安全性、正确性与 MCP 规范

CrawlForge MCP Server v5.0.0 已经发布。这是我们发布过的最大版本,而其中几乎没有新功能。

相反,v5.0.0 汇集了一项由完整内部代码审计推动的七阶段整改计划:每一个 SSRF 漏洞、每一个悄悄返回错误结果的工具、每一处泄漏的定时器和浏览器上下文、那个始终只支持单会话的 HTTP 传输层、每一个已停止维护的依赖,以及我们尚未采用的 MCP 规范特性。单元测试套件从 480 个测试增加到 914 个。npm audit 从 16 个漏洞降到 0 个。

只有 一处破坏性变更:Node 最低版本从 >=18.0.0 提高到 >=20.16.0。如果你使用 Node 20 或更高版本,升级只需一行命令。

目录

v5.0.0 包含哪些内容

阶段主题核心成果
0依赖更新npm audit 从 16 个漏洞降到 4 个中危,零代码改动
1关键安全SSRF IP 字面量绕过、OAuth 令牌签发、密钥泄露、计费正确性
2正确性52 项修复 — 包括让真实抓取重新可用的 crawl_deep 重写
3泄漏与超时24 项修复 — 浏览器上下文、无界缓存、每次响应体读取的截止时间
4HTTP 传输层19 项修复 — 多会话流式 HTTP、可用的 prompts、webhook HMAC
5依赖现代化Node ≥ 20 最低版本,npm audit 0 漏洞
6采用 MCP 规范结构化输出、异步任务、工具白名单、注册表 server.json

整个计划的测试覆盖:480 → 914 个单元测试,且在每个阶段关卡上 MCP 协议合规性始终保持 100.0% COMPLIANT,0 错误。

唯一的破坏性变更:Node 20

engines.node 从 >=18.0.0 提高到 >=20.16.0。

Node 18 已于 2025 年 4 月结束生命周期,而 20.16 是 pdf-parse 2.4.5 所要求的最低版本 —— 那是我们清除最后一批审计问题所需要的、仍在维护的 ESM 重写版本。我们的 Dockerfile(node:20-alpine)和 CI(Node 22)本来就满足这一要求,所以那里没有任何改动。如果你仍在使用 Node 18,现在安装时会看到 engines 警告。

破坏性影响仅此而已。对现有调用方而言,没有任何工具 schema、输出结构或 credits 成本发生变化。

第 1 阶段:我们封堵的安全漏洞

如果你在私有网络附近运行 CrawlForge,这一阶段值得仔细阅读。

SSRF IP 字面量绕过是其中最关键的一个。 我们的防护会解析主机名并检查得到的地址,但从不对主机本身已经是 IP 字面量的 URL 执行同样的检查。http://127.0.0.1/、十进制形式 2130706433、十六进制形式 0x7f000001 —— WHATWG URL 解析器会把这些全部规范化,而 Node 从不将 IP 字面量交给 lookup 处理,因此它们畅通无阻。v5.0.0 在预检阶段对 IP 字面量主机名执行 ipBlocked(),并且 用逐次连接检查包装了 undici dispatcher 的 buildConnector,因此直接跳转到内部地址的重定向同样会被阻断。

与之一同交付的还有另外三项防护修复:

  • 识别 IPv4 映射的 IPv6。 ::ffff:127.0.0.1 和 ::ffff:169.254.169.254 现在会在范围检查之前被规范化为其内嵌的 IPv4,在默认模式和 SSRF_STRICT 模式下都是如此。这消除了由 DNS 控制的 AAAA 记录绕过。
  • BLOCKED_DOMAINS 不再是死配置。 config.security.ssrfProtection.blockedDomains 此前只是声明了却无人读取。现在它会在预检阶段生效。
  • 白名单按每一跳评估。 此前,被允许的第一跳会让后续所有跳转都失去防护。

我们还把防护接入了五条此前完全没有防护的路径:scrape_with_actions(并在导航后重新检查 page.url(),若重定向落入被阻断范围则关闭页面,从而封堵 Playwright 的内网读取原语)、map_site、process_document 的 PDF 下载、webhook 投递与健康检查,以及 deep_research 的 webhook 通知。

除 SSRF 之外:

  • OAuth。 /oauth/authorize 现在要求先证明持有运营方的 API key 才会签发授权码,并使用常数时间摘要比较。此前那条匿名的「注册 → 授权 → 令牌」流程会签发由运营方计费的 bearer 令牌,现已封堵。
  • 密钥泄露。 用量遥测现在会先让工具参数通过 maskSecrets() 处理,再让载荷离开进程 —— 第三方 API key、认证头和 webhook 签名密钥不再以明文外传。deep_research 也不再把 LLM API key 写入 Winston 文件日志。
  • 计费。 如果 credits 检查本身抛出异常,现在计费为 零 —— 错误路径上的半额扣费只在处理器真正开始执行之后才适用。checkCredits 现在会区分 401/403(key 无效或已吊销)与 5xx(宽限窗口),而不是把两者都报告为「credits 不足」。

第 2 阶段:工具悄悄出错的 52 种方式

第 2 阶段针对的是「通过了冒烟测试却返回误导性结果」这一类问题。重点如下:

crawl_deep 重新可用于真实抓取。 BFS 的子页面此前是在一个已被占用的队列槽内部等待的,这意味着每个任务的队列超时限制的是整个递归抓取,而不是单个页面。任何超过 30 秒 CRAWL_TIMEOUT 的抓取都会把已经取回的每一个页面连同一句干巴巴的 Promise timed out 一起丢弃,而低并发设置(包括 concurrency: 1)则会直接死锁。两个问题都已修复。

其余修复的代表性样本:

  • 与请求相矛盾的缓存键。 crawl_deep 的结果缓存键现在涵盖 extract_content、内容长度、包含/排除模式、follow_external、respect_robots、concurrency、域名过滤器和会话。map_site 的缓存键涵盖 search、域名过滤器、include_metadata 和 group_by_path。此前,一次缓存命中可能在长达一小时的 TTL 内一直与你的参数相矛盾。
  • 字符编码。 响应体现在会按其声明的字符集解码(Content-Type 头或 <meta charset> 嗅探),而不是一律当作 UTF-8。ISO-8859-1 或 Shift_JIS 站点上那种被 U+FFFD 污染的文本不会再出现。
  • 被悄悄丢弃的选项。 extract_content、summarize_content 和 analyze_content 的 options schema 现在使用 .passthrough()。此前每一个已写入文档的选项键在到达处理器之前就被剥离了 —— 这也正是 summarize_content 始终返回同一段被错误标记为 extractive 的两句话兜底内容的原因。抽取式摘要器现在会真正运行,而 summaryLength 也会改变输出。
  • 链接解析。 extract_links 现在基于页面的最终 URL 而非源站来解析相对 href,会遵循 <base href>,并将协议相对链接归类为外部链接。同样的修复也进入了 scrape 的链接提取器,因此两者终于一致。
  • track_changes 的相似度。 内容相似度现在是基于内容的 token Jaccard 相似度。此前用的是 sha256 十六进制摘要之间的汉明距离 —— 这意味着任何细微改动的相似度都约等于 0%,并会触发「中等」变更告警。
  • search_web 的评分。 部分指定的 ranking_weights 现在会与默认值深度合并,而不是整体替换,因此不会再出现 NaN 的最终得分或被悄悄禁用的重复检查。零结果时的扩展重试被限制为一次兜底,而不是最多五次计费的后端搜索。

第 3 阶段:可以连续运行数天

第 3 阶段封闭了 24 个只会在长时间运行的进程中暴露出来的问题。

浏览器生命周期。 关闭 Playwright 页面并不会关闭它的上下文 —— 因此每一次 scrape_with_actions 调用、每一次基于浏览器渲染的 extract_content 都会泄漏一个上下文直到进程关闭。非 stealth 上下文现在会与其页面一并关闭。失败的 page.goto(DNS 错误、超时、被阻断的 URL)此前会同时遗留一个存活的页面和上下文;现在两者都会被拆除。

有界缓存。 crawl_deep 现在会在 finally 中销毁其每次抓取的 CacheManager。此前,N 次抓取会永久泄漏 N 个缓存,每个缓存最多容纳 1000 份完整 HTML 文档,而且每一个都会永远每隔 60 秒重新执行一次 JSON.stringify 内存扫描。被丢弃的实例现在通过 WeakRef 回归测试进行 GC 验证。batch_scrape 的结果获得了 20 个批次的 LRU 上限以及 TTL 淘汰。

每次响应体读取都有截止时间。 中止定时器现在会在响应体流式传输期间保持激活,因此 timeout 参数终于覆盖了「先返回响应头、随后卡住响应体」的服务器。分块重组改为单次遍历 —— 此前是 O(n²),在 25 MB 的响应体上约有 1.5 秒的同步事件循环阻塞。PDF 下载获得了真正的 30 秒 AbortSignal.timeout(旧的 fetch-init timeout: 选项被 undici 悄悄忽略),SearXNG 提供方获得了 15 秒,而不是 undici 默认的约 5 分钟。

对 Claude Desktop 用户尤其值得一提的一项修复: 快照存储现在默认使用 ~/.crawlforge/snapshots,而不是 process.cwd()。像 Claude Desktop 这样的 MCP 客户端会以 / 作为工作目录启动服务器,而在那里每一次快照写入都会悄无声息地失败。

第 4 阶段:远程与 HTTP 部署终于可用

如果你曾通过 npm run start:http 部署 CrawlForge,情况比你以为的更糟:单一共享传输层意味着自始至终只存在一个会话,而任何一次正常断开都会让 /mcp 瘫痪,直到你重启进程。

有状态模式现在遵循 SDK 文档化的按会话模式 —— 一个 Map<sessionId, {transport, server}>,每次 initialize 都创建全新的传输层和克隆的 McpServer,在 DELETE 时释放,并对未知会话 ID 返回 JSON-RPC 404。第二个并发客户端、网络中断后的重连,以及 DELETE 后重新 initialize,现在都能正常工作。

第 4 阶段还包括:

  • getting-started prompt 此前 对任何客户端都无法获取 —— 配置对象命中了 SDK 的位置参数 argsSchema 重载,导致它声明了一个并不存在的必填参数,并让每一次 prompts/get 都失败。现已修复,且合规套件现在覆盖全部 6 个已注册 prompt 的发现与获取。
  • webhook 的 HMAC 签名现在覆盖实际 POST 出去的那份序列化载荷。 此前只对 data 子对象签名,因此接收方基于原始载荷的标准验证每一次都会失败。
  • scrape 不再把数 MB 的 base64 截图字节内联进 JSON 工具结果 —— 图片存储后,结果只保留元数据和 crawlforge://screenshot/{id} 资源 URI。
  • 自动安装的状态横幅从 stdout 移到了 stderr,因此在设置了 CRAWLFORGE_API_KEY 的情况下首次启动,不会再向 stdio 的 JSON-RPC 通道注入非 JSON 行。
  • 当 CRAWLFORGE_API_KEY 缺失时,search_web 会回退到 ~/.crawlforge/config.json 中的 API key。此前通过 npm run setup 配置的用户会通过 credits 检查,然后必定撞上适配器失败 —— 每次调用还要被扣掉一半、即 2 个 credits。

第 5 阶段:npm audit 零漏洞

在确立 Node 20 最低版本之后,第 5 阶段淘汰了所有已停止维护的依赖,并采纳了此前因旧版本下限而无法进行的安全升级。npm audit 从 4 个中危降到 0。

被彻底移除的有:node-cron(自第 3 阶段将变更监控调度改为 setInterval 定时器后便无人使用;移除它顺带清除了其存在漏洞的 uuid 依赖链)、@googleapis/customsearch(无人使用 —— Google 适配器直接调用 REST 端点),以及 node-summarizer(自 2019 年起已停止维护;抽取式摘要器被重写为基于 compromise 的 Luhn 式词频打分器,结果结构完全不变)。

其中最重要的升级:pdf-parse 1.1.1 → 2.4.5。PDFProcessor 被移植到 v2 的类式 API,这意味着 password 选项现在会真正解密受保护的 PDF —— v1 只是悄悄忽略它。按页范围提取现在使用 v2 原生的部分文本提取,而加密元数据标志读取的是 pdfjs-dist 真实的 EncryptFilterName。

关于供应链: 这一阶段恰逢 ChainDrop npm 蠕虫活跃期(自 2026 年 8 月 4 日起)。所有安装都使用 --ignore-scripts 执行,所有采纳的版本都按发布日期限定在 2026 年 8 月 4 日之前,完整的 lockfile 差异也与 Socket 和 StepSecurity 的受污染包列表做了交叉核对,无一命中。IoC 扫描在前后均为干净。

第 6 阶段:采用 MCP 规范

最后一个阶段让 CrawlForge 跟上了当前的 MCP 规范。

结构化输出(MCP 2025-06-18)。 scrape、map_site、serp_rank、search_web、extract_structured 和 crawl_deep 现在都声明了 outputSchema,并在原有的 JSON 文本之外返回 structuredContent。这些 schema 在设计上是宽松的,因此合法结果绝不会导致 SDK 输出校验失败。

异步任务。 crawl_deep、batch_scrape、deep_research 和 agent 以 taskSupport: 'optional' 注册在 io.modelcontextprotocol/tasks 扩展之下。支持任务的客户端会立即拿到一个句柄并轮询 tasks/get;不支持任务的客户端仍会像以前一样拿到同步结果。这正是长时间抓取在客户端工具调用窗口内超时问题的解法。

客户端侧工具选择。 两个新的环境变量让你只暴露 27 个工具中的一个子集,从而减少上下文膨胀:

Bash
# By name
CRAWLFORGE_TOOLS=scrape,search_web,extract_content

# Or by group — 12 available: basic, search, crawl, extract, batch,
# research, tracking, llmstxt, stealth, templates, scrape, agent
CRAWLFORGE_TOOL_GROUPS=search,extract

不设置即表示启用全部工具。未知名称会被忽略并在 stderr 上给出警告,batch_scrape 会自动启用 get_batch_results,启动横幅则会报告在总数中启用了多少个。

协议规范性。 工具 schema 现在以 JSON Schema 2020-12 而非 draft-07 对外声明。tools/list 采用确定性排序,以保证客户端 prompt 缓存的稳定性。非法的工具参数现在会以 isError: true 的工具结果返回 —— 调用方模型可以据此自我纠正 —— 而不是 -32602 协议错误。图标现在随 serverInfo、每个工具和每个 prompt 一并提供。

MCP 注册表。 server.json 已按 2025 年 12 月 11 日的注册表 schema 补全,并配有 GitHub OIDC 发布流程,会在下一个版本发布时推送到 registry.modelcontextprotocol.io。

自 v4.8.0 以来的新增:serp_rank 与工具引导

如果你上一次升级停留在 v4.8.0,中间还有两个较小的版本。

v4.9.0 新增了 serp_rank,即 第 27 个工具 —— 通过 DataForSEO 获取真实的 Google 自然排名位置,每次已配置的查询计 5 个 credits。v4.10.0 让它在返回目标域名排名位置的同时,也返回完整的前十条自然搜索结果列表。

v4.10.0 还新增了 服务器级别的 MCP instructions。服务器现在会告知任何连接进来的客户端,在网页搜索、抓取、爬取和研究方面优先使用 CrawlForge 工具,而非其自带的网页能力。由于这段说明随服务器二进制文件一起分发,所有 MCP 客户端都会在升级后的下一次启动时自动获取,无需重新执行 init。这是引导而非强制:MCP server 无法禁用客户端自带的工具。

价格:27 个计量工具,保持不变

v5.0.0 没有任何价格变动。全部 27 个工具 都是计量的并需要 API key,每次调用计 1 到 10 个 credits。

方案价格Credits
Free一次性(无需银行卡)1,000 试用 credits
Hobby$19/月5,000
Professional$99/月50,000
Business$399/月250,000

所有方案都包含全部工具。LLM 提取默认使用本地 Ollama,因此除非你主动选择,否则不需要 OpenAI 或 Anthropic 的 key。

如何升级

先检查你的 Node 版本 —— 这是唯一可能让你踩坑的地方:

Bash
node --version   # must be >= 20.16.0

然后:

Bash
npm install -g crawlforge-mcp-server@latest

新用户:

Bash
npm install -g crawlforge-mcp-server
npx crawlforge init

已在使用 MCP 客户端的用户也可以直接触发一次 /mcp 重连。由于第 2 阶段修复的是工具行为而非工具 schema,你现有的调用会继续工作 —— 只是现在会返回正确的结果。

接下来的计划

第 6 阶段的若干方向被有意推迟而非仓促上马:带 OAuth 的托管远程端点、无需 key 的层级、作为服务的定时监控、持久会话,以及 PII 脱敏。SDK v2 迁移则排在 Node 22 最低版本决策之后。

在此期间,v4.8.0 时的邀请依然有效。如果你发现某个控制项的行为与文档所述不符,那正是我们最想知道的 bug。


想试试看?免费开始,赠送 1,000 credits —— 然后运行 npx crawlforge init 注册 MCP server。查看完整文档、serp_rank 参考,或阅读 v4.8.0 发布文章了解此前的内容。

亲自试一试——无需注册

在 Playground 中探索全部 31 个 CrawlForge 抓取与提取工具,然后免费开始,获取 1,000 credits。

1,000 免费 credits • 一次性 • 无需信用卡

标签

  • release
  • v5.0.0
  • security
  • MCP
  • announcement
  • changelog

关于作者

CrawlForge Team

工程团队

我们正在打造功能最全面的 Web 抓取 MCP server。我们开发的工具帮助开发者为 AI 应用提取、分析和转换 Web 数据。

邮件订阅

及时获取最新洞察

将教程、产品更新与 Web 抓取技巧直接发送到你的收件箱。

拒绝垃圾邮件,随时可取消订阅。

FAQ

常见问题

01升级到 CrawlForge v5.0.0 会破坏我现有的工具调用吗?

几乎可以肯定不会。v5.0.0 中唯一的破坏性变更是 Node 最低版本从 >=18.0.0 提高到 >=20.16.0 —— 如果你运行 Node 20 或更高版本,升级只需一行命令。对现有调用方而言,没有任何工具 schema、输出结构或 credits 成本发生变化,工具总数仍为 27 个。第 2 阶段修复的是工具行为而非工具契约,因此你现有的调用会继续工作,只是现在会返回正确的结果。

02为什么 Node 版本要求提高到了 20.16.0?

Node 18 已于 2025 年 4 月结束生命周期,而 20.16 是 pdf-parse 2.4.5 所要求的最低版本 —— 那是 CrawlForge 清除最后一批 npm audit 问题所必需的、仍在积极维护的 ESM 重写版本,也让 password 选项能够真正解密受保护的文档(版本 1 只是悄悄忽略它)。项目的 Dockerfile 本来就使用 node:20-alpine,CI 也已在运行 Node 22,因此其他部分没有任何改动。使用 Node 18 的用户现在安装时会看到 engines 警告。

03第 1 阶段修复的 SSRF 漏洞是什么?

CrawlForge 的防护会解析主机名并检查得到的地址,但当 URL 的主机本身已经是 IP 字面量时,从不执行同样的检查。由于 WHATWG URL 解析器会规范化诸如 127.0.0.1、十进制 2130706433 和十六进制 0x7f000001 之类的形式,而且 Node 从不将 IP 字面量交给 DNS 解析处理,这些请求便绕过了防护。v5.0.0 在预检阶段对 IP 字面量主机名执行范围检查,并用逐次连接检查包装 undici dispatcher 的 buildConnector,因此指向内部地址的重定向跳转同样会被阻断。第 1 阶段还修复了 IPv4 映射 IPv6 的识别,让 BLOCKED_DOMAINS 真正生效,并把白名单评估改为按每一跳进行。

04什么是 MCP 异步任务,CrawlForge 的哪些工具支持它?

异步任务是一项 MCP 扩展(io.modelcontextprotocol/tasks),它让长时间运行的工具立即返回一个句柄,而不是一直阻塞到执行结束。CrawlForge 将 crawl_deep、batch_scrape、deep_research 和 agent 注册为 taskSupport 为 optional:支持任务的客户端会收到句柄并轮询 tasks/get,而不支持任务的客户端仍会像以前一样拿到同步结果。这正是长时间抓取在客户端工具调用窗口内超时问题的解法。

05我如何只向 MCP 客户端暴露部分 CrawlForge 工具?

v5.0.0 新增了两个用于客户端侧工具选择的环境变量。将 CRAWLFORGE_TOOLS 设置为以逗号分隔的工具名列表,或将 CRAWLFORGE_TOOL_GROUPS 设置为分组列表 —— 共有 12 个分组:basic、search、crawl、extract、batch、research、tracking、llmstxt、stealth、templates、scrape 和 agent。两者都不设置则暴露全部 27 个工具。未知名称会被忽略并在 stderr 上给出警告,batch_scrape 会自动启用 get_batch_results,启动横幅则会报告在总数中启用了多少个工具。这能减少那些一开始就加载全部工具 schema 的客户端的上下文膨胀。

继续阅读

相关文章

产品更新

8 分钟

CrawlForge v4.8.0:可自动激活的 Claude Skills

CrawlForge MCP v4.8.0 为其 26 个工具带来 7 个可自动激活的 Claude Agent Skills、真正强制执行的 SSRF 防护、可用的 screenshot 截图、基于设计令牌的 branding 格式,以及内置的定时变更监控。