DeepSeek Harness Plugin Hub

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

探索

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

社区

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

相关链接

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

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

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

dsh-web-search-tavily-relay

Web Search Tavily Relay

适用于 DeepSeek Harness Web 接口(ctx.web)的 Tavily 兼容网页搜索提供商:可通过配置使用官方 Tavily API、Tavily 形状的中继服务或 OpenAI 兼容网关

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

npx -y @deepseek-ai/dsh plugin --profile web add github:hjnvv00v/dsh-web-search-tavily-relay#4736f42bb944f9925e8c839ac894c6cd10b3bd22
README兼容性版本

兼容性与来源证明

Web Search Tavily Relay 以 dsh-web-search-tavily-relay 发布,当前版本为 0.2.0。Plugin Hub 会校验它的 manifest,并保存精确安装来源,便于复现安装结果。

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

版本

0.2.0stable
2026/10/9

相关插件

正在加载相关插件…

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

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

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

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

认领这个 Plugin →
报告问题

相关插件

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

Ab Wechat Scrapedsh-ab-wechat-scrape--- description: "树外 wechat_scrape 工具:获取微信公众号文章,过滤推广区块,并将每篇文章保存为 Markdown 文件,供此机器的 dsh 配置文件维护者使用。" kind: "package-reference" ---Ab Market Researchdsh-ab-market-research一个树外 DeepSeek Harness 插件:将 trade_search 工具(多轮扩展方面的查询规划、出版商级别排序、来源多样性、JSON 快照)及其浏览器卡片集成在一个包中。Weknora@wxg-prc-cpg/dsh-weknora适用于 DeepSeek Harness (dsh) 的 WeKnora 知识检索工具:通过自有知识库进行语义搜索、文档阅读以及 RAG/代理回答。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/Claude

README

dsh-web-search-tavily-relay

Tavily-backed web search for the DeepSeek Harness web seam (ctx.web) — with the endpoint, credential, and wire protocol all configurable, so a relay or gateway domain works exactly like the official one.

Registering into ctx.web means the harness's built-in web_search tool uses this provider directly. There is no extra tool to learn and no MCP process in the middle.

Why not the official Tavily MCP server?

Tavily does ship one (tavily-mcp), and DSH can consume it through dsh-mcp-client. It does not fit a relay deployment:

  • Its endpoints are hardcoded to https://api.tavily.com/{search,extract,crawl,map,research,feedback} with no base-URL setting, so a custom domain cannot be used.
  • Its tools bypass the ctx.web seam, so the built-in web_search keeps using whatever provider the seam selected, and the model has to choose between two parallel tool sets.

This plugin is the seam-native route: one provider, three wire protocols, one configurable endpoint.

Protocols

protocolRequestUse it for
tavily (default)POST {base}/search with Tavily's own bodyTavily itself, and relays that mirror its REST shape
openai-responsesPOST {base}/responses with the native web_search toolOpenAI-compatible gateways that expose the Responses API
openai-chatPOST {base}/chat/completions with web_search_optionsOpenAI-compatible gateways whose models search and cite

