AI

Crie Web Scrapers a partir de um Prompt com Kiro e Bright Data

Crie web scrapers a partir de prompts com o Kiro Power da Bright Data.
33 min de leitura
Kiro Power with Bright Data

Um web scraper para de funcionar quando um site altera sua marcação ou começa a bloqueá-lo. O brightdata-scrape Kiro Power escreve um a partir de um prompt em linguagem simples e o executa no Web MCP da Bright Data, que cuida do desbloqueio e do parsing. Este guia aplica um padrão de Power repetível em 4 casos de uso, levando 2 deles até uma execução ao vivo na API, incluindo um que verifica se o ChatGPT menciona sua marca.

TL;DR

Ao final, você terá um padrão de Power que pode ser aplicado a 4 casos de uso, cada um orientado por um prompt em linguagem simples, com 2 levados até uma execução ao vivo na API:

  • Rastreador de preços no varejo, acompanha um produto na Amazon e no Walmart.
  • Monitor de visibilidade de marca, verifica quais assistentes de IA mencionam sua marca.
  • Pipeline de geração de leads no LinkedIn, monitora uma lista de prospects em busca de mudanças de emprego.
  • Dashboard de inteligência do Crunchbase, coleta dezenas de campos em tempo real por empresa.
Agente Kiro: search_engine e depois scrape_as_markdown retornam um preço ao vivo do Sony WH-1000XM5 na Amazon de $248,00 com status de estoque. 0,9 créditos.

O agente Kiro faz 2 chamadas de ferramentas ao vivo, search_engine e depois scrape_as_markdown, e retorna um preço real da Amazon de $248.

O que é um Kiro Power?

Kiro é a IDE de IA desenvolvida pela AWS. Um Power é o formato de extensão próprio do Kiro: uma pasta que contém um manifesto, uma configuração de servidor MCP, arquivos de direcionamento e modelos de código. O Kiro carrega um Power no contexto apenas quando seu prompt o ativa. Navegue pelo catálogo oficial em kiro.dev/powers. A Bright Data publica o brightdata-scrape separadamente no GitHub, para que você possa importá-lo diretamente.

Os Powers diferem das Claude Skills de uma forma importante: cada Power vem com uma configuração de servidor MCP (Model Context Protocol) já definida. Assim, o agente obtém novas ferramentas para chamar, não apenas instruções. Para o brightdata-scrape, esse servidor é o Web MCP da Bright Data.

Esse endpoint oferece Web Unlocker, API SERP, Browser API e o catálogo de conjuntos de dados pré-construídos da Bright Data. O MCP da Bright Data permite que o agente use qualquer um deles em uma única chamada de ferramenta. Essas ferramentas (search_engine, scrape_as_markdown, as 50 ferramentas Pro web_data_*, scraping_browser_* e discover) substituem o que antes eram 3 integrações separadas — um proxy, uma API SERP e um farm de navegadores — por um conjunto de credenciais e um padrão de retry.

Instale o Kiro Power brightdata-scrape

São 5 etapas para configurar o projeto e confirmar a conexão:

  1. Obtenha um token de API da Bright Data. Em Usuários e chaves de API → Chaves de API, adicione uma chave com permissão de Usuário, defina uma expiração e copie o valor. Não é necessário cartão de crédito para o plano gratuito.
  2. Instale o Kiro, depois crie e abra o projeto. Baixe e instale o Kiro. O Power precisa de um projeto para funcionar, e este guia usa Next.js, então crie um e abra a pasta price-tracker no Kiro:

npx create-next-app@latest price-tracker \

–typescript, app, tailwind, src-dir, use-npm

cd price-tracker

Você não precisa instalar mais nada agora. O Kiro adiciona os pacotes necessários ao scraper gerado posteriormente, na Fase 3.

  1. Instale o Power. Abra o painel de Powers no Kiro (o ícone na barra de atividades à esquerda). Clique em Adicionar Power personalizado, depois em Importar power do GitHub e cole esta URL:

https://github.com/brightdata/kiro-powers/tree/main/brightdata-scrape

Modal Adicionar Power personalizado do Kiro: URL do GitHub do brightdata-scrape colada no campo de entrada, com a dica 'Pressione Enter para confirmar' visível.
  1. Forneça o token ao Kiro. Ao instalar o Power, um servidor brightdata é adicionado ao .kiro/settings/mcp.json do seu projeto com a URL https://mcp.brightdata.com/mcp?token=${BRIGHTDATA_API_KEY}. Abra esse arquivo, substitua ${BRIGHTDATA_API_KEY} pelo token literal que você copiou na Etapa 1 e salve. Em seguida, adicione .kiro/settings/mcp.json ao .gitignore para que o token nunca seja commitado.

