Back to home

kenzone

dsh-anysearch

An AnySearch-backed WebSearchProvider plugin for DeepSeek Harness (ctx.web). It calls AnySearch's MCP-style POST /mcp JSON-RPC endpoint with the search tool and parses the rendered Markdown result blocks into the harness web capability seam's normalized WebSearchResult.

Stars
0
Language
TypeScript
Created
Aug 15, 2026
Updated
Aug 15, 2026

Introduction

dsh-anysearch

CI npm version License: MIT dsh-plugin

An AnySearch-backed WebSearchProvider plugin for DeepSeek Harness (ctx.web). It calls AnySearch's MCP-style POST /mcp JSON-RPC endpoint with the search tool and parses the rendered Markdown result blocks into the harness web capability seam's normalized WebSearchResult.

Features

  • Web search for the harness web_search tool through the AnySearch API
  • No API key required — anonymous access works at lower rate limits; the provider stays available either way
  • Settings card in the official Web GUI — configure the API key and endpoint under Settings → Plugins → AnySearch
  • Credential-first key handling — keys go through the credentials domain, never into the settings file
  • Vertical search supportfinance, code, and other AnySearch domains via static config
  • Per-search re-resolution — a changed key or endpoint takes effect on the next search, no restart

This is an implementation plugin: it registers a provider into ctx.web, it does not own the ctx.web key and it does not register a model-facing tool (that is @deepseek-ai/dsh-tool-web). It is a function/namespace plugin (inject: ['web']) that registers its backend, not a default-export service.

Requirements

  • DeepSeek Harness 0.1.0-rc.6 or newer (the @deepseek-ai/dsh-* peer packages this plugin targets are published on npm at 0.1.0-rc.6).

Install

From a DeepSeek Harness profile (e.g. web):

dsh plugin --profile web add dsh-anysearch

Then route the model-facing web_search tool through the AnySearch provider by editing the profile's cordis.patch.yml:

- id: web
  config:
    searchProvider: anysearch

- insert:
    - id: web-search-anysearch
      name: 'dsh-anysearch'

The official Web GUI ships an AnySearch settings card (Settings → Plugins → Plugin configuration), which appears once the plugin is installed and exposes the API key and endpoint for configuration.

API key

  1. Create a free key at https://anysearch.com/console/api-keys.
  2. Configure it in the Web GUI (Settings → Plugins → Plugin configuration → AnySearch → API key), or export ANYSEARCH_API_KEY in the launch environment, or write it to $DSH_HOME/.env.
  3. Restart dsh web if you changed the environment (the launch environment is a frozen boot-time snapshot).

Without a key the provider works anonymously at lower rate limits.

Config

KeyDefaultMeaning
apiKey(unset)Literal AnySearch API key; prefer apiKeyEnv so no secret enters configuration files. Empty/absent → anonymous access (lower rate limits); the provider stays available either way.
apiKeyEnvANYSEARCH_API_KEYCredential reference resolved for each search through the credentials domain, falling back to the launch environment (process > project .env > $DSH_HOME/.env).
baseURLhttps://api.anysearch.comEndpoint base; /mcp is appended. An unparseable value makes the provider unavailable.
domain(unset)Optional vertical-domain name (finance, code, …); sent as AnySearch's domain. Pairs with subDomain.
subDomain(unset)Optional vertical sub-domain; sent as AnySearch's sub_domain. Requires domain.
subDomainParams(unset)Optional structured parameters required by a chosen sub-domain; sent as AnySearch's sub_domain_params.
numResults(unset)Default result count when a request carries no maxResults. Unset sends no default. Must be a positive integer.
- id: web-search-anysearch
  name: 'dsh-anysearch'
  config:
    apiKeyEnv: ANYSEARCH_API_KEY

The plugin also installs its settings section (web-search-anysearch), which the Web client's Plugins page exposes as the AnySearch card: the key is written through the credentials domain (never into the settings file) and the endpoint can be overridden there. A section edit takes effect on the next search without a restart.

How it works

AnySearch's search tool returns rendered Markdown, not structured JSON, so this provider parses the result blocks (### N. title, - **URL**: url, then snippet lines) into WebSearchSources: url ← the URL line, title ← the numbered heading, snippet ← the folded body lines. A heading without a following URL line is dropped (nothing citeable), and the title is optional because a block may render without one. AnySearch returns no generated answer, so content is omitted. A request's maxResults wins over the configured numResults default and is capped at the API's limit of 10 before being sent as AnySearch's max_results; the final bound is enforced by the seam. Provider failures (HTTP errors, tool isError, network failure, unparseable or wrong-shape bodies) surface as WebError WEB_PROVIDER_ERROR; an aborted request surfaces as WEB_ABORTED. HTTP redirects are rejected before the Location target is contacted and surface as WEB_PROVIDER_ERROR.

Development

npm install
npm run typecheck
npm test
npm run test:e2e   # live API smoke (anonymous access)
npm run build

Publishing

npm run build
npm test
npm publish

The package is MIT-licensed. Add the dsh-plugin topic to this GitHub repository so it appears in the DeepSeek Harness community plugin list.

License

MIT