CrawlForge
HomePlaygroundUse CasesIntegrationsPricingDocumentationBlog
How to Use CrawlForge with Mastra AI Agents
Tutorials
Back to Blog
Tutorials

How to Use CrawlForge with Mastra AI Agents

C
CrawlForge Team
Engineering Team
April 21, 2026
7 min read

On this page

Mastra is a TypeScript-first AI agent framework designed for building production-ready AI applications. CrawlForge gives those agents the ability to fetch, extract, and analyze live web data. Together, they let you build agents that can research topics, monitor competitors, and extract structured data from any website.

This guide shows you how to wire CrawlForge tools into Mastra agents with working TypeScript examples.

Table of Contents

  • What Is Mastra?
  • Prerequisites
  • Step 1: Set Up Your Mastra Project
  • Step 2: Create CrawlForge Tool Definitions
  • Step 3: Build a Web Research Agent
  • Step 4: Build a Data Extraction Workflow
  • Step 5: Add Error Handling and Retries
  • Credit Cost Reference
  • Architecture Overview
  • Next Steps

What Is Mastra?

Mastra is the modern TypeScript framework for AI-powered applications and agents. It provides primitives for agent creation, tool integration, workflows, and memory -- all with full type safety. Think of it as the Express.js of AI agents: minimal, composable, and production-oriented.

Mastra agents can use external tools through a standardized tool interface. CrawlForge tools map directly to this interface, giving your agents 20 web scraping capabilities without writing HTTP client code.

Prerequisites

  • Node.js 18+ and TypeScript 5+
  • A CrawlForge account with an API key (1,000 free credits)
  • Basic familiarity with TypeScript and async/await

Step 1: Set Up Your Mastra Project

Create a new Mastra project and install dependencies:

Bash
npm create mastra@latest my-web-agent
cd my-web-agent

# Install additional dependencies
npm install dotenv node-fetch

Add your CrawlForge API key to .env:

Bash
CRAWLFORGE_API_KEY=cf_live_your_key_here
ANTHROPIC_API_KEY=sk-ant-your_key_here

Step 2: Create CrawlForge Tool Definitions

Create a tools file that wraps CrawlForge's API as Mastra-compatible tools:

Typescript
// src/tools/crawlforge.ts
import { createTool } from '@mastra/core';
import { z } from 'zod';

const CRAWLFORGE_BASE = 'https://crawlforge.dev/api/v1/tools';