> Por que o token literal e não o placeholder ${…}? O Kiro atualmente não expande ${VAR} no mcp.json (um problema conhecido em aberto), então o placeholder resulta em Connection Failed / HTTP 404 em vez de uma conexão.

  1. Confirme a conexão. Reabra o painel de Servidores MCP. Após alguns segundos, brightdata exibe Conectado com search_engine e scrape_as_markdown entre suas ferramentas, que é o sinal necessário.
Painel de Servidores MCP da IDE Kiro mostrando brightdata Conectado (5 ferramentas), após instalar o Kiro Power brightdata-scrape.

Agora crie .env.local na raiz do projeto e coloque o mesmo token nele. Você cola o token duas vezes de propósito: a cópia em .kiro/settings/mcp.json (Etapa 4) conecta o Kiro à Bright Data durante a construção, e esta cópia é lida pelo app gerado quando ele é executado.

BRIGHTDATA_API_KEY=...          # o token que você gerou acima
BRIGHTDATA_UNLOCKER_ZONE=...    # placeholder está bom para a build de varejo; defina antes de um caso de uso com Web Unlocker

Em uma conta nova, ou antes de executar um caso de uso com Web Unlocker, defina primeiro o nome da sua zona. Consulte Defina sua zona do Web Unlocker em Escale todos os 4 casos de uso para produção abaixo.

Em todos os 4 casos de uso, apenas o prompt muda; o fluxo de trabalho de 4 fases permanece o mesmo.

O fluxo de trabalho de 4 fases do Kiro (um padrão para todos os 4)

O Power executa as mesmas 4 fases para cada prompt. Cada fase aguarda sua aprovação antes de continuar:

  1. Detectar e planejar. O Power verifica o manifesto do workspace (package.json, pyproject.toml, Cargo.toml, go.mod, etc.) e as dependências dentro dele. Em seguida, escolhe como integrar: se encontrar um framework web, gera uma rota de API; se encontrar um SDK de agente, gera uma ferramenta de agente; e se o projeto for uma biblioteca, gera um módulo. Ele pergunta o que fazer o scraping e quantos itens.
  1. Playbook de scraping. O Power verifica a escada de ferramentas da Bright Data e, para cada site de destino, escolhe o melhor caminho que seu plano permite: uma ferramenta Web Data Pro (uma das 50 ferramentas web_data_* em mais de 30 plataformas, campos tipados, requer &pro=1) → um gatilho de conjunto de dados (os mesmos dados, pesquisados periodicamente, sem necessidade de &pro=1) → Web Unlocker (proxy + parsing para sites de cauda longa) → Browser API (fluxos de login/clique) → API SERP (resultados de busca).
Kiro Fase 2: conjunto de dados pré-construído escolhido para Amazon e Walmart, com o portão de confirmação 'Pronto para prosseguir para a Fase 3?'. 0,38 créditos, 1m 24s.
  1. Integrar. O Power gera os arquivos. A execução de varejo abaixo produziu 4: um módulo de scraper, uma rota de API, uma página de dashboard e uma nova seção ## Web scraping no README.md. (O .env.local já tinha o token de API, então a Fase 3 o ignorou. Essa é a regra de segurança de arquivos: ele não sobrescreve um arquivo que já existe.)
Chat do Kiro mostrando a Fase 3 do Power brightdata-scrape concluída: quatro arquivos escritos, zero erros de TypeScript, 1,38 créditos usados em 1m 56s.
  1. MCP e verificação. O Power mescla o servidor MCP da Bright Data no .kiro/settings/mcp.json e executa um teste de fumaça na URL de destino. Duas proteções de produção são executadas nesta fase: o diff-antes-de-sobrescrever e a recuperação FALHA → ITERAR. A Fase 4 do caso de uso 1 mostra a recuperação completa.

O que foi executado ao vivo e o que é mostrado

Tudo aqui foi verificado na API ao vivo, não é uma simulação. Os preços exatos, ferramentas e tempos vêm de execuções capturadas específicas. Como os scrapers leem dados ao vivo, seus próprios resultados refletirão preços, páginas e respostas de modelos atuais, não os capturados aqui.

  • Os casos de uso 1 e 4 foram executados completamente na API ao vivo: varejo (sem gasto Pro) e Crunchbase (no plano Pro). Cada captura de tela de varejo abaixo é dessa execução, e o código completo do caso de uso 4 está em sua seção.
  • Os casos de uso 2 e 3 são mostrados, não reconstruídos: o prompt, as ferramentas que a Fase 2 escolheria e formatos de campos cujos nomes verificamos ao vivo em cada ferramenta. Eles reutilizam o cliente callMcpTool do caso de uso 4, então não há código quase idêntico a re-colar.
  • Os casos de uso 2, 3 e 4 são executados no modo Pro (&pro=1), que é abordado em Escalar para produção abaixo.

