Modules
A small web search, scrape and research toolkit, in the spirit of Firecrawl or Exa.
The result of Perplexed.answer/2.
One unique search hit an answer considered.
One page an answer was written from. number is its citation number;
tier is the scraper that read it and cost what reading it cost.
Perplexed's settings.
One scraped page as Markdown, with how it was obtained.
Chooses which parts of a long page a model gets to read.
The behaviour that turns PDF bytes into Markdown for a scrape.
One-shot web answering, in fixed steps
Scrapes a URL to Markdown by climbing a ladder of Perplexed.Scrapers,
cheapest first.
The behaviour of one scrape tier, and the registry of built-in tiers.
Cloudflare Browser Run /markdown quick action as a Perplexed.Scraper:
loads the URL in headless Chrome, runs its JavaScript, and returns the
rendered page as Markdown.
DeepSeek Fetch API (POST /v1/tools/fetch) as a Perplexed.Scraper:
DeepSeek fetches the URL and returns the page as Markdown.
Plain HTTP as a Perplexed.Scraper, sending browser-like request headers.
Free and fast; the first tier of the default ladder.
Firecrawl v2 scrape as a Perplexed.Scraper.
HTTP through CloakedReq (Rust wreq) as a Perplexed.Scraper: the
request carries a real browser's TLS and HTTP/2 fingerprint and headers,
which gets past sites that refuse plain clients on that signal alone.
Swappable web search: every provider takes a query and returns normalized
Perplexed.Search.Hits, so callers change engines by changing one option.
Built-in providers, by name, with list price per successful request (USD,
as of 2026-11-10) used for per-run cost accounting
Cloudflare Web Search API (through AI Gateway) as a Perplexed.Search provider.
DeepSeek Search API (POST /v1/tools/search) as a Perplexed.Search provider.
Opt-in provider fallback: a list of provider specs, tried in order until one answers, such as free first and paid last
Firecrawl v2 search as a Perplexed.Search provider.
Merges ranked hit lists from several sources (SearXNG instances, search engines) into one list: de-duplicates by normalized URL, scores by reciprocal rank, boosts hits several engines agree on, and demotes hits that share no terms with the query.
One search result, normalized across providers.
One search call: the hits, the provider that answered, and what it cost.
Keyless web search through SearXNG metasearch instances, as a
Perplexed.Search provider (:searxng). Free: price 0.
Picks public SearXNG instances from searx.space's daily health check
(https://searx.space/data/instances.json).
The live set of public SearXNG instances, discovered instead of
hard-coded. Set searxng_instances: :auto and Perplexed.Search.SearXNG
asks this store for its instances.
Health, speed and rate-limit state for SearXNG instances, learned from the
searches this node makes. One pool runs under the :perplexed application;
tests and hosts can start more with :name.
:telemetry events Perplexed emits. Attach handlers to track spend or to
be told when a provider needs attention.
Refuses URLs that would point a scrape at a private network.
Judges whether fetched page text is worth handing to a model.
Mix Tasks
Fetches today's public SearXNG instances from searx.space, probes each start page from this machine, and prints which are up, fastest first.
Starts the app and serves Tidewave's MCP at
http://localhost:<port>/tidewave/mcp so a coding agent can evaluate code
inside the running project. Tidewave ships only as a Phoenix plug, so this
runs that plug under Bandit for a library with no endpoint.