Tools & Capabilities
dsh-search-free
lmcsh9527/dsh-search-free · ★ 0
Free multi-layer web search + fetch provider for DeepSeek Harness (DSH).
安装
dsh plugin --profile web add github:lmcsh9527/dsh-search-freeGitHub 源码安装:首次需按提示配置 allowBuilds 构建授权后重试
For install and environment setup, plus plugin development tutorials, see DSH community docs ↗
README
English · 简体中文
Free multi-layer web search + fetch provider for DeepSeek Harness (DSH).
Why this exists: the official
@deepseek-ai/dsh-web-search-exa@0.0.1-rc.1imports@deepseek-ai/dsh-environment, which does not exist on npm, so it cannot load; and the official DeepSeek search requires a funded DeepSeek account. This plugin provides a working, free search stack out of the box.
Features
- Search provider
freesearchwith automatic layer fallback:- Exa — semantic search (quality first, uses your Exa API key)
- Tavily — general web search (free tier ~1000 requests/month)
- Bing RSS — zero-key, zero-cost last resort
- Fetch provider
native— plainfetch, redirects followed, HTML/text classified - Model tool
web_fetch— same contract as the standard tool (registered only when not already present)
No API keys are embedded in code: they come from the plugin row config (exaApiKey / tavilyApiKey). An empty key skips its layer.
⚠️ Install pitfalls (read this first — v0.1.1)
Do NOT run npm install / pnpm add / pnpm install inside a live DSH profile directory
($DSH_HOME/profiles/<profile>) while the instance is running. pnpm creates a
shadow node_modules whose layout differs from the profile's real
dependency tree; the running instance lazily loads modules from it and the
whole tool pipeline dies with:
Cannot read properties of undefined (reading 'prepare')
This happened to us. The fix is to remove that shadow node_modules (the
instance then resolves the parent/global tree again) and mount the plugin via
a symlink instead:
# profile with a parent hoisted tree (web/desktop profiles)
ln -s <path-to>/dsh-search-free "$DSH_HOME/profiles/node_modules/dsh-search-free"
v0.1.1 also removes the @deepseek-ai/schemastery dependency entirely: a
plugin-local schemastery copy can clash with the host DSH's copy. The config
is now a plain object (no validation needed).
Install
# from npm
npm i dsh-search-free
# or from GitHub
npm i github:lmcsh9527/dsh-search-free
Then mount it in your profile patch (cordis.patch.yml):
- id: web
config:
searchProvider: freesearch
- insert:
- id: web-search-free
name: 'dsh-search-free'
config:
exaApiKey: <EXA_API_KEY> # optional; empty skips the Exa layer
tavilyApiKey: <TAVILY_API_KEY> # optional; empty skips the Tavily layer
Usage
web_searchnow routes throughfreesearch(Exa → Tavily → Bing with automatic fallback).web_fetchretrieves any HTTP(S) URL and returns it as readable text (HTML is stripped to text, capped at 20k chars).
Test
EXA_API_KEY=... TAVILY_API_KEY=... npm test
Runs against real endpoints with a mock ctx.
License
MIT © lmcsh9527