Caso de uso 1: rastreamento de preços em múltiplos varejistas

Aqui está o prompt para o Kiro:

Prompt para o Kiro: “Adicione um agente de comparação de preços que faça scraping dos preços do Sony WH-1000XM5 na Amazon e no Walmart.”

Escolha da Fase 2: Na execução capturada sem Pro, o Power escolheu o caminho de gatilho de conjunto de dados (mesmos dados, pesquisados periodicamente). Com &pro=1, ele escolheria as ferramentas Pro web_data_amazon_product e web_data_walmart_product.

Expandindo para mais varejistas: o mesmo padrão adiciona web_data_ebay_product, web_data_homedepot_products e web_data_bestbuy_products ao re-solicitar ao Kiro com uma lista de varejistas mais ampla. Alguns varejistas (Best Buy, Target) geralmente precisam de domínios Premium habilitados na zona; Amazon e Walmart não precisaram na execução capturada.

A arquitetura que o Kiro gerou

O dashboard busca a API ao montar. A API chama os gatilhos de conjunto de dados da Bright Data em paralelo e retorna os registros estruturados.

       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   │
   └────────────────────────────────────┘

Um caminho de leitura: dashboard → rota de API → módulo de scraper → 2 gatilhos de conjunto de dados da Bright Data. Com &pro=1, o módulo de scraper se torna chamadas MCP diretas de web_data_, e o loop de polling do lado do cliente se move para o servidor MCP.*

O módulo de scraper

src/scrapers/price-tracker.ts contém os IDs dos conjuntos de dados, um helper triggerAndPoll e uma etapa normalise que achata a resposta da Bright Data em um formato consistente PriceResult. Aqui está o núcleo do arquivo, e o arquivo completo tem cerca de 85 linhas:

// 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]))),
  );
}

O chat do Kiro é um cliente MCP ao vivo, não uma consulta de memória

Durante a construção, o painel de chat do Kiro fala com o mesmo servidor brightdata que seu código chama. Ao ser perguntado sobre o preço do Sony, o chat não respondeu a partir da memória do modelo. Ele fez chamadas ao vivo de search_engine e scrape_as_markdown e retornou uma tabela ($195,55 recondicionado a $248 novo, mais uma comparação com o XM6 a $398):

Chat do Kiro, execução completa: o agente escolhe search_engine e depois scrape_as_markdown por conta própria, retornando um preço ao vivo do Sony WH-1000XM5 na Amazon. 1m 24s, 0,9 créditos.

O chat é como você explora durante a construção. O dashboard abaixo é o que seus usuários finais veem.

O dashboard

A rota inicial (/) que o Kiro gerou renderiza o JSON retornado pela API como 2 cartões coloridos (laranja Amazon e azul Walmart) mais um banner verde “Melhor preço” indicando o mais barato dos 2:

A rota inicial (/) às 14:27 de 28 de maio de 2026: Sony WH-1000XM5 a $248 na Amazon e no Walmart, mostrado como cartões com um banner verde "Melhor preço" na Amazon.

A visão da rota inicial (/). Sony WH-1000XM5 a $248 na Amazon e no Walmart com títulos de produtos, status de estoque e carimbos de tempo por varejista lidos diretamente de cada fonte. O in_stock bruto do Walmart e o In Stock da Amazon são passados como estão, então você vê exatamente o que cada fonte retorna. Normalize para seu próprio esquema quando construir alertas sobre isso.

Se você inspecionar as páginas brutas, o seletor de preço óbvio da Amazon (span.a-price-whole) geralmente retorna vazio, e o real é .a-price .a-offscreen. O Walmart não coloca o preço no HTML renderizado; ele fica dentro de um blob JSON em <script id="NEXT_DATA">. Os gatilhos de conjunto de dados acima ignoram ambos os problemas porque a Bright Data analisa as páginas no servidor e retorna campos tipados.

Fase 4: autocorreção quando a URL muda

A Fase 4 é a rotina de recuperação que o Power executa automaticamente quando um teste de fumaça falha. Na execução capturada, a Amazon retornou dados limpos ($248, In Stock), mas o Walmart retornou todos os campos definidos como nulos. O Kiro não declarou sucesso. Em vez disso, leu a chave error do registro bruto ("dead page (404)"), chamou search_engine para encontrar a URL atual do Walmart, re-acionou o conjunto de dados e mudou para scrape_as_markdown quando o polling parou (retornou $248, correspondendo à Amazon). Em seguida, corrigiu o scraper gerado:

