Foreword¶
In DeepSeek Harness (DSH), models initiate web searches through the native web_search tool. The default path uses the built-in DeepSeek search provider, with the provider and result format fixed by the framework. To switch to third-party search services like Tavily, Brave, Exa, etc., you typically need to modify the combined configuration or separately attach an MCP tool, which can also lead to redundancy with the web_search entry point.
The approach of dsh-search-mcp is to retain the name and presentation of the model-side web_search tool, redirect all actual search requests to a configurable search MCP server, and disable the built-in DeepSeek search provider when enabled. Below, we introduce its positioning, installation steps, and configuration methods.
What It Is¶
dsh-search-mcp is an independent DSH plugin released by maintainer gxpppp, categorized as a web tool. The plugin registers a stable provider ID search-mcp and uses cordis.patch.yml to override the Web profile’s search combination: it points web.searchProvider to search-mcp, disables web-search-deepseek, and keeps tool-web enabled.
The current compatibility baseline is DeepSeek Harness 0.1.0-rc.7, requiring Node.js 20 or higher. The license is MIT.
Core Functionality¶
The model-side continues to use the native web_search tool with unchanged calling methods and result presentation; search requests are no longer routed through the built-in DeepSeek search but are handed over to the configured MCP server.
Supported provider types include:
- Tavily
- Brave
- Exa
- Perplexity
- DuckDuckGo
- Custom HTTP (Streamable HTTP) or stdio MCP
The configuration entry is in the Web settings page: Settings → Plugins → Plugin Configuration → Search MCP. Here, you can maintain the server list, switch the default provider, fill in credentials, and adjust global or per-server result counts and timeouts. Settings take effect immediately for the next search after saving; after installing, upgrading, or uninstalling the browser bundle, you need to restart DSH Web and refresh the page. Uninstalling the plugin removes the bundle overlay, restoring the built-in search combination in DSH.
web_fetch is not within the scope of this plugin and remains disabled in the bundle (tool-web.config.fetch: false).
How It Works¶
The plugin achieves switching through four combination overrides:
- insert:
- id: search-mcp
- id: web
config:
searchProvider: search-mcp
- id: web-search-deepseek
disabled: true
- id: tool-web
disabled: false
config:
fetch: false
searchTimeoutMs: 60000
searchMaxResults: 50
tool-web.searchMaxResults is increased to 50 to prevent the model-side tool from truncating provider-returned results first; the actual returned quantity is still controlled by the Search MCP’s global or per-server maxResults.
On the host side, search-mcp is registered via ctx.web.registerSearchProvider(); each search creates a new MCP connection using @modelcontextprotocol/sdk, which is closed in the finally block. Results are normalized: objects with HTTP(S) url are recursively collected, common title, snippet, and date fields are extracted, and deduplication is performed by URL.
Installation and Enabling¶
1. Obtain the Plugin and Install Dependencies¶
git clone https://github.com/gxpppp/dsh-search-mcp.git
cd dsh-search-mcp
npm install
2. Link to the Web Profile¶
dsh plugin --profile web add link:<absolute path of dsh-search-mcp>
link: allows subsequent source code updates to directly affect the profile without needing to reinstall the plugin.
If the profile already has a separately configured Tavily MCP (e.g., an mcp-tavily line exists), it is recommended to first remove that line from $DSH_HOME/profiles/web/cordis.patch.yml to avoid having both mcp__tavily__* tools and the web_search provider active simultaneously.
3. Configure Credentials¶
It is recommended to save credentials in $DSH_HOME/.credentials.yaml:
TAVILY_API_KEY: <your-key>
The default bundle already references it using apiKeyEnv: TAVILY_API_KEY. You can also enter a new value in the API key field of the settings card; the RC7 client will write it to the DSH credentials domain and automatically change the server configuration to a stable apiKeyEnv reference. The key is not returned through the settings read interface.
4. Start or Restart Web¶
dsh web
After refreshing the browser, go to Settings → Plugins → Plugin Configuration → Search MCP to complete the server configuration.
Settings Page Configuration¶
The card is collapsed by default; when expanded, you can configure the following global options:
| Field | Description |
|---|---|
defaultServer |
Default server ID; if left blank, the first row is used |
maxResults |
Global result count limit, default 8, optional 1–50 |
searchTimeoutMs |
MCP search timeout, default 30000 ms; displayed in seconds on the interface |
Each servers entry supports fields such as id, kind, transport (http or stdio), url, command / args, apiKey, apiKeyEnv, authStyle, authParam, toolName, maxResults, etc. Common providers can be added via quick buttons, with default endpoints, authentication locations, and tool names auto-completed.
Provider Presets¶
| Kind | Default Connection | Authentication | Default Tool | Result Count Parameter |
|---|---|---|---|---|
tavily |
https://mcp.tavily.com/mcp/ |
query tavilyApiKey |
tavily_search |
max_results |
brave |
https://mcp.brave.com/mcp/ |
query braveApiKey |
brave_web_search |
count |
exa |
https://mcp.exa.ai/mcp |
header x-api-key |
web_search_exa |
numResults |
perplexity |
https://mcp.perplexity.ai/mcp/ |
query pplx_api_key |
pplx_search |
max_results |
duckduckgo |
npx -y duckduckgo-mcp-server |
No key required | ddg_web_search |
None |
custom |
User-configured | User-configured | User-configured | None |
Verifying the Combination is Effective¶
You can use the following command to check the final combination of the Web profile:
dsh --profile web --dump-config |
Select-String -Pattern "searchProvider|search-mcp|web-search-deepseek|searchMaxResults"
Expected results:
web.searchProvider: search-mcpweb-search-deepseek.disabled: truetool-web.disabled: falsetool-web.searchMaxResults: 50
Within the plugin repository, you can also run npm test or npm run check for automated checks.
Use Cases and Considerations¶
This is suitable for developers who need to unify the web_search entry point in the DSH Web environment and switch as needed between Tavily / Brave / Exa / Perplexity / DuckDuckGo or custom MCP search backends. The DuckDuckGo preset requires no API key, while most other providers require valid credentials.
A few notes:
- The plugin runs with the current DSH process permissions. Before installation, you should review the source code and MIT license to confirm that the endpoint and credential management methods meet your environment requirements.
- Do not merely disable the
search-mcpplugin line: the bundle also overridesweb,web-search-deepseek, andtool-web; only a complete uninstall will restore the built-in search combination. - When
serversis empty, you will seeconfigured web provider "search-mcp" is registered but unavailable; if no key is configured, the corresponding provider will reporthas no API key. - If the Search MCP card is not present on the settings page, confirm that the plugin client module is loaded, restart DSH Web, and force-refresh the page.
Uninstallation¶
dsh plugin --profile web remove dsh-search-mcp
Subsequently, you can optionally delete the search-mcp: user override in $DSH_HOME/settings.yaml; if you need to restore the standalone Tavily MCP tool, re-add the original mcp-tavily line; finally, restart DSH Web and refresh the page.
Conclusion¶
dsh-search-mcp replaces the built-in web search in DSH with a configurable search MCP backend without altering the model-side web_search interface, making it suitable for scenarios where you want to choose your own search provider and manage it centrally in the Web settings page.
- Community directory page: gxpppp/dsh-search-mcp
- Source code and documentation: github.com/gxpppp/dsh-search-mcp