Files
claude-plugins/marketing/skills/seo-audit/SKILL.md
T
ealmeida 2d05873642 marketing: migra superfície SEO para OpenSEO (motor único)
As skills de SEO assentavam em quatro dependências, nenhuma operacional:
SEO Tools API (localhost:3000, pasta inexistente em disco), Ahrefs MCP
(nunca esteve em config), gsc e lighthouse (em disabledServers). Os seis
passos da /seo-audit e o workflow inteiro da /seo-report apontavam para
tooling morto — não eram executáveis.

- seo-audit v3.0: ordem por custo (grátis → lote pago → unitário pago),
  gate de mercado (PT = 2620/pt) e gate de maxPages
- seo-report v3.0: cobertura de crawl obrigatória no entregável
- ferramentas-api.md: inventário das 24 ferramentas OpenSEO + tabela de
  migração endpoint a endpoint
- implementacao-tecnica.md: striking distance, desperdício e filtro de
  ruído do GSC em código
- seo-specialist v3.0: primary_mcps [openseo], bloco de MCPs desligados,
  FID → INP nos Core Web Vitals

maxPages tem default 50: descomplicar.pt auditado com o default deu 25
URLs e 92 issues sem críticos; com maxPages 600 deu 1337 issues e 9
críticos. Documentado como gate — a fase Search Console dimensiona o crawl.

Limitações declaradas nas skills: get_audit_issues devolve contagens sem
URLs pela bridge MCP (structuredContent.issues não é entregue) e o whoami
não expõe saldo de créditos em self-hosted.
2026-07-30 22:39:40 +01:00

10 KiB

name, description
name description
seo-audit Auditoria SEO completa com dados reais via OpenSEO (crawl, Search Console, SERP, backlinks, keywords). Analisa SEO técnico, conteúdo, autoridade e desempenho, e prioriza por retorno. Usar quando "auditoria SEO", "audit", "analisar site", "Core Web Vitals", "Search Console", "striking distance", "porque não tenho tráfego".

SEO Audit — Auditoria Completa (OpenSEO)

Auditoria SEO com dados reais. Motor único: OpenSEO (seo.descomplicar.pt), que substituiu o stack antigo (SEO Tools API + Ahrefs + GSC MCP + Lighthouse MCP) — ver references/ferramentas-api.md para a tabela de migração.


Regra zero — a ordem é económica, não estética

O OpenSEO tem ferramentas grátis e ferramentas que gastam créditos. Executar pela ordem errada gasta dinheiro a produzir conclusões que as ferramentas grátis já davam.

Fase Ferramentas Custo Porquê nesta ordem
1 get_search_console_performance, inspect_urls grátis Dados de primeira mão. Diz o que já posiciona e quais páginas importam
2 run_site_audit, get_audit_issues, get_audit_pages grátis Estado técnico. O dimensionamento do crawl depende da fase 1
3 get_keyword_metrics pago (lote) Hidrata até 700 keywords conhecidas de uma vez — a melhor relação valor/crédito
4 get_ranked_keywords, get_domain_overview, get_backlinks_overview pago Contexto competitivo
5 get_serp_results, find_serp_competitors pago (~30-60/keyword) Só nas keywords que sobreviveram à filtragem

Nunca começar pela fase 3 ou acima. As fases 1-2 resolvem a maioria das auditorias sem gastar um crédito.


Pré-voo obrigatório (3 verificações, 30 segundos)

1. openseo → whoami            → confirma ligação, org, modo
2. openseo → list_projects     → obtém projectId E o mercado do projecto
3. confirmar mercado           → PT = locationCode 2620, languageCode "pt"

GATE — mercado. Se o projecto estiver em 2840/en (EUA/inglês, que é o default) e o cliente for português, todas as chamadas pagas devolvem dados do mercado errado. Ou se corrige o mercado do projecto, ou se passa locationCode/languageCode explicitamente em cada chamada. Um esquecimento = créditos gastos em lixo.

