Un scraper web se rompe cuando un sitio cambia su marcado o comienza a bloquearte. El brightdata-scrape Kiro Power escribe uno desde un prompt en lenguaje natural y lo ejecuta contra el Web MCP de Bright Data, que gestiona el desbloqueo y el parseo. Esta guía aplica un patrón de Power repetible en 4 casos de uso, llevando 2 hasta una ejecución en vivo con la API, incluyendo uno que comprueba si ChatGPT menciona tu marca.
TL;DR
Al finalizar tendrás un patrón de Power que puedes aplicar a 4 casos de uso, cada uno impulsado por un prompt en lenguaje natural, con 2 llevados hasta una ejecución en vivo con la API:
- Rastreador de precios retail , sigue un producto en Amazon y Walmart.
- Monitor de visibilidad de marca , detecta qué asistentes de IA mencionan tu marca.
- Pipeline de generación de leads en LinkedIn , monitorea cambios laborales en una lista de prospectos.
- Dashboard de inteligencia de Crunchbase , obtiene decenas de campos en vivo por empresa.

El agente Kiro realiza 2 llamadas de herramientas en vivo, search_engine y luego scrape_as_markdown, y devuelve un precio real de Amazon de $248.
¿Qué es un Kiro Power?
Kiro es el IDE de IA creado por AWS. Un Power es el formato de extensión propio de Kiro: una carpeta que contiene un manifiesto, una configuración de servidor MCP, archivos de steering y plantillas de código. Kiro carga un Power en contexto solo cuando tu prompt lo activa. Explora el catálogo oficial en kiro.dev/powers. Bright Data publica brightdata-scrape por separado en GitHub, para que puedas importarlo directamente.
Los Powers se diferencian de las Claude Skills en un aspecto importante: cada Power incluye una configuración de servidor MCP (Model Context Protocol) ya preparada. Así, el agente obtiene nuevas herramientas para invocar, no solo instrucciones. Para brightdata-scrape, ese servidor es el Web MCP de Bright Data.
Ese endpoint te proporciona Web Unlocker, API SERP, Browser API y el catálogo de conjuntos de datos preconfigurados de Bright Data. El MCP de Bright Data permite al agente usar cualquiera de ellos en una sola llamada de herramienta. Esas herramientas (search_engine, scrape_as_markdown, las 50 herramientas Pro web_data_*, scraping_browser_* y discover) reemplazan lo que antes eran 3 integraciones separadas —un proxy, una API SERP y una granja de navegadores— con un único conjunto de credenciales y un patrón de reintentos unificado.
Instalar el Kiro Power brightdata-scrape
Hay 5 pasos para configurar el proyecto y confirmar la conexión:
- Obtén un token de API de Bright Data. En Usuarios y claves de API → Claves de API, añade una clave con permiso de Usuario, establece una fecha de vencimiento y copia el valor. No se necesita tarjeta de crédito para el nivel gratuito.
- Instala Kiro, luego crea y abre el proyecto. Descarga e instala Kiro. El Power necesita un proyecto para funcionar, y esta guía usa Next.js, así que crea uno y abre la carpeta
price-trackeren Kiro:
npx create-next-app@latest price-tracker \
–typescript, app, tailwind, src-dir, use-npm
cd price-tracker
No necesitas instalar nada más ahora. Kiro añadirá los paquetes que el scraper generado necesite más adelante, en la Fase 3.
- Instala el Power. Abre el panel de Powers en Kiro (el ícono en la barra de actividad izquierda). Haz clic en Add Custom Power, luego en Import power from GitHub y pega esta URL:
https://github.com/brightdata/kiro-powers/tree/main/brightdata-scrape

- Proporciona el token a Kiro. Al instalar el Power se añade un servidor
brightdataal archivo.kiro/settings/mcp.jsonde tu proyecto con la URLhttps://mcp.brightdata.com/mcp?token=${BRIGHTDATA_API_KEY}. Abre ese archivo, reemplaza${BRIGHTDATA_API_KEY}con el token literal que copiaste en el Paso 1 y guarda. Luego añade.kiro/settings/mcp.jsona.gitignorepara que el token nunca quede registrado en el repositorio.
> ¿Por qué el token literal y no el marcador ${…}? Kiro actualmente no expande ${VAR} en mcp.json (un problema conocido y abierto), por lo que el marcador genera Connection Failed / HTTP 404 en lugar de una conexión.
- Confirma la conexión. Vuelve a abrir el panel de servidores MCP. Tras unos segundos,
brightdatamostrará Connected consearch_engineyscrape_as_markdownentre sus herramientas, que es la señal que necesitas.