Resumo da Fase 4 do Kiro mostrando recuperação de autocorreção: Amazon $248 confirmada, URL desatualizada do Walmart detectada e corrigida via scrape MCP. 4,5 créditos, 18m 54s.

A Fase 4 detecta a URL morta do Walmart, encontra a ativa e corrige o scraper por conta própria. Os 18m 54s incluem o job de conjunto de dados re-pesquisado, e os 4,5 créditos são um custo único da fase de construção, não um custo de execução.

O loop de recuperação captura falhas que lançam um erro ou retornam campos nulos (404s mortos, páginas redesenhadas, erros de snapshot). Mas ele não captura uma URL que ainda resolve, mas aponta para o produto errado. Por exemplo, um ID walmart.com/ip/... que silenciosamente mudou de fones de ouvido Sony para uma listagem de PS5 retorna dados válidos para o produto errado. Para capturar esse caso, você precisa de URLs orientadas por busca em vez de IDs codificados (abordado na seção de escalonamento para produção abaixo).

Custo capturado nas fases 2 e 4 (cada um visível nas capturas de tela acima): 0,38 → 1,38 → 4,5 créditos (um total acumulado). Estes são créditos de tempo de construção da IDE Kiro, o uso do agente enquanto escreve o código, separado do faturamento da Bright Data. Portanto, esta execução capturada custou 4,5 créditos no total, mas a maior parte foi a autocorreção única da Fase 4. Uma build limpa sem recuperação é de cerca de 2 créditos (estimativa, já que não capturamos uma execução sem autocorreção).

Proteções de produção: autocorreção, sem sobrescritas silenciosas, modelos validados por CI

No caso de uso 1, a Fase 4 detectou uma URL morta do Walmart e recusou-se a declarar sucesso. Esse comportamento não é improvisado a cada execução. Ele vem das regras de produção incorporadas nos arquivos de direcionamento do Power. Aqui está o conjunto completo dessas regras:

  • Segurança de arquivos (Fase 3). O Power não sobrescreve um scraper existente (sugere _2.ts), acrescenta ao README.md / .env.example em vez de substituir, e exibe uma lista de CRIAR/MODIFICAR antes de escrever.
  • Mesclagem de configuração MCP (Fase 4). O Power detecta uma entrada brightdata existente em .kiro/settings/mcp.json, exibe um diff se a URL diferir e pergunta antes de substituir, para que não haja sobrescritas silenciosas.
  • Teste de fumaça FALHA → ITERAR. Após conectar o MCP, o Power executa o scraper no seu alvo. Em caso de vazio, nulo ou erro, o direcionamento diz, palavra por palavra, “retorne à Fase 2… Não declare sucesso.”
  • Modelos testados por CI (49 testes aprovados). validate_power.py e test_validate_power.py verificam frontmatter, configuração MCP, direcionamento e presença de modelos. Eles não testam código gerado em um site ao vivo; esse é o trabalho do teste de fumaça da Fase 4, por projeto.
  • Provisionamento automático de zona. O servidor MCP chama /zone/get_active_zones e cria zonas ausentes na primeira execução, para que uma nova conta não precise criar manualmente uma zona do Web Unlocker primeiro.

Caso de uso 2: monitor de visibilidade de marca GEO

O problema de visibilidade. Os compradores formam cada vez mais sua lista de preferências em páginas de respostas de LLM (ChatGPT, Grok, Perplexity) antes de falar com vendas, então não estar entre os 3 primeiros significa que muitos compradores podem nunca te ver. O problema é que as ferramentas tradicionais de monitoramento de marca (PR, escuta social, SEO) não foram criadas para monitorar respostas de LLM, então você não consegue ver de forma confiável onde está classificado.

Prompt para o Kiro: “Adicione um monitor de visibilidade de marca que faça scraping de como o ChatGPT, Grok e Perplexity respondem às minhas 5 consultas prioritárias de compradores, e me alerte quando minha marca parar de ser mencionada.”

As ferramentas GEO e o que elas retornam

Ferramentas Pro para este caso de uso: A Fase 2 escolheria o grupo geo: web_data_chatgpt_ai_insights, web_data_grok_ai_insights e web_data_perplexity_ai_insights. Cada ferramenta é seu motor (não há seletor de motor), recebe um único argumento prompt e retorna a resposta do LLM renderizada como markdown. Com uma ferramenta por motor, você cobre as 3 principais páginas de respostas que seus compradores usam hoje, não apenas a do ChatGPT.