locationCode: 2620 = Portugal — confirmado empiricamente (SERP devolve domínios .pt). Não inventar códigos: se houver dúvida, correr uma query de teste e validar pelos resultados.


Fase 1 — Search Console primeiro (grátis, é o mapa)

openseo → get_search_console_performance
  dimensions: ["query"]   dateRange: "last_3_months"   rowLimit: 1000
openseo → get_search_console_performance
  dimensions: ["page"]    dateRange: "last_3_months"   rowLimit: 1000

Paginar com startRow enquanto o cabeçalho disser more available.

As três armadilhas do GSC

1. Vista por query ≠ vista por página. O GSC anonimiza queries raras, por isso os totais por query são sempre muito menores que os totais por página. A vista por página é a real; usar essa para números globais.

2. O GSC não filtra por posição. striking distance tem de ser filtrado do lado do cliente, depois de puxar as linhas.

3. Há lixo nas queries. Colagens de relatórios do Google Ads, operadores site:, strings com mojibake. Filtrar antes de contar, ou as métricas mentem.

def is_noise(k):
    return ('ativado' in k and 'correspond' in k) or k.startswith('-site:') \
           or k.startswith('=') or len(k) > 90 or '0,00' in k

O que extrair

Métrica Cálculo Leitura
CTR global cliques ÷ impressões (vista por página) < 1% = problema de captação, não de ranking
Distribuição por posição buckets 1-3 / 4-10 / 11-20 / 21-50 / 51+ Impressões concentradas em 21+ = visibilidade inútil
Branded vs não-branded queries com o nome da marca vs resto Se só a marca converte, o SEO não está a trabalhar
Striking distance pos 4-20 e impressões ≥ 25 É aqui que está o retorno
Desperdício pos > 40 e impressões ≥ 300 Páginas com procura real enterradas

O sinal mais accionável de todos

Posição 4-10 com CTR perto de 0%. Não é problema de ranking — o site está na primeira página. É o título e a meta description a não convencerem. Cruzar esta lista com os issues missing-meta-description e title-too-long da fase 2: a intersecção é a lista de trabalho, por ordem.


Fase 2 — Auditoria técnica (grátis)

openseo → run_site_audit
  url: "<url>"   maxPages: <N>   runLighthouse: true
openseo → get_audit_status      (poll até "completed")
openseo → get_audit_issues      (severity: critical → warning → info)

GATE — maxPages (o erro que cega a auditoria)

maxPages tem default 50. Um site de 600 páginas auditado com o default devolve um relatório limpo e falso: descreve 8% do site e omite exactamente o hub de conteúdo que gera o tráfego.

Regra: maxPages ≥ número de páginas com impressões no GSC (fase 1), com folga de ~25%. Por isso é que a fase 1 vem primeiro — é ela que dimensiona o crawl.

Caso real (descomplicar.pt, 07-2026): auditoria com default 50 → 25 URLs únicos, 92 issues, zero críticos, nenhuma das 119 páginas /guia-*. Relançada com maxPages: 600 → 1337 issues, 9 críticos. O relatório "limpo" descrevia 4% do site.

Prioridade dos issues

Severidade Tipos Acção
critical broken-internal-link, blocked-page, server-error, broken-page Corrigir já — sangram autoridade e crawl budget
warning missing-h1, missing-meta-description, duplicate-content, multiple-h1, duplicate-title Priorizar pelas páginas com impressões (fase 1)
info title-too-long, noindex-page, slow-response, heading-order-skip Lote; só vale a pena onde há procura

Nunca tratar a lista de issues por ordem de contagem. 300 metas em falta em páginas sem impressões valem menos que 6 em páginas na posição 8. A fase 1 é que ordena a fase 2.

Limitação conhecida — issues sem URL

get_audit_issues e get_audit_pages devolvem apenas contagens agregadas através da bridge MCP. As linhas por URL vivem em structuredContent.issues, que a bridge não entrega; get_audit_pages trunca a listagem em ~25 linhas independentemente do limit.

