用 dsh-search-mcp 把 DeepSeek Harness 內置搜索換成 MCP 搜索服務

前言

DeepSeek Harness(dsh)把聯網能力拆成兩層:模型側始終看到名爲 web_search 的工具,真正發請求的是掛在 ctx.web 上的搜索 provider。默認那一層是內置的 web-search-deepseek,走 DeepSeek 官方搜索接口,需要能解析 DEEPSEEK_API_KEY,而且每次搜索都會消耗一次模型調用。

這在只用官方賬號時沒問題。一旦聊天走了別的網關、搜索額度想單獨結算,或者手頭已經有 Tavily、Brave、Exa 這類搜索 MCP,默認後端就會變成約束:工具名改不了,provider 卻綁在官方搜索上。官方倉庫的討論裏也有人碰到過類似情況——會話模型換了,web_search 仍打原來的 DeepSeek 搜索端點。

dsh-search-mcp 做的是替換這一層 provider,而不是再註冊一套 mcp__tavily__* 之類的新工具。模型還是調用 web_search,界面展示不變,請求改走你在 Web 設置頁配好的搜索 MCP 服務器。本文按社區目錄頁、GitHub 倉庫 README、package.json / cordis.patch.yml 源碼,以及 DeepSeek Harness 官方的 Web 能力說明覈對後整理。

這是什麼

dsh-search-mcp 是由 gxpppp 維護的社區插件,許可證 MIT,主要語言 JavaScript,當前 package.json 版本爲 0.1.0。GitHub 倉庫截至 2026 年 8 月 18 日爲 10 星;社區目錄頁當時顯示 7 星,以倉庫頁面爲準。

它在目錄裏歸在「界面增強」,原因是插件會向 Web 設置頁注入 search-mcp 配置卡片,並且 package.json 裏聲明瞭 dsh.client.platformweb。真正替換的能力是搜索 provider:啓用期間把 web.searchProvider 切到 search-mcp,同時禁用內置的 web-search-deepseek。卸載後這一層 bundle 消失,內置搜索按原樣恢復。

需要先分清兩件事。DeepSeek Harness 官方的口號是「一切皆插件」,模型、工具、會話、UI 都可以在配置層替換,不必改核心源碼。社區插件目錄 deepseek-harness-plugin.com 是獨立站點,和 DeepSeek / 幻方沒有官方從屬關係,不能當成官方應用商店。

核心功能

工具名不變,後端整段換掉

插件通過 ctx.web.registerSearchProvider() 註冊 id 固定爲 search-mcp 的 provider。返回形狀與內置 provider 一致({ sources, truncated, content? }),由原生 web_search 工具負責格式化。因此模型側工具名、參數和展示都不必改,執行通道換成 MCP。

安裝時由包內的 cordis.patch.yml 自動做三件事:

- insert:
    - id: search-mcp
- id: web
  config:
    searchProvider: search-mcp
- id: web-search-deepseek
  disabled: true

README 寫明:這一層加在 dsh-base / dsh-web-app 之後、用戶自己的 cordis.patch.yml 之前;刪掉插件後整層消失,內置搜索還原。

範圍只覆蓋搜索。web_fetch 保持 dsh 默認關閉,插件不會順手打開網頁抓取。

一套設置頁切換多家搜索 MCP

打開 Web 界面 → 設置 → Plugins → search-mcp,維護 servers 列表。倉庫爲這些 kind 寫了預設:

kind 默認端點 / 啓動方式 鑑權 默認工具名
tavily https://mcp.tavily.com/mcp/ query tavilyApiKey tavily_search
brave https://mcp.brave.com/mcp/ query braveApiKey brave_web_search
exa https://mcp.exa.ai/mcp header x-api-key web_search_exa
perplexity https://mcp.perplexity.ai/mcp/ query pplx_api_key pplx_search
duckduckgo npx -y duckduckgo-mcp-server(stdio) 無需 key ddg_web_search
custom 自己填 自己選 自己填