A Fase 3 gera um módulo src/scrapers/brand_visibility.ts que chama cada ferramenta web_data_* com um único { prompt } e coleta seu answer_text_markdown. ChatGPT e Perplexity retornam inline e rodam juntos sob Promise.all. O Grok geralmente ultrapassa a janela de polling do MCP e retorna de forma assíncrona, então permanece em um caminho separado não bloqueante; trate-o como eventualmente consistente, não como uma chamada bloqueante.

Aqui está o formato de resposta ao vivo, capturado diretamente de web_data_chatgpt_ai_insights e web_data_perplexity_ai_insights com o prompt “Qual é o melhor CDP para SaaS de médio porte?”, e ambos retornaram o mesmo formato de campo único (a chamada assíncrona do Grok ultrapassou um polling 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..."
}

A ferramenta retorna a resposta do modelo como uma única string answer_text_markdown, não um ranking de marcas pré-analisado. A etapa de extração de marca é sua. Uma primeira abordagem ingênua é uma única verificação includes() no markdown, mas ela perde maiúsculas/minúsculas, variantes de nome e sua marca aparecendo dentro de outra palavra. Para qualquer uso real, passe o markdown para uma chamada de LLM barata e peça a lista classificada.

Kiro executando web_data_chatgpt_ai_insights: um `prompt` de entrada, um `answer_text_markdown` de saída; a resposta classifica Hightouch, Twilio Segment, RudderStack.

O loop de alertas e quem o instala

O loop de alertas funciona assim: armazena 1 linha answer_text_markdown por motor por dia, depois extrai se (e onde) sua marca aparece, depois alerta você quando sua marca desaparece de uma resposta em que costumava estar, e finalmente renderiza uma grade de 3 motores com as respostas de hoje com sinalizadores de presença de marca.

Uma ressalva antes de configurar alertas: as respostas de LLM são não determinísticas, então o mesmo prompt pode classificar marcas de forma diferente de uma execução para a próxima. Uma única busca diária é uma amostra, não um sinal estável, então uma marca saindo por um dia geralmente é ruído, não uma mudança real. Amostre cada prompt algumas vezes, ou suavize ao longo de vários dias, antes de tratar uma queda como real.

Quem instala isso: É para equipes de marketing B2B SaaS e DevRel, agências de monitoramento de marca que adicionam cobertura de LLM, e pesquisadores de IA/ML rastreando deriva de saída de modelos. O uso resulta em 5 prompts em 3 motores pesquisados diariamente, o que são cerca de 450 chamadas/mês, ou aproximadamente $0,68/mês nas tarifas de pagamento por uso.

Caso de uso 3: pipeline de geração de leads no LinkedIn

O problema B2B é que você precisa rastrear 50 prospects de vendas (ou candidatos, ou contatos de programas de parceiros) em busca de mudanças de emprego, mudanças de empresa ou promoções. A solução habitual é o LinkedIn Sales Navigator mais um fluxo de revisão manual. A opção de dados estruturados é 1 chamada MCP por prospect, pesquisada diariamente.

Prompt para o Kiro: “Monitore esses 50 prospects do LinkedIn em busca de mudanças de emprego, mudanças de empresa ou promoções. Notifique meu CRM quando algo mudar.”

As ferramentas do LinkedIn e o que elas retornam

Ferramentas Pro para este caso de uso. A Fase 2 escolheria o cluster do LinkedIn dentro do grupo social: web_data_linkedin_person_profile, web_data_linkedin_company_profile, web_data_linkedin_job_listings e web_data_linkedin_people_search.

Aqui está o que a Fase 3 gera (nomes de campos verificados ao vivo em relação à ferramenta):

// 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] }));
}

O registro completo retorna mais de 30 campos tipados, incluindo current_company (objeto), experience[], education[], about, followers, connections, city, country_code e mais.

O loop de notificação do CRM e quem o instala

O loop de notificação do CRM funciona assim: armazena o snapshot de ontem por prospect, depois executa a busca e diff de hoje uma vez por dia a partir de um worker em segundo plano, e depois envia as mudanças para o webhook do seu CRM (Salesforce, HubSpot, Attio, não o MCP da Bright Data).

Quem instala isso: É para vendas B2B, recrutamento, RevOps e gerentes de programas de parceiros. O uso resulta em 50 prospects pesquisados diariamente, o que são cerca de 1.500 chamadas/mês, ou aproximadamente $2,25/mês no PAYG.

Caso de uso 4: dashboard de inteligência competitiva

O problema de desenvolvimento corporativo e estratégia é este: as equipes precisam rastrear uma lista de concorrentes e alvos de aquisição em busca de rodadas de financiamento, mudanças de headcount e mudanças de momentum. O ponto de partida comum é um fluxo de trabalho manual de atualização do Crunchbase e planilha. A opção de dados estruturados é 1 chamada MCP por empresa, pesquisada semanalmente.