Ahora crea .env.local en la raíz del proyecto y coloca el mismo token en él. Pegas el token dos veces de forma intencionada: la copia en .kiro/settings/mcp.json (Paso 4) conecta Kiro con Bright Data mientras construyes, y esta copia la lee la app generada cuando se ejecuta.
BRIGHTDATA_API_KEY=... # el token que generaste arriba
BRIGHTDATA_UNLOCKER_ZONE=... # el marcador está bien para la build retail; configúralo antes de un caso de uso con Web Unlocker
En una cuenta nueva, o antes de ejecutar un caso de uso con Web Unlocker, configura primero el nombre de tu zona. Consulta Configura tu zona de Web Unlocker en la sección Escala los 4 casos de uso a producción más abajo.
En los 4 casos de uso, solo cambia el prompt; el flujo de trabajo de 4 fases permanece igual.
El flujo de trabajo de 4 fases de Kiro (un patrón para todos los 4)
El Power ejecuta las mismas 4 fases para cada prompt. Cada fase espera tu aprobación antes de continuar:
- Detectar y planificar. El Power verifica el manifiesto del workspace (
package.json,pyproject.toml,Cargo.toml,go.mod, etc.) y las dependencias que contiene. Luego elige cómo integrarse: si encuentra un framework web, genera una ruta de API; si encuentra un SDK de agente, genera una herramienta de agente; y si el proyecto es una biblioteca, genera un módulo. Te pregunta qué scrapeará y cuántos elementos.
- Playbook de scraping. El Power verifica la escalera de herramientas de Bright Data y, para cada sitio objetivo, elige el mejor camino que permite tu nivel: una herramienta Web Data Pro (una de las 50 herramientas
web_data_*en más de 30 plataformas, campos tipados, requiere&pro=1) → un trigger de conjunto de datos (los mismos datos, sondeados, sin necesidad de&pro=1) → Web Unlocker (proxy + parseo para sitios de larga cola) → Browser API (flujos de login/clic) → API SERP (resultados de búsqueda).

- Integrar. El Power genera los archivos. La ejecución retail de abajo produjo 4: un módulo scraper, una ruta de API, una página de dashboard y una nueva sección
## Web scrapingenREADME.md. (.env.localya tenía el token de API, por lo que la Fase 3 lo omitió. Esa es la regla de seguridad de archivos: no sobrescribe un archivo que ya existe.)

- MCP y verificar. El Power fusiona el servidor MCP de Bright Data en
.kiro/settings/mcp.jsony ejecuta una prueba de humo contra la URL objetivo. En esta fase se ejecutan dos salvaguardas de producción: el diff-antes-de-sobrescribir y la recuperación FAIL → ITERATE. La Fase 4 del caso de uso 1 muestra la recuperación completa.
Qué se ejecutó en vivo y qué se muestra
Todo lo que aparece aquí está verificado contra la API en vivo, no es una maqueta. Los precios exactos, herramientas y tiempos provienen de ejecuciones capturadas específicas. Como los scrapers leen datos en vivo, tus propios resultados reflejarán los precios, páginas y respuestas del modelo actuales, no los de estas capturas.
- Los casos de uso 1 y 4 se ejecutaron completamente contra la API en vivo: retail (sin gasto Pro) y Crunchbase (en el nivel Pro). Cada captura de pantalla retail de abajo proviene de esa ejecución, y el código completo del caso de uso 4 está en su sección.
- Los casos de uso 2 y 3 se muestran, no se reconstruyeron: el prompt, las herramientas que la Fase 2 elegiría y las formas de campo cuyos nombres verificamos en vivo contra cada herramienta. Reutilizan el cliente
callMcpTooldel caso de uso 4, así que no hay código casi idéntico que volver a pegar. - Los casos de uso 2, 3 y 4 se ejecutan en modo Pro (
&pro=1), que se cubre más abajo en la sección de escala a producción.
Caso de uso 1: rastreo de precios en múltiples retailers
Aquí está el prompt para Kiro:
Prompt para Kiro: “Añade un agente de comparación de precios que scrapee los precios del Sony WH-1000XM5 en Amazon y Walmart.”
Elección de la Fase 2: En la ejecución capturada sin Pro, el Power eligió la ruta de trigger de conjunto de datos (mismos datos, sondeados). Con &pro=1 elegiría en cambio las herramientas Pro web_data_amazon_product y web_data_walmart_product.
Extensión a más retailers: el mismo patrón añade web_data_ebay_product, web_data_homedepot_products y web_data_bestbuy_products volviendo a promtear a Kiro con una lista de retailers más amplia. Algunos retailers (Best Buy, Target) normalmente necesitan dominios Premium habilitados en la zona; Amazon y Walmart no lo necesitaron en la ejecución capturada.
La arquitectura que generó Kiro
El dashboard obtiene los datos de la API al montarse. La API llama a los triggers de conjuntos de datos de Bright Data en paralelo y devuelve los registros estructurados.
Browser opens /
│
▼ (auto-fetch on mount)
GET /api/scrape-prices
│
▼
src/scrapers/price-tracker.ts
fetchAllPrices()
│
▼ (Promise.allSettled, parallel)
┌────────────────────────────────────┐
│ Bright Data Datasets API │
│ gd_l7q7dkf244hwjntr0 → Amazon │
│ gd_l95fol7l1ru6rlo116 → Walmart │
└────────────────────────────────────┘
Una ruta de lectura: dashboard → ruta de API → módulo scraper → 2 triggers de conjuntos de datos de Bright Data. Con &pro=1, el módulo scraper pasa a ser llamadas MCP directas de web_data_, y el bucle de sondeo del lado del cliente se traslada al servidor MCP.*
El módulo scraper
src/scrapers/price-tracker.ts contiene los IDs de conjuntos de datos, un helper triggerAndPoll y un paso normalise que aplana la respuesta de Bright Data en una forma PriceResult consistente. Aquí está el núcleo del archivo, que tiene unas 85 líneas en total:
// src/scrapers/price-tracker.ts (excerpt)
const BASE = "https://api.brightdata.com/datasets/v3";
const DATASETS = { Amazon: "gd_l7q7dkf244hwjntr0", Walmart: "gd_l95fol7l1ru6rlo116" } as const;
async function triggerAndPoll(datasetId: string, url: string) {
// 1. POST trigger with the target URL
const trigger = await fetch(`${BASE}/trigger?dataset_id=${datasetId}&include_errors=true`, {
method: "POST",
headers: { Authorization: `Bearer ${process.env.BRIGHTDATA_API_KEY}`,
"Content-Type": "application/json" },
body: JSON.stringify([{ url }]),
});
const { snapshot_id } = await trigger.json();
if (!snapshot_id) throw new Error("no snapshot_id returned from trigger");
// 2. Poll the snapshot endpoint (in-progress = HTTP 202; ~120 s cap)
for (let i = 0; i < 24; i++) {
await new Promise((r) => setTimeout(r, 5000));
const res = await fetch(`${BASE}/snapshot/${snapshot_id}?format=json`,
{ headers: { Authorization: `Bearer ${process.env.BRIGHTDATA_API_KEY}` } });
if (res.status === 202) continue;
return await res.json();
}
throw new Error("snapshot timed out after 120s");
}
// triggers both retailers in parallel; Promise.allSettled isolates errors per retailer,
// so one bad snapshot doesn't fail the other. The full file maps each settled result
// into a PriceResult (rejected ones carry an `error` field).
export async function fetchAllPrices() {
return Promise.allSettled(
Object.entries(DATASETS).map(([retailer, id]) =>
triggerAndPoll(id, PRODUCT_URLS[retailer]).then((r) => normalise(r[0], retailer, PRODUCT_URLS[retailer]))),
);
}
El chat de Kiro es un cliente MCP en vivo, no una búsqueda en memoria
Durante la construcción, el panel de chat de Kiro se comunica con el mismo servidor brightdata que llama tu código. Al preguntar el precio del Sony, el chat no respondió desde la memoria del modelo. Realizó llamadas en vivo a search_engine y scrape_as_markdown y devolvió una tabla ($195.55 reacondicionado hasta $248 nuevo, más una comparación del XM6 a $398):