傳輸方式支持 http(streamable-http,默認)和 stdio(本機命令,DuckDuckGo 走這條)。全局字段包括 defaultServermaxResults(默認 8)、searchTimeoutMs(默認 30000)。單條服務器還可以覆蓋自己的 maxResults

設置寫入 $DSH_HOME/settings.yamlsearch-mcp: 段,優先於行配置。provider 每次搜索重新讀快照,改完立即生效,不必爲改配置再重啓。

默認 bundle 會插入一條 Tavily 服務器:defaultServertavilyapiKeyEnvTAVILY_API_KEY。也就是說,裝上插件並不等於搜索立刻可用,還要把對應 key 配好,或改成免 key 的 DuckDuckGo。

密鑰不進倉庫,結果按 URL 歸一化

密鑰解析順序在 README 和 lib/index.js 裏一致:字面量 apiKey → dsh 憑證服務(apiKeyEnv,例如 $DSH_HOME/.credentials.yaml)→ 啓動環境變量。設置頁裏 apiKey 按密碼框顯示、落盤脫敏;倉庫的 cordis.patch.yml 明確寫了不提交任何 API key。

MCP 客戶端用 @modelcontextprotocol/sdk。每次搜索新建連接(http 或 stdio),結束時關閉;調用方的取消信號與 searchTimeoutMs 超時競速,中止時拋 WEB_ABORTED。結果側會遞歸掃描 MCP 返回的 JSON,凡帶 url 的對象當作 source(title / snippet / 發佈日期取常見字段名),answer 當作摘要,不綁死某一家廠商的字段名。

安裝與啓用

社區目錄頁給出的安裝命令是:

dsh plugin add github:gxpppp/dsh-search-mcp

dsh CLI 會從 GitHub 解析插件並裝進當前配置。插件聲明運行在 web 平臺,README 裏的本地開發示例也是裝進 web profile。如果當前默認 profile 不是 web,可以按 README 寫成:

dsh plugin --profile web add github:gxpppp/dsh-search-mcp

需要可復現安裝時,按目錄頁說明固定 commit 哈希:

dsh plugin add github:gxpppp/dsh-search-mcp#<commit>

<commit> 換成倉庫裏的具體哈希,不要留空。

本地改源碼時,README 的步驟是:先在倉庫目錄執行 npm install,再用 dsh plugin --profile web add link:<本倉庫路徑> 以 link 方式掛上,然後重啓 dsh web。Web bundle 未啓用 HMR,首次安裝或改插件代碼後必須重啓進程;之後只改設置頁裏的服務器列表,則不必重啓。

目錄頁和倉庫都提醒:插件以當前 dsh 進程的權限運行,安裝時可能執行代碼。裝之前應檢查源代碼倉庫和許可證。

配置與驗證

在設置頁補上服務器和密鑰

  1. 啓動 dsh web,打開網頁界面。
  2. 進入 設置 → Plugins → search-mcp
  3. 確認 servers 裏至少有一條記錄。默認是 Tavily;也可以改成 Brave / Exa / Perplexity,或加一條 kind: duckduckgo 的 stdio 服務器。
  4. 需要密鑰的服務,任選一種方式:
    - 在卡片裏直接填 apiKey
    - 或填 apiKeyEnv(如 TAVILY_API_KEY),並在 $DSH_HOME/.credentials.yaml 或啓動環境裏提供同名憑證。
  5. defaultServer 設成某條 servers[].id,保存。

README 記錄的申請入口:Tavily(tavily.com)、Brave Search API(brave.com/search/api;README 寫明有免費 2000 次/月額度,具體以 Brave 當前說明爲準)、Exa(exa.ai)、Perplexity(perplexity.ai)。DuckDuckGo 這條預設不需要 key,但本機要能執行 npx