Prompt para o Kiro: “Rastreie esses 30 concorrentes no Crunchbase. Me alerte quando qualquer um levantar uma rodada, cruzar uma faixa de contagem de funcionários ou subir no ranking de crescimento.”

A ferramenta Crunchbase e o que ela retorna

Ferramenta Pro escolhida na Fase 2: O Power escolhe web_data_crunchbase_company (o grupo business). Verificado ao vivo, retorna 93 campos tipados por empresa, incluindo funds_raised, num_funding_rounds, acquisitions, exits, num_employees, cb_rank, growth_score, heat_score, founders, built_with_tech, ipo_status e region.

Aqui está o que a Fase 3 gera:

// 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;
}

Amostra ao vivo. Uma chamada real a web_data_crunchbase_company para a Stripe retornou num_employees: "5001-10000", cb_rank: 300, growth_score: 98, heat_score: 60, ipo_status: "private", region: "California", além de um array funds_raised populado com eventos de investimento.

Kiro executando web_data_crunchbase_company para a Stripe: uma `url` de entrada, um registro estruturado de saída mostrando `name: Stripe`, `cb_rank: 300`, `region: California`.

O Power gerou os 4 arquivos (o scraper acima, o cliente abaixo, uma rota de API, uma página de dashboard), e o código gerado compilou sem erros de TypeScript. Com BRIGHTDATA_API_KEY definido, executá-lo no MCP ao vivo (~58 s para o scraping ao vivo) retornou o registro da Stripe acima e renderizou isto:

Dashboard de inteligência competitiva a partir de uma chamada ao vivo de web_data_crunchbase_company: Stripe no cb_rank #300, crescimento 98/100, calor 60/100, 10 eventos de financiamento.

A rota inicial (/), renderizada ao vivo a partir da mesma chamada web_data_crunchbase_company que retornou o registro da Stripe acima.

Para executar você mesmo, clone o repositório de exemplo: git clone https://github.com/triposat/crunchbase-intel-demo && cd crunchbase-intel-demo && npm install && cp .env.example .env.local, cole um token habilitado para Pro e execute npm run dev. (&pro=1 já está no mcp-client.ts do repositório; você só precisa de uma conta com o modo Pro habilitado.)

O cliente MCP compartilhado

O callMcpTool que o scraper importa é um cliente MCP fino que o Power gera na Fase 3 — o mesmo que os módulos GEO e LinkedIn são escritos para reutilizar. Aqui está na íntegra:

// 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;
}

Coloque esse arquivo em src/lib/, e o scraper do Crunchbase acima estará pronto para executar.

O loop de monitoramento e quem o instala

O loop de monitoramento funciona assim: armazena o snapshot da semana passada por empresa, depois compara o snapshot desta semana com o da semana passada, e então posta qualquer evento de financiamento, cruzamento de faixa de headcount ou surto de pontuação de crescimento no seu canal do Slack de estratégia. O uso resulta em 30 empresas pesquisadas semanalmente, o que são cerca de 120 chamadas/mês, ou aproximadamente $0,18/mês no PAYG.

Quem instala isso: É para desenvolvimento corporativo, inteligência competitiva, estratégia, equipes de deals de VC/PE e representantes de vendas construindo inteligência de conta. Essas equipes precisam de profundidade de dados em vez de volume de varejo, porque querem 93 campos estruturados por empresa que de outra forma coletariam manualmente.

Escale todos os 4 casos de uso para produção