El chat es cómo exploras mientras construyes. El dashboard de abajo es lo que ven tus usuarios finales.
El dashboard
La ruta home (/) que generó Kiro renderiza el JSON que devuelve la API como 2 tarjetas de colores (naranja de Amazon y azul de Walmart) más un banner verde de “Mejor precio” que elige el más barato de los 2:

Vista de la ruta home (/). Sony WH-1000XM5 a $248 en Amazon y Walmart con títulos de producto, estado de stock y marcas de tiempo por retailer leídas directamente de cada fuente. El in_stock raw de Walmart y el In Stock de Amazon se pasan tal cual, para que veas exactamente lo que devuelve cada fuente. Normaliza según tu propio esquema cuando construyas alertas sobre ello.
Si inspeccionas las páginas raw tú mismo, el selector de precio obvio de Amazon (span.a-price-whole) suele devolver vacío, y el real es .a-price .a-offscreen. Walmart no pone el precio en el HTML renderizado en absoluto; se encuentra dentro de un blob JSON en <script id="NEXT_DATA">. Los triggers de conjuntos de datos anteriores evitan ambos problemas porque Bright Data parsea las páginas en el lado del servidor y devuelve campos tipados.
Fase 4: autocorrección cuando la URL cambia
La Fase 4 es la rutina de recuperación que el Power ejecuta automáticamente cuando falla una prueba de humo. En la ejecución capturada, Amazon devolvió datos limpios ($248, In Stock), pero Walmart devolvió todos los campos como null. Kiro no declaró éxito. En cambio, leyó la clave error del registro raw ("dead page (404)"), llamó a search_engine para encontrar la URL actual de Walmart, volvió a disparar el conjunto de datos y cambió a scrape_as_markdown cuando el sondeo se estancó (devolvió $248, coincidiendo con Amazon). Luego parcheó el scraper generado:

