# Firecrawl AI SDK Tools

Firecrawl tools for [Vercel AI SDK](https://ai-sdk.dev). Web scraping, search, interact, and crawling for AI applications.

**[Full documentation →](https://docs.firecrawl.dev/developer-guides/llm-sdks-and-frameworks/vercel-ai-sdk)**

## Install

```bash
npm install firecrawl-aisdk ai
```

```bash
export FIRECRAWL_API_KEY=fc-your-key  # https://firecrawl.dev
```

## Quick Start

```typescript
import { generateText, stepCountIs } from 'ai';
import { FirecrawlTools } from 'firecrawl-aisdk';

const { text } = await generateText({
  model: 'anthropic/claude-sonnet-4-5',
  tools: FirecrawlTools(),
  stopWhen: stepCountIs(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](https://ai-sdk.dev/docs/ai-sdk-core/ai-gateway). You can also use provider imports like `anthropic('claude-sonnet-4-5-20250514')` from `@ai-sdk/anthropic`.

With logging:

```typescript
import { generateText, stepCountIs } 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: stepCountIs(30),
  onStepFinish: logger.onStep,
  experimental_onToolCallFinish: logger.onToolCallFinish,
  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.

```typescript
// 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({
  system: `${tools.systemPrompt}\n\n${yourPrompt}`,
  tools,
  // ...
});
```

When scraping to answer a question about a page, prefer query format:

```typescript
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.

## Individual Tools

Every tool can be used directly or called with options:

```typescript
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.

```typescript
import { generateText, stepCountIs } 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: stepCountIs(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:

```typescript
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`:

```typescript
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

```typescript
import { stepLogger, logStep } from 'firecrawl-aisdk';

// Detailed — call .summary() at the end
const logger = stepLogger();
const { text, usage } = await generateText({
  /* ... */
  onStepFinish: logger.onStep,
  experimental_onToolCallFinish: logger.onToolCallFinish,
});
logger.close();
logger.summary(usage);

// Simple — one-liner per tool call
const { text } = await generateText({
  /* ... */
  onStepFinish: logStep,
});
```

## Exports

```typescript
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

  // 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

```bash
pnpm test && pnpm build
```

## License

MIT
