En esta página
El Model Context Protocol (MCP) es la forma en que asistentes de IA como Claude llaman a herramientas externas. Si quieres que tu asistente haga scraping de la web, una opción es crear tu propio MCP server. Esta guía te lleva paso a paso por un MCP server de web scraping mínimo y funcional en TypeScript, y es honesta sobre dónde termina el protocolo y dónde empieza la parte difícil del scraping.
Al final tendrás un servidor que Claude puede llamar, además de una idea clara de cuándo crear el tuyo es la decisión correcta frente a apuntar tu agente a un MCP server de scraping gestionado.
Tabla de contenidos
- Qué es realmente un MCP server
- Requisitos previos
- Paso 1: configuración del proyecto
- Paso 2: un MCP server mínimo
- Paso 3: añade una herramienta de scraping real
- Paso 4: pruébalo con el MCP Inspector
- Paso 5: conéctalo a Claude Desktop
- La parte difícil: el scraping en producción
- Construir vs comprar
- Trucos y trampas
Qué es realmente un MCP server
Un MCP server expone tres tipos de capacidad a un cliente de IA:
- Tools -- funciones invocadas por el modelo que hacen trabajo o provocan efectos secundarios. Una herramienta
scrape_pagees una de ellas. - Resources -- datos de solo lectura expuestos por URI para contexto, sin cómputo pesado.
- Prompts -- plantillas de mensaje reutilizables y activadas por el usuario.
Para scraping, lo que quieres es una tool. El cliente (Claude Desktop, Claude Code, Cursor) muestra tu herramienta al modelo; cuando un prompt necesita datos en vivo, el modelo emite una llamada de herramienta estructurada, tu servidor la ejecuta y el resultado vuelve. Para conocer más a fondo el protocolo, consulta MCP vs REST.
Requisitos previos
- Node.js 18+ (compruébalo con
node --version) - Familiaridad básica con TypeScript
- El SDK oficial y una librería de esquemas:
npm install @modelcontextprotocol/sdk zodEste tutorial apunta a @modelcontextprotocol/sdk v1.x (actualmente 1.29.x), que los mantenedores recomiendan para producción. Una línea v2 que se divide en @modelcontextprotocol/server y @modelcontextprotocol/client está en pre-alpha; cuando se estabilice cambiarán los imports, pero los conceptos de abajo siguen siendo válidos.
Paso 1: configuración del proyecto
Crea un proyecto y márcalo como módulo ES; el SDK es solo ESM:
// package.json
{
"name": "scraper-mcp",
"version": "1.0.0",
"type": "module",
"bin": { "scraper-mcp": "build/index.js" },
"scripts": { "build": "tsc" }
}Un tsconfig.json mínimo apuntando a ES2022:
{
"compilerOptions": {
"target": "ES2022",
"module": "Node16",
"moduleResolution": "Node16",
"outDir": "build",
"strict": true
},
"include": ["src/**/*.ts"]
}Paso 2: un MCP server mínimo
Aquí tienes el servidor más pequeño que registra una herramienta y se comunica con un cliente por stdio. Las extensiones .js en los imports son obligatorias bajo ESM:
// src/index.ts
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
const server = new McpServer({ name: "scraper", version: "1.0.0" });
server.registerTool(
"scrape_page",
{
title: "Scrape Page",
description: "Fetch a URL and return its raw HTML",
inputSchema: { url: z.string().url() }, // raw Zod shape, not z.object(...)
},
async ({ url }) => {
const res = await fetch(url);
const html = await res.text();
return { content: [{ type: "text", text: html }] };
}
);
const transport = new StdioServerTransport();
await server.connect(transport);Eso es un MCP server completo. La API actual es server.registerTool(name, config, handler); el inputSchema es una forma de Zod en crudo ({ url: z.string() }), no un z.object() envuelto. Compílalo con npm run build.
Paso 3: añade una herramienta de scraping real
Devolver HTML en crudo rara vez resulta útil: lo que quieres es texto limpio. Añade un parser de HTML:
npm install cheerioimport * as cheerio from "cheerio";
server.registerTool(
"scrape_text",
{
title: "Scrape Visible Text",
description: "Fetch a URL and return readable text, stripped of scripts and chrome",
inputSchema: { url: z.string().url() },
},
async ({ url }) => {
const res = await fetch(url, { headers: { "User-Agent": "scraper-mcp/1.0" } });
if (!res.ok) {
return {
content: [{ type: "text", text: "Request failed with status " + res.status }],
isError: true,
};
}
const $ = cheerio.load(await res.text());
$("script, style, nav, footer").remove();
const text = $("body").text().replace(/\s+/g, " ").trim();
return { content: [{ type: "text", text: text.slice(0, 8000) }] };
}
);Devuelve isError: true ante fallos para que el modelo pueda reaccionar en lugar de tratar una cadena de error como contenido de la página. cheerio parsea HTML estático del lado del servidor, rápido, pero ten en cuenta lo que no puede hacer, que veremos más abajo.
Paso 4: pruébalo con el MCP Inspector
Antes de conectar nada a Claude, pruébalo de forma aislada con el MCP Inspector:
npx @modelcontextprotocol/inspector node build/index.jsAbre una interfaz interactiva con pestañas de Tools, Resources y Prompts. Selecciona scrape_text, introduce una URL y ejecútalo: verás la respuesta más un registro en vivo de JSON-RPC. También puedes definir variables de entorno por servidor aquí, que es como probarías una API key más adelante.
Paso 5: conéctalo a Claude Desktop
Edita la configuración de Claude Desktop (crea el archivo si no existe):
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
Añade tu servidor bajo la clave mcpServers, usando una ruta absoluta al archivo compilado:
{
"mcpServers": {
"scraper": {
"command": "node",
"args": ["/ABSOLUTE/PATH/TO/build/index.js"],
"env": { "SCRAPER_API_KEY": "optional" }
}
}
}Cierra Claude Desktop por completo y vuelve a abrirlo. Tu herramienta scrape_text ahora aparece, y puedes pedirle a Claude en lenguaje natural que haga scraping de una página.
La parte difícil: el scraping en producción
El código del protocolo de arriba es el 20 % fácil. El scraping del mundo real es el otro 80 %, y nada de eso es específico de MCP:
- Renderizado de JavaScript.
cheeriosolo ve el HTML inicial. Las aplicaciones de una sola página renderizan el contenido en el cliente, así que necesitas un navegador headless como Playwright o Puppeteer, que es lento, consume mucha memoria y es un dolor de cabeza de despliegue. - Sistemas anti-bots. Cloudflare, WAFs, CAPTCHAs y fingerprinting de navegador bloquean a los clientes HTTP ingenuos. Superarlos es una carrera armamentística continua.
- Proxies. Evitar baneos de IP a cualquier volumen significa rotar pools de proxies residenciales o de centro de datos.
- Límites de tasa, reintentos y backoff. Un crawling cortés y resiliente necesita control de concurrencia y backoff exponencial.
- Fragilidad del parsing. Los selectores se rompen en el momento en que un sitio objetivo cambia su markup.
Construir vs comprar
Crea tu propio MCP server para aprender el protocolo, o para sitios internos simples, estáticos y que se comportan bien. En cuanto llegas al renderizado de JavaScript, las defensas anti-bots y la rotación de proxies, la carga de mantenimiento eclipsa al código del protocolo, que es exactamente por lo que la mayoría de los equipos apuntan sus agentes a un MCP server de scraping gestionado en su lugar.
Ese es el nicho que llena CrawlForge: 26 herramientas listas para usar incluyendo scrape_with_actions (navegador headless), stealth_mode (anti-bots), batch_scrape y deep_research, con renderizado de JS, proxies y límites de tasa gestionados por ti. Lo instalas igual que instalarías tu propio servidor (consulta cómo añadir web scraping a Claude Desktop), pero te saltas la cinta de correr de navegadores y proxies. Para ver cómo se comparan las opciones gestionadas, consulta los mejores MCP servers para web scraping.
Trucos y trampas
- Nunca hagas log a stdout en un servidor stdio. stdout transporta el stream de JSON-RPC, así que un
console.logperdido lo corrompe y rompe el servidor. Haz log a stderr conconsole.error, o a un archivo. - Usa rutas absolutas en
claude_desktop_config.json: las rutas relativas fallan. - Mantente en ESM:
"type": "module"en package.json y extensiones.jsen los imports del SDK, contarget: ES2022. - Reinicia el cliente después de cualquier cambio de configuración. Usa Node.js 18 o más reciente.
- Prefiere la v1.x del SDK para producción; trata la v2 como experimental por ahora.
- ¿Python en su lugar? El SDK oficial de Python (el paquete
mcp, con FastMCP y un decorador@mcp.tool()) habla el mismo protocolo y necesita Python 3.10+.
Sáltate el mantenimiento: empieza gratis con CrawlForge y obtén 26 herramientas de scraping de producción con 1.000 credits, sin tarjeta de crédito.
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.