La Fase 4 detecta la URL muerta de Walmart, encuentra la activa y parchea el scraper por sí sola. Los 18m 54s incluyen el trabajo de conjunto de datos re-sondeado, y los 4.5 créditos son un coste único de la fase de construcción, no un coste de ejecución.
El bucle de recuperación captura fallos que lanzan un error o devuelven campos null (404s muertos, páginas rediseñadas, errores de snapshot). Pero no captura una URL que sigue resolviendo pero apunta al producto equivocado. Por ejemplo, un ID walmart.com/ip/... que cambió silenciosamente de auriculares Sony a un listado de PS5 devuelve datos válidos para el producto incorrecto. Para capturar este caso, necesitas URLs basadas en búsqueda en lugar de IDs codificados (cubierto en la sección de escalado a producción más abajo).
Coste capturado a través de las fases 2 y 4 (cada uno visible en las capturas de pantalla anteriores): 0.38 → 1.38 → 4.5 créditos (total acumulado). Estos son créditos de tiempo de construcción del IDE Kiro, el uso del agente mientras escribe el código, separados de la facturación de Bright Data. Así que esta ejecución capturada costó 4.5 créditos en total, pero la mayor parte fue la autocorrección única de la Fase 4. Una build limpia sin recuperación es de aproximadamente 2 créditos (estimado, ya que no capturamos una ejecución sin autocorrección).
Salvaguardas de producción: autocorrección, sin sobrescrituras silenciosas, plantillas validadas por CI
En el caso de uso 1, la Fase 4 detectó una URL muerta de Walmart y se negó a declarar éxito. Ese comportamiento no se improvisa en cada ejecución. Proviene de las reglas de producción integradas en los archivos de steering del Power. Aquí está el conjunto completo de esas reglas:
- Seguridad de archivos (Fase 3). El Power no sobrescribirá un scraper existente (sugiere
_2.ts), añade al final deREADME.md/.env.exampleen lugar de reemplazarlos, y muestra una lista CREATE/MODIFY antes de escribir. - Fusión de configuración MCP (Fase 4). El Power detecta una entrada
brightdataexistente en.kiro/settings/mcp.json, muestra un diff si la URL difiere y pregunta antes de reemplazar, por lo que no hay sobrescrituras silenciosas. - Prueba de humo FAIL → ITERATE. Tras conectar MCP, el Power ejecuta el scraper contra tu objetivo. En caso de vacío, null o error, el steering dice, textualmente, “volver a la Fase 2… No declarar éxito.”
- Plantillas probadas en CI (49 pruebas pasan).
validate_power.pyytest_validate_power.pycomprueban el frontmatter, la configuración MCP, el steering y la presencia de plantillas. No prueban el código generado contra un sitio en vivo; ese es el trabajo de la prueba de humo de la Fase 4, por proyecto. - Aprovisionamiento automático de zonas. El servidor MCP llama a
/zone/get_active_zonesy crea las zonas faltantes en la primera ejecución, para que una cuenta nueva no tenga que crear manualmente una zona de Web Unlocker primero.
Caso de uso 2: monitor GEO de visibilidad de marca
El problema de visibilidad. Los compradores forman cada vez más su lista de candidatos en páginas de respuestas LLM (ChatGPT, Grok, Perplexity) antes de hablar con ventas, por lo que estar fuera del top 3 significa que muchos compradores pueden no verte nunca. El problema es que las herramientas tradicionales de monitoreo de marca (PR, escucha social, SEO) no fueron diseñadas para observar respuestas LLM, por lo que no puedes ver de forma fiable dónde te posicionas.
Prompt para Kiro: “Añade un monitor de visibilidad de marca que scrapee cómo ChatGPT, Grok y Perplexity responden mis 5 consultas prioritarias de compradores, y me alerte cuando mi marca deje de ser mencionada.”
Las herramientas GEO y lo que devuelven
Herramientas Pro para este caso de uso: La Fase 2 elegiría el grupo geo: web_data_chatgpt_ai_insights, web_data_grok_ai_insights y web_data_perplexity_ai_insights. Cada herramienta es su motor (no hay selector de motor), toma un único argumento prompt y devuelve la respuesta LLM renderizada como markdown. Con una herramienta por motor, cubres las 3 principales páginas de respuestas que tus compradores usan hoy, no solo las de ChatGPT.
La Fase 3 genera un módulo src/scrapers/brand_visibility.ts que llama a cada herramienta web_data_* con un único { prompt } y recoge su answer_text_markdown. ChatGPT y Perplexity devuelven inline y se ejecutan juntos bajo Promise.all. Grok normalmente supera la ventana de sondeo MCP y devuelve de forma asíncrona, por lo que permanece en una ruta separada no bloqueante; trátalo como eventualmente consistente, no como una llamada bloqueante.
Aquí está la forma de respuesta en vivo, capturada directamente de web_data_chatgpt_ai_insights y web_data_perplexity_ai_insights con el prompt “¿Cuál es el mejor CDP para SaaS de mercado medio?”, y ambos devolvieron la misma forma de un solo campo (la llamada asíncrona de Grok superó un sondeo de 9 minutos):
{
"answer_text_markdown": "For most **mid-market SaaS companies (roughly 50,1,000 employees)**, the answer depends less on \"which CDP is best\" than on your data-stack maturity. My ranking: 1) [Hightouch](https://hightouch.com?utm_source=chatgpt.com) , warehouse-native; 2) [Twilio Segment](https://segment.com?utm_source=chatgpt.com) , all-in-one; 3) [RudderStack](https://www.rudderstack.com?utm_source=chatgpt.com) , engineering-led..."
}
La herramienta devuelve la respuesta del modelo como una única cadena answer_text_markdown, no un ranking de marca pre-parseado. El paso de extracción de marca es tuyo. Un primer enfoque ingenuo es una simple comprobación includes() contra el markdown, pero pierde mayúsculas, variantes del nombre y tu marca apareciendo dentro de otra palabra. Para cualquier uso real, pasa el markdown a una llamada LLM económica y pide la lista clasificada.

