用途
mcp-search 是一个自托管的 MCP 服务器,面向网页搜索场景。它要解决的核心问题是:搜索工具失败的方式往往看起来和成功一模一样——某个引擎返回了别人主题的内容、页面返回的其实是反爬盾文本、十六个来源其实是两个引擎被重复计算了八次。这些情况都不会抛出错误,而下游的模型会在这些内容上继续构建。这个服务器的职责就是让这些情况变得可以区分,并落在可以用于分支判断的字段里。它运行在你自己的机器上,基于你自己的元搜索实例,使用你自己的模型密钥,或者完全不用模型密钥。
主要能力
- 网页搜索、页面阅读、图片搜索、截图与多轮深度研究,并给出每个回答的置信程度。
- 报告查询了哪些引擎,以及哪些内容应当被质疑。
- 通过可分支的字段区分失败与成功:引擎失败有多种方式,阅读也有七种不同结果,返回反爬盾的页面被标记为 stub 而不是空文本。
- 引擎列表自我维护:探测程序用已知正确答案的问题持续询问每个已知引擎,引擎池按引用命中率取最优的若干并自行重算。在观测积累足够之前,池为种子列表,且每个回答都会说明这一点(默认 trouble.pool_unmeasured,verbose 下显示 pool_source)。
- 成本可控:一个参数即可让回答规模相差一个数量级;read: false 适合梳理存在什么内容或在狭窄上下文上限下工作,read_top: 0 表示“无偏好”而非“不阅读”。
使用方式
采用 Docker Compose 部署,需配置多项环境变量:
- SEARXNG_SECRET 为必填,否则 up 命令会拒绝执行;没有自有密钥时,元搜索会静默地使用镜像模板中公开已知的密钥启动。
- BROWSER_WS_SECRET 是浏览器 sidecar 端点的秘密路径,缺少时 up 同样拒绝;路径可猜时,任何能打开 WebSocket 的容器或页面都能获得自己的浏览器。
- 需要创建 compose 挂载的用于调用方认证与 TLS 的两个路径,二者默认关闭;不存在的路径会被 Docker 创建为 root 所有的目录。
- 覆盖文件仅在回环地址发布端口。
MCP 有两种接入方式:HTTP 用于已在某处运行的服务器;stdio 是协议默认方式,客户端以进程方式启动服务器并通过管道通信,每行一个 JSON-RPC 对象,一行一个回答。模式需显式选择,绝不通过是否连接终端来猜测。stdio 模式下 stdout 只承载协议内容,日志走 stderr,任何多余的一行都会破坏客户端读取。
搜索引擎方面,SEARXNG_URL 必须可达,否则所有搜索都以 cause: upstream 拒绝。浏览器路径在未连通时报 not_wired_up,异常时带 pool_unmeasured。
适用场景
- 需要在自托管、可控环境下进行网页搜索与内容阅读的 MCP 客户端与桌面工具。
- 需要对搜索结果可信度做分支判断的自动化流程。
- 需要深度多轮研究、图片搜索与截图能力的场景。
- 希望搜索与阅读不消耗模型 token,仅在深度搜索与识别扫描版 PDF 时才调用模型的用户。
限制
- 元搜索实例必须可达,否则搜索全部失败。
- 没有模型密钥时,web_deep_search 与无文本层 PDF 识别不可用;web_search 不会在背后调用模型。
- 引擎池在观测不足时为种子列表,此时结果标注为未测量。
- 令牌文件不可读与空令牌文件不是一回事:不可读的列表在 on 模式下拒绝所有人,在 warn 模式下服务所有人;路径缺失更糟,Docker 会将其创建为目录。
- 机密文件属主需为 uid 10001,权限 600;chmod 644 会让令牌与私钥对宿主机所有用户可读。
- 存在一个不会出现在常规监控中的故障:浏览器 sidecar 会累积进程,headless_shell 数量达到数千时容器运行时无法再启动进程,所有健康检查同时报错。缓解方式是 force-recreate browser,0.3.1 起镜像使用真正的 init 回收僵尸进程。
其他信息
完整参数参考、响应结构与失败模式见 HOWTO-CALL.md。字段对照表见 contracts/ag.search.v3.md 与 contracts/ag.images.v3.md。README 记录了 0.3.3、0.3.4、0.3.5 的升级步骤与变量变化。