关于 FetchGate
FetchGate 是面向 Agent 的确定性抓取关口,仅在确认页面确实读取成功时才提供内容。它适用于希望在抓取失败或页面为空时让 Agent 拒绝作答的开发者。
主要功能
- 01区分已读取、失败和不确定结果
- 02检查状态码、重定向和提取文本
- 03识别可能的拦截页与错误页
- 04可选使用 Playwright 渲染 JavaScript
- 05核心功能无需模型或 API 密钥
适用场景
- 01避免依据空抓取结果作答
- 02核实页面是否实际可读
- 03用浏览器渲染重试文本不足的 JavaScript 页面
MCP 相关
FetchGate 向 MCP 客户端提供 `fetch_url` 工具。只有确认页面读取成功时才返回内容,否则会拒绝提供内容。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
我们还没有获取到这个服务的安装包或远程地址,请按项目 README 中的说明安装。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
FetchGate
返回 200 不代表页面已读取。
当 AI Agent 抓取网页后,页面却悄无声息地返回空内容(可能是 JavaScript 应用、403 或 Cloudflare 拦截页)时,Agent 往往不会就此停下。它会根据记忆作答,却从不告诉你自己其实没有读到网页内容。FetchGate 是设在抓取边界的一道小关卡,能阻止这种情况发生:只有确实读到页面时,Agent 才能获取内容;否则就会如实拒绝。
它具有确定性(无需模型或 API 密钥),核心部分仅依赖标准库,而且免费。
快速开始
git clone https://github.com/MoAz06/FetchGate
cd FetchGate
python demo.py https://example.com https://httpbin.org/status/403
https://example.com
verdict : RETRIEVED (clean)
answerable : ALLOW
bytes : raw 559 / extracted 127
tiers : static
gate-confirmed content (127 chars): Example Domain This domain is for use ...
https://httpbin.org/status/403
verdict : FAILED (transport.http_403)
answerable : STOP
refused: the model gets no content and cannot answer as if it read this page.
运行测试(无需网络或模型):
pip install -e .
python -m unittest discover -s tests
最简单的方式:双击一次(Claude Desktop)
从 Releases
页面下载 fetchgate.mcpb,然后双击。Claude Desktop 会显示“安装”按钮,无需编辑 JSON。
打包源文件位于 bundle/,使用
npx @anthropic-ai/mcpb pack bundle fetchgate.mcpb 重新构建。
Vibecoders:在编辑器中添加
Cursor,一键添加(需要 uv,大多数环境都已安装):
或者直接问你的 AI。 将以下内容粘贴到 Cursor、Claude Code 或 Windsurf 中:
将 fetchgate MCP 服务添加到此环境中。运行
pip install "fetchgate[mcp]"并将其注册为名为fetchgate的 MCP 服务,命令为fetchgate-mcp。它可以防止 Agent 假装读过实际无法抓取的网页后作答。
你的助手会为你运行安装并配置好相关设置。
在 Claude Desktop 或 Cursor 中使用(手动配置)
pip install ".[mcp,http,extract]" # the fetch tool, real redirect chain, better extraction
pip install ".[browser]" # optional: render JavaScript pages
python -m playwright install chromium
添加到你的 MCP 配置中(详情见 docs/mcp.md):
{ "mcpServers": { "fetchgate": { "command": "fetchgate-mcp" } } }
现在,你的 Agent 拥有了 fetch_url 工具:只有确认读取成功时才会返回内容,否则就会拒绝。
此仓库也是一个 Claude Code 插件。运行 pip install "fetchgate[mcp]" 后:
/plugin marketplace add MoAz06/FetchGate
/plugin install fetchgate@fetchgate
参见 docs/claude-code-plugin.md。
在你自己的 Agent 中使用
from fetchgate import default_gate
gate = default_gate() # renders JS pages if the [browser] extra is installed
def read_url(url: str) -> str:
out = gate.guarded_fetch(url)
content = gate.content_for(out.handle)
if content is None:
return f"NOT READ: {url} ({out.result.reason}). Do not answer as if you read it."
return content
判定方式
每次抓取都会得到一个判定结果:
- RETRIEVED:确实读取成功。Agent 可以据此作答并引用内容。
- FAILED:确定未能读取(4xx 或 5xx 错误、超时、从 https 降级到 http、正文为空)。停止。
- UNKNOWN:已抓取,但可读内容不足,无法确认是否成功读取(通常是 JavaScript 页面)。停止,或渲染后重试。
判定结果由以下三层共同决定,并取其中最严格的结果:
- 传输层:状态码和重定向链。
- 内容提取:将可读文本与原始字节分开处理。17 字节的价格 JSON 算作已读取,文本占比为 2% 的 400 KB 文章也算作已读取,没有文本的 JS 框架页则不算。
- 内容有效性:针对 Cloudflare、Cookie 同意页、付费墙和软 404 拦截页生成尽力而为的指纹。它只能将结果降级为 UNKNOWN,绝不会伪造读取成功。
当页面内容看起来稀少或为空,且渲染层已启用时,FetchGate 会升级为使用真实的无头浏览器重新检查。它会渲染页面,而非绕过拦截:经过正常渲染后仍被拦截的页面,依然视为未读取。
已知限制
content_sha256是回执锚点,不提供防篡改证据。伪装页面也能生成正常的哈希。- 来源可追溯性不等于真实性。此关卡采用“空内容时静默失败”的策略,而非“抓取成功但内容错误”。
- 读取成功不等于答案正确。RETRIEVED 表示收到的内容足够多,并不代表其中包含你需要的事实。论断是否有依据,需要后续环节处理。
- 失败即关闭会牺牲可用性。任何能让抓取失败的人都能迫使系统拒绝作答。这是保证正确性的代价。
构建内容
确定性核心、带签名清单的离线评估、会导致构建失败的作弊测试、MCP 服务和 Playwright 渲染层。可选扩展:[mcp]、[http](httpx 重定向链)、[extract](trafilatura)、[browser](Playwright)、[sign](Ed25519)。安装后会自动使用;核心仍仅依赖标准库。
MIT 许可。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。