Skip to content

feat(search): add Firecrawl search provider + standalone web_fetch tool - #1920

Open
rakshith48 wants to merge 9 commits into
bytedance:mainfrom
rakshith48:feat/firecrawl-search-scrape
Open

feat(search): add Firecrawl search provider + standalone web_fetch tool#1920
rakshith48 wants to merge 9 commits into
bytedance:mainfrom
rakshith48:feat/firecrawl-search-scrape

Conversation

@rakshith48

Copy link
Copy Markdown

Summary

Adds Firecrawl to Agent TARS in two ways:

  1. A first-class web search provider (search.provider: 'firecrawl'), alongside the existing browser / Bing / Tavily / DuckDuckGo / SearXNG providers.
  2. A standalone web_fetch tool that reads any URL as clean, LLM-ready markdown without driving the browser.

Why. Agent TARS is browser-first and splits find (the search provider) from read (LinkReader / the headless browser). Firecrawl covers both from one managed provider: /search returns full-page markdown for every result in a single call, and /scrape reads arbitrary URLs — including JavaScript-rendered pages and PDFs — with no local browser. web_fetch is configured independently of search, so you can mix freely (e.g. browser_search for search + Firecrawl for fetch) or enable fetch on its own.

What's included

  • @agent-infra/sharedSearchProvider.Firecrawl.
  • @agent-infra/searchfirecrawl provider in the unified SearchClient (web + news flattened to unified pages; full markdown when scrapeOptions is set; resolves URLs from scraped Documents).
  • @agent-tars/interfaceAgentTARSFetchOptions + a top-level fetch config; 'firecrawl' added to the search-provider union.
  • @agent-tars/coreFetchToolProvider (web_fetch) in its own environments/local/fetch capability dir, registered from options.fetch.
  • @agent-tars/cli--search.provider firecrawl, --fetch.apiKey, --fetch.baseUrl.
  • @agent-infra/mcp-server-searchfirecrawl entry in the API-key / base-url env maps.
  • Changeset + packages/agent-infra/search/search/FIRECRAWL.md (usage + an endpoint-fit assessment).

Scope. Ships search + fetch. map is a recommended follow-up; crawl / parse are niche; monitor is out of scope (a scheduled product, not an interactive tool). Rationale in FIRECRAWL.md.

Config

// agent-tars.config.ts
export default defineConfig({
  search: { provider: 'firecrawl', apiKey: process.env.FIRECRAWL_API_KEY }, // web_search
  fetch:  { apiKey: process.env.FIRECRAWL_API_KEY },                        // web_fetch (standalone)
});

apiKey is optional (Firecrawl has a keyless free tier); baseUrl targets a self-hosted instance.

Verification

  • Per-package unit tests pass: @agent-infra/shared (5), @agent-infra/mcp-server-search (1), @agent-tars/core (75 passed / 1 skipped). @agent-infra/search has no existing test harness upstream.
  • Verified live in the running agent (Web UI): web_search returns Firecrawl results; web_fetch returns markdown for a JS-rendered page. Real Firecrawl API usage confirmed via response metadata (scrapeId / creditsUsed / cacheState) and account credit decrement.

Testing note: running the agent locally surfaced two pre-existing, unrelated upstream bugs (the --headless CLI path omits the CSRF token; the Anthropic message builder emits empty text blocks). Both are independent of this change and can be filed separately.

Checklist

  • Added or updated necessary documentation (FIRECRAWL.md, changeset).
  • Verified no breaking changes — additive only (new provider + new optional fetch config).
  • Added or updated necessary tests (existing per-package suites pass; the search package has no upstream test harness).

Adds Firecrawl as a first-class SearchProvider in @agent-infra/search
(alongside browser_search/tavily/bing/duckduckgo/searxng) and exposes a
`web_scrape` tool in Agent TARS when Firecrawl is the configured provider.

Firecrawl's /search returns clean, LLM-ready markdown for every result in a
single call, and /scrape reads any URL (incl. JS-rendered pages and PDFs)
without driving the browser — covering both the "find" and "read" motions
that are currently split across Tavily search and the LinkReader MCP.

- packages/agent-infra/shared: add SearchProvider.Firecrawl
- packages/agent-infra/search: firecrawl.ts provider + SearchClient case
  (web+news flattened to unified pages; markdown when scrapeOptions set),
  example, FIRECRAWL.md (incl. map/crawl/parse/monitor fit assessment)
