DeepSeek Harness Plugin Hub

发布与管理完整 Harness Profiles,发现适合你的插件。

探索

插件目录环境预设文档中心动态

社区

发布插件联系我们报告问题

相关链接

Plugin Hub GitHubDeepSeek Harness 官方项目系统状态隐私说明
© 2026 DeepSeek Harness Plugin HubPowered byPaxTech

独立、非官方社区项目,与 DeepSeek 官方无隶属、授权或背书关系。

Web Search Opencode Style — DeepSeek Harness 插件(DSH Plugin)
DeepSeek Harness Plugin Hub
ProfilesPlugins分类动态文档登录管理 Profiles
ProfilesPlugins分类动态文档登录
← Plugins
W

dsh-web-search-opencode-style

Web Search Opencode Style

面向 DeepSeek Harness 的 Opencode 风格网页搜索:直接调用 Exa / Parallel MCP,无需 API 密钥。注册一个 ctx.web 搜索提供程序。

插件会安装到这里;不确定时保持 web。

npx -y @deepseek-ai/dsh plugin --profile web add github:DOCUTEE/dsh-web-search-opencode-style#d779a62f6904da8bde4ab6e80289bf6b82f46857
README兼容性版本

兼容性与来源证明

Web Search Opencode Style 以 dsh-web-search-opencode-style 发布,当前版本为 0.1.2。Plugin Hub 会校验它的 manifest,并保存精确安装来源,便于复现安装结果。

DSH 兼容范围
*
运行环境
any
发布来源
github
Registry 更新时间
2026/9/21

版本

0.1.2stable
2026/9/21

相关插件

正在加载相关插件…

最新版
0.1.2
DSH
*
HMR
重启进程
Tree shaking
未声明可安全裁剪
解包体积
未提供
文件数
未提供
Surface
any
许可证
MIT
发布源
github
GitHub
★ 0
周下载
0
最近提交
2026/9/21
查看源码 ↗
README Badge

点击下方 Badge 复制 Markdown,粘贴到 README 即可。

这是你的 Plugin?认领权益 · 优先安全扫描

验证 package.json 声明的 GitHub 仓库,即可管理这个公开页面。认领后,Hub 会优先安排当前版本的安全扫描,并在通过后公开展示结果。

认领这个 Plugin →
报告问题

相关插件

继续浏览 search-research 分类下经过校验的插件。