Os scrapers gerados compilam sem erros de TypeScript e são executados na API ao vivo (as execuções de varejo e Crunchbase acima), com as proteções acima. Essas mudanças os levam à escala de produção, adicionando os jobs em segundo plano, tabelas de snapshot e configurações de volume que cargas de trabalho reais precisam:

  • Mude para ferramentas Pro. Acrescente &pro=1 à URL do MCP em .kiro/settings/mcp.json para que fique https://mcp.brightdata.com/mcp?token=<seu-token>&pro=1, e reinicie o servidor. (Note o & inicial, porque token= já abre a string de consulta.) A Fase 2 escolhe ferramentas web_data_* em vez de gatilhos de conjunto de dados. O polling geralmente cai para segundos, e o parsing se torna uma leitura de campo tipado. O flag vai em 2 lugares: .kiro/settings/mcp.json, para que o agente do Kiro veja as ferramentas Pro, e o src/lib/mcp-client.ts do app gerado, para que o app em execução as chame.
  • Defina sua zona do Web Unlocker. O caminho do Web Unlocker lê BRIGHTDATA_UNLOCKER_ZONE, e sua zona tem um nome específico da conta (web_unlocker, mcp_unlocker, web_unlocker1, etc.). Encontre o nome exato no seu dashboard de Acesso Web e defina-o em .env.local. Uma incompatibilidade retorna HTTP 400 com zone not found. Em uma conta nova, a tabela pode estar vazia até que o servidor MCP provisione automaticamente uma zona em sua primeira chamada. Se 2 zonas aparecerem, escolha a marcada como Plano gratuito.
  • Mova o polling para fora do caminho de solicitação. Em nossas execuções, um gatilho web_data_* de registro único retornou em aproximadamente 10 a 90 s e multi-registro em vários minutos. A latência varia, e ferramentas de resposta de LLM como o Grok podem ultrapassar a janela de polling. O servidor MCP continua pesquisando por vários minutos antes de expirar (a variável de ambiente POLLING_TIMEOUT define o limite). Para produção, execute gatilhos a partir de um worker em segundo plano (Vercel Cron, Inngest, Trigger.dev) e escreva em uma tabela de snapshot. O dashboard lê da tabela, não do scraping ao vivo. (A API de Conjuntos de dados diretos fora do MCP suporta entrega via webhook se você precisar de push em vez de poll, definido com os parâmetros notify e endpoint. Consulte a documentação de acionamento de coleção da Bright Data.)
  • Batch + escopo. scrape_batch e search_engine_batch executam múltiplas URLs por chamada, reduzindo a sobrecarga de token por URL. Acrescentar &groups=ecommerce,social,geo,business à URL do MCP carrega apenas os grupos de ferramentas que seu caso de uso precisa, reduzindo o handshake de lista de ferramentas que o agente precisa ler. Os 11 grupos são ecommerce, social, finance, business, research, app_stores, travel, geo, code, browser e advanced_scraping.
  • Modelos entre stacks. O Power inclui 22 modelos de produção: rotas de framework web para TS (Next, Express, Fastify, Hono, Koa) e Python (FastAPI, Flask, Django), ferramentas de SDK de agente (Anthropic, OpenAI, LangChain, Vercel AI SDK, Mastra) e módulos genéricos (TS fetch + Cheerio, Python stdlib + BeautifulSoup e um curl.sh universal). O Kiro detecta 7 linguagens por manifesto e escolhe a correspondência, mas a geração de código de primeira classe é apenas TS e Python. Go, Rust, Ruby, Java e PHP são detectados e roteados para o fallback curl.sh.
  • URLs orientadas por busca, não codificadas. URLs codificadas podem quebrar na rotação de ID de listagem, onde um ID desatualizado ainda resolve, mas aponta para o produto errado (a falha PS5-vs-fones-de-ouvido do caso de uso 1 que o loop de recuperação não consegue capturar). A correção incorporada é acionar conjuntos de dados no modo de descoberta em vez de por URL. Troque o corpo do gatilho de conjunto de dados de [{ url }] para uma consulta de descoberta (discover_by=keyword, category_url ou best_sellers_url), para que a Bright Data encontre o produto atual. Consulte a documentação de acionamento de coleção da Bright Data para o formato da solicitação de descoberta.
  • Fluxos de login + direcionamento. A Browser API lida com sites protegidos por autenticação com uma interface de snapshot ARIA (refs estilo Playwright-MCP) projetada para uso de agente. Adicione .kiro/steering/<seu-domínio>.md ao seu workspace para substituir o direcionamento incorporado do Power sem fazer fork. Use APIs oficiais quando a fonte as publica.
Dashboard de Acesso Web da Bright Data: cinco linhas de API, duas do tipo 'Web Unlocker API' — `mcp_unlocker` (badge verde 'Plano gratuito') e `web_unlocker`.

Com &pro=1 definido, reabrir o painel MCP mostra o catálogo completo de ferramentas:

Painel de Servidores MCP do Kiro após `&pro=1`: `brightdata Conectado (72 ferramentas)`, a família Pro `web_data_*` expandida (geo, finance, social, code, browser).

Próximos passos

Um Power orienta todos os 4 casos de uso a partir de um único endpoint MCP, então você gasta seu tempo em lógica de integração e alertas em vez de na infraestrutura de scraping.

Construa o rastreador de varejo você mesmo. Cole https://github.com/brightdata/kiro-powers/tree/main/brightdata-scrape em Adicionar Power personalizado → Importar power do GitHub do Kiro, depois execute o prompt do caso de uso 1. Em nossa execução, isso levou 20 a 30 minutos, não usou gasto Pro e confirmou tanto a instalação quanto o fluxo de trabalho de 4 fases. Com pressa? Clone o app finalizado: git clone https://github.com/triposat/retail-price-tracker && cd retail-price-tracker && npm install && cp .env.example .env.local, adicione um token gratuito da Bright Data e execute npm run dev.

