关于 Searchfetch - Mcp Server For Web Search And Fetching
SearchFetch 是为 AI Agent 提供网页搜索和内容抓取的 MCP 服务,通过隐身浏览器渲染页面并转换为精简 Markdown。它提供 Python 和 Node.js 两种运行时、模板化提取及搜索引擎回退机制。
主要功能
- 01通过浏览器渲染网页
- 02网页内容转为精简 Markdown
- 03搜索引擎故障时自动回退
- 04按站点模板提取内容
- 05支持自定义 JSON 模板
- 06提供 Python 与 Node.js 运行时
适用场景
- 01为 Agent 搜索网页并获取结果摘要
- 02读取经过 JavaScript 渲染的页面
- 03按结构提取 GitHub、npm 或文档页面内容
MCP 相关
作为 MCP 服务,SearchFetch 向客户端提供只读的 `websearch` 和 `webfetch` 工具,分别用于搜索网页和抓取页面内容。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
SearchFetch
一个 MCP 服务,通过隐蔽浏览器为 AI Agent 提供网页搜索和页面抓取功能。页面经 JavaScript 渲染、去除冗余内容后,以精简的 Markdown 返回。
- 浏览器渲染: CloakBrowser 使用拟人化输入运行 Chromium。每次抓取都会使用独立的浏览器上下文。网站仍可能要求登录或通过验证。
- 容错能力: 重新启动断开连接的浏览器,并对超时、网络故障和 HTTP 429 重试一次(遵循
Retry-After,最长不超过 30 s)。内置搜索引擎会依次回退到 DuckDuckGo HTML 和 DuckDuckGo Lite。 - 节省令牌的输出: 转换前会移除脚本、样式、SVG、内联样式和嵌入的
data:图片;图片、媒体和字体会在网络层被拦截。 - 模板驱动的提取: 提供适用于 GitHub、GitLab、npm、PyPI、crates.io、docs.rs、Docker Hub、Wikipedia、MDN、Reddit、YouTube、DEV、pkg.go.dev、Javadoc 和通用文档网站的 JSON 模板。也可直接传入自定义模板。
- 两种运行时: Python(
uvx,Python 3.11.5+)或 Node.js(npx,Node 24+),两者提供相同的工具、模板和输出。首次运行时会下载浏览器二进制文件。
设置
无需手动安装。将 MCP 客户端指向 uvx 或 npx:
{
"mcpServers": {
"searchfetch": {
"command": "uvx",
"args": ["searchfetch"]
}
}
}
对于 Node.js,请使用 "command": "npx", "args": ["-y", "searchfetch"]。在 Cursor 中,添加一个 command 服务并使用 uvx searchfetch 或 npx -y searchfetch。
工具
这两个工具均为只读。失败时会作为 MCP 工具错误返回。
websearch
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
query | string | 必填 | 搜索查询(不能为空白)。 |
engine | string | "duckduckgo" | "duckduckgo"、"google"、搜索模板名称或内联 JSON 模板。 |
region | string/null | null | 区域语言代码,例如 "us-en"。DuckDuckGo 使用 kl;Google 使用 gl 和 hl。 |
safe_search | boolean/null | null | true 或 false 用于设置引擎的安全搜索;null 则保留引擎默认设置。 |
max_results | integer | 10 | 最大结果数(必须为正数)。 |
block_media | boolean | true | 在网络层拦截图片、媒体和字体。 |
结果以编号列表的形式呈现,包含标题、URL 和摘要。如果引擎失败或未返回结果,则尝试其 fallback 链中的下一个模板(google → duckduckgo-search → duckduckgo-lite-search),并在输出顶部添加 [websearch: …] 说明原因。
webfetch
| 参数 | 类型 | 默认值 | 描述 |
|---|---|---|---|
url | string | required | 绝对 http/https URL。 |
template | string | "auto" | "auto"(根据 URL 检测)、模板名称或内联 JSON 模板。 |
start_index | integer | 0 | 起始偏移量,以 Unicode 码点计(非负)。 |
max_length | integer | 10000 | 要返回的最大码点数(正数)。 |
block_media | boolean | true | 在网络层屏蔽图像、媒体和字体。 |
输出末尾会附带标明模板和字符范围的页脚;如果还有更多内容,则会提供下一个
start_index。对于不匹配任何模板的页面,会先移除导航、页眉、页脚、侧边栏、对话框和媒体,再转换整个页面(template="auto (fallback)")。
raw 模板会转换完整的 <body>,不移除任何内容。
模板
内置模板位于 templates/,供两种运行时共用。页面模板:github-repo、github-issue、npm-package、pypi-package、crates-package、docs-rs、javadoc、docs-page、docker-hub、wikipedia、gitlab、reddit、mdn-web-docs、devto、go-pkg、youtube、raw。搜索模板:google-search、duckduckgo-search、duckduckgo-lite-search。
模板在加载或以内联方式传入时会进行验证:
| 字段 | 描述 |
|---|---|
name | 必填的唯一名称(内联模板默认为 "custom")。 |
sections | 必填的节列表(见下文)。 |
order | auto 检测的优先级;数值越小,优先级越高。 |
url_patterns | 与 JavaScript 和 Python 兼容的正则表达式,用于为 auto 选择模板。 |
remove | 提取前要移除的 CSS 选择器。默认移除脚本、样式、SVG、导航栏、页脚和 iframe。 |
source_url | 优先尝试的原始 Markdown 源,例如 "{url}.md";忽略 HTML 响应。 |
cookies | 添加到浏览器上下文的 Playwright cookie。 |
block_resources | 启用 block_media 时要拦截的资源类型。默认值:image、media、font。 |
url_template | 带有 {placeholders} 的搜索 URL;使模板可供 websearch 使用。 |
url_params | 每个占位符的配置:required、default 和 encode: "url"。 |
engine | "duckduckgo" 或 "google":决定 region 和 safe_search 如何映射到 URL 参数。 |
fallback | 此模板失败时要尝试的搜索模板名称。 |
每个节都有一个 name、一个 selector(为空时选择 <body>),以及可选的 format(text、markdown、带有 attribute 的 attribute,或 html)、transform(一个或多个 strip、decode_google_url、decode_ddg_url、json_parse、resolve_href)、required、multiple、max_items 和 children(从每个匹配元素内部提取的字段)。
由顶层逗号分隔的选择器是有序回退项:优先使用第一个匹配的选择器;若回退项为空,则选择当前元素。子项会在其父元素及其祖先内部搜索,不会搜索相邻结果,因此缺失字段会保持缺失。缺少必需的节或字段时会报告错误。
如果记录节的第一项包含 Author/User 和 Comment/Body 字段,则会将其呈现为评论串;其他记录则呈现为缩进的 Key: value 块。
开发
npm ci && uv sync --locked --extra dev
git config core.hooksPath .githooks # optional: format, lint and unit tests before commits
npm test # Node (node:test) and Python (pytest) unit tests
npm run lint # ESLint and Ruff
npm run format # Prettier and Ruff format (format:check to verify)
npm run e2e # real browser against local fixtures, plus the packed npm and wheel builds
npm run check # everything CI runs
npm run inspect:node # MCP Inspector (inspect:py for Python)
布局
| 路径 | 内容 |
|---|---|
src/ | Node.js 运行时(index.js 是 searchfetch 可执行文件)。 |
searchfetch/ | Python 包(python -m searchfetch 或 searchfetch 脚本)。 |
templates/ | 共享模板;打包到 npm 包和 Python wheel 中。 |
tests/fixtures/ | 共享测试夹具,确保两个运行时的提取结果和输出一致。 |
tests/node, tests/python | 单元测试。 |
tests/e2e/ | 通过 stdio 与本地 HTTP 服务进行 MCP 端到端测试。 |
两个运行时的模块一一对应(templates、extract、markdown、compose、
browser、server)。修改其中一个时,也应修改另一个;如果行为可观察,还应添加共享测试夹具。
发布
更新 package.json 和 pyproject.toml 中的 version(然后运行 npm install 和 uv lock),
提交更改,并推送一个匹配的标签:
git tag -a v4.0.1 -m "v4.0.1" && git push origin main v4.0.1
Publish 工作流会检查标签是否与两个版本号匹配,运行 lint 和单元测试, 发布到 npm 和 PyPI,然后使用生成的说明创建 GitHub Release。若要重试某个标签,请在 Actions 选项卡中手动运行工作流,并指定该标签。
限制
- HTML 到 Markdown 的转换分别使用 turndown(Node)和 markdownify(Python)。它们对常见内容的处理一致,但表格等边缘情况可能有所不同。
- DOM 就绪后,每次抓取最多等待五秒,直到网络活动稳定下来。之后仍继续渲染的页面可能只返回部分内容。
- 端到端测试使用本地测试夹具。实时搜索引擎的可用性和第三方页面布局会随时间变化,需要单独进行实时检查。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。