En esta página
Mastra es un framework de agentes de IA con TypeScript como prioridad, diseñado para crear aplicaciones de IA listas para producción. CrawlForge da a esos agentes la capacidad de obtener, extraer y analizar datos web en vivo. Juntos, te permiten crear agentes que pueden investigar temas, monitorizar a la competencia y extraer datos estructurados de cualquier sitio web.
Esta guía te muestra cómo conectar las herramientas de CrawlForge a los agentes de Mastra con ejemplos de TypeScript funcionales.
Índice
- ¿Qué es Mastra?
- Requisitos previos
- Paso 1: Configura tu proyecto de Mastra
- Paso 2: Crea las definiciones de herramientas de CrawlForge
- Paso 3: Crea un agente de investigación web
- Paso 4: Crea un workflow de extracción de datos
- Paso 5: Añade manejo de errores y reintentos
- Referencia de costes en credits
- Visión general de la arquitectura
- Próximos pasos
¿Qué es Mastra?
Mastra es el framework de TypeScript moderno para aplicaciones y agentes con IA. Ofrece primitivas para la creación de agentes, integración de herramientas, workflows y memoria, todo con seguridad de tipos completa. Piénsalo como el Express.js de los agentes de IA: minimalista, componible y orientado a producción.
Los agentes de Mastra pueden usar herramientas externas a través de una interfaz de herramientas estandarizada. Las herramientas de CrawlForge se asignan directamente a esta interfaz, dando a tus agentes 20 capacidades de web scraping sin escribir código de cliente HTTP.
Requisitos previos
- Node.js 18+ y TypeScript 5+
- Una cuenta de CrawlForge con una API key (1.000 credits gratis)
- Familiaridad básica con TypeScript y async/await
Paso 1: Configura tu proyecto de Mastra
Crea un nuevo proyecto de Mastra e instala las dependencias:
npm create mastra@latest my-web-agent
cd my-web-agent
# Install additional dependencies
npm install dotenv node-fetchAñade tu API key de CrawlForge a .env:
CRAWLFORGE_API_KEY=cf_live_your_key_here
ANTHROPIC_API_KEY=sk-ant-your_key_herePaso 2: Crea las definiciones de herramientas de CrawlForge
Crea un archivo de herramientas que envuelva la API de CrawlForge como herramientas compatibles con Mastra:
// 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,
});
},
});Paso 3: Crea un agente de investigación web
Crea un agente que pueda buscar en la web y extraer contenido para tareas de investigación:
// 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,
},
});Ejecuta el agente:
// 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();Paso 4: Crea un workflow de extracción de datos
Los workflows de Mastra te permiten encadenar herramientas en pipelines deterministas. Aquí tienes un monitor de precios de la competencia:
// 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],
});Paso 5: Añade manejo de errores y reintentos
Los agentes en producción necesitan un manejo de errores resiliente. Aquí tienes un patrón para las llamadas a las herramientas de CrawlForge:
// 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 });
},
});Referencia de costes en credits
| Credits | Herramientas | Caso de uso en Mastra |
|---|---|---|
| 1 | fetch_url, extract_text, extract_links, extract_metadata | Obtención rápida de datos en herramientas de agentes |
| 2 | scrape_structured, extract_content, map_site, process_document, localization | Extracción en workflows, auditorías de sitios, procesamiento de documentos |
| 3 | track_changes, analyze_content | Detección de cambios, análisis de contenido |
| 4 | summarize_content, crawl_deep | Resúmenes, rastreo de múltiples páginas |
| 5 | search_web, batch_scrape, scrape_with_actions, stealth_mode | Agentes de investigación, operaciones masivas |
| 10 | deep_research | Agentes de análisis exhaustivo |
Visión general de la arquitectura
| Componente | Rol |
|---|---|
| Agente de Mastra | Orquesta las llamadas a herramientas, mantiene el contexto de la conversación |
| Herramientas de Mastra | Wrappers tipados alrededor de los endpoints de la API de CrawlForge |
| Workflow de Mastra | Pipelines deterministas de múltiples pasos para operaciones por lotes |
| API de CrawlForge | Ejecuta el web scraping, devuelve datos estructurados |
| Sistema de credits | Lleva el seguimiento del uso por API key, aplica los límites |
El agente de Mastra decide qué herramienta de CrawlForge llamar según la tarea. El wrapper de la herramienta maneja la comunicación HTTP, y CrawlForge ejecuta el scraping real. Los credits se deducen de forma atómica en cada llamada a herramienta exitosa.
Próximos pasos
- Guía de inicio rápido de Mastra -- documentación oficial de Mastra
- Referencia de la API de CrawlForge -- documentación completa de endpoints
- Crea un asistente de investigación -- patrón similar usando Claude directamente
- Automatización con Deep Research -- workflows de investigación avanzados
Crea hoy tu primer agente de IA con acceso a la web. Regístrate en CrawlForge (1.000 credits gratis), genera un proyecto de Mastra y da a tus agentes el poder de hacer scraping de toda la web.
Pruébalo tú mismo — sin necesidad de registrarte
Ejecuta cualquiera de las 27 herramientas de scraping y extracción de CrawlForge en el playground y luego empieza gratis con 1,000 credits.
1,000 credits gratis • Se recargan cada mes • No se requiere tarjeta de crédito
Etiquetas
Sobre el autor
Mantente al día con los últimos artículos
Recibe tutoriales, novedades del producto y consejos de web scraping en tu bandeja de entrada.
Sin spam. Cancela tu suscripción cuando quieras.