offline_websearch
DSH/Claude Code 的本地 Web Search
- Stars
- 1
- Language
- Python
- Created
- Aug 19, 2026
- Updated
- Aug 19, 2026
Introduction
offline_websearch
一个本地部署、基于 DuckDuckGo 的 Web 搜索 MCP server。无需 API key、不依赖 Deepseek 服务端,把 web_search 工具以标准 MCP 协议暴露给任意 MCP 客户端(DeepSeek Harness / DSH、Claude Code 等)。
- ✅ 无需 API key
- ✅ 无 Anthropic 依赖
- ✅ 本地客户端侧搜索(只用 DuckDuckGo 及其回退引擎)
- ✅ 域名 allow/block 过滤(含子域)
它解决什么问题
Deepseek harness 原生的 WebSearch 工具依赖 Deepseek 服务端的能力,只在官方 / Vertex / Foundry 后端可用。当你把 agent 跑在第三方模型网关上(DeepSeek、Ollama、自建代理……)时,原生 WebSearch 会静默失败。本 server 把搜索放到客户端本地做,绕过这个依赖,而且免 key。
工作原理
MCP 客户端(DSH / Claude Code)
│ tool call: web_search(query, ...)
▼
offline_websearch(FastMCP,stdio)
│ 经 ddgs 库多引擎元搜索(见下)
▼
标题 / URL / 摘要 文本结果
底层 ddgs 是多引擎元搜索:并行查询 DuckDuckGo、Brave、Yahoo、Startpage、Wikipedia、Mojeek、Grokipedia,合并去重后返回。只要其中一部分引擎可达,就能出结果。
环境要求
- Python ≥ 3.10
- 机器能访问上述搜索引擎(见「常见问题」里关于超时的说明)
安装(clone 之后)
git clone https://github.com/enilmalus/offline_websearch offline_websearch
cd offline_websearch
按你的环境三选一:
# 方式 A:直接装(Debian/Kali/Ubuntu 等 PEP 668 externally-managed 环境,无 sudo 装 venv)
python3 -m pip install --user --break-system-packages .
# 方式 B:venv 隔离(机器上装了 python3-venv 时)
python3 -m venv .venv
.venv/bin/pip install .
# 方式 C:pipx(装了 pipx 时)
pipx install .
装完会得到一个 offline-websearch 命令:
- 方式 A 落在
~/.local/bin/offline-websearch(需确保~/.local/bin在PATH)。 - 方式 B 落在
.venv/bin/offline-websearch。
验证安装:
which offline-websearch
python3 -c "from offline_websearch.server import web_search; print(web_search('hello', max_results=2))"
依赖说明:
pyproject.toml已把mcp钉在>=1.2.0,<2.0.0。mcp 2.x 移除了FastMCP,如果不钉,import 会直接报No module named 'mcp.server.fastmcp'。
接入 MCP 客户端
DeepSeek Harness(DSH)
DSH 用 @deepseek-ai/dsh-mcp-client 桥接外部 MCP server,一个 server 对应一个插件实例。在 profile 的 cordis.patch.yml(如 ~/.dsh/profiles/web/cordis.patch.yml)里追加:
- insert:
- id: mcp-offline-websearch
name: '@deepseek-ai/dsh-mcp-client'
config:
serverName: offline_websearch
transport: stdio
command: /home/kali/.local/bin/offline-websearch
字段说明:
serverName:命名空间,只允许[A-Za-z0-9_-],且在同一 profile 内唯一。transport:stdio(本地子进程)。command:可执行命令。建议用绝对路径——DSH 给子进程的 env 会剥掉*KEY*/*PASSWORD*/*SECRET*/*TOKEN*和DSH_*,但保留PATH/HOME,绝对路径最稳。
重启 DSH,模型会得到工具 mcp__offline_websearch__web_search(命名规则:mcp__<serverName>__<原始工具名>)。
@deepseek-ai/dsh-mcp-client随 DSH 的dsh包(apps/cli)一起发布,一般无需单独安装。若 boot 时报解析不到,先dsh plugin --profile web add @deepseek-ai/dsh-mcp-client。
Claude Code(可选)
claude mcp add offline_websearch -- offline-websearch
如果装进了 venv,就用 venv 里的绝对路径:
claude mcp add offline_websearch -- /path/to/offline_websearch/.venv/bin/offline-websearch
工具 API
| 参数 | 类型 | 默认 | 说明 |
|---|---|---|---|
query | string | — | 搜索词(必填) |
max_results | int | 8 | 返回条数(自动截断到 1–20) |
allowed_domains | string[] | null | 只保留这些域名(子域也匹配) |
blocked_domains | string[] | null | 排除这些域名 |
region | string | wt-wt | 地区码(wt-wt = 全球,cn-zh = 中国/中文,格式 国家-语言) |
验证是否生效
- 重启 DSH,看启动日志里
dsh-mcp-client是否连接成功——没有reconnecting/final failure刷屏即连上、工具已注册。 - 直接点工具名测,避开可能同时存在的其它搜索工具:
用 mcp__offline_websearch__web_search 搜索 "claude code mcp"
返回真实结果即生效。
常见问题
搜索超时 / Error: web search failed after 3 attempts
offline_websearch 底层 ddgs 会并行查询多个搜索引擎(DuckDuckGo、Brave、Yahoo、Startpage、Wikipedia、Mojeek、Grokipedia)。如果这些引擎在你的网络里被墙或不可达,请求会超时,server.py 重试 3 次后返回 Error: web search failed after 3 attempts: TimeoutException ...。这是网络可达性问题,不是安装或配置问题。
排查:
-
在装了这个包的环境里直接跑一次,确认是不是网络问题:
python3 -c "from offline_websearch.server import web_search; print(web_search('test', max_results=2))" -
换
region(如cn-zh)不影响底层引擎可达性——引擎还是那几个。 -
若只有某个引擎可达(例如 Mojeek),当前
server.py没暴露ddgs的backend参数(默认auto= 全部引擎)。可在server.py里给ddgs.text(...)传backend="mojeek"(或逗号分隔的引擎列表)来只走指定引擎。
import 报 No module named 'mcp.server.fastmcp'
装了 mcp 2.x(2.x 移除了 FastMCP)。降到 1.x:
python3 -m pip install --user --break-system-packages "mcp>=1.2.0,<2.0.0"
DSH 里看不到 mcp__offline_websearch__web_search
依次检查:
dsh-mcp-client是否可解析(dsh plugin --profile web add @deepseek-ai/dsh-mcp-client)。offline-websearch是否在PATH(或command用的绝对路径是否正确)。- 启动日志里
dsh-mcp-client有没有连接错误。