Aliases are accepted (responses, chat, rest, …), and the endpoint may be either a base (https://relay.example/v1 → …/v1/search) or a complete URL.

Sources are read from structured evidence only: Tavily's results[], a Responses payload's url_citation annotations and web_search_call sources, or a Chat payload's annotations — falling back to the answer's markdown links when a gateway returns no annotations at all.

Configuration

Everything below is editable on the plugin's page under Plugins in the Web sidebar, or written into the profile's cordis.patch.yml.

FieldDefaultMeaning
providerIdtavilyRegistry id; must match the web entry's searchProvider
protocoltavilytavily, openai-responses, or openai-chat
baseURLprotocol defaultRelay domain or full endpoint; empty uses https://api.tavily.com or https://api.openai.com/v1
apiKeyomittedLiteral key; prefer apiKeyEnv so no secret enters the settings file
apiKeyEnvTAVILY_API_KEYCredential reference resolved through ctx.credentials, then the launch environment
authStyleautoauto, bearer, body, header, or none
authHeaderomittedHeader name for authStyle: header
authSchemeBearerPrefix before the key; empty sends the key bare
modelgpt-4o-search-preview / gpt-4oModel name for the OpenAI-compatible protocols
searchDepthbasicTavily search_depth
topicgeneralTavily topic
maxResults5Upper bound requested from the provider
includeAnswer"false"Ask Tavily for a synthesized answer, surfaced as the result's content (the paragraph above the source list)
includeRawContentfalseAsk Tavily for raw_content as well; the seam's source shape has no slot for full page text, so it only backs a missing snippet — use for a whole page

Catch-all parameters

Tavily's official MCP configures search behaviour with one DEFAULT_PARAMETERS environment variable (or request header) holding a JSON object that overrides any parameter of the tavily_search tool. This plugin takes the same object as defaultParameters, so a parameter Tavily adds later needs no plugin change:

- id: web-search-tavily
  name: dsh-web-search-tavily-relay
  config:
    baseURL: https://relay.example
    defaultParameters:
      time_range: week
      country: China
      exact_match: true

A settings form stages a string, so the card writes the same value as JSON text ({"time_range":"week"}); a profile's YAML may write the object directly. Both resolve to the same fields.

It merges into the request body last, which is how the MCP applies its defaults over the tool's own arguments — so it also overrides the modelled fields above. The one field it cannot replace is query: a search whose subject came from configuration rather than from the model would be a silent, confusing failure.

One deliberate difference from the MCP. The MCP's merge loop walks the parameters it already sends (for (const key in searchParams) if (key in defaults) …), so DEFAULT_PARAMETERS can only override a value — it cannot introduce a key the server never sends. That makes include_answer and chunks_per_source unreachable through the official MCP by any means. This plugin's loop walks the configured object instead, so it can add fields as well as override them.

Official MCP tavily_search parameterThis plugin
querythe caller's query — never overridable
search_depthsearchDepth
topictopic
max_resultsmaxResults
include_raw_contentincludeRawContent
include_domains / exclude_domainsincludeDomains / excludeDomains
time_range, start_date, end_date, country, exact_match, include_images, include_image_descriptions, include_favicondefaultParameters
— not reachable through the MCP at allincludeAnswer, chunks_per_source, and any other parameter Tavily accepts

Authentication

authStyle: auto sends Authorization: Bearer <key> and, for the tavily protocol, also api_key in the body — relays in the wild implement one or the other. Pick bearer, body, or header when a relay is strict, and none for an endpoint that needs no credential.

The key resolves in this order: a literal apiKey, then ctx.credentials under apiKeyEnv, then the environment DSH was launched from. A key written on the configuration page goes through the credentials domain, so it never lands in the settings document.

Without any key, a request to https://api.tavily.com is sent in Tavily's keyless mode.

Install

dsh plugin --profile web add github:hjnvv00v/dsh-web-search-tavily-relay

web is the profile name — use your own (desktop for the desktop app). Then open the plugin's page under Plugins in the Web sidebar to set the credential and, if you use a relay, the endpoint, and reload the UI.

A plain dsh plugin add is enough on its own. The package ships a cordis.patch.yml, so the bundle both mounts its loader row and points the web entry's searchProvider at tavily — see Selecting the provider for why the pin has to travel with the plugin.

From a clone

node install.mjs                 # copies into the desktop profile and wires the seam
node install.mjs --profile web   # or any other profile

The installer copies the package into <profile>/node_modules, adds it to the profile's dsh.profile.bundles, and records the dependency. It is idempotent, backs up every file it edits, and node install.mjs --uninstall reverses all of it.

Selecting the provider

ctx.web reads searchProvider once, when the seam is constructed, and refuses to guess when more than one provider is usable — an unselected provider is a provider that is never called. So the pin ships inside the plugin's own cordis.patch.yml:

- id: web
  name: '@deepseek-ai/dsh-web'
  config:
    searchProvider: tavily

A patch replaces the whole config object of the entry it targets rather than merging into it, so this restates only searchProvider. fetchProvider is deliberately left alone: a stock profile mounts exactly one fetch provider, which the seam then auto-selects, and restating it would pin a backend this plugin does not own.

A profile's own cordis.patch.yml is applied after every bundle layer, so a profile that wants a different search backend sets searchProvider there and wins over the shipped pin. Change tavily to match providerId if you renamed it.

Failures

Errors carry the seam's machine-routable codes: WEB_PROVIDER_CREDENTIAL_MISSING for an absent key, WEB_ABORTED for caller cancellation, and WEB_PROVIDER_ERROR for everything else — a timeout, a non-2xx response, or an unreadable body. Every post-dispatch failure names the resolved endpoint, and an HTTP 401/403 message points at the authStyle and key settings rather than leaving the model to guess.

Tests

npm install            # the schema checks need the @deepseek-ai/schemastery peer
node test/smoke.mjs    # host half: protocols, auth, errors, and the Host's schema projection
node test/client.mjs   # browser half: bundle contract, slot registration, and a rendered card
node test/install.mjs  # installer: what it must write, and what it must never write

Nothing in the tests reaches the network: test/smoke.mjs spins up its own stub endpoint on 127.0.0.1. @deepseek-ai/schemastery is an optional peer — at runtime the Host supplies its own copy, so the plugin loads with or without it — and is listed under devDependencies purely so that npm install fetches a copy for these checks. Run without it, the schema-dependent checks report skip rather than failing.

test/smoke.mjs deliberately round-trips the Config schema through the host's own copy of @deepseek-ai/schemastery: a plugin resolves the peers the Host supplies, and the settings projection is the one contract that crosses that boundary. That check needs to know where the running host keeps its copy, so it is skipped unless you point at one:

DSH_HOST_SCHEMASTERY='file:///C:/path/to/dsh/node_modules/@deepseek-ai/schemastery/lib/index.mjs' \
  node test/smoke.mjs

License

MIT

web_fetch
includeDomains / excludeDomains[]Tavily domain filters
responsesToolTypeweb_searchSome gateways need web_search_preview
chatWebSearchOptionstrueSend web_search_options on Chat Completions requests
timeoutMs30000Per-request timeout
defaultParametersomittedCatch-all request fields, merged last — the counterpart to the official MCP's DEFAULT_PARAMETERS
extraHeaders{}Extra headers, merged last