DeepSeek Harness Plugin Hub

Publish and manage complete Harness Profiles. Discover Plugins for your next setup.

Explore

PluginsPresetsDocsNews

Community

Publish a pluginContactReport an issue

Resources

Plugin Hub on GitHubDeepSeek HarnessSystem statusPrivacy notice
© 2026 DeepSeek Harness Plugin HubPowered byPaxTech

Independent and unofficial. Not affiliated with, authorized by, or endorsed by DeepSeek.

Web Search Tavily Relay — DSH Plugin for DeepSeek Harness
DeepSeek Harness Plugin Hub
ProfilesPluginsCategoriesNewsDocsSign inManage Profiles
ProfilesPluginsCategoriesNewsDocsSign in
← Plugins
W

dsh-web-search-tavily-relay

Web Search Tavily Relay

Tavily-compatible web search provider for the DeepSeek Harness web seam (ctx.web): the official Tavily API, a Tavily-shaped relay, or an OpenAI-compatible gateway, all from configuration

The plugin will be installed here. Keep web if you are unsure.

npx -y @deepseek-ai/dsh plugin --profile web add github:hjnvv00v/dsh-web-search-tavily-relay#4736f42bb944f9925e8c839ac894c6cd10b3bd22
READMECompatibilityVersions

Compatibility and provenance

Web Search Tavily Relay is published as dsh-web-search-tavily-relay and currently resolves to version 0.2.0. The Hub verifies its manifest and preserves the exact installation source for reproducible installs.

DSH compatibility
*
Runtime surfaces
web
Release source
github
Registry updated
10/9/2026

Versions

0.2.0stable
10/9/2026

Related plugins

Loading related plugins…

Latest
0.2.0
DSH
*
HMR
Process restart
Tree shaking
Safe tree shaking not declared
Unpacked size
Unavailable
Files
Unavailable
Surface
web
License
MIT
Source
github
GitHub
★ 0
Weekly downloads
0
Last push
10/9/2026
View source ↗
README badge

Click the badge to copy Markdown for your README.

Do you maintain this Plugin?Claim benefit · Priority security scan

Verify the GitHub repository declared in package.json to manage this listing. After you claim it, Hub will prioritize a security scan of the current version and publish the result when it passes.

Claim this Plugin →
Report an issue

Related plugins

More verified plugins in search-research.

Ab Wechat Scrapedsh-ab-wechat-scrape--- description: "The out-of-tree wechat_scrape tool: retrieves WeChat official-account articles, filters promotional blocks, and saves each as a Markdown file, for maintainers of this machine's dsh profiles." kind: "package-reference" ---Ab Market Researchdsh-ab-market-researchAn out-of-tree DeepSeek Harness plugin: the trade_search tool (multi-round aspect-broadening query planning, publisher-tier ranking, source diversity, JSON snapshot) and its browser card in one package.Weknora@wxg-prc-cpg/dsh-weknoraWeKnora knowledge retrieval tools for DeepSeek Harness (dsh): semantic search, document reading and RAG/agent answers over your own knowledge bases.Free Searchdsh-free-searchFree web search for DeepSeek Harness: 24 engines (Bing/DuckDuckGo/AnySearch/SearXNG/Exa/Tavily/Keenable/Firecrawl/Parallel keyless; Zhihu global/site via MCP and Perplexity/SerpBase/DeepSeek/You.com/Baidu/Kimi/Aliyun/Doubao with key; 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