Back to home

A3Boy

dsh-web-tools

Multi-provider Web Search & Fetch for DeepSeek Harness — Tavily, Exa, Firecrawl, Brave, You.com, Jina & SearXNG with fallback and native settings UI.

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

Introduction

dsh-web-tools

dsh-web-tools

Configurable multi-search-source backends for DeepSeek Harness's web_search / web_fetch.

Configure Tavily, Exa, Firecrawl, Brave, You.com, Jina, or SearXNG — when one source is rate-limited, exhausted, or down, the plugin switches to the next in your configured order. The agent keeps using DSH's original web_search / web_fetch; no new tools are added.

BYOK · API keys live in DSH Credentials and requests go directly to each provider — no intermediary server.

License: MIT PRs Welcome DeepSeek Harness

English | 简体中文

7 Providers · Native DSH tools · Fallback · BYOK · SearXNG


Why

  • 7 search providers: Tavily, Exa, Firecrawl, Brave, You.com, Jina, SearXNG
  • Native DSH tools only: the model sees just web_search / web_fetch — no tavily_search-style provider tools
  • Custom priority: default provider + ordered fallback chain
  • Multi-key + health + quota: credential pools, provider health, quota state
  • Native DSH settings page: providers, credentials, connection tests, and test search in one place

Quick Start

Requirements

  • DeepSeek Harness: developed and tested against 0.1.0-rc.6
  • Uses the DSH web profile
  • Installing external bundles requires pnpm
  • Commercial providers use your own API keys; SearXNG works with no commercial API key

Install

dsh plugin --profile web add github:A3Boy/dsh-web-tools

Restart dsh web, then open the plugin settings page to configure providers. The plugin integrates through DSH's official Profile Bundle mechanism — no Harness core changes.

# check the composed config
dsh --profile web --dump-config

# update / remove
dsh plugin --profile web update dsh-web-tools
dsh plugin --profile web remove dsh-web-tools

Configure providers

  1. Settings → Plugins → Plugin configuration → dsh-web-tools
  2. Fill in API keys per provider (comma-separated keys → credential pool)
  3. Pick the default provider and adjust the fallback order
  4. Use Test Search to run a real query and verify

Providers

ProviderSearchFetchBest for
TavilyGeneral agent search
ExaSemantic / research
FirecrawlReading pages after search
Brave SearchTraditional web search
You.comWeb / News
JinaPage content reading
SearXNGSelf-hosted

Not sure which one?

  • General: Tavily
  • Research / semantic: Exa
  • Need to read pages: Firecrawl / Jina
  • Traditional web search: Brave
  • Self-hosted / privacy: SearXNG
Provider selection reference: free tiers & pricing (2026-08-16)
ProviderFree allowanceTypeBilling
Tavily1,000 credits / monthmonthlycredits (Basic=1)
Exa$20 signup + $10/mosignup + monthlyper request ($7/1k)
Firecrawl1,000 credits + 1,000 search credits / momonthly2 credits per 10 results
Brave$5/mo ≈ 1,000 searchesmonthlyper request ($5/1k)
You.com$100 one-timeone-timeper call ($5/1k)
Jina10M tokens one-timeone-timeper token
SearXNGno platform quotaself-hostednone

Pricing and free tiers come from upstream sites and may change — always check each provider's site.

Fallback

The attempt order for one search:

Tavily → Exa → Brave → SearXNG

On a recoverable failure of the default provider, the next one is tried:

401 / 403 · 408 · 429 · 5xx · network error · timeout · provider unavailable

A credential that fails auth is marked unhealthy while the search continues.

These errors do not switch providers: 400 bad request, local configuration errors.

Caller cancellation (abort) terminates the whole search chain immediately — it never falls back.

Settings

Configuration entry:

Settings → Plugins → Plugin configuration → dsh-web-tools

Manages: enable toggle, default provider, fallback order, per-attempt timeout, provider enable/disable, API keys / credential pools, base URLs, connection tests, quota state, test search.

Result count and the overall search timeout are owned by the DSH tool layer (web_search); the plugin does not override them. The settings page's per-attempt timeout is how long a single provider may run before the plugin aborts it and tries the next one.

Credentials & Quota

Credential pools

Each provider can hold multiple API keys:

Tavily
├── Key A
├── Key B
└── Key C

Keys are selected least-used-first; a failing key is marked unhealthy and skipped; when all keys are unavailable, health resets. Values can be separated by commas, whitespace, newlines, or semicolons.

Credential pools are for legitimate scenarios (team keys, workspaces, key rollover, environment isolation) — not for bypassing provider limits.

Quota

Providers use different units (credits / requests / tokens / USD / self-hosted); the plugin does not force them into one percentage.

Quota is split into authoritative and best-effort for display in the settings page. Quota does not drive search routing — fallback is triggered by real request failures (402 / 429, etc.).

