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.0or>=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