async function callCrawlForge(tool: string, params: Record<string, unknown>) {
  const response = await fetch(`${CRAWLFORGE_BASE}/${tool}`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${process.env.CRAWLFORGE_API_KEY}`,
    },
    body: JSON.stringify(params),
  });

  if (!response.ok) {
    throw new Error(`CrawlForge ${tool} failed: ${response.status}`);
  }

  return response.json();
}

// Extract clean content from a URL (2 credits)
export const extractContent = createTool({
  id: 'crawlforge-extract-content',
  description: 'Extract clean, readable content from any web page. Costs 2 credits.',
  inputSchema: z.object({
    url: z.string().url().describe('The URL to extract content from'),
  }),
  execute: async ({ context }) => {
    return callCrawlForge('extract_content', { url: context.url });
  },
});

// Search the web (5 credits)
export const searchWeb = createTool({
  id: 'crawlforge-search-web',
  description: 'Search the web using Google. Returns titles, URLs, and snippets. Costs 5 credits.',
  inputSchema: z.object({
    query: z.string().describe('Search query string'),
    limit: z.number().optional().default(10).describe('Max results to return'),
  }),
  execute: async ({ context }) => {
    return callCrawlForge('search_web', {
      query: context.query,
      limit: context.limit,
    });
  },
});

// Fetch raw HTML (1 credit)
export const fetchUrl = createTool({
  id: 'crawlforge-fetch-url',
  description: 'Fetch raw HTML content from a URL. Cheapest option at 1 credit.',
  inputSchema: z.object({
    url: z.string().url().describe('The URL to fetch'),
  }),
  execute: async ({ context }) => {
    return callCrawlForge('fetch_url', { url: context.url });
  },
});

// Extract structured data with CSS selectors (2 credits)
export const scrapeStructured = createTool({
  id: 'crawlforge-scrape-structured',
  description: 'Extract data using CSS selectors. Costs 2 credits.',
  inputSchema: z.object({
    url: z.string().url().describe('The URL to scrape'),
    selectors: z.record(z.string()).describe('CSS selectors mapping field names to selectors'),
  }),
  execute: async ({ context }) => {
    return callCrawlForge('scrape_structured', {
      url: context.url,
      selectors: context.selectors,
    });
  },
});

Step 3: Build a Web Research Agent

Create an agent that can search the web and extract content for research tasks:

Typescript
// src/agents/researcher.ts
import { Agent } from '@mastra/core';
import { searchWeb, extractContent, fetchUrl } from '../tools/crawlforge';

export const researcherAgent = new Agent({
  name: 'Web Researcher',
  instructions: `You are a web research agent. When asked to research a topic:
    1. Use search_web to find relevant pages (5 credits)
    2. Use extract_content on the top 2-3 results (2 credits each)
    3. Synthesize findings into a structured summary

    Always report the total credits used.
    Prefer fetch_url (1 credit) over extract_content (2 credits) when you only need raw HTML.
    Never use search_web if the user provides a specific URL.`,
  model: {
    provider: 'ANTHROPIC',
    name: 'claude-sonnet-4-20250514',
  },
  tools: {
    searchWeb,
    extractContent,
    fetchUrl,
  },
});

Run the agent:

Typescript
// src/index.ts
import { researcherAgent } from './agents/researcher';

async function main() {
  const result = await researcherAgent.generate(
    'Research the current state of MCP protocol adoption. ' +
    'Which companies are using it and for what use cases?'
  );

  console.log(result.text);
  // Output: Structured research summary with sources
  // Credits used: ~11 (1 search + 3 extractions)
}

main();

Step 4: Build a Data Extraction Workflow

Mastra workflows let you chain tools into deterministic pipelines. Here is a competitive pricing monitor:

Typescript
// src/workflows/pricing-monitor.ts
import { Workflow, Step } from '@mastra/core';
import { searchWeb, scrapeStructured } from '../tools/crawlforge';

const findCompetitors = new Step({
  id: 'find-competitors',
  execute: async ({ context }) => {
    // Search for competitors (5 credits)
    const results = await searchWeb.execute({
      context: { query: `${context.product} pricing plans`, limit: 5 },
    });
    return { urls: results.results.map((r: { link: string }) => r.link) };
  },
});

const extractPricing = new Step({
  id: 'extract-pricing',
  execute: async ({ context }) => {
    const pricingData = [];

    // Extract pricing from each competitor (2 credits each)
    for (const url of context.urls.slice(0, 3)) {
      try {
        const data = await scrapeStructured.execute({
          context: {
            url,
            selectors: {
              planNames: '.plan-name, .pricing-tier h3',
              prices: '.price, .plan-price',
              features: '.feature-list li, .plan-features li',
            },
          },
        });
        pricingData.push({ url, ...data });
      } catch (error) {
        pricingData.push({ url, error: 'Extraction failed' });
      }
    }

    return { pricingData };
    // Total: 5 + (3 * 2) = 11 credits
  },
});

export const pricingMonitorWorkflow = new Workflow({
  name: 'Pricing Monitor',
  steps: [findCompetitors, extractPricing],
});

Step 5: Add Error Handling and Retries

Production agents need resilient error handling. Here is a pattern for CrawlForge tool calls:

Typescript
// src/tools/resilient-crawlforge.ts
import { createTool } from '@mastra/core';
import { z } from 'zod';

const CRAWLFORGE_BASE = 'https://crawlforge.dev/api/v1/tools';

async function callWithRetry(
  tool: string,
  params: Record<string, unknown>,
  maxRetries = 2
): Promise<unknown> {
  let lastError: Error | null = null;

  for (let attempt = 0; attempt <= maxRetries; attempt++) {
    try {
      const response = await fetch(`${CRAWLFORGE_BASE}/${tool}`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'Authorization': `Bearer ${process.env.CRAWLFORGE_API_KEY}`,
        },
        body: JSON.stringify(params),
      });

      if (response.status === 429) {
        // Rate limited -- wait and retry
        const retryAfter = parseInt(response.headers.get('Retry-After') || '2');
        await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
        continue;
      }

      if (!response.ok) {
        throw new Error(`HTTP ${response.status}: ${await response.text()}`);
      }

      return response.json();
    } catch (error) {
      lastError = error as Error;
      if (attempt < maxRetries) {
        await new Promise(resolve => setTimeout(resolve, 1000 * (attempt + 1)));
      }
    }
  }

  throw lastError;
}

export const resilientExtractContent = createTool({
  id: 'crawlforge-extract-content-resilient',
  description: 'Extract content with automatic retry on failure. 2 credits per successful call.',
  inputSchema: z.object({
    url: z.string().url(),
  }),
  execute: async ({ context }) => {
    return callWithRetry('extract_content', { url: context.url });
  },
});

Credit Cost Reference

CreditsToolsMastra Use Case
1fetch_url, extract_text, extract_links, extract_metadataQuick data fetching in agent tools
2scrape_structured, extract_content, map_site, process_document, localizationWorkflow extraction, site audits, document processing
3track_changes, analyze_contentChange detection, content analysis
4summarize_content, crawl_deepSummaries, multi-page crawling
5search_web, batch_scrape, scrape_with_actions, stealth_modeResearch agents, bulk operations
10deep_researchComprehensive analysis agents

Architecture Overview

ComponentRole
Mastra AgentOrchestrates tool calls, maintains conversation context
Mastra ToolsTyped wrappers around CrawlForge API endpoints
Mastra WorkflowDeterministic multi-step pipelines for batch operations
CrawlForge APIExecutes web scraping, returns structured data
Credit SystemTracks usage per API key, enforces limits

The Mastra agent decides which CrawlForge tool to call based on the task. The tool wrapper handles HTTP communication, and CrawlForge executes the actual scraping. Credits are deducted atomically on each successful tool call.

Next Steps

  • Mastra Quickstart Guide -- official Mastra documentation
  • CrawlForge API Reference -- full endpoint documentation
  • Build a Research Assistant -- similar pattern using Claude directly
  • Deep Research Automation -- advanced research workflows

Build your first web-aware AI agent today. Sign up for CrawlForge (1,000 free credits), scaffold a Mastra project, and give your agents the power to scrape the entire web.

Try this yourself — no signup needed

Run any of CrawlForge's 27 scraping and extraction tools in the playground, then start free with 1,000 credits.

1,000 free credits • Refills monthly • No credit card required

Tags

mastraai-agentsmcpintegrationtutorialtypescriptweb-scraping

About the Author

C

CrawlForge Team

Engineering Team

Building the most comprehensive web scraping MCP server. We create tools that help developers extract, analyze, and transform web data for AI applications.

Stay updated with the latest insights

Get tutorials, product updates, and web scraping tips delivered to your inbox.

No spam. Unsubscribe anytime.

Put this into practice

Test CrawlForge's tools on any URL — free, no signup.

On this page

Related Articles

How to Use CrawlForge with LangGraph Agents
Tutorials

How to Use CrawlForge with LangGraph Agents

Build stateful web scraping agents with LangGraph and CrawlForge. TypeScript guide covering graph nodes, state management, and conditional scraping flows.

C
CrawlForge Team
|
Apr 24
|
8m
How to Build a Web-Scraping MCP Server in TypeScript (2026)
Tutorials

How to Build a Web-Scraping MCP Server in TypeScript (2026)

Build a working web-scraping MCP server in TypeScript with the official SDK: a minimal server, a real cheerio scraping tool, testing, and Claude Desktop setup.

C
CrawlForge Team
|
Jun 16
|
12m
How to Use CrawlForge with Dify Workflows
Tutorials

How to Use CrawlForge with Dify Workflows

Add CrawlForge as a custom tool in Dify for web scraping in your LLM app workflows. No-code and API integration guide with workflow examples.

C
CrawlForge Team
|
Apr 22
|
7m

Footer

CrawlForge

Enterprise web scraping for AI Agents. 27 specialized MCP tools designed for modern developers building intelligent systems.

Product

  • Features
  • Playground
  • Pricing
  • Use Cases
  • Integrations
  • Alternatives
  • Changelog

Resources

  • Getting Started
  • API Reference
  • Templates
  • Guides
  • Blog
  • Glossary
  • FAQ
  • Sitemap

Developers

  • MCP Protocol
  • Claude Desktop
  • Cursor IDE
  • LangChain
  • LlamaIndex

Company

  • About
  • Contact
  • Privacy
  • Terms
  • Acceptable Use
  • Cookies

Stay updated

Get the latest updates on new tools and features.

Built with Next.js and MCP protocol

© 2025-2026 CrawlForge. All rights reserved.