Preface

DeepSeek Harness (DSH) breaks down internet capabilities into two native tools: web_search and web_fetch, with the ctx.web service mounting specific providers. The default assembly often relies on a cloud-based search backend; if you want both search and fetching to run on your own controllable infrastructure, you need to integrate a separate provider and handle issues like aligning Cordis assembly, authentication, and timeouts with the native tools.

dsh-surfing-plugin takes a different approach: it registers two self-hosted providers with DSH—search via SearXNG and fetching via Crawl4AI. The native tool names, parameters, rendering, timeouts, cancellation, and result limits remain unchanged; only the backend implementation is replaced.

What This Is

dsh-surfing-plugin, published by maintainer cyijun, is categorized as an internet tool. It registers surfing-searxng (corresponding to web_search) and surfing-crawl4ai (corresponding to web_fetch) in DSH’s ctx.web layer, interfacing with SearXNG’s /search and Crawl4AI’s /crawl respectively. The plugin’s accompanying cordis.patch.yml mounts the plugin, selects the two providers, and adds a fetch-only native tool consumer to ensure proper division of labor in both headless and Web UI DSH assemblies: web_search is mounted by the assembly or Agent Preset, while the fetch side is uniformly consumed by this consumer.

Architecture and Data Flow

flowchart LR
  A[Native DSH web_search] --> B[surfing-searxng provider]
  B --> C[SearXNG /search]
  D[Native DSH web_fetch] --> E[surfing-crawl4ai provider]
  E --> F[Crawl4AI /crawl]

The SearXNG provider sends a form request to POST /search with format=json, preserves absolute HTTP(S) result URLs, deduplicates by URL, and maps title, content, and publishedDate to DSH sources; non-empty SearXNG answers are returned as result content.

The Crawl4AI provider sends a minimal body { "urls": [url] } to POST /crawl; model inputs cannot include browser or crawler configurations. Only HTTP(S) targets are accepted; a non-2xx status code on the target page can still be returned as a successful DSH fetch result, while Crawl4AI API-level failures are converted into structured WebError.

Environment and Dependencies

Prerequisites before running:

  • Node.js ^22.19.0 or >=24.0.0
  • DeepSeek Harness >=0.1.0-rc.6 <0.2.0
  • Accessible SearXNG and Crawl4AI services
  • SearXNG configuration with JSON enabled in search.formats

Installation and Activation

Endpoints can be filled with the service root address or the full /search and /crawl URLs. First, export the environment variables:

export SEARXNG_URL=http://127.0.0.1:8080
export CRAWL4AI_URL=http://127.0.0.1:11235

# The current Crawl4AI distribution enables Bearer authentication by default
export CRAWL4AI_API_TOKEN=replace-with-your-token

Local checkout installation to the web profile:

dsh plugin --profile web add .
dsh --profile web --dump-config
dsh --profile web

After npm publication, install using the package name:

dsh plugin --profile web add dsh-surfing-plugin

Removal:

dsh plugin --profile web remove dsh-surfing-plugin

To pin a version from GitHub by commit, the command given in the README is:

dsh plugin --profile web add github:cyijun/surfing-plugin#COMMIT_SHA

If using pnpm 10 or above, Git dependencies might be blocked on first installation due to build-script approval; write the package name from the prompt into the profile’s pnpm-workspace.yaml and retry:

allowBuilds:
  dsh-surfing-plugin: true

The npm package and pnpm pack output already include lib/, so the above approval is usually unnecessary.

Configuration

Explicit configuration takes precedence over environment variables. You can override the corresponding lines for this plugin in $DSH_HOME/profiles/web/cordis.patch.yml:

- id: surfing-plugin
  config:
    searxng:
      url: https://search.example.com
      apiKeyEnv: MY_SEARXNG_KEY
      authHeader: X-API-Key
      authScheme: ''
      language: en
      categories: general,news
      safeSearch: 1
      timeRange: month
    crawl4ai:
      url: https://crawl.example.com
      apiKeyEnv: CRAWL4AI_API_TOKEN
      authHeader: Authorization
      authScheme: Bearer
      markdownMode: raw
      maxContentChars: 100000

Common fields and their corresponding environment variables are as follows (excerpt):

Field Environment Variable or Default Meaning
searxng.url SEARXNG_URL Service root or /search endpoint
searxng.apiKeyEnv SEARXNG_API_KEY Optional environment variable for the key
searxng.language Server default SearXNG language parameter
searxng.categories Server default Comma-separated categories
searxng.safeSearch Server default 0, 1, or 2
searxng.timeRange None day, month, or year
crawl4ai.url CRAWL4AI_URL Service root or /crawl endpoint
crawl4ai.apiKeyEnv CRAWL4AI_API_TOKEN Optional environment variable for the key
crawl4ai.markdownMode raw Prefer raw, fit, or citations markdown
crawl4ai.maxContentChars 100000 Content limit before returning to DSH

A literal apiKey takes precedence over the environment variable pointed to by apiKeyEnv; no authentication header is sent when no key is available. fit and citations modes fall back to raw markdown if preferred fields are empty; HTML is only returned when no markdown representation exists.

Typical Usage

After completing installation and starting dsh --profile web, the Agent side still calls the native web_search and web_fetch; no changes to tool names or parameters are needed. Search requests go through surfing-searxng to the self-hosted SearXNG; fetching requests go through surfing-crawl4ai to Crawl4AI. Queries and natural language URL intents you pose in the conversation follow DSH’s original semantic flow, but the backend no longer relies on the default cloud search provider.

When developing or self-testing the plugin itself, the repository convention is:

corepack pnpm install
corepack pnpm run check
corepack pnpm pack

Applicable Scenarios and Notes

Suitable for developers who need to use self-hosted search and fetching uniformly within DSH and have deployed or can deploy SearXNG and Crawl4AI. The plugin runs with the current dsh process permissions; before installation, you should read the source code and MIT license, and assess the network exposure of the backend services yourself.

Regarding security, the README recommends: prioritize using apiKeyEnv, do not commit credentials to the repository; use HTTPS for non-loopback addresses; Crawl4AI handles browser isolation, target network access, and SSRF policies, so restrict its network and authentication before exposing it externally; backend redirects will be rejected to prevent credentials from being forwarded to other endpoints.

The DSH ecosystem follows the “everything is a plugin” philosophy; community directories like SkillHub are independent sites with no official affiliation with DeepSeek / High-Flyer. This plugin has about 13 stars on GitHub, belonging to the community internet tools category.

Links

  • SkillHub Directory Page: https://www.skillhub.cn/plugins/cyijun/dsh-surfing-plugin
  • GitHub Repository: https://github.com/cyijun/dsh-surfing-plugin