Contorno: o campo details.mcpMeta.url da resposta traz o link do relatório na UI. Entregar esse link ao humano para os URLs concretos:

https://seo.descomplicar.pt/p/<projectId>/audit?auditId=<auditId>

Declarar esta limitação no relatório — não fingir que se verificaram URLs que não se viram.

Core Web Vitals por página

run_site_audit com runLighthouse: true corre Lighthouse numa amostra (até 20 páginas). Para uma página específica, usar chrome-devtools:

chrome-devtools → lighthouse_audit          (SEO, acessibilidade, best practices)
chrome-devtools → performance_start_trace   (LCP, INP, CLS reais)

Thresholds 2026: LCP < 2,5s · INP < 200ms · CLS < 0,1 (INP substituiu o FID — se algum documento ainda disser FID, está desactualizado.)


Fase 3 — Hidratar keywords (pago, lote)

openseo → get_keyword_metrics
  keywords: [<as keywords em striking distance da fase 1>]
  locationCode: 2620   languageCode: "pt"

Até 700 keywords numa só chamada — volume, dificuldade (KD), intenção, CPC, tendência. É a forma barata de priorizar. Só depois disto se decide onde vale a pena competir.

Guardar o que sobreviver: openseo → save_keywords (grátis, idempotente).


Fase 4 — Contexto competitivo (pago)

openseo → get_domain_overview        (tráfego orgânico estimado, nº keywords, backlinks)
openseo → get_ranked_keywords        (onde o domínio posiciona, por mercado)
openseo → get_backlinks_overview     (~50 créditos por domínio)
openseo → get_backlinks_profile      (linhas detalhadas: anchors, dofollow, spam)

Fase 5 — SERP (pago, por último)

openseo → get_serp_results       (1-10 keywords por chamada, ~30-60 créditos cada)
openseo → find_serp_competitors  (quem compete num conjunto de keywords)

Ler a SERP como estrutura, não como lista: se o top-10 estiver cheio de directórios e artigos "melhores X", a intenção é comparativa e uma homepage não entra — é preciso uma página de comparação. Se estiver cheio de homepages de concorrentes, é disputa de marca.

Local/Maps: get_local_serp_results, search_local_businesses, get_google_business_questions.


Custos — o que sabemos e o que não sabemos

whoami não expõe saldo de créditos em modo self-hosted (verificado antes e depois de uma chamada paga: output idêntico). Os ~30-60 créditos/keyword são a estimativa do schema, não uma medição.

Consequência prática: não há medidor no OpenSEO. O contador real vive na conta DataForSEO. Para lotes grandes, confirmar saldo aí primeiro. Nunca reportar custo consumido como facto — reportar como estimativa.


Anti-patterns

  • Correr run_site_audit com o maxPages por omissão. Produz relatórios limpos e falsos.
  • Começar por ferramentas pagas. O GSC é grátis e responde a metade das perguntas.
  • Usar totais por query como totais do site (o GSC anonimiza — usar a vista por página).
  • Priorizar issues por contagem em vez de por impressões da página afectada.
  • Correr chamadas pagas sem confirmar o mercado do projecto.
  • Apresentar contagens de issues como se fossem URLs verificados.
  • Auditar sem dados reais ou simular métricas.
  • Recomendações sem prioridade (crítico/importante/melhoria) e sem esforço estimado.

References

Ficheiro Conteúdo
references/ferramentas-api.md Inventário OpenSEO completo + tabela de migração do stack antigo
references/template-relatorio-auditoria.md Template do relatório com todas as secções e tabelas

Versão: 3.0.0 | Autor: Descomplicar® | Motor: OpenSEO

Healing Log

{"date":"2026-07-30","issue":"Skill dependia de SEO Tools API (localhost:3000), Ahrefs MCP, GSC MCP e Lighthouse MCP — todos inexistentes ou desligados. Nenhum dos 6 passos era executável.","fix":"Reescrita completa sobre OpenSEO, com ordem por custo, gates de mercado e maxPages.","source":"auto"}