ProviderData sourceStatus
TavilyOfficial /usage✅ implemented
FirecrawlOfficial /v2/team/credit-usage✅ implemented
You.comOfficial Account Balance API✅ implemented
Exano public balance APIlocal estimate (non-authoritative)
BraveX-RateLimit-* headersparsing ready, full display pending
JinaReader balance infobest-effort
SearXNGno platform quotaself-hosted

For multi-key pools, quota queries the FIRST key in the pool; the settings page marks it as such. Quota failures only affect display; results are cached 5 minutes (no polling).

A quota lookup failure only affects display — never search.

Search & Fetch

web_search → candidate URLs → web_fetch → read page content

Tavily, Exa, Firecrawl, and Jina use their native content-fetch capabilities; Brave, You.com, and SearXNG are used for search.

Note: web_fetch walks fetch-capable providers in search priority order, but it does NOT reuse the provider that web_search actually hit, and it does not guarantee the target page's real HTTP status / final URL (provider native extract usually returns clean text). For strict Fetch semantics (real status / redirects / truncation), rely on DSH's official HTTP Fetch; use this plugin's provider extract for content enhancement.

Security & Privacy

  • API keys are resolved on the Host only — full credentials never reach the browser (only configured/masked state).
  • Test results and logs never return full API keys.
  • Config writes are restricted to the local configuration plane.
  • No dsh-web-tools remote server, no shared keys.
  • No search usage telemetry uploaded.
  • Can run with self-hosted SearXNG only.

Compatibility / Limitations

  • Developed and tested against DeepSeek Harness 0.1.0-rc.6; DSH is a developer preview and may introduce breaking changes.
  • Brave quota full display is pending (header parsing exists).
  • web_fetch does not guarantee real HTTP status / final URL semantics (see Search & Fetch).
  • SearXNG quality depends on the instance and the upstream engines it enables.
  • Free tiers/pricing come from upstream and may change.

Architecture

flowchart TD
    Agent[DSH Agent] -->|web_search / web_fetch| Tool[dsh-tool-web]
    Tool --> Web[ctx.web]
    Web -->|searchProvider: dsh-web-tools| Hub[SearchHubProvider]

    Hub --> Registry[Provider Registry]
    Hub --> FB[Fallback]
    Hub --> Pools[Credential Pools]
    Hub --> Quota[Quota]
    Hub --> Health[Health / Stats]

    Registry --> T[Tavily]
    Registry --> E[Exa]
    Registry --> F[Firecrawl]
    Registry --> B[Brave]
    Registry --> Y[You.com]
    Registry --> J[Jina]
    Registry --> S[SearXNG]

Settings ↔ Host:

flowchart LR
    Client[Web Client] -->|/web-tools/api/*| Routes[Host routes]
    Routes --> Cfg[config]
    Routes --> Cred[credentials]
    Routes --> Test[provider test]
    Routes --> TS[test search]
    Routes --> Q[quota]
    Cfg --> S1[ctx.settings]
    Cred --> S2[ctx.credentials]

Routing uses no extra LLM requests and adds no model-visible tools.

Verification

ItemStatus
TypeScript / Build
Unit (pool / fallback / Jina / Brave header)
Route smoke (config · credential no-leak · quota · persist-before-ok · loopback/cross-site 403)
Runtime invariants (abort no-fallback · timeout real-abort then fallback · 401 marks key · fetch key rotation)
Tavily Search + Quota✅ E2E
Exa Search + credential pool✅ E2E
Firecrawl Search + Fetch + Quota✅ E2E
Brave / You / Jina / SearXNGadapter ready, E2E pending

Development

npm install
npx tsc -p tsconfig.json --noEmit           # Host
npx tsc -p tsconfig.client.json --noEmit    # Client
npx tsc -p tsconfig.build.json              # Build
npm test                                    # Unit + route smoke + runtime invariants

Local development needs DSH peer deps resolvable (link to the DSH profile's node_modules). If the plugin is missing from --dump-config, check bundle loading; if the settings card is missing, fully restart dsh web.

Provider development

Provider adapters live in src/host/providers/. Add a provider by implementing the ProviderAdapter contract and registering it; provide Fetch / Quota implementations if supported. The agent side needs no new tools. See CONTRIBUTING.md.

Roadmap

  • Brave quota full display (header parsing exists)
  • Serper, Parallel (OAuth), Perplexity providers
  • Real per-provider comparison and usage history
  • Optional: route web_fetch back to DSH's official HTTP Fetch semantics

Install with your coding agent

Expand the prompt
Install dsh-web-tools from:
https://github.com/A3Boy/dsh-web-tools

Requirements:
- Use the current DSH profile's standard plugin install flow.
- Do not read, print, or ask me to paste API keys.
- Do not modify DeepSeek Harness core.
- After installing, check the composed config with
  `dsh --profile web --dump-config`.
- Do not terminate or restart a running DSH process without asking.
- Report whether the plugin made it into the web profile.

Contributing

Issues and PRs are welcome. Before adding a search provider, review the existing adapters and CONTRIBUTING.md, and keep the provider layer simple.

License

MIT © A3Boy