The built-in web_search tool in DeepSeek Harness (DSH) relies on DeepSeek’s server-side interface. It requires DEEPSEEK_API_KEY and also consumes a full model turn. dsh-keyless-search is a third-party Provider plugin that replaces the underlying search backend of ctx.web. By issuing real browser requests locally, it provides keyless retrieval without consuming model turns.

Core features

This plugin is implemented in Node.js, does not depend on official DeepSeek packages, and has the following capabilities:

  • No API Key: It does not consume model turns and does not rely on keys in environment variables.
  • Real browser rendering: It uses local Chrome/Edge to render Google, bypassing the JS wall that HTTP scraping inevitably encounters.
  • Multi-engine concurrency and fallback: The default chain is google-browser (proxy) + bing-global (global version) + bing (direct). When the proxy is unavailable, it automatically switches to direct connections; when google-browser fails, it automatically falls back.
  • Automatic proxy detection: There is no need to manually configure proxyUrl; the plugin automatically scans common local ports (such as 7890, 1080, etc.).
  • Language-aware behavior: When CJK characters are detected, it automatically skips Bing Global to avoid English result contamination.
  • Multi-topic splitting: For compound queries such as “topic1, topic2”, it automatically splits them into up to 8 subqueries, deduplicates them, and merges the results before returning them.
  • Browser instance recycling: Chrome instances launched by the plugin are automatically closed after being idle (default 5 minutes), so they do not occupy system resources.
  • Zero host dependency: It only uses node: built-in modules and imports nothing from @deepseek-ai/*.

Installation and enabling

Installing this plugin requires a DeepSeek Harness environment. Ensure your Node version is ≥ 22.

dsh plugin --profile <profile> add github:Wandering233/dsh-keyless-search

You need to restart DSH after installation for the changes to take effect. The plugin automatically applies configuration through dsh.bundle.patch, so there is no need to manually modify cordis.patch.yml.

Configuration notes

Configure web-search-local in the profile’s cordis.patch.yml:

- insert:
    - id: web-search-local
      name: 'dsh-keyless-search'
      config:
        engines: [google-browser, bing-global, bing]
        proxyUrl: ''            # '' = 自动探测;'off' = 强制直连;或 'http://host:port'
        maxSources: 16
        browserTimeoutMs: 30000
        searchTimeoutMs: 15000
        chromePath: ''          # 留空自动探测浏览器路径
        browserIdleTimeoutMs: 300000 # 5分钟空闲后回收

Key field descriptions:
* engines: Specifies the list of search engines. The default is [google-browser, bing-global, bing].
* proxyUrl: When empty, local ports are automatically probed; set to 'off' to force direct connections.
* browserIdleTimeoutMs: Sets how long the browser instance can remain idle before being recycled; 0 disables recycling.

Known limitations

  1. Cold-start cost: Using the browser engine for the first time requires launching Chrome (about 3-6 seconds); reusing an existing instance takes about 3-4 seconds.
  2. Result truncation: The tool layer returns at most 8 results by default (searchMaxResults), so even if the plugin returns more, the output is truncated. This limit cannot be adjusted through configuration.
  3. Engine-specific issues:
    • DuckDuckGo is unavailable and returns a botnet page.
    • Mojeek was tested and returns 0 results.
    • SearXNG requires specific configuration and depends on Unix-specific modules (such as os.uname()); public instances are usually unavailable.
  4. Dependency requirements: Chrome / Chromium / Edge must be installed locally. When installing from a local directory, it is recommended to explicitly install puppeteer-core.

Development and self-check

The package includes selftest.mjs, which can run a pure Node.js self-check without starting DSH:

node selftest.mjs

Summary

dsh-keyless-search addresses the problem that DSH’s native search consumes model turns by introducing local browser rendering and smart splitting strategies. It is suitable for scenarios that require high-frequency, keyless search capabilities, but note the cold-start latency and result-count limit before using it.

Project URL: https://github.com/Wandering233/dsh-keyless-search