firecrawl-aisdk
v0.13.1
Published
Firecrawl tools for Vercel AI SDK - Web scraping and search capabilities for AI applications
Readme
Firecrawl AI SDK Tools
Firecrawl tools for Vercel AI SDK. Web scraping, search, interact, and crawling for AI applications.
Install
npm install firecrawl-aisdk aiexport FIRECRAWL_API_KEY=fc-your-key # https://firecrawl.devSupports AI SDK ai v7 (latest) and v6. Examples below use the v7 option names (isStepCount, instructions, onStepEnd, onToolExecutionEnd); on v6 use stepCountIs, system, onStepFinish, and experimental_onToolCallFinish — the stepLogger helper works with both. Note that ai@7 itself requires Node.js 22+.
Quick Start
import { generateText, isStepCount } from 'ai';
import { FirecrawlTools } from 'firecrawl-aisdk';
const { text } = await generateText({
model: 'anthropic/claude-sonnet-4-5',
tools: FirecrawlTools(),
stopWhen: isStepCount(30),
prompt: `
1. Use interact on Hacker News to identify the top story
2. Search for other perspectives on the same topic
3. Scrape the most relevant pages you found
4. Summarize everything you found
`,
});Model strings like
'anthropic/claude-sonnet-4-5'use AI Gateway. You can also use provider imports likeanthropic('claude-sonnet-4-5-20250514')from@ai-sdk/anthropic.
With logging:
import { generateText, isStepCount } from 'ai';
import { FirecrawlTools, stepLogger } from 'firecrawl-aisdk';
const logger = stepLogger();
const { text, usage } = await generateText({
model: 'anthropic/claude-sonnet-4-5',
tools: FirecrawlTools(),
stopWhen: isStepCount(30),
onStepEnd: logger.onStep,
onToolExecutionEnd: logger.onToolExecutionEnd,
prompt: `
1. Use interact on Hacker News to identify the top story
2. Search for other perspectives on the same topic
3. Scrape the most relevant pages you found
4. Summarize everything you found
`,
});
logger.close();
logger.summary(usage);FirecrawlTools
FirecrawlTools() bundles search, scrape, and interact by default.
// Defaults (search, scrape, interact)
FirecrawlTools();
// Add crawl + agent to defaults (poll auto-included)
FirecrawlTools({ crawl: true, agent: true });
// Disable interact, keep search + scrape
FirecrawlTools({ interact: false });
// Opt into deprecated browser compatibility
FirecrawlTools({ browser: {} });
// Set defaults for bundled tools
FirecrawlTools({
search: { limit: 5 },
scrape: { formats: ['markdown'], onlyMainContent: true },
interact: { profile: { name: 'my-session', saveChanges: true } },
});
// tools.systemPrompt has an auto-generated tool selection guide
const tools = FirecrawlTools();
const { text } = await generateText({
instructions: `${tools.systemPrompt}\n\n${yourPrompt}`,
tools,
// ...
});When scraping to answer a question about a page, prefer query format:
formats: [{ type: 'query', prompt: 'What does this page say about pricing and rate limits?' }]Use formats: ['markdown'] only when you need the full page content.
Bash (context-efficient research)
Scrape a page, then query it with rg, grep, sed, awk — the full markdown stays in a WASM sandbox (just-bash), never in the LLM context. The agent pulls back only the lines it needs.
import { generateText, isStepCount } from 'ai';
import { search, scrapeBash, stepLogger } from 'firecrawl-aisdk';
const logger = stepLogger();
const { text, usage } = await generateText({
model: 'anthropic/claude-haiku-4-5',
tools: { search, scrapeBash },
stopWhen: isStepCount(25),
onStepEnd: logger.onStep,
prompt: `Scrape https://www-cdn.anthropic.com/08ab9158070959f88f296514c21b7facce6f52bc.pdf
and answer these three questions with line citations:
1. What are all the concrete incidents of reckless or deceptive behavior documented?
2. What was the cover-up rate and how does Mythos compare to Opus 4.6 on deception?
3. What did interpretability analysis find during the cover-up incidents?`,
});
console.log(text);
logger.summary(usage);scrapeBash is one tool with two modes — pass url to scrape, pass command to query. No system prompt needed — the tool description guides the agent.
Token efficiency:
| | scrape → dump in context | scrape + bash | |---|---|---| | Tokens in context | 114,000 | ~3,000 | | Model required | Long-context (Opus/Sonnet) | Haiku works fine | | Cost per question | ~$1.71 | ~$0.05 | | Multi-hop | No | Yes — agent drills into what it finds |
Warm bash calls run in 1-5ms. Pages persist across calls with a 50MB LRU cap.
loadPage(url, markdown) loads content from any source — not just Firecrawl:
import { bash, loadPage } from 'firecrawl-aisdk';
await loadPage('https://example.com/docs', markdownFromAnywhere);
const { text } = await generateText({
model: 'anthropic/claude-haiku-4-5',
tools: { bash },
prompt: 'Search for pricing information',
});Individual Tools
Every tool can be used directly or called with options:
import { generateText } from 'ai';
import { scrape, search } from 'firecrawl-aisdk';
// Use directly
const { text } = await generateText({
model: 'anthropic/claude-sonnet-4-5',
prompt: 'Search for Firecrawl, then scrape the most relevant result',
tools: { search, scrape },
});
// Or call with options
const custom = scrape({ apiKey: 'fc-custom-key', apiUrl: 'https://...' });Interact
The interact tool creates a scrape-backed interactive session. Call start(url) to bootstrap a session and get the live view URL, then let the model reuse that session through the interact tool.
import { generateText, isStepCount } from 'ai';
import { interact, search } from 'firecrawl-aisdk';
const interactTool = interact();
console.log('Live view:', await interactTool.start('https://news.ycombinator.com'));
const { text } = await generateText({
model: 'anthropic/claude-sonnet-4-5',
tools: { interact: interactTool, search },
stopWhen: isStepCount(25),
prompt: 'Use interact on the current Hacker News session, find the top story, then search for more context.',
});
await interactTool.close();If you want the explicit interactive URL after startup, use interactTool.interactiveLiveViewUrl.
Reuse browser state across interact sessions with profiles:
const interactTool = interact({
profile: { name: 'my-session', saveChanges: true },
});browser() is now deprecated. Prefer interact().
Async Tools
Crawl, batch scrape, and agent return a job ID. Pair them with poll:
import { crawl, poll } from 'firecrawl-aisdk';
const { text } = await generateText({
model: 'anthropic/claude-sonnet-4-5',
prompt: 'Crawl https://docs.firecrawl.dev (limit 3 pages) and summarize',
tools: { crawl, poll },
});Logging
import { stepLogger, logStep } from 'firecrawl-aisdk';
// Detailed — call .summary() at the end
const logger = stepLogger();
const { text, usage } = await generateText({
/* ... */
onStepEnd: logger.onStep,
onToolExecutionEnd: logger.onToolExecutionEnd,
});
logger.close();
logger.summary(usage);
// Simple — one-liner per tool call
const { text } = await generateText({
/* ... */
onStepEnd: logStep,
});Exports
import {
// Core tools
search, // Search the web
scrape, // Scrape a single URL
map, // Discover URLs on a site
crawl, // Crawl multiple pages (async, use poll)
batchScrape, // Scrape multiple URLs (async, use poll)
agent, // Autonomous web research (async, use poll)
// Job management
poll, // Poll async jobs for results
status, // Check job status
cancel, // Cancel running jobs
// Browser (factory — has start/close lifecycle)
interact, // interact({ profile: { name: '...' } })
browser, // deprecated compatibility export
// Bash sandbox (scrape + query, context-efficient)
scrapeBash, // One tool: pass url to scrape, command to query
bash, // Standalone bash (use with loadPage for custom content)
loadPage, // Load markdown into sandbox from any source
// All-in-one bundle
FirecrawlTools, // FirecrawlTools({ search, scrape, interact, crawl, agent })
// Helpers
stepLogger, // Token stats per tool call
logStep, // Simple one-liner logging
} from 'firecrawl-aisdk';Development
pnpm test && pnpm buildLicense
MIT