Depois escale re-solicitando, não reescrevendo. Adicione &pro=1 em .kiro/settings/mcp.json e execute qualquer um dos 3 prompts de plano Pro acima (GEO, LinkedIn ou inteligência do Crunchbase) nas tarifas de pagamento por uso. Nenhum código novo, apenas um novo prompt no mesmo Power.

Leitura adicional: a página do Web MCP para a lista completa de ferramentas, e o artigo de fluxo de trabalho de chat do Kiro da Bright Data para as mesmas ferramentas usadas interativamente.

Perguntas frequentes

O que é gratuito e o que é pago?

Gratuito: você obtém 5 ferramentas base no Web MCP (search_engine, search_engine_batch, scrape_as_markdown, scrape_batch e discover), com 5.000 solicitações/mês sem custo (conforme o README do MCP da Bright Data). Pago: as ferramentas Pro web_data* custam dinheiro, assim como o caminho de gatilho de conjunto de dados que a build de varejo usa, que chama a API de Conjuntos de dados da Bright Data diretamente. Esse caminho é cobrado separadamente, com um teste gratuito de ~1.000 registros primeiro e depois ~$1,50/1.000 registros, então fazer scraping de alguns produtos por execução geralmente custa uma fração de centavo.

Quanto custam as ferramentas Pro?

As ferramentas Pro web_data_* custam $1,00 a $1,50 por 1.000 resultados dependendo do seu plano (página de preços da Bright Data):

Plano Preço por 1.000 resultados
Pagamento por uso $1,50
Starter $1,30
Professional $1,10
Business $1,00

Para chamadas Pro de entidade única — 1 busca de resposta de LLM, 1 perfil do LinkedIn ou 1 empresa do Crunchbase por chamada — as estimativas mensais assumem 1 chamada = 1 resultado cobrado, o que corresponde ao faturamento baseado em uso da Bright Data para ferramentas web_data_* de registro único. Para ferramentas de busca em massa como web_data_amazon_product_search, a contagem por resultado escala com os itens retornados. Use o parâmetro limit ao prototipar e verifique as tarifas atuais em sua conta antes de orçar.

A Browser API é cobrada separadamente a $5 a $8/GB de largura de banda. Se você adicionar uma camada de agente de IA, os preços da Anthropic, OpenAI ou Google também se aplicam, por chamada de LLM.

Isso funciona com GPT ou Gemini?

Sim, o Power brightdata-scrape funciona com OpenAI (GPT) e Google (Gemini), não apenas com a Anthropic. Quando você solicita ao Kiro uma camada de agente (“adicione uma rota /api/agent que use esses scrapers como ferramentas”), ele escolhe o modelo de ferramenta correspondente (SDK Anthropic, SDK OpenAI, LangChain, Mastra ou Vercel AI SDK) com base nas dependências do seu projeto. Troque anthropic(...) por openai(...) ou google(...) na rota gerada, depois ajuste a configuração do cliente do provedor e o ID do modelo para corresponder.

Ele consegue fazer scraping de sites que exigem login?

O Power brightdata-scrape pode fazer scraping de sites protegidos por login, mas não a partir do padrão de gatilho de conjunto de dados. Mude para a Browser API para sessões com estado e adicione seu próprio armazenamento de credenciais. A escada da Fase 2 do Power escala para a Browser API para fluxos de login e clique.

Posso executar todos os 4 casos de uso em um projeto?

Sim. Cada caso de uso é um módulo autocontido (seu próprio arquivo src/scrapers/, rota de API e visualização) que reutiliza o mesmo servidor MCP, então todos os 4 podem coexistir em um projeto Next.js. Este guia não os combina em um único app (as 2 builds ao vivo, varejo e Crunchbase, são repositórios de demonstração separados, e GEO e LinkedIn são mostrados como prompts), mas nada impede que você faça isso.

Posso usar isso do Claude Code ou Cursor?

Para Claude Code ou Cursor, use as Claude Skills da Bright Data em vez do Kiro Power brightdata-scrape. A Bright Data disponibiliza Skills de scraping em github.com/brightdata/skills (como scraper-builder e scrape) que rodam no Claude Code, Cursor ou qualquer host de agente que suporte Skills. Elas cobrem praticamente os mesmos trabalhos de scraping na mesma infraestrutura da Bright Data, mas são empacotadas como Skills mais a CLI bdata em vez da geração de código MCP-e-Next.js deste Power, então a instalação e o código gerado diferem.