DeepSeek Harness plugin

dsh-web-search-ext

Multi-backend web_search provider for the DeepSeek Harness web seam (ctx.web): Exa (REST with key, anonymous hosted MCP without) and Firecrawl (v2 search API) today, extensible to more backends

Jump to install

Source facts

Repository
fno2010/dsh-web-search-ext
Latest update
Aug 22, 2026
Category
Tools & Capabilities
GitHub stars
1
Format
plugin
Catalog evidence
Upstream dsh.bundle evidence
Evidence path
package.json#dsh.bundle
Checked against
0.1.0-rc.8
Upstream check date
2026-08-20

This evidence comes from the upstream catalog. This site has not installed, run, or security-reviewed the plugin.

Install

Start with a prompt that asks an agent to review the GitHub repository and source. Switch to the command if you want to install it yourself.

Copy this prompt into DSH, Codex, or another agent and ask it to review the GitHub repository and source first.

Do not install or run any commands yet. Read this plugin's GitHub repository, README, and relevant source code. Then answer the questions below clearly and directly so I can decide whether it fits my needs:

1. What is this plugin, and what problem does it solve?
2. Who is it for, and what are its typical use cases?
3. How is it used after installation? Include one minimal example.
4. What known limitations or privacy, security, compatibility, or maintenance risks does it have?
5. Give a clear recommendation: recommend, conditionally recommend, or do not recommend, with reasons.

Distinguish statements documented by the repository, inferences from source code, and unknowns. If evidence is insufficient, say so explicitly. Do not guess or simply repeat the README.

GitHub: https://github.com/fno2010/dsh-web-search-ext
Plugin: dsh-web-search-ext
Author: fno2010

Check the source files

Read the README and other files from this plugin directory before installing.

File explorer4 files
README.mdSource · read only
README language

dsh-web-search-ext

English | 中文

!CI !npm version !npm downloads !license !node

Multi-backend web_search provider for DeepSeek Harness (DSH). Works with no API keys at all; add keys to unlock higher limits. Registered into the web capability seam (ctx.web) under one stable provider id (web-search-ext).

Why

The built-in web_search tool is backend-pluggable; the in-box default provider (deepseek-official) requires a DeepSeek API key. This plugin is a key-free-capable alternative: it works out of the box via Exa's anonymous MCP endpoint, and fails over automatically when one backend saturates.

Features

  • Two backends today: Exa (REST with key, anonymous hosted MCP without) and Firecrawl (v2 search API, keyed or keyless)
  • Automatic failover: on any backend failure (429, 401/402/403, 5xx, network, malformed body) the search falls through to the next backend in preference order
  • Per-backend 429 cooldown (default 60 s): a saturated backend is skipped on subsequent searches; when all backends fail, the error lists every failure including cooldown state
  • Optional keys with per-backend precedence: settings literal → credentials service → launch environment variable
  • Settings card on the Web: Settings → Plugins → Plugin configuration exposes the five config fields and both API keys, with key state auto-discovered from the credentials layers
  • No install-time scripts: plain ESM JavaScript, no build step, no postinstall/prepare
  • Extensible: adding a backend is one search function + one plan entry + config fields — see [CONTRIBUTING](CONTRIBUTING.md)

Backends

BackendWith keyWithout key
ExaREST POST https://api.exa.ai/search (higher limits, highlight snippets)Anonymous hosted MCP POST https://mcp.exa.ai/mcp (JSON-RPC 2.0, documented public fallback, rate-limited → HTTP 429)
FirecrawlPOST https://api.firecrawl.dev/v2/search (Bearer)Keyless requests when firecrawlKeyless: true (unofficial; may be rate-limited or removed)

Install

dsh plugin --profile web add @fno2010/dsh-web-search-ext
# or from a local checkout:
dsh plugin --profile web add ./path/to/dsh-web-search-ext

Installing a plugin requires restarting the running dsh web process (the profile bundle list is resolved at boot). Config changes afterwards are hot — no restart.

The bundle patch selects this provider for the web_search tool by setting web.searchProvider: web-search-ext. The official deepseek-official provider stays registered but unused; an explicit selection also prevents WEB_PROVIDER_AMBIGUOUS.

Configuration

Settings namespace web-search-ext in ~/.dsh/settings.yaml (hot-reloaded):

| Field | Default | Description | |---|---|---| | preferred | exa | Backend to try first: exa \| firecrawl | | numResults | 8 | Default result count when the tool doesn't cap it | | maxSnippetChars | 500 | Snippet length bound | | rateLimitCooldownSec | 60 | Skip a 429'd backend this long; 0 disables | | firecrawlKeyless | true | Allow keyless Firecrawl requests | | exaApiKey / firecrawlApiKey | — | Literal API key per backend | | exaApiKeyEnv / firecrawlApiKeyEnv | EXA_API_KEY / FIRECRAWL_API_KEY | Env var names for key resolution | | exaApiUrl / exaMcpUrl / firecrawlBaseUrl | https://api.exa.ai/search / https://mcp.exa.ai/mcp / https://api.firecrawl.dev/v2 | Endpoint overrides |

web-search-ext:
  preferred: exa
  numResults: 8
  # rateLimitCooldownSec: 60   # all other values are defaults

Or select this provider without the bundle patch: DSH_WEB_SEARCH_PROVIDER=web-search-ext.

Keys (optional but recommended)

Any of these, in order of precedence per backend:

1. Literal key in the settings section (exaApiKey / firecrawlApiKey) 2. Credentials service: the EXA_API_KEY / FIRECRAWL_API_KEY entries in ~/.dsh/.credentials.yaml (or a .env file) 3. Launch environment variable of the same name

Settings UI (Web): this plugin has a card on Settings → Plugins → Plugin configuration that edits the five config fields and both API keys. Key state is auto-discovered from the layers above — the configured/not-configured badges update live when ~/.dsh/.credentials.yaml changes — and a key supplied by the live process environment is rendered read-only, because the host rejects UI writes that an environment value would shadow. (The "Models" page manages LLM provider credentials only.)

No keys at all still works: Exa uses its anonymous MCP endpoint and Firecrawl is tried keyless.

How failover works

Each search builds an ordered plan (preferred backend first) from the backends that are available under the current key situation. The first backend whose request fails is reported as the failure only if every later backend also fails — a 429 additionally starts that backend's cooldown so it is skipped on subsequent searches until the window expires.

Uninstall

dsh plugin --profile web remove @fno2010/dsh-web-search-ext   # then restart dsh web

Security notes

  • The only outbound requests are to the configured Exa and Firecrawl endpoints; nothing else is contacted.
  • API keys travel only in the authorization header of their own backend's requests — never in bodies, never to the other backend, never in error messages.
  • No install-time scripts: plain ESM JavaScript, no build step, no postinstall/prepare.
  • Snippets are bounded (maxSnippetChars) and Firecrawl's page-markdown descriptions are stripped of image links before entering model context.

Development

  • Tests: npm test — 10 mocked failover/mapping scenarios plus live keyless smoke calls (smoke is skipped in CI).
  • Adding a backend, branch/PR conventions, and the release process: [CONTRIBUTING.md](CONTRIBUTING.md).

License

[MIT](LICENSE)