Back to home@enilmalus

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/binPATH)。
  • 方式 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 内唯一。
  • transportstdio(本地子进程)。
  • 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

参数类型默认说明
querystring搜索词(必填)
max_resultsint8返回条数(自动截断到 1–20)
allowed_domainsstring[]null只保留这些域名(子域也匹配)
blocked_domainsstring[]null排除这些域名
regionstringwt-wt地区码(wt-wt = 全球,cn-zh = 中国/中文,格式 国家-语言

验证是否生效

  1. 重启 DSH,看启动日志里 dsh-mcp-client 是否连接成功——没有 reconnecting / final failure 刷屏即连上、工具已注册。
  2. 直接点工具名测,避开可能同时存在的其它搜索工具:
用 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 ...这是网络可达性问题,不是安装或配置问题。

排查:

  1. 在装了这个包的环境里直接跑一次,确认是不是网络问题:

    python3 -c "from offline_websearch.server import web_search; print(web_search('test', max_results=2))"
    
  2. region(如 cn-zh)不影响底层引擎可达性——引擎还是那几个。

  3. 若只有某个引擎可达(例如 Mojeek),当前 server.py 没暴露 ddgsbackend 参数(默认 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

依次检查:

  1. dsh-mcp-client 是否可解析(dsh plugin --profile web add @deepseek-ai/dsh-mcp-client)。
  2. offline-websearch 是否在 PATH(或 command 用的绝对路径是否正确)。
  3. 启动日志里 dsh-mcp-client 有没有连接错误。

License

MIT