Mounts the hosted Exa search MCP endpoint (https://mcp.exa.ai/mcp) through the in-box @deepseek-ai/dsh-mcp-client bridge: web_search_exa and web_fetch_exa tools, anonymous on the free tier or with your own EXA_API_KEY.
Install
# from npm (prebuilt)
dsh plugin --profile web add dsh-exa-mcp
# from GitHub (first run asks for allowBuilds approval — follow the hint, retry)
dsh plugin --profile web add github:MicroHEROX/dsh-exa-mcp
Any plugin you install runs third-party code with your own permissions — it can read your files, use your credentials, and reach the network, and tool approvals don’t sandbox it. GitHub-sourced plugins also run build scripts at install time — pnpm blocks those until you allow them, so an install can stop with ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED or ERR_PNPM_IGNORED_BUILDS; dsh prints the exact key to add under allowBuilds in your profile’s pnpm-workspace.yaml, and the install works on the next run. Allowing a build is a trust decision: only install sources you trust, and pin a commit (github:owner/repo#sha).
README
A third-party plugin that brings Exa — the neural web search and fetch engine — into DeepSeek Harness (dsh). It connects to Exa's hosted MCP endpoint (Streamable HTTP) through the MCP client bridge that ships with the dsh CLI, and registers Exa's tools as native agent tools under the exa namespace.
mcp__exa__web_search_exa · mcp__exa__web_fetch_exa
mcp__exa__web_search_advanced_exa · mcp__exa__agent_run (with an API key)
- Zero install footprint: no code runs in the dsh process — the upstream is Exa's official hosted endpoint.
- Pure configuration bundle: one patch layer, no build step, no runtime API.
- Never touches your deepseek-harness installation; it only adds one row to the composed
cordis.yml.
Quick Start
1. Install
Option A — install as a plugin bundle (recommended, requires pnpm):
npm install -g pnpm
dsh plugin --profile web add github:MicroHEROX/dsh-exa-mcp
dsh web
Verify after a
github:install — when the route to github.com is unstable, agithub:(git) install can silently fail or finish with an un-synceddsh.profile.bundles(locallink:/file:installs are unaffected). Verify and fix in one step:# check: does the bundle layer appear? dsh --profile web --dump-config | grep -A2 "== dsh-exa-mcp" # if not (or to fix preemptively), append the bundle to the profile manifest: node -e "const fs=require('fs');const p=process.env.DSH_HOME+'/profiles/web/package.json';const j=JSON.parse(fs.readFileSync(p,'utf8'));if(!(j.dsh.profile.bundles||[]).includes('dsh-exa-mcp')){j.dsh.profile.bundles=[...(j.dsh.profile.bundles||[]),'dsh-exa-mcp'];fs.writeFileSync(p,JSON.stringify(j,null,2)+'\n','utf8');console.log('fixed: dsh-exa-mcp appended');}else{console.log('already present');}"The timing issue is reported upstream (Discussions #656);
--patchoverlays are never affected.
Option B — one-off overlay, no install:
dsh web --patch /path/to/dsh-exa-mcp/cordis.patch.yml
Option C — keep it permanently without installing: merge the single insert block from cordis.patch.yml into $DSH_HOME/profiles/<name>/cordis.patch.yml (or $DSH_HOME/cordis.patch.yml for every profile).
Install behavior: pnpm installs git dependencies through the
filesfield, sodocs/is not installed into your runtime — onlycordis.patch.ymlis. The docs live in this repository.
2. Provide an Exa API key (optional)
The hosted endpoint works anonymously on Exa's free tier (rate-limited, basic tools only). To lift limits and unlock advanced search / Exa Agent, create an API key and set it in the environment:
export EXA_API_KEY="your-key" # macOS / Linux
$env:EXA_API_KEY = "your-key" # Windows PowerShell
The plugin auto-detects the key at load time: EXA_API_KEY set → sends x-api-key; unset → anonymous. Never put the key into any patch file.
3. Verify
- Start
dsh web(with the bundle or overlay applied). - Wait a moment for initial discovery (it is asynchronous).
- Ask: "Use Exa to find the latest release notes of the DeepSeek Harness project on GitHub and summarize them."
- Confirm the model called
mcp__exa__web_search_exa(andweb_fetch_exafor full text) and answered from the results.
What This Plugin Does
- Connects
https://mcp.exa.ai/mcpvia@deepseek-ai/dsh-mcp-client(streamable-httptransport), the official bridge shipped with the dsh CLI. - Registers every tool Exa advertises under the spec-compliant name
mcp__exa__<tool>; re-syncs automatically ontools/list_changednotifications. - Auto-authenticates: attaches
x-api-keyonly whenEXA_API_KEYis present (graceful anonymous fallback — no brokenundefinedheader). - Tunes the bridge for search workloads:
toolCallTimeoutMs: 180000for long research tasks; reconnect policy left at bridge defaults. - Follows dsh plugin conventions exactly: bundle manifest (
dsh.bundle.patch), patch-layer composition, per-id override (mcp-exa),!!jsconfig expressions only.
What This Plugin Does NOT Do
- Does not download, host, or supervise any Exa server — the upstream is Exa's hosted endpoint.
- Does not implement OAuth login (
https://mcp.exa.ai/mcp?login) — the dsh MCP bridge has no OAuth flow; use an API key. - Does not bridge MCP resources or prompts — the harness only consumes MCP tools.
- Does not choose Exa plans, manage billing, or store your API key — the key lives in your environment only.
- Does not modify your deepseek-harness installation — installing/uninstalling only touches
$DSH_HOME/profiles/.
Routes That Work
| Route | How |
|---|---|
| Anonymous search + fetch | Do nothing — free tier, rate-limited, 2 tools |
| Full tool set (advanced search, Agent) | Set EXA_API_KEY + restart; whitelist Agent via ?tools= (below) |
| Tool whitelist / default search type | Override the mcp-exa row's url with ?tools=web_search_exa,web_fetch_exa,agent_run or ?defaultSearchType=fast (see docs/API.md) |
| Multiple MCP servers | Add more mcp-client rows with unique serverName values |
| Hot reload | Edit the row in a patch layer — HMR reconnects without process restart |
| Uninstall | dsh plugin --profile <name> remove dsh-exa-mcp — profile and base bundles stay intact |
Routes That Do NOT Work (by design)
| Route | Why not |
|---|---|
| OAuth login flow | dsh mcp-client does not implement the OAuth handshake — use an API key |
| MCP resources / prompts from Exa | The harness bridges tools only |
| Per-request auth switching | The EXA_API_KEY decision is made at config evaluation (startup / HMR), not per call |
Using the same patch twice (bundle installed and --patch) |
dsh fails loud with duplicate loader entry id: mcp-exa — pick one method |
| API key in patch files | Keys belong in environment variables; committing them is a leak |
Uninstall
Bundle installs (installed via dsh plugin add):
dsh plugin --profile <name> remove dsh-exa-mcp
Verify nothing remains:
dsh --profile <name> --dump-config | grep -c "dsh-exa-mcp" # expect 0
If installed from a
github:spec during an unstable network window,removecan leave a danglingdsh-exa-mcpentry indsh.profile.bundles, which makes the profile fail to boot withcannot resolve profile bundle "dsh-exa-mcp". Fix by removing the entry (node, no BOM):node -e "const fs=require('fs');const p=process.env.DSH_HOME+'/profiles/<name>/package.json';const j=JSON.parse(fs.readFileSync(p,'utf8'));j.dsh.profile.bundles=(j.dsh.profile.bundles||[]).filter(b=>b!=='dsh-exa-mcp');fs.writeFileSync(p,JSON.stringify(j,null,2)+'\n','utf8')"
Overlay / manual installs (no bundle):
--patchoverlays: just drop the--patch <path>/cordis.patch.ymlflag from your start command — nothing persists.- Patch merged into a profile file: delete the
mcp-exablock (or the wholeinsertlist) from$DSH_HOME/profiles/<name>/cordis.patch.yml, or$DSH_HOME/cordis.patch.ymlfor every profile.
Optional: unset EXA_API_KEY in your environment if you no longer use Exa.
Uninstalling never touches your deepseek-harness installation or any other bundle — it only edits the profile directory under $DSH_HOME.
Version Compatibility
| Component | Version | Notes |
|---|---|---|
dsh-exa-mcp (this plugin) |
0.1.0 | See releases |
DeepSeek Harness CLI (@deepseek-ai/dsh) |
≥ 0.1.0-rc.5, tested on 0.1.0-rc.8 / 0.1.1-rc.1 | The CLI ships the @deepseek-ai/dsh-mcp-client bridge this bundle mounts |
MCP bridge (@deepseek-ai/dsh-mcp-client) |
^0.1.0-rc.8 / ^0.1.1-rc.1 (resolved from the dsh CLI) |
No separate install needed |
Exa MCP endpoint (mcp.exa.ai/mcp) |
server 3.2.1 (probed 2026-08-14) | Exa-managed; may change without notice |
| MCP protocol version | 2025-06-18 |
Negotiated automatically |
| Node.js | tested on v24.16.0; Node ≥ 22 recommended | dsh itself does not declare an engines range |
| Platform | Windows / macOS / Linux | Config-only bundle; no platform-specific code |
dsh is in developer preview and iterates rapidly. After upgrading dsh, re-run the verification steps from docs/SOLUTIONS.md.
Security
- The only secret involved is
EXA_API_KEY, read from the environment at load time; it is sent to Exa as thex-api-keyheader and never written to any file by this plugin. - No third-party code executes inside the dsh process — the plugin is declarative configuration over the official bridge.
- This repository contains no keys, no local paths, and no machine-specific data.
License
MIT. Not an official DeepSeek or Exa product.
Acknowledgements
Built for DeepSeek Harness by DeepSeek AI — the "everything is a plugin" harness built on Cordis. Powered by:
- Exa MCP Server — the hosted web search endpoint
- Model Context Protocol SDK — the protocol this plugin speaks through
- @deepseek-ai/dsh-mcp-client — the MCP bridge used by this bundle
- Cordis and its plugin ecosystem — the framework under dsh
Thank you to the DeepSeek Harness team and every open-source project this work builds on.
Documentation
- Project documentation · Glossary · API reference · Solutions & pitfalls
- DeepSeek Harness: https://github.com/deepseek-ai/deepseek-harness
- Exa MCP docs: https://exa.ai/docs/reference/exa-mcp
Links
More in this category
Tencent/BrowserSkill#dsh-plugin-browserskill★ 7779
BrowserSkill bridge for controlling visible Chrome and Edge Agent Windows from DeepSeek Harness, with native browser tools, accessibility and VOM observations, screenshots, owned multi-session control, and a live Web UI overlay.
omdsh-dev/dsh-browser#packages/browser/bridge-browser★ 740
Chrome sidebar extension that lets DSH operate your browser directly, no vision capabilities required.
liustack/modsearch★ 568
Web search bridge for text-only agents: ask the web or X, get structured JSON evidence (search, fetch, citations).
DDDMUC/dsh-free-search★ 272
Free, keyless web search for DSH: 7 engines (DuckDuckGo/Bing/SearXNG free + Exa/Perplexity/DeepSeek paid), auto-failover, settings-page UI with API key inputs and official links, web_fetch, and an engine test tool.
Tabbit-Browser/dsh-tabbit★ 101
Gives DeepSeek Harness control of the Tabbit Browser: auto-loads the tabbit-browser skill on install, detects official Tabbit and Tabbit Browser releases (>= 1.9.0), checks the tabbit-cli persistent runtime, diagnoses the per-platform DSH sandbox mode needed to call the CLI, and downloads the region-matched official installer via a background job when no qualifying version is present.
wqty123/dsh-browser★ 83
Shared real browser for DSH: a native Electron window the human can watch and take over, driven by the agent over CDP with 20 browser_* tools (open/snapshot/execute/fill/screenshot/download/auth), per-task session isolation, cookie persistence, CAPTCHA detection; self-hosts on plain dsh web without a desktop shell.
Community comments
Comments are public GitHub Discussions. Loading them connects to GitHub and Giscus; a GitHub account is required to post.