El bucle de alertas y quién lo instala
El bucle de alertas funciona así: almacena 1 fila de answer_text_markdown por motor por día, luego extrae si (y dónde) aparece tu marca, luego te alerta cuando tu marca desaparece de una respuesta en la que solía estar y, finalmente, renderiza una cuadrícula de 3 motores con las respuestas de hoy y flags de presencia de marca.
Una advertencia antes de configurar alertas: las respuestas LLM son no deterministas, por lo que el mismo prompt puede clasificar marcas de forma diferente de una ejecución a la siguiente. Una sola obtención diaria es una muestra, no una señal estable, por lo que una marca que desaparece durante un día suele ser ruido, no un cambio real. Muestrea cada prompt varias veces, o suaviza durante varios días, antes de tratar una caída como real.
Quién instala esto: Es para equipos de marketing B2B SaaS y DevRel, agencias de monitoreo de marca que añaden cobertura LLM, e investigadores de IA/ML que rastrean la deriva de salidas del modelo. El uso equivale a 5 prompts en 3 motores sondeados diariamente, que son aproximadamente 450 llamadas/mes, o aproximadamente $0.68/mes a tarifas de pago por uso.
Caso de uso 3: pipeline de generación de leads en LinkedIn
El problema B2B es que tienes que rastrear 50 prospectos de ventas (o candidatos, o contactos del programa de partners) para cambios de trabajo, movimientos de empresa o ascensos. La solución habitual es LinkedIn Sales Navigator más un flujo de revisión manual. La opción de datos estructurados es 1 llamada MCP por prospecto, sondeada diariamente.
Prompt para Kiro: “Monitorea estos 50 prospectos de LinkedIn para cambios de trabajo, movimientos de empresa o ascensos. Notifica a mi CRM cuando algo cambie.”
Las herramientas de LinkedIn y lo que devuelven
Herramientas Pro para este caso de uso. La Fase 2 elegiría el clúster de LinkedIn dentro del grupo social: web_data_linkedin_person_profile, web_data_linkedin_company_profile, web_data_linkedin_job_listings y web_data_linkedin_people_search.
Aquí está lo que genera la Fase 3 (nombres de campos verificados en vivo contra la herramienta):
// src/scrapers/linkedin_prospects.ts (excerpt)
import { callMcpTool } from "@/lib/mcp-client"; // Kiro generates this MCP-client call in Phase 3 , not an installable package
interface ProspectSnapshot {
url: string;
current_company_name: string; // current_company is a nested object; *_name is the string
position: string; // job-title field , there is no "current_title"
location: string;
followers: number;
}
type Change = { field: string; from: string; to: string };
export const snapshotProspect = (url: string) =>
callMcpTool("web_data_linkedin_person_profile", { url }) as Promise<ProspectSnapshot>;
// Diff today vs. yesterday; emit a Change for any field that moved.
export function diffProspect(prev: ProspectSnapshot, now: ProspectSnapshot): Change[] {
return (["current_company_name", "position"] as const)
.filter((f) => prev[f] !== now[f])
.map((f) => ({ field: f, from: prev[f], to: now[f] }));
}
El registro completo devuelve más de 30 campos tipados, incluyendo current_company (objeto), experience[], education[], about, followers, connections, city, country_code y más.
El bucle de notificación al CRM y quién lo instala
El bucle de notificación al CRM funciona así: almacena el snapshot de ayer por prospecto, luego ejecuta la obtención y el diff de hoy una vez al día desde un worker en segundo plano, y luego hace POST de los cambios al webhook de tu CRM (Salesforce, HubSpot, Attio, no el MCP de Bright Data).
Quién instala esto: Es para ventas B2B, reclutamiento, RevOps y gerentes de programas de partners. El uso equivale a 50 prospectos sondeados diariamente, que son aproximadamente 1,500 llamadas/mes, o aproximadamente $2.25/mes a tarifas PAYG.
Caso de uso 4: dashboard de inteligencia competitiva
El problema de desarrollo corporativo y estrategia es este: los equipos tienen que rastrear una lista de competidores y objetivos de adquisición para rondas de financiación, cambios de plantilla y cambios de impulso. La base común es un flujo de trabajo manual de actualización de Crunchbase y hoja de cálculo. La opción de datos estructurados es 1 llamada MCP por empresa, sondeada semanalmente.
Prompt para Kiro: “Rastrea estos 30 competidores en Crunchbase. Alértame cuando alguno cierre una ronda, cruce una banda de número de empleados o suba en el ranking de crecimiento.”
La herramienta de Crunchbase y lo que devuelve
Herramienta Pro elegida en la Fase 2: El Power elige web_data_crunchbase_company (el grupo business). Verificado en vivo, devuelve 93 campos tipados por empresa, incluyendo funds_raised, num_funding_rounds, acquisitions, exits, num_employees, cb_rank, growth_score, heat_score, founders, built_with_tech, ipo_status y region.
Aquí está lo que genera la Fase 3:
// src/scrapers/competitor_intel.ts
import { callMcpTool } from "@/lib/mcp-client"; // Kiro generates this MCP-client call in Phase 3 , not an installable package
interface CompanySnapshot {
name: string;
num_employees: string; // band, e.g. "5001-10000"
cb_rank: number; // Crunchbase rank (lower = more prominent)
growth_score: number; // 0-100
heat_score: number; // 0-100 momentum signal
funds_raised: unknown[]; // array of funding/investment events
ipo_status: string; // "private" | "public" | ...
region: string;
url: string;
}
type Alert =
| { kind: "headcount_band"; from: string; to: string }
| { kind: "new_funding_event"; count: number }
| { kind: "growth_surge"; from: number; to: number };
// the MCP row arrives untyped, so you map just the fields you track into a typed CompanySnapshot
export async function snapshotCompany(url: string): Promise<CompanySnapshot> {
const row = await callMcpTool<Record<string, unknown>>("web_data_crunchbase_company", { url });
return {
name: String(row.name ?? ""),
num_employees: String(row.num_employees ?? ""),
cb_rank: Number(row.cb_rank ?? 0),
growth_score: Number(row.growth_score ?? 0),
heat_score: Number(row.heat_score ?? 0),
funds_raised: Array.isArray(row.funds_raised) ? row.funds_raised : [],
ipo_status: String(row.ipo_status ?? ""),
region: String(row.region ?? ""),
url,
};
}
export function detectMoves(
prev: CompanySnapshot, now: CompanySnapshot,
): Alert[] {
const alerts: Alert[] = [];
if (now.num_employees !== prev.num_employees) {
alerts.push({ kind: "headcount_band", from: prev.num_employees, to: now.num_employees });
}
if (now.funds_raised.length !== prev.funds_raised.length) {
alerts.push({ kind: "new_funding_event", count: now.funds_raised.length - prev.funds_raised.length });
}
if (now.growth_score - prev.growth_score >= 5) {
alerts.push({ kind: "growth_surge", from: prev.growth_score, to: now.growth_score });
}
return alerts;
}
Muestra en vivo. Una llamada real a web_data_crunchbase_company para Stripe devolvió num_employees: "5001-10000", cb_rank: 300, growth_score: 98, heat_score: 60, ipo_status: "private", region: "California", más un array funds_raised poblado con eventos de inversión.

