Documentation
Introduction
Every web-search and scrape provider has a different API shape, auth scheme, and response format — and every agent framework has its own tool format. You end up rewriting glue for each combination. websearch-sdk normalizes both sides.
- Unified output —
search()andscrape()always return the same shape, regardless of provider. - Plug-and-play providers — one small factory per provider; switch by changing a single line.
- Framework adapters — turn the unified capabilities into framework-native tools via
web.tools().
Installation
Install the core package plus whichever provider you need. The Vercel AI SDK adapter is built into core; add ai (v5) only if you want agent tools.
Requires Node.js 18+ (uses the global fetch).
Quick start
Pass a provider to WebSearch, then call the unified API or hand tools to your agent.
Search
search() accepts a query string or an options object and resolves to a SearchResponse.
Pass provider-specific knobs that aren't part of the unified API through providerOptions— they're forwarded verbatim to the provider.
Scrape
scrape() resolves to a ScrapeResult. It throws a WebSearchErrorif the active provider doesn't support scraping (e.g. Brave, Serper).
Tools for agents
web.tools() returns a Vercel AI SDK ToolSet you can pass straight into generateText / streamText. The AI SDK adapter is built into core and used by default — no extra package or framework option required.
See Adapters for customizing tool names or targeting other frameworks.
Error handling
Errors are normalized to WebSearchError (with provider and optional status), so you can handle failures uniformly. A missing key throws MissingApiKeyError.
Unified types
search() resolves to a SearchResponse; scrape() to a ScrapeResult.
Architecture
core is provider-agnostic and ships the AI SDK adapter as the default framework; providers depend only on core. Adding a provider or framework is purely additive.
Adding a provider
Implement the SearchProvider contract from core, add a pure normalize* function that maps the raw response to the unified types, and unit-test it with a mocked fetch. No changes to core are required.