Integre o Firecrawl ao Mastra, o framework TypeScript para criar agentes e workflows de IA.
Configuração#
npm install @mastra/core firecrawl zodCrie o arquivo .env:
FIRECRAWL_API_KEY=your_firecrawl_keyOPENAI_API_KEY=your_openai_keyObservação: Se estiver usando Node < 20, instale
dotenve adicioneimport 'dotenv/config'ao seu código.
Fluxo de trabalho em múltiplas etapas#
Este exemplo demonstra um fluxo de trabalho completo que pesquisa, executa scraping e resume a documentação usando Firecrawl e Mastra.
import { createWorkflow, createStep } from "@mastra/core/workflows";import { z } from "zod";import { Firecrawl } from "firecrawl";import { Agent } from "@mastra/core/agent";const firecrawl = new Firecrawl({ apiKey: process.env.FIRECRAWL_API_KEY || "fc-YOUR_API_KEY"});const agent = new Agent({ name: "summarizer", instructions: "Você é um assistente útil que cria resumos concisos de documentação.", model: "openai/gpt-5-nano",});// Etapa 1: Pesquisar com o SDK do Firecrawlconst searchStep = createStep({ id: "search", inputSchema: z.object({ query: z.string(), }), outputSchema: z.object({ url: z.string(), title: z.string(), }), execute: async ({ inputData }: { inputData: { query: string } }) => { console.log(`Pesquisando: ${inputData.query}`); const searchResults = await firecrawl.search(inputData.query, { limit: 1 }); const webResults = (searchResults as any)?.web; if (!webResults || !Array.isArray(webResults) || webResults.length === 0) { throw new Error("Nenhum resultado de pesquisa encontrado"); } const firstResult = webResults[0]; console.log(`Encontrado: ${firstResult.title}`); return { url: firstResult.url, title: firstResult.title, }; },});// Etapa 2: Raspar a URL com o SDK do Firecrawlconst scrapeStep = createStep({ id: "scrape", inputSchema: z.object({ url: z.string(), title: z.string(), }), outputSchema: z.object({ markdown: z.string(), title: z.string(), }), execute: async ({ inputData }: { inputData: { url: string; title: string } }) => { console.log(`Raspando: ${inputData.url}`); const scrapeResult = await firecrawl.scrape(inputData.url, { formats: ["markdown"], }); console.log(`Raspado: ${scrapeResult.markdown?.length || 0} caracteres`); return { markdown: scrapeResult.markdown || "", title: inputData.title, }; },});// Etapa 3: Resumir com Claudeconst summarizeStep = createStep({ id: "summarize", inputSchema: z.object({ markdown: z.string(), title: z.string(), }), outputSchema: z.object({ summary: z.string(), }), execute: async ({ inputData }: { inputData: { markdown: string; title: string } }) => { console.log(`Resumindo: ${inputData.title}`); const prompt = `Resuma a documentação a seguir em 2-3 frases:\n\nTítulo: ${inputData.title}\n\n${inputData.markdown}`; const result = await agent.generate(prompt); console.log(`Resumo gerado`); return { summary: result.text }; },});// Criar fluxo de trabalhoexport const workflow = createWorkflow({ id: "firecrawl-workflow", inputSchema: z.object({ query: z.string(), }), outputSchema: z.object({ summary: z.string(), }), steps: [searchStep, scrapeStep, summarizeStep],}) .then(searchStep) .then(scrapeStep) .then(summarizeStep) .commit();async function testWorkflow() { const run = await workflow.createRunAsync(); const result = await run.start({ inputData: { query: "Firecrawl documentation" } }); if (result.status === "success") { const { summarize } = result.steps; if (summarize.status === "success") { console.log(`\n${summarize.output.summary}`); } } else { console.error("Fluxo de trabalho falhou:", result.status); }}testWorkflow().catch(console.error);Para mais exemplos, veja a documentação do Mastra.