如果以前在 cordis.patch.yml 裏直接插過 Tavily MCP,README 建議刪掉那一段 insert,避免工具目錄裏再出現 mcp__tavily__*,和 web_search 重複。

確認 provider 已經切過去

README 用 web profile 做組合層檢查。PowerShell 示例是:

dsh --profile web --dump-config | Select-String -Pattern "searchProvider|search-mcp|web-search-deepseek"

在 bash 下可以對同一份輸出做過濾:

dsh --profile web --dump-config | grep -E "searchProvider|search-mcp|web-search-deepseek"

預期能看到 searchProvider 已是 search-mcp,且 web-search-deepseek 處於 disabled。然後開一個新會話,讓智能體調用 web_search(README 的例子是「搜索 MCP 服務器列表」)。返回結果應來自當前 defaultServer 對應的 MCP,而不是內置 DeepSeek 搜索。

卸載

dsh plugin --profile web remove dsh-search-mcp

之後按 README:清掉 settings.yaml 裏的 search-mcp: 段(如果改過設置頁),重啓 dsh web。內置 web-search-deepseek 會隨 bundle 層一起恢復。

只在 cordis.patch.yml 裏給 search-mcp 行加 disabled: true 並不足夠:README 寫明,此時內置搜索仍處於被替換狀態,要同時還原 webweb-search-deepseek 兩行,或者直接卸載插件。

適用場景與注意事項

比較適合這幾類用法:

  • 希望保留 web_search 這個模型工具,但搜索流量走 Tavily / Brave / Exa / Perplexity 等專業搜索 API。
  • 已經在用搜索類 MCP,不想再讓同一套能力以 mcp__*__* 工具名暴露一份。
  • 需要在設置頁裏切換多家搜索後端,而不改 dsh 源碼。
  • 暫時沒有 DeepSeek 官方搜索額度,但有 DuckDuckGo MCP 或其它免 key / 自建搜索 MCP。

使用前注意這些邊界:

  1. 這是 Web 插件。 package.json 的 client 注入指向 @deepseek-ai/dsh-client-ui-settings,平臺爲 web。headless 流程不在倉庫說明範圍內。
  2. 依賴版本寫死在 0.1.0-rc.6。 package.json@deepseek-ai/dsh-webdsh-settingsdsh-credentialsdsh-launch-environment 均爲 0.1.0-rc.6,MCP SDK 爲 ^1.30.0。dsh 若已升到不兼容的版本,需要自己覈對。
  3. 空列表不能搜。 servers 爲空會報 configured web provider "search-mcp" is registered but unavailableno search MCP servers configured。缺 key、defaultServer 對不上 id、URL 不通、stdio 的 npx 不在 PATH,都會在搜索時以 WEB_PROVIDER_ERROR 一類錯誤冒出來。
  4. 只換搜索,不換抓取。 cordis.patch.ymltool-webfetch 維持爲 false,並把 searchMaxResults 提到 50,讓插件自己的 maxResults 決定實際條數。
  5. 第三方搜索各有條款和費用。 插件本身 MIT、可免費安裝;Tavily / Brave / Exa / Perplexity 的配額以各家控制檯爲準,不要把 README 裏的免費額度理解成永久保證。
  6. 權限與來源。 插件與當前 dsh 進程同權,能讀憑證、能拉起 stdio 子進程。安裝前看倉庫源碼和 MIT 許可證;需要可復現環境時固定 commit。

小結

dsh-search-mcp 把 dsh 的搜索 provider 從內置 DeepSeek 換成可配置的搜索 MCP,同時保住 web_search 這個工具名。配置集中在 Web 設置頁,卸載即可還原。它解決的是「後端想換、模型側不想改」這一類需求,並不是再做一套並行的搜索工具。

目錄頁:https://deepseek-harness-plugin.com/zh-CN/plugins/dsh-search-mcp/

GitHub:https://github.com/gxpppp/dsh-search-mcp

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