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
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-mcp
  • web-search-deepseek.disabled: true
  • tool-web.disabled: false
  • tool-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-mcp plugin line: the bundle also overrides web, web-search-deepseek, and tool-web; only a complete uninstall will restore the built-in search combination.
  • When servers is empty, you will see configured web provider "search-mcp" is registered but unavailable; if no key is configured, the corresponding provider will report has 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.