Free Searchdsh-free-searchDeepSeek Harness 的免费网页搜索:24 个引擎(Bing/DuckDuckGo/AnySearch/SearXNG/Exa/Tavily/Keenable/Firecrawl/Parallel 无需密钥;通过 MCP 使用 Zhihu 全局/站内搜索,以及 Perplexity/SerpBase/DeepSeek/You.com/Baidu/Kimi/Aliyun/Doubao,需密钥;OpenAI/Gemini/ClaudeDejadsh-dejaDeepSeek Harness 的 deja-vu 记忆:其他 40 个编码代理的会话历史,可搜索,并在每个步骤前调用——本地索引,无需 LLM。Builtin Browserdsh-builtin-browser适用于 DeepSeek Harness 的共享真实浏览器插件:安装即用——可由人类接管的可见原生浏览器,并由代理通过 CDP 驱动。DOM 级交互(兼容 React/Vue)、按任务隔离会话、Cookie 持久化(dsh_browser_auth)、CBladebrobladebro面向 AI 智能体的隐蔽高效代理式浏览器驱动。工具少、控制全面、真正隐匿,并最大限度提高令牌效率。

README

dsh-web-search-opencode-style

An opencode-style web search provider for DeepSeek Harness (DSH). It registers a single opencode-style provider into ctx.web, so the model-facing web_search tool from @deepseek-ai/dsh-tool-web keeps working (cards, citations, timeout, searchMaxResults) without tripping WEB_PROVIDER_AMBIGUOUS.

No MCP server to install. No API key. No LLM credits burned.

How it works

This is a direct port of how opencode performs web search (packages/opencode/src/tool/websearch.ts + packages/opencode/src/tool/mcp-websearch.ts): the CLI POSTs a JSON-RPC tools/call straight to two public MCP endpoints, then parses the MCP response (plain JSON or SSE data: ... lines):

  • Exa: https://mcp.exa.ai/mcp → web_search_exa
  • Parallel: https://search.parallel.ai/mcp → web_search

The plugin is zero-dependency: it only uses the global fetch (Node >= 20).

Fidelity to opencode

Ported 1:1 and cross-checked against websearch.ts + mcp-websearch.ts:

  • Same endpoints, tool names, JSON-RPC body (id: 1, tools/call), accept header, 25s timeout, default redirect (follow).
  • Same default args: type: auto, numResults: 8, livecrawl: fallback, contextMaxCharacters only sent when set; numResults = request || config || 8 (no clamping, exactly params.numResults || 8).
  • Same backend selection order as selectWebSearchProvider(): env OPENCODE_WEBSEARCH_PROVIDER → config provider → flags enableExa/enableParallel (env OPENCODE_ENABLE_EXA, OPENCODE_ENABLE_PARALLEL, OPENCODE_EXPERIMENTAL* as RuntimeFlags) → checksum(sessionID) % 2. The session comes from ctx.agents.currentInitiator(), so every search inside one session hits the same backend, exactly like opencode.
  • Same fields sent to Parallel: objective, search_queries, session_id (real session; without one, dsh_<checksum(query)>), model_name (agent.options.model, truncated to 100 chars — mirrors webSearchModelName).
  • Same parsing: raw JSON first, then scan data: lines; a {...} payload that is not an McpResult (JSON-RPC error, malformed JSON) is an error, not a silent "no results".
  • Same empty-result sentence: No search results found. Please try a different query.
  • Same FNV-1a base36 checksum (ported from packages/core/src/util/encode.ts).

What cannot be reproduced from the provider layer (DSH architectural limits):

PointopencodeDSH
numResults/livecrawl/type/contextMaxCharacters chosen by the modeltool parametersDSH's web_search only takes queries[]; maxResults is fixed by the tool-web row (searchMaxResults), the rest is config
Asking permission before searchingctx.ask({permission:'websearch'})dsh-tool-web has no approval layer; permission belongs to the host, the provider has no channel
Card title + metadata.provider"Exa Web Search: <query>"the seam's WebSearchResult has no metadata channel
User-Agent (Parallel)opencode/<version>dsh-web-search-opencode-style/<version> — deliberately not impersonating another product

sources[] is the only translation step opencode does not have: the seam needs structure to render cards and citations. The plugin parses structured formats first — Parallel's JSON results[] (title, publish_date → publishedAt, excerpts → snippet), then Exa's Title:/URL:/Published:/Highlights: blocks — and only falls back to scanning raw URLs when the text matches no known format. truncated is set when more sources were extracted than maxResults, so web_search can nudge the model to refine the query.

Error codes: WEB_PROVIDER_ERROR (HTTP failure / network failure / unparseable body / response larger than 4 MiB), WEB_SEARCH_TIMEOUT (past timeoutMs, same message as opencode: <tool> request timed out, same name family as dsh-web-fetch-http's WEB_FETCH_TIMEOUT), WEB_ABORTED (caller aborted).

Install (one command)

dsh plugin --profile web add dsh-web-search-opencode-style

This runs pnpm add inside the profile and wires the bundle into dsh.profile.bundles (via reconcilePlugins: any package declaring dsh.bundle joins the stack automatically). The bundle patch both mounts the provider and overrides the web row to searchProvider: opencode-style (env DSH_WEB_SEARCH_PROVIDER still wins), so there is no WEB_PROVIDER_AMBIGUOUS clash with the built-in deepseek-official. Restart dsh --profile web and the model sees web_search as before — no key, no extra file edits.

Go back to the old DeepSeek search: DSH_WEB_SEARCH_PROVIDER=deepseek-official dsh --profile web. Pin one opencode backend: OPENCODE_WEBSEARCH_PROVIDER=exa|parallel.

Install from a local checkout instead:

dsh plugin --profile web add /path/to/dsh-web-search-opencode-style

Uninstall:

dsh plugin --profile web remove dsh-web-search-opencode-style

Configuration

Everything below is editable from Settings → Plugins → Plugin configuration (namespace web-search-opencode-style): the plugin registers a real settings section, so the form lists every key and changes apply from the next search onward. That section needs @deepseek-ai/schemastery from the running DSH install; the plugin loads it from $DSH_HOME/profiles/node_modules (DSH's shared fallback), so a symlinked dsh plugin add <path> install works without anything extra. Without schemastery the plugin still works — only the form is missing.

You can also use the row's cordis.patch.yml (see the template file), or the config object passed to apply() directly:

keydefaultmeaning
providerundefined (auto)"exa" / "parallel" to pin; lower priority than env OPENCODE_WEBSEARCH_PROVIDER (same order as opencode)
enableExaenv OPENCODE_ENABLE_EXA / OPENCODE_EXPERIMENTAL_EXA / OPENCODE_EXPERIMENTALforce Exa, like RuntimeFlags.enableExa
enableParallelenv OPENCODE_ENABLE_PARALLEL / OPENCODE_EXPERIMENTAL_PARALLELforce Parallel; checked before enableExa, like opencode
exaApiKeyenv EXA_API_KEYoptional — the public endpoint works without a key
parallelApiKeyenv PARALLEL_API_KEYoptional
numResults8used when the caller sends no maxResults; in practice tool-web.searchMaxResults decides
type"auto"auto / fast / deep (Exa)
livecrawl"fallback"fallback / preferred (Exa)
contextMaxCharacters(not sent)Exa context cap
timeoutMs25000matches opencode's "25 seconds"
enabledtruefalse → available() returns false

Development

The module exports name, inject, apply and Config — and no default export. cordis' loader normalizes module exports with default ?? exports (cordis-plugin-loader), so a default export shadows the named metadata and the plugin loses its inject/Config (this caused cannot get property "web" without inject). Add a default export only if it carries that metadata itself.

node --test test/*.test.mjs        # plugin.test.mjs (ported logic) + dsh-seam.test.mjs (real cordis + dsh-web)
DSH_INTEGRATION=1 node --test test/dsh-seam.test.mjs   # plus one real search against Exa/Parallel

test/dsh-seam.test.mjs mounts the plugin on a real cordis context with the real ctx.web seam and stubs only the network, so the export shape and the settings wiring are covered too; it skips itself when no dsh install is on PATH.

License

MIT