Introduction

DeepSeek Harness (DSH) comes with two built-in internet tools, web_search and web_fetch, allowing the model to make queries or URL requests in its original manner. In the default bundle, web_fetch is disabled: the local HTTP fetching backend lacks SSRF protection, meaning URLs selected by the model will connect directly to any address your machine can access, including internal networks.

If you need your agent to stably read webpage content without opening model-specified connections locally, @firecrawl/dsh-firecrawl offers an alternative path: it delegates both search and fetching to Firecrawl’s infrastructure. The Harness process only submits requests to the API and retrieves markdown, without directly connecting to URLs chosen by the model.

What Is This

@firecrawl/dsh-firecrawl is a DSH internet plugin maintained by the Firecrawl team, classified as an “internet tool.” It does not introduce new tool names but instead redirects the web_search and web_fetch capabilities on Harness’s ctx.web seam to Firecrawl’s search and fetching backends.

The current version is 0.1.0, under the MIT license, supporting @deepseek-ai/dsh@0.1.0-rc.6, with Node.js requiring ^22.19.0 || >=24.0.0. DSH is still in developer preview, and future Harness version upgrades may require synchronized plugin updates.

Core Features

The plugin registers searchProvider: firecrawl and calls the Firecrawl /v2/search endpoint. By default, it only searches the web source; you can add news in the configuration to retrieve news results with publication dates. Optionally, you can enable scrapeContent to fetch the main text markdown for each result as a summary, providing more complete information at the cost of consuming more quota and increasing latency.

Fetching (web_fetch)

The plugin registers fetchProvider: firecrawl and calls the Firecrawl /v2/scrape endpoint, defaulting to markdown output and retaining only the main content (onlyMainContent: true). Compared to Harness’s built-in local fetching, Firecrawl offers JS rendering, anti-scraping handling, and PDF parsing, which is why this plugin can supplement fetching capabilities when the base bundle disables local web_fetch by default.

Security Boundary

The Harness process does not directly connect to URLs specified by the model; it POSTs the URL to the Firecrawl API, allowing Firecrawl’s infrastructure to fetch the page. This reduces local SSRF risk, but Firecrawl can still scrape any public URL requested by the model—not just addresses you have whitelisted in advance. If this behavior conflicts with your deployment strategy, you can disable web_fetch via configuration and retain only search.

Installation and Activation

Prerequisites:

  1. pnpm 10 or later;
  2. A Firecrawl API Key;
  3. A configured model provider in DSH.

You do not need to install dsh globally; the following commands use npx to pin @deepseek-ai/dsh@0.1.0-rc.6.

First, export the API Key in the terminal running Harness:

export FIRECRAWL_API_KEY="fc-your-key"

Install the plugin into the web profile:

npx --yes @deepseek-ai/dsh@0.1.0-rc.6 \
  plugin --profile web add @firecrawl/dsh-firecrawl

Stop any running Harness process and restart it:

npx --yes @deepseek-ai/dsh@0.1.0-rc.6 web

It is recommended to install via npm packages. If you must install from Git, pnpm 11 will intercept Git dependency prepare build scripts. As per the README, you need to add dependency keys with commit SHAs to the allowBuilds section in ~/.dsh/profiles/web/pnpm-workspace.yaml, which is a somewhat cumbersome process.

Verifying Installation

Check the merged profile configuration:

npx --yes @deepseek-ai/dsh@0.1.0-rc.6 \
  --profile web --dump-config | \
  grep -E 'searchProvider: firecrawl|fetchProvider: firecrawl|@firecrawl/dsh-firecrawl'

You should see both searchProvider and fetchProvider as firecrawl, along with two plugin entries: web-search-firecrawl and web-fetch-firecrawl. The presence of the built-in web-search-deepseek is normal, as actual search is determined by the searchProvider.

Then, ask the agent a question requiring real-time webpage information (e.g., inquire about Firecrawl’s recent changelog). If web_search or web_fetch cards appear in the conversation log, the tool is functioning correctly.

Typical Usage and Configuration

The default configuration works out of the box. When parameter tuning is needed, edit ~/.dsh/profiles/web/cordis.patch.yml (user-layer overrides have the highest priority).

Search example—search both web and news simultaneously, and fetch the main text summary for each result:

- id: web-search-firecrawl
  config:
    sources: [web, news]
    scrapeContent: true
    maxCharsPerResult: 4000

Fetch example—force fresh fetching, use stealth proxy to handle anti-scraping:

- id: web-fetch-firecrawl
  config:
    proxy: stealth
    maxAgeMs: 0

If you want to retain only search and disable fetching:

- id: tool-web
  config:
    fetch: false

The API Key should be placed in the environment variable FIRECRAWL_API_KEY and not written into cordis.patch.yml (which stores it in plaintext).

To uninstall the plugin:

npx --yes @deepseek-ai/dsh@0.1.0-rc.6 \
  plugin --profile web remove @firecrawl/dsh-firecrawl

After uninstallation, you need to restart Harness.

Use Cases and Notes

Who it’s for: Developers already using DSH’s web profile who need internet search and webpage content reading, and are willing to use Firecrawl’s quota to gain JS rendering and anti-scraping capabilities.

Runtime Permissions: The plugin loads with the current DSH process, inheriting that process’s environment and network access scope. Before installation, it is recommended to read the source repository and the MIT license to ensure compliance with your security and regulatory requirements.

Common Errors:

  • WEB_PROVIDER_CONFIGURED_UNAVAILABLE: The terminal running Harness has not set the FIRECRAWL_API_KEY.
  • WEB_PROVIDER_AMBIGUOUS: Multiple search providers are available but searchProvider is not locked down; it needs to be restored to firecrawl.
  • Provider still shows deepseek-official: Restart Harness and check if your own cordis.patch.yml is overriding the searchProvider.

The model decides whether to call web_search; if the response does not use the internet, try again with a prompt that explicitly requires current information.

Conclusion

@firecrawl/dsh-firecrawl does not alter Harness’s tool interface; it only replaces the backend implementations of web_search and web_fetch. For scenarios requiring stable internet access without local direct connections to model-specified URLs, it unifies fetching and search under Firecrawl while supplementing the web_fetch capability that is disabled by default in the base bundle.