El Power generó los 4 archivos (el scraper anterior, el cliente siguiente, una ruta de API, una página de dashboard), y el código generado compiló con cero errores de TypeScript. Con BRIGHTDATA_API_KEY configurado, ejecutarlo contra el MCP en vivo (~58 s para el scraping en vivo) devolvió el registro de Stripe anterior y renderizó esto:

La ruta home (/), renderizada en vivo desde la misma llamada a web_data_crunchbase_company que devolvió el registro de Stripe anterior.
Para ejecutarlo tú mismo, clona el repositorio de ejemplo: git clone https://github.com/triposat/crunchbase-intel-demo && cd crunchbase-intel-demo && npm install && cp .env.example .env.local, pega un token habilitado para Pro y ejecuta npm run dev. (&pro=1 ya está en el mcp-client.ts del repositorio; solo necesitas una cuenta con el modo Pro habilitado.)
El cliente MCP compartido
El callMcpTool que importa el scraper es un cliente MCP ligero que el Power genera en la Fase 3, el mismo que los módulos GEO y LinkedIn están escritos para reutilizar. Aquí está completo:
// src/lib/mcp-client.ts , the client callMcpTool resolves to
const MCP_URL = `https://mcp.brightdata.com/mcp?token=${process.env.BRIGHTDATA_API_KEY}&pro=1`;
async function post(body: unknown, sessionId?: string) {
const headers: Record<string, string> = {
"Content-Type": "application/json",
Accept: "application/json, text/event-stream",
};
if (sessionId) headers["mcp-session-id"] = sessionId;
return fetch(MCP_URL, { method: "POST", headers, body: JSON.stringify(body) });
}
// the server replies as SSE: one JSON object per `data:` line
function parseSse(text: string) {
if (!text.includes("data:")) {
try { return [JSON.parse(text)]; }
catch { throw new Error(`MCP returned a non-JSON response: ${text.slice(0, 120)}`); }
}
return text.split("\n").filter((l) => l.startsWith("data:"))
.map((l) => { try { return JSON.parse(l.slice(5).trim()); } catch { return null; } })
.filter(Boolean);
}
export async function callMcpTool<T = unknown>(name: string, args: Record<string, unknown>): Promise<T> {
// 1. initialize , the session id comes back as a response header
const init = await post({ jsonrpc: "2.0", id: 1, method: "initialize",
params: { protocolVersion: "2024-11-05", capabilities: {}, clientInfo: { name: "intel", version: "1.0" } } });
if (!init.ok) throw new Error(`MCP connection failed: HTTP ${init.status} ${init.statusText}. Check BRIGHTDATA_API_KEY.`);
const sessionId = init.headers.get("mcp-session-id") ?? undefined;
await init.text();
// 2. confirm initialized, then 3. call the tool
await post({ jsonrpc: "2.0", method: "notifications/initialized", params: {} }, sessionId);
const res = await post({ jsonrpc: "2.0", id: 2, method: "tools/call", params: { name, arguments: args } }, sessionId);
if (!res.ok) throw new Error(`MCP tool call failed: HTTP ${res.status} ${res.statusText}.`);
const reply = parseSse(await res.text()).find((m: { id?: number }) => m?.id === 2);
if (reply?.error) throw new Error(`MCP error: ${reply.error.message}`);
const text = reply?.result?.content?.find((c: { type: string }) => c.type === "text")?.text;
const payload = text ? JSON.parse(text) : reply?.result;
return (Array.isArray(payload) ? payload[0] : payload) as T;
}
Coloca ese archivo en src/lib/, y el scraper de Crunchbase anterior estará listo para ejecutarse.
El bucle de vigilancia y quién lo instala
El bucle de vigilancia funciona así: almacena el snapshot de la semana pasada por empresa, luego compara el snapshot de esta semana con el de la semana pasada, y luego publica cualquier evento de financiación, cruce de banda de plantilla o aumento de puntuación de crecimiento en tu canal de Slack de estrategia. El uso equivale a 30 empresas sondeadas semanalmente, que son aproximadamente 120 llamadas/mes, o aproximadamente $0.18/mes a tarifas PAYG.
Quién instala esto: Es para desarrollo corporativo, inteligencia competitiva, estrategia, equipos de deal de VC/PE y representantes de ventas que construyen inteligencia de cuentas. Estos equipos necesitan profundidad de datos en lugar de volumen retail, porque quieren 93 campos estructurados por empresa que de otro modo recopilarían manualmente.
Escala los 4 casos de uso a producción
Los scrapers generados compilan con cero errores de TypeScript y se ejecutan contra la API en vivo (las ejecuciones de retail y Crunchbase anteriores), con las salvaguardas anteriores. Estos cambios los llevan a escala de producción, añadiendo los trabajos en segundo plano, tablas de snapshots y configuraciones de volumen que necesitan las cargas de trabajo reales:
- Cambia a herramientas Pro. Añade
&pro=1a la URL MCP en.kiro/settings/mcp.jsonpara que leahttps://mcp.brightdata.com/mcp?token=<tu-token>&pro=1y reinicia el servidor. (Nota el&inicial, porquetoken=ya abre la cadena de consulta.) La Fase 2 elige herramientasweb_data_*en lugar de triggers de conjuntos de datos. El sondeo normalmente cae a segundos, y el parseo se convierte en una lectura de campo tipado. El flag va en 2 lugares:.kiro/settings/mcp.json, para que el agente de Kiro vea las herramientas Pro, y elsrc/lib/mcp-client.tsde la app generada, para que la app en ejecución las llame. - Configura tu zona de Web Unlocker. La ruta de Web Unlocker lee
BRIGHTDATA_UNLOCKER_ZONE, y tu zona tiene un nombre específico de cuenta (web_unlocker,mcp_unlocker,web_unlocker1, etc.). Encuentra el nombre exacto en tu dashboard de Web Access y configúralo en.env.local. Un nombre incorrecto devuelve HTTP 400 conzone not found. En una cuenta nueva la tabla puede estar vacía hasta que el servidor MCP aprovisione automáticamente una zona en su primera llamada. Si aparecen 2 zonas, elige la marcada como Free tier. - Mueve el sondeo fuera de la ruta de solicitud. En nuestras ejecuciones, un trigger
web_data_*de un solo registro devolvió en aproximadamente 10-90 s y los de múltiples registros en varios minutos. La latencia varía, y las herramientas de respuestas LLM como Grok pueden superar ampliamente la ventana de sondeo. El servidor MCP sigue sondeando durante varios minutos antes de agotar el tiempo (la variable de entornoPOLLING_TIMEOUTestablece el límite). Para producción, ejecuta los triggers desde un worker en segundo plano (Vercel Cron, Inngest, Trigger.dev) y escribe en una tabla de snapshots. El dashboard lee desde la tabla, no desde el scraping en vivo. (La API de Datasets directa fuera de MCP admite entrega por webhook si necesitas push en lugar de poll, configurado con los parámetrosnotifyyendpoint. Consulta la documentación de trigger-a-collection de Bright Data.) - Batch + scope.
scrape_batchysearch_engine_batchejecutan múltiples URLs por llamada, reduciendo la sobrecarga de tokens por URL. Añadir&groups=ecommerce,social,geo,businessa la URL MCP carga solo los grupos de herramientas que necesita tu caso de uso, reduciendo el handshake de lista de herramientas que el agente tiene que leer. Los 11 grupos sonecommerce,social,finance,business,research,app_stores,travel,geo,code,browseryadvanced_scraping. - Plantillas multi-stack. El Power incluye 22 plantillas de producción: rutas de framework web para TS (Next, Express, Fastify, Hono, Koa) y Python (FastAPI, Flask, Django), herramientas de SDK de agente (Anthropic, OpenAI, LangChain, Vercel AI SDK, Mastra) y módulos genéricos (TS fetch + Cheerio, Python stdlib + BeautifulSoup, y un
curl.shuniversal). Kiro detecta 7 lenguajes por manifiesto y elige la coincidencia, pero el codegen de primera clase es solo TS y Python. Go, Rust, Ruby, Java y PHP se detectan y se enrutan al fallbackcurl.sh. - URLs basadas en búsqueda, no codificadas. Las URLs codificadas pueden romperse por rotación de ID de listado, donde un ID obsoleto sigue resolviendo pero apunta al producto incorrecto (el fallo PS5-vs-auriculares del caso de uso 1 que el bucle de recuperación no puede capturar). La solución integrada es disparar conjuntos de datos en modo de descubrimiento en lugar de por URL. Cambia el cuerpo del trigger de conjuntos de datos de
[{ url }]a una consulta de descubrimiento (discover_by=keyword,category_urlobest_sellers_url), para que Bright Data encuentre el producto actual. Consulta la documentación de trigger-a-collection de Bright Data para la forma de la solicitud de descubrimiento. - Flujos de login + steering. Browser API maneja sitios con muros de autenticación con una interfaz de snapshot ARIA (estilo Playwright-MCP-refs) diseñada para uso de agentes. Añade
.kiro/steering/<tu-dominio>.mda tu workspace para anular el steering integrado del Power sin bifurcarlo. Usa APIs oficiales cuando la fuente las publique.

