|
| 1 | +# Content Scraper MCP |
| 2 | + |
| 3 | +MCP para extração, deduplicação e sumarização de conteúdo web usando Firecrawl e Supabase. |
| 4 | + |
| 5 | +## Funcionalidades |
| 6 | + |
| 7 | +- **Extração de Conteúdo**: Usa Firecrawl para extrair title, body, author e date de URLs |
| 8 | +- **Deduplicação por Fingerprint**: Gera hash SHA-256 de title + body para identificar conteúdo único |
| 9 | +- **Persistência de Estado**: Armazena registros no Supabase para evitar reprocessamento |
| 10 | +- **Watermarks por Domínio**: Rastreia última vez que cada domínio foi processado |
| 11 | +- **Resumos Focados em Insights**: Gera resumos curtos extraindo frases-chave |
| 12 | + |
| 13 | +## Configuração |
| 14 | + |
| 15 | +### 1. Supabase - Criar Tabelas |
| 16 | + |
| 17 | +Execute no SQL Editor do seu projeto Supabase: |
| 18 | + |
| 19 | +```sql |
| 20 | +-- Tabela de conteúdo processado |
| 21 | +CREATE TABLE scraped_content ( |
| 22 | + id UUID DEFAULT gen_random_uuid() PRIMARY KEY, |
| 23 | + url TEXT UNIQUE NOT NULL, |
| 24 | + fingerprint TEXT NOT NULL, |
| 25 | + domain TEXT NOT NULL, |
| 26 | + title TEXT NOT NULL, |
| 27 | + first_seen_at TIMESTAMPTZ NOT NULL, |
| 28 | + last_seen_at TIMESTAMPTZ NOT NULL, |
| 29 | + updated_count INTEGER DEFAULT 0, |
| 30 | + created_at TIMESTAMPTZ DEFAULT NOW() |
| 31 | +); |
| 32 | + |
| 33 | +-- Índices para performance |
| 34 | +CREATE INDEX idx_scraped_content_domain ON scraped_content(domain); |
| 35 | +CREATE INDEX idx_scraped_content_fingerprint ON scraped_content(fingerprint); |
| 36 | +CREATE INDEX idx_scraped_content_url ON scraped_content(url); |
| 37 | + |
| 38 | +-- Tabela de watermarks por domínio |
| 39 | +CREATE TABLE scraper_watermarks ( |
| 40 | + domain TEXT PRIMARY KEY, |
| 41 | + last_processed_at TIMESTAMPTZ NOT NULL, |
| 42 | + created_at TIMESTAMPTZ DEFAULT NOW() |
| 43 | +); |
| 44 | +``` |
| 45 | + |
| 46 | +### 2. Firecrawl API Key |
| 47 | + |
| 48 | +Obtenha sua API key em https://firecrawl.dev |
| 49 | + |
| 50 | +### 3. Instalar o MCP |
| 51 | + |
| 52 | +Ao instalar, preencha: |
| 53 | +- `firecrawlApiKey`: Sua chave de API do Firecrawl |
| 54 | +- `supabaseUrl`: URL do seu projeto Supabase (ex: https://xxx.supabase.co) |
| 55 | +- `supabaseKey`: Service role key ou anon key com RLS configurado |
| 56 | + |
| 57 | +## Tools Disponíveis |
| 58 | + |
| 59 | +### `process_urls` |
| 60 | + |
| 61 | +Processa uma lista de URLs: |
| 62 | +- Extrai conteúdo limpo usando Firecrawl |
| 63 | +- Gera fingerprint único (SHA-256 de title + body normalizado) |
| 64 | +- Verifica se já existe no Supabase |
| 65 | +- Salva novo conteúdo ou atualiza se fingerprint mudou |
| 66 | +- Retorna resumo focado em insights |
| 67 | + |
| 68 | +**Input:** |
| 69 | +```json |
| 70 | +{ |
| 71 | + "urls": ["https://example.com/article-1", "https://example.com/article-2"], |
| 72 | + "generateSummaries": true |
| 73 | +} |
| 74 | +``` |
| 75 | + |
| 76 | +**Output:** |
| 77 | +```json |
| 78 | +{ |
| 79 | + "processed": [ |
| 80 | + { |
| 81 | + "url": "https://example.com/article-1", |
| 82 | + "status": "new", |
| 83 | + "title": "Article Title", |
| 84 | + "summary": "Key insights from the content...", |
| 85 | + "fingerprint": "abc123...", |
| 86 | + "domain": "example.com" |
| 87 | + } |
| 88 | + ], |
| 89 | + "stats": { |
| 90 | + "total": 2, |
| 91 | + "new": 1, |
| 92 | + "updated": 0, |
| 93 | + "unchanged": 1, |
| 94 | + "errors": 0 |
| 95 | + } |
| 96 | +} |
| 97 | +``` |
| 98 | + |
| 99 | +### `check_updates` |
| 100 | + |
| 101 | +Verifica status de URLs processadas anteriormente sem re-extrair: |
| 102 | + |
| 103 | +**Input:** |
| 104 | +```json |
| 105 | +{ |
| 106 | + "domain": "example.com" |
| 107 | +} |
| 108 | +``` |
| 109 | + |
| 110 | +### `get_watermarks` |
| 111 | + |
| 112 | +Obtém watermarks (última vez processada) por domínio: |
| 113 | + |
| 114 | +**Input:** |
| 115 | +```json |
| 116 | +{ |
| 117 | + "domain": "example.com" |
| 118 | +} |
| 119 | +``` |
| 120 | + |
| 121 | +## Lógica de Deduplicação |
| 122 | + |
| 123 | +1. **Normalização**: title e body são normalizados (lowercase, whitespace colapsado, Unicode normalizado) |
| 124 | +2. **Fingerprint**: SHA-256 do texto normalizado `title|body` |
| 125 | +3. **Verificação**: |
| 126 | + - Se URL não existe → conteúdo **novo** |
| 127 | + - Se URL existe mas fingerprint diferente → **update** |
| 128 | + - Se URL existe e fingerprint igual → **ignorar** |
| 129 | + |
| 130 | +## Desenvolvimento |
| 131 | + |
| 132 | +```bash |
| 133 | +cd content-scraper |
| 134 | +bun install |
| 135 | +bun run dev # Desenvolvimento local |
| 136 | +bun run deploy # Deploy para produção |
| 137 | +``` |
| 138 | + |
| 139 | +## Arquitetura |
| 140 | + |
| 141 | +``` |
| 142 | +content-scraper/ |
| 143 | +├── server/ |
| 144 | +│ ├── main.ts # Entry point e StateSchema |
| 145 | +│ ├── lib/ |
| 146 | +│ │ ├── firecrawl.ts # Cliente Firecrawl API |
| 147 | +│ │ ├── supabase.ts # Cliente Supabase para persistência |
| 148 | +│ │ ├── content.ts # Normalização, fingerprint, resumo |
| 149 | +│ │ └── types.ts # Tipos compartilhados |
| 150 | +│ └── tools/ |
| 151 | +│ ├── index.ts # Exporta todas as tools |
| 152 | +│ └── scraper.ts # Tools de processamento |
| 153 | +├── shared/ |
| 154 | +│ └── deco.gen.ts # Tipos gerados |
| 155 | +├── package.json |
| 156 | +├── wrangler.toml |
| 157 | +└── tsconfig.json |
| 158 | +``` |
0 commit comments