关于 searxng-deepdive
searxng-deepdive 是面向研究型 Agent 的 SearXNG MCP 服务,提供可按引擎或类别筛选的搜索,以及网页内容读取。它会从实例获取可用引擎和类别信息,并支持单次多页搜索。
主要功能
- 01按引擎或类别搜索
- 02单次请求获取多页结果
- 03分页、语言与时间范围选项
- 04紧凑或完整结果格式
- 05网页转 Markdown 并提取章节
- 06动态展示实例可用引擎
适用场景
- 01针对指定学术引擎检索资料
- 02跨多个搜索引擎收集结果
- 03先查看网页目录再提取章节
- 04读取 JSON、YAML 或 TOML 内容
MCP 相关
它作为 MCP 服务注册四个工具,供 MCP 客户端调用:三种 SearXNG 搜索方式和网页读取。工具描述会根据实例的实时引擎与类别列表生成。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
npx -y searxng-deepdiveSEARXNG_URLBase URL of the SearXNG instance (e.g. http://127.0.0.1:7979/). Defaults to http://127.0.0.1:8080 if unset; set this to the address of your running SearXNG.本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。
工具
4收录的工具列表 · 更新于 2 周前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| pages | integer | 否 | 多页并行获取:并行获取指定数量的连续页面,并按 URL 去重后合并。默认值为 1。可与 pageno 组合:pageno=3 + pages=2 会获取第 3 和第 4 页。超过第 2 页后收益递减(引擎会耗尽其结果池);扩大搜索范围也可能触发上游引擎的速率限制。上限为 5,以控制令牌成本。 |
| query | string | 是 | 自然语言搜索查询。转发至各引擎的原生解析器;引擎专用运算符(如 site:、filetype:)将原样传递。 |
| format | enum | 否 | 'compact'(默认)仅返回每条结果的 url/title/content/engine,通常体积小得多,建议用于排序和初筛。'full' 还会添加相关性评分、publishedDate、所有返回该结果的引擎列表,以及引擎专属元数据(学术引擎的作者、DOI 等)。仅在确实需要其中某个字段时切换到 'full'。full | compact |
| pageno | integer | 否 | 从 1 开始计数的起始页码。默认值为 1。较大的页码会从各引擎获取更多结果,并按 URL 与前面的页面去重。引擎的结果池耗尽后,每页产出会在前 1-2 页后急剧下降。 |
| language | string | 否 | 语言筛选条件,例如 'en'、'fr'、'de'、'pt-BR';使用 'all' 可停用筛选。若省略,则使用 SearXNG 实例配置的默认值(不会根据查询自动检测,尽管名称可能让人如此以为)。 |
| time_range | enum | 否 | 筛选此时间范围内发布的结果。警告:并非所有引擎都支持时间范围筛选——有些引擎(尤其是学术引擎)在设置此项时会返回零条结果,而不是忽略该条件。仅在确实需要时效性时设置 time_range;如果设置后查询返回 0 条结果,请重试并移除此项。day | week | month | year |
| safe_search | any | 否 | 安全搜索级别。0 = 关闭,1 = 中等,2 = 严格。若省略,则使用 SearXNG 实例配置的默认值(可自托管实例通常为 0,但不保证)。 |
详细介绍
searxng-deepdive
一个面向 SearXNG 的 MCP 服务,专为开展真实研究的 LLM Agent 设计。提供四种工具,配备适合 Agent 使用的架构、多页结果分发、轻量级 URL→Markdown 阅读功能,以及根据你的 SearXNG 实例实时引擎池动态生成的工具描述。
为什么还要有另一个 mcp-searxng?
现有的软件包都很精简——大多数只提供一个 search(query) 工具,模型无法借此请求更多结果、指定特定引擎或限定类别。功能更丰富的软件包则采用静态描述,因此 LLM 无法了解当前实例实际上启用了哪些功能。它们都没有将提升 Agent 选择工具的体验作为设计重点。
searxng-deepdive 开放了这些选项:
| 功能 | 本项目 | npm mcp-searxng(ihor-sokoliuk) | PyPI mcp-searxng(SecretiveShell) |
|---|---|---|---|
| 指定引擎 | ✅ 通过 search_on_engines | ❌ | ❌ |
| 指定类别 | ✅ 通过 search_by_category | ❌ | ❌ |
| 单次调用分发多页结果 | ✅ 通过 pages: N | ❌(每次调用一页) | ❌ |
| 分页 | ✅ 通过 pageno | ✅ | ❌ |
| 精简响应 | ✅ 通过 format: "compact" | ❌ | ❌ |
| 根据每个实例动态生成描述 | ✅ 注入实时引擎列表 | ❌ 静态 | ❌ 静态 |
| 带跨工具提示的验证 | ✅ 区分引擎与类别、不区分大小写 | ❌ | ❌ |
| 无结果提示 | ✅ 提示 time_range、不响应的引擎和单引擎情况 | ❌ | ❌ |
| URL 阅读器(HTML→Markdown) | ✅ 支持目录扫描和章节提取 | ✅ 基本功能 | ❌ |
| 测试套件 | ✅ 102 项单元测试和集成测试 | 精简 | ❌ |
快速开始
通过 npx -y 从任意 MCP 客户端安装:
{
"mcpServers": {
"searxng": {
"command": "npx",
"args": ["-y", "searxng-deepdive"],
"env": { "SEARXNG_URL": "http://127.0.0.1:7979/" }
}
}
}
SEARXNG_URL 应指向正在运行的 SearXNG 实例。还没有实例?配套仓库 SearXNG-Compose 提供了即插即用的 Docker 技术栈,专为 LLM 使用进行了优化。
要求: Node.js 22 或更高版本。
工具
该服务注册了四种工具。LLM 会根据以下描述选择工具;服务启动时还会使用你实例中的实时引擎和类别列表扩充这些描述。
search(query, [...])
在全部已启用的引擎池中进行广泛的网络搜索。没有特定来源偏好时使用。返回来自任意数量响应引擎的合并去重结果。
search_on_engines(query, engines, [...])
仅使用指定的引擎进行搜索(例如 ["arxiv", "pubmed", "semantic scholar"])。注册到 MCP 客户端的工具描述会包含你实例上实际启用的引擎列表,Agent 无需猜测名称。如果输入的名称无效且看起来是类别而非引擎,验证会给出“你是不是想找”的提示。
search_by_category(query, categories, [...])
在指定类别中搜索——运行标记为每个类别的所有引擎。描述中包含实时类别列表及各类别对应的引擎。验证方式相同:无效的类别名称会触发清晰的错误提示;如果无效值实际上是引擎名称,则会提示使用 search_on_engines。
web_url_read(url, [readHeadings, section, paragraphRange, startChar, maxLength])
获取 URL 并将其 HTML 转换为简洁的 Markdown。轻量级 HTTP + HTML→Markdown(不使用无头浏览器)——可处理约 80% 的静态 HTML 网页(Wikipedia、文档网站、博客、新闻、GitHub README)。
高效利用令牌的提取模式(按优先级排列,以第一个设置的模式为准):
readHeadings: true— 仅返回标题列表,作为分层目录section: "Installation"— 返回匹配标题下的内容paragraphRange: "3-7"— 按段落切片(索引从 1 开始)startChar+maxLength— 按字符窗口分页
长页面的推荐工作流:先扫描目录(readHeadings),再定向读取
(section)。这比一开始就获取整个页面节省得多的令牌。
如果 readHeadings 返回空列表(Reddit 主题、评论区、用粗体段落
而非 <h*> 标签的博客文章),说明页面结构扁平——改用
paragraphRange 进行顺序采样,或者直接获取内容,不使用提取模式。
web_url_read 也可以直接处理 JSON、YAML 和 TOML 内容类型
(规范文件、软件包清单、注册表 API 响应、CI 工作流
YAML),因此研究 Agent 无需借助仅支持 HTML 的桩工具即可读取这些内容。
对于由 JS 渲染的 SPA 和受机器人防护的网站,此工具只会返回极少或空白 内容——请改用基于 Chromium 的读取工具(例如 Crawl4AI)。
所有搜索工具的通用参数
pageno— 起始页码(索引从 1 开始,默认为 1)pages— 单次调用中并行获取的页数(1–5,默认为 1)time_range—day/week/month/year(警告:并非所有引擎都支持此参数;某些引擎设置后会返回空结果)language— BCP-47 代码或allsafe_search— 0 / 1 / 2format—compact(默认)或full
配置
| 环境变量 | 默认值 | 含义 |
|---|---|---|
SEARXNG_URL | http://127.0.0.1:8080 | SearXNG 实例的基础 URL |
开发
git clone <this repo>
cd searxng-deepdive # or wherever you cloned to
npm install
npm run build # tsc
npm test # vitest
SEARXNG_URL=http://127.0.0.1:7979 npm run probe # exercise the SearXNG client
SEARXNG_URL=http://127.0.0.1:7979 npm run dev # start the MCP stdio server
开发时将 MCP 客户端指向源代码
使用 tsx 直接从 src/ 运行,这样每次编辑后都无需重新构建:
{
"mcpServers": {
"searxng": {
"command": "npx",
"args": ["-y", "tsx", "/absolute/path/to/searxng-deepdive/src/index.ts"],
"env": { "SEARXNG_URL": "http://127.0.0.1:7979/" }
}
}
}
MCP 客户端会缓存子进程。 编辑代码后,运行中的 服务会继续使用旧行为,直到子进程被终止并重新启动。请完全退出宿主 (LM Studio、Claude Desktop 等),然后重新打开——仅关闭聊天窗口 通常还不够。如果不这样做,可能会出现以下情况:刚发布的修复没有生效。
测试
npm test
测试覆盖七个文件:
- normalize-name — 不区分大小写的名称处理
- validators — 引擎/类别验证,并提供交叉引用提示
- zero-result-hint — 每种提示触发条件及其反向条件
- trim-to-compact — 响应裁剪和提示包含情况
- descriptions — 检查描述文案中是否存在反模式正则表达式;这些文案曾在早期版本中误导真实模型(“被引擎忽略”、“默认值为 'auto'”等)——若这些内容再次出现,构建将失败
- searxng-client — 使用
MockAgent的 HTTP 客户端:格式错误的 JSON、 HTML 502 页面、429 速率限制处理、多页并行获取去重、 所有页面均失败时抛出异常 - url-reader — 提取模式 + HTTP 集成
设计说明
-
为什么使用四个工具,而不是一个带可选引擎/类别参数的工具? 这样能让 Agent 的决策更清晰。使用不同的工具时,大模型能看到明确的用途;如果只有一个功能繁杂的工具,它就得记住何时设置哪些可选标志。权衡之处在于:MCP 工具列表中的条目更多,但处理程序代码大多相同。总体而言,这样能让 Agent 更易使用,尤其适合较小的模型。
-
为什么默认使用
format: "compact"? SearXNG 的完整结果对象比仅包含 url、title、content 和 engine 的对象大好几倍。对于典型的 Agent 工作流(对候选结果排序,再选几个详细获取),大模型实际会用到的是精简格式。需要分数、日期、作者或 DOI 时,只需设置一个参数即可使用format: "full"。 -
为什么使用动态描述? 静态描述要么列出所有上游引擎(大多数实例并未启用其中的大部分,浪费上下文),要么一个都不列(大模型不知道
engines应该填什么)。在服务启动时实时读取/config,就能为大模型提供适用于当前实例的准确提示。 -
为什么要把悄无声息地出错改为明确地出错? 在 LM Studio 中进行的实际测试表明,搜索失败看起来像是成功了(结果为零,看起来像是“没有匹配项”;或返回 60 条垃圾结果,看起来像是搜索正常运行),导致 Agent 反复陷入重试循环。采用验证加零结果提示的模式,每次都能明确显示实际原因。描述反模式测试套件会固定那些经实测证明会误导模型的文案。
安全说明
此软件包设计为在用户的信任边界内,与支持 MCP 的大模型客户端(Claude Desktop、LM Studio、 Cursor 等)一起本地运行。其信任模型假设:
- 大模型代表用户行事
- 用户控制连接到服务的模型
- MCP 传输方式为 stdio,不会暴露给远程调用方
在此边界内,有两个方面值得了解:
-
web_url_read会获取模型提供的任意 HTTP(S) URL,最多跟随五次重定向。如果主机能够连接到私有网络,那么模型也就能访问内网服务、链路本地地址或云实例元数据端点(169.254.169.254等)。这是本地研究工具的设计初衷,但这意味着不应在不受信任方可以选择 URL 的拓扑中运行此 MCP 服务(例如,面向公共互联网的托管 MCP 网关)。如果想限制访问,可设置SEARXNG_DEEPDIVE_BLOCK_PRIVATE=1,拒绝私有、环回、链路本地和元数据目的地;此限制会在每次重定向时执行,并针对实际拨号的 IP,因此 DNS 重绑定无法绕过。还可通过SEARXNG_DEEPDIVE_ALLOWED_HOSTS重新允许特定内部主机。始终拒绝非 HTTP(S) 方案(包括file://),因此该工具不会读取本地文件。正文大小上限为 10 MB,单个请求的总期限为 45 秒,返回的 Markdown 也有长度上限(使用startChar/maxLength分页),因此格式错误或体积过大的上游内容无法轻易耗尽内存或调用方的上下文窗口。 -
search工具会将模型的查询原样转发给 SearXNG。 上游引擎流量的信任边界由 SearXNG 承担;此软件包不会额外添加速率限制或重写查询。 -
工具输出是对抗性输入——可能发生提示词注入。 搜索结果摘要和
web_url_read返回的 Markdown 都包含模型会在工作上下文中读取的文本。你无法控制的网页或摘要可能包含指令(“忽略之前的指令并……”)。这不是此 MCP 服务的缺陷——任何会返回外部文本的工具都有这种固有风险——但自动根据工具输出采取行动、且不经人工审核的 Agent 循环才是威胁模型。应将工具输出视为不受信任的输入,尤其是模型自行选择而非用户提供 URL 时使用web_url_read。
此软件包按原样提供,遵循 MIT 许可,不提供任何保证,也不承担损害赔偿责任——参见 LICENSE。如怀疑存在漏洞,请通过 GitHub Security Advisories 私下报告,而不要公开提交问题。参见 SECURITY.md。
许可证
MIT——参见 LICENSE。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。