Con &pro=1 configurado, volver a abrir el panel MCP muestra el catálogo completo de herramientas:

Próximos pasos
Un Power impulsa los 4 casos de uso desde un único endpoint MCP, por lo que dedicas tu tiempo a la lógica de integración y alertas en lugar de a la fontanería del scraper.
Construye el rastreador retail tú mismo. Pega https://github.com/brightdata/kiro-powers/tree/main/brightdata-scrape en el Add Custom Power → Import power from GitHub de Kiro, luego ejecuta el prompt del caso de uso 1. En nuestra ejecución esto tardó 20-30 minutos, no usó gasto Pro y confirmó tanto la instalación como el flujo de trabajo de 4 fases. ¿Con prisa? Clona la app terminada en su lugar: git clone https://github.com/triposat/retail-price-tracker && cd retail-price-tracker && npm install && cp .env.example .env.local, añade un token gratuito de Bright Data y ejecuta npm run dev.
Luego escala volviendo a promtear, no reescribiendo. Añade &pro=1 en .kiro/settings/mcp.json y ejecuta cualquiera de los 3 prompts del nivel Pro anteriores (GEO, LinkedIn o inteligencia de Crunchbase) a tarifas de pago por uso. Sin código nuevo, solo un nuevo prompt contra el mismo Power.
Lectura adicional: la página de Web MCP para la lista completa de herramientas, y el artículo del flujo de trabajo de chat de Kiro de Bright Data para las mismas herramientas usadas de forma interactiva.
Preguntas frecuentes
¿Qué es gratuito y qué es de pago?
Gratuito: obtienes 5 herramientas base en el Web MCP (search_engine, search_engine_batch, scrape_as_markdown, scrape_batch y discover), con 5,000 solicitudes/mes sin coste (según el README de MCP de Bright Data). De pago: las herramientas Pro web_data* cuestan dinero, y también la ruta de trigger de conjuntos de datos que usa la build retail, que llama directamente a la API de Datasets de Bright Data. Esa ruta factura por separado, con una prueba gratuita de ~1,000 registros primero y luego ~$1.50/1,000 registros, por lo que scrapear un par de productos por ejecución normalmente te cuesta una fracción de centavo.
¿Cuánto cuestan las herramientas Pro?
Las herramientas Pro web_data_* cuestan $1.00-$1.50 por 1,000 resultados según tu plan (página de precios de Bright Data):
| Plan | Precio por 1,000 resultados |
|---|---|
| Pago por uso | $1.50 |
| Starter | $1.30 |
| Professional | $1.10 |
| Business | $1.00 |
Para llamadas Pro de entidad única —1 obtención de respuesta LLM, 1 perfil de LinkedIn o 1 empresa de Crunchbase por llamada— las estimaciones mensuales asumen 1 llamada = 1 resultado facturado, lo que coincide con la facturación basada en uso de Bright Data para herramientas web_data_* de registro único. Para herramientas de búsqueda masiva como web_data_amazon_product_search, el recuento por resultado escala con los elementos devueltos. Usa el parámetro limit al hacer prototipos y verifica las tarifas actuales en tu cuenta antes de presupuestar.
Browser API factura por separado a $5-8/GB de ancho de banda. Si añades una capa de agente de IA, también se aplican los precios de Anthropic, OpenAI o Google, por llamada LLM.
¿Funciona esto con GPT o Gemini?
Sí, el Power brightdata-scrape funciona con OpenAI (GPT) y Google (Gemini), no solo con Anthropic. Cuando le pides a Kiro una capa de agente (“añade una ruta /api/agent que use estos scrapers como herramientas”), elige la plantilla de herramienta correspondiente (SDK de Anthropic, SDK de OpenAI, LangChain, Mastra o Vercel AI SDK) según las dependencias de tu proyecto. Cambia anthropic(...) por openai(...) o google(...) en la ruta generada, luego ajusta la configuración del cliente del proveedor y el ID del modelo para que coincidan.
¿Puede scrapear sitios que requieren login?
El Power brightdata-scrape puede scrapear sitios con muros de login, pero no desde el trigger de conjuntos de datos predeterminado. Cambia a Browser API para sesiones con estado y añade tu propio almacenamiento de credenciales. La escalera de la Fase 2 del Power escala a Browser API para flujos de login y clic.
¿Puedo ejecutar los 4 casos de uso en un solo proyecto?
Sí. Cada caso de uso es un módulo autocontenido (su propio archivo src/scrapers/, ruta de API y vista) que reutiliza el mismo servidor MCP, por lo que los 4 pueden coexistir en un proyecto Next.js. Esta guía no los combina en una sola app (las 2 builds en vivo, retail y Crunchbase, son repositorios de demo separados, y GEO y LinkedIn se muestran como prompts), pero nada te impide hacerlo.
¿Puedo usar esto desde Claude Code o Cursor?
Para Claude Code o Cursor, usa las Claude Skills de Bright Data en lugar del Kiro Power brightdata-scrape. Bright Data publica Skills de scraping en github.com/brightdata/skills (como scraper-builder y scrape) que se ejecutan en Claude Code, Cursor o cualquier host de agente que admita Skills. Cubren prácticamente los mismos trabajos de scraping en la misma infraestructura de Bright Data, pero están empaquetados como Skills más la CLI bdata en lugar del codegen MCP-y-Next.js de este Power, por lo que la instalación y el código generado difieren.