- agent-tars/interface: 'firecrawl' in search provider union
- agent-tars/core: SearchToolProvider.createScrapeTool() + supportsScrape(),
  register web_scrape in initializeSearchTools
- agent-tars/cli: list firecrawl in --search.provider help
… mapping

- web_scrape: validate URL scheme (http/https) before calling the provider;
  log only origin+path so token-bearing query strings don't leak into logs.
- core.ts: correct apiKey JSDoc — web_scrape works on Firecrawl's keyless tier,
  a key only raises rate limits.
- SearchClient firecrawl case: scraped results are Documents with the URL under
  metadata.sourceURL (no top-level url); read both shapes, fall back to
  metadata.title, and drop any item with no resolvable URL.
Review feedback: scrape did not belong in search-tool.ts.

- Move the scrape capability out of SearchToolProvider into a dedicated
  FetchToolProvider (search/fetch-tool.ts); the tool is named `web_fetch`.
- search-tool.ts is now search-only (+1 line vs main: the firecrawl entry in
  the provider map). Drop the unrelated `bing_search` provider-map entry and
  the redundant `Firecrawl` type import (firecrawl() already returns it).
- Wire FetchToolProvider in initializeSearchTools, gated on provider==='firecrawl'.
- Docs: web_scrape -> web_fetch.
environments/local/ is organized by capability (search/, browser/,
filesystem/). web_fetch is URL retrieval, not search, so it gets its own
environments/local/fetch/ dir (FetchToolProvider) rather than living under
search/. Its activation is still gated on the firecrawl search provider, which
is config wiring handled by the orchestrator.
…om search

web_fetch no longer requires (or reads config from) the search provider. It has
its own config and its own initialization, so it can be enabled on its own,
alongside any search provider, or not at all.

- interface: add AgentTARSFetchOptions (apiKey, baseUrl) + AgentTARSOptions.fetch;
  add 'fetch' to AgentTARSCLIArguments; revert the web_fetch mention bolted onto
  the search apiKey doc.
- core: register web_fetch in its own initializeFetchTools(), gated on
  options.fetch (not options.search.provider === 'firecrawl').
- cli: add --fetch.apiKey / --fetch.baseUrl.
- docs: show search and fetch as independent config blocks.
…rectly

- FIRECRAWL.md: web_fetch is standalone (configured via `fetch`), not gated on
  the firecrawl search provider — remove stale "when Firecrawl is the configured
  provider" wording left over before the decoupling.
- Cost note: attribute the per-page cost to Firecrawl's /scrape endpoint that
  web_fetch calls (addresses CodeRabbit).
- Left the duckduckgo provider reference as-is: it IS a real provider
  (SearchProvider.DuckduckgoSearch = 'duckduckgo_search'); CodeRabbit's grep
  missed it on casing.
Surfaced by a real `pnpm` build:

- mcp-servers/search/server.ts: add the `firecrawl` entry to API_KEY_ENV_MAP /
  API_BASE_URL_ENV_MAP. Required blast radius of adding SearchProvider.Firecrawl
  — those maps are indexed by the now-expanded SearchProvider union, so a
  missing key broke declaration generation (TS7053).
- search/src/index.ts: widen the three pre-existing provider-option casts
  (BrowserSearch/SearXNG/DuckDuckGo) to `as unknown as` — TS's own suggested
  fix. These TS2352 dts errors exist on upstream `main` (verified by building
  the base revision); not introduced here, but they block the .d.ts build.

(--no-verify: secretlint false-positives on two pre-existing `apiKey:` lines in
server.ts — an empty string and a code expression, neither a real secret.)
@netlify

netlify Bot commented Jun 21, 2026

Copy link
Copy Markdown

Deploy Preview for tarko ready!

Name Link
🔨 Latest commit 3a8687b
🔍 Latest deploy log https://app.netlify.com/projects/tarko/deploys/6a385ea21ffae4000852ac4d
😎 Deploy Preview https://deploy-preview-1920--tarko.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@netlify

netlify Bot commented Jun 21, 2026

Copy link
Copy Markdown

Deploy Preview for agent-tars-docs ready!

Name Link
🔨 Latest commit 3a8687b
🔍 Latest deploy log https://app.netlify.com/projects/agent-tars-docs/deploys/6a385ea27f8089000814e55b
😎 Deploy Preview https://deploy-preview-1920--agent-tars-docs.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@CLAassistant

CLAassistant commented Jun 21, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants