DSH PLUGIN / MCP SERVER · 联网检索
keyless-web-mcp
给 agent 用的网页搜索与正文抓取:不需要 API key,不需要账号,不需要配置。
它既是一个 stdio 的 MCP 服务器,也可以作为 DeepSeek Harness 的 web provider,
直接把 harness 自带的 web_search / web_fetch 换成自己的实现。
- MIT
- Python 3.10+
- MCP · stdio
- DSH web provider
- 零 key
为什么会有它
常见的搜索 MCP 要么要付费搜索 API(Brave、Tavily、Serper、Bing),要么要厂商账号,要么要一个你的机器 未必连得上的托管端点。可很多时候只是想让 agent 查一下资料。所以这个项目把三件事当成硬约束:
- 开箱即用:不需要注册、不需要填卡号、改完配置就能打第一个查询。
- 能穿过企业网:先直连,失败再退回显式代理;启动时把操作系统证书库注入 TLS 栈, 企业 TLS 拦截和杀软替换的根证书不用关校验也能过。
- 结果可引用:每条结果都带来源 URL,跳转链接会被解回真实地址,而不是给你一串
bing.com/ck/a或google.com/goto包装。
两个工具
| 工具 | 参数 | 返回 |
|---|---|---|
web_search |
query 必填;max_results 1–20,默认 10;engines 可选 |
JSON 数组,元素为 {title, url, snippet, engine},新闻命中另有 source、date |
web_fetch |
url 必填(仅 http/https);max_chars 500–100000;include_links |
以 Title: / URL: 开头的可读正文;JSON 接口美化输出 |
引擎
| 引擎 | 端点 | 默认 | 说明 |
|---|---|---|---|
google_web | google.com/search | ① | 真正的 Google 网页索引。纯 HTTP 只会拿到 JS 外壳,自带的 HeadlessChrome UA 会被
「unusual traffic」拦下;换成桌面 UA 的无头 Chrome 就能拿到正常结果。结果 URL 从
/goto 的 302 恢复,拿不到时用 <cite> 面包屑兜底 |
duckduckgo | html.duckduckgo.com | ② | 无 JS 的 HTML 端点,免 key 免 cookie,uddg= 跳转会解开 |
bing | www.bing.com/search | ③ | 纯 HTTP 取有机结果;/ck/a?...&u=a1<base64url> 解码回真实 URL,
mkt/setlang 跟随查询语言(中文查询不会变成英文比分) |
google | news.google.com/rss | ④ | 是 Google News RSS,不是网页索引,偏向新闻与技术报道 |
wikipedia | *.wikipedia.org/w/api.php | 可选 | 百科兜底;按 Wikimedia 的机器人政策自带描述性 UA |
默认的四个引擎同时并发跑,结果按 URL 去重后轮转交织合并——
每个引擎的头条都保留优先权,一次查询能同时引用几个独立来源,而不是被返回最多的那个引擎挤满。
单个引擎挂掉不影响整体;全部失败才返回 []。
装在 DSH 里
三种用法按需选一个:
① 插件市场索引
DSH 打开 插件 → 实验性插件 → 自定义插件索引,在 发现 里添加 AI V5 的索引源:
https://ai-v5.github.io/market/index.json
② 直接链接本地 checkout 的 provider
仓库里的 extras/dsh-provider 就是 DSH 组合包(dsh-plugin-keyless-web):
dsh plugin --profile desktop add D:\path\to\keyless-web-mcp\extras\dsh-provider
它会把自己的 patch 叠上去:把 web.searchProvider / web.fetchProvider
指向 keyless,并停用需要 API key 的 DeepSeek 搜索插件。装完重启 DSH。
③ 当成普通 MCP 服务器
uvx keyless-web-mcp
任何 stdio 型 MCP 客户端:
{
"mcpServers": {
"web": {
"command": "uvx",
"args": ["keyless-web-mcp"],
"env": { "MCP_WEB_PROXY": "" }
}
}
}
DSH 里走 MCP 而不是 provider 时,加一条 @deepseek-ai/dsh-mcp-client 记录即可;工具名会带命名空间,例如 mcp__web__web_search。
配置
全部来自环境变量,启动时读一次:
| 变量 | 默认 | 含义 |
|---|---|---|
MCP_WEB_PROXY | 未设置 | 兜底代理,host:port 或 http://host:port;始终先直连 |
KEYLESS_WEB_ENGINES | google_web,duckduckgo,bing,google | 默认引擎列表,未知名字丢弃 |
KEYLESS_WEB_BROWSER | 自动探测 | google_web 用的浏览器;off 关闭浏览器能力 |
KEYLESS_WEB_BROWSER_TIMEOUT | 25 | 单页渲染的墙钟预算(秒) |
KEYLESS_WEB_BROWSER_WAIT | 6000 | 交给浏览器的虚拟时间预算(毫秒) |
KEYLESS_WEB_MIN_INTERVAL | 1.0 | 同一 host 两次请求的最小间隔(秒),0 关闭 |
KEYLESS_WEB_CACHE_TTL | 300 | 搜索结果缓存(秒) |
KEYLESS_WEB_CACHE_TTL_FETCH | 900 | 抓取页面缓存(秒) |
KEYLESS_WEB_TIMEOUT | 15 | 单请求超时(秒) |
KEYLESS_WEB_USER_AGENT | 桌面 Chrome UA | 抓取、web_fetch 与无头浏览器使用的 UA |
没有装 Chrome/Edge 时 google_web 自己退场(KEYLESS_BROWSER),
其余引擎和 web_fetch 都是纯 HTTP,照常工作。
实测
- 四引擎并发的中文查询(
华为 昇腾 CANN 9.0 发布):约 9 秒拿到 10 条,四个引擎都有贡献。 - Google 单次渲染 5.5–7 秒(开销几乎全在 Chrome 启动);
--no-proxy-server反而慢到 22 秒,所以没采用。 - 单元测试全离线:浏览器用假
subprocess.run,Google 解析用固定 DOM fixture;覆盖率 91.9%。
链接
- 源码仓库 · 中文 README
- DSH provider(
dsh-plugin-keyless-web) - MIT License