SEO MCP

Servidor MCP para evidencia SEO — auditoría en página, rastreo, GSC, PageSpeed, SERP opcional

Documentación

mcp-server-seo

Servidor MCP en Rust para evidencia SEO utilizado por Grok Build y Claude Code: auditoría on-page, robots/sitemap, rastreo cortés, PageSpeed Insights, Google Search Console, SERP de pago opcional.

stdio + JSON-RPC a través de rmcp. Sin Docker.

Dos binarios comparten el mismo motor:

BinarioRol
seoCLI sin interfaz (doctor, tool, audit daily|weekly, mail)
mcp-server-seoServidor MCP stdio para agentes de IA

Compilación

cargo build --release
install -Dm755 target/release/seo ~/.local/bin/seo
install -Dm755 target/release/mcp-server-seo ~/.local/bin/mcp-servers/mcp-server-seo

Cron / SeoAuditBot usa seo. Los agentes siguen usando mcp-server-seo.

Configuración

Opcional: ~/.config/mcp-server-seo/config.toml (ver config.example.toml).

mkdir -p ~/.config/mcp-server-seo
cp config.example.toml ~/.config/mcp-server-seo/config.toml
chmod 600 ~/.config/mcp-server-seo/config.toml

Las herramientas de la Fase 1 funcionan con cero claves. GSC necesita un JSON de cuenta de servicio; PageSpeed necesita una clave API gratuita; SERP necesita Serper (opcional).

Herramientas (resumen)

GrupoHerramientas
Fundamentosstatus, sites_list, site_resolve
On-pagepage_audit (mode=quick|full, target_keyword), page_text, redirect_trace, robots_check, sitemap_*, extract_structured_data, schema_validate, link_check, entity_coverage
Rastreo / grafocrawl_run (reanudable, seed_sitemap), crawl_report, crawl_results, crawl_diff, sitemap_coverage, sitemap_build, internal_link_graph (huérfanos reales)
Local / arquitecturaurl_architecture_plan, nap_consistency (primero esquema), citation_prospects, gbp_audit, gbp_reviews_snapshot, local_audit
Contenido / KWcontent_brief (basado en SERP), keyword_research (clasificado), keyword_volumes, keyword_intent, keyword_suggest
Autoridadauthority_snapshot (gratis, Open PageRank), backlink_overview (de pago, restringido)
Rendimientopagespeed_audit
GSCgsc_*, gsc_opportunities, gsc_trends, log_event
SERP / rankingserp_fetch (num, paquete local), rank_history (serie), rank_watch
Compuestospage_snapshot, page_history, audit_page, audit_site, verify_live, rank_diagnosis
Bucle de correcciónfindings_list, findings_diff (por defecto las dos últimas ejecuciones), url_to_source

Playbook de agente recomendado, primero gratuito (v0.7)

  1. page_audit mode=full (+ target_keyword) en la página de inicio + plantillas clave
  2. page_text en cualquier página cuyo contenido necesites evaluar — la auditoría devuelve recuentos, esto devuelve las secciones reales
  3. crawl_run con seed_sitemap=trueinternal_link_graph; si coverage.truncated, vuelve a llamar con resume_crawl_id hasta que la frontera se agote, luego lee true_orphans
  4. local_audit para NAP/GBP/autoridad/reseñas en una sola pasada
  5. authority_snapshot antes de concluir que una página limpia "solo necesita más on-page" — un veredicto de déficit significa enlaces, no pulido
  6. serp_fetch una vez por consulta objetivo (~$0.001, confirm=YES-PAY) → content_brief lee la SERP almacenada para preguntas PAA y H2 respaldados por competidores
  7. rank_diagnosis cuando una palabra clave específica rinde por debajo de lo esperado — clasifica indexación vs relevancia vs autoridad vs técnico
  8. verify_live después del despliegue, luego log_event para que el movimiento tenga una causa asociada
  9. Próxima sesión: findings_diff (sin IDs de ejecución) — fixed vs new/regressed. url_to_source mapea una URL al archivo bajo [[sites]].source_root

Bucle semanal (programa desde tu cliente MCP — este servidor no ejecuta demonios)

gsc_trends site=<property> refresh=true      # stores today's snapshot, returns movers
rank_watch action=run confirm=YES-PAY        # re-checks tracked queries

Lee movers_up / movers_down junto al events que registraste.

Sitio nuevo, sin historial de GSC (~$0.10)

keyword_research seed=<service> geo=<city> mode=all
keyword_volumes keywords=[...] confirm=YES-PAY        # one call, cached 90 days
serp_fetch <top terms> confirm=YES-PAY                # unlocks difficulty + SERP clustering
keyword_research ...                                  # now returns a ranked shortlist
url_architecture_plan / content_brief                 # human approval before publish

La publicación de contenido permanece en el CMS — este servidor es evidencia + briefs, no un redactor.

Seguridad

  • SSRF: solo http(s) público; IPv4+IPv6 privadas/reservadas bloqueadas; saltos de redirección re-verificados
  • sitemap_build: escrituras solo bajo storage.data_dir (out_path relativo)
  • Envío GSC: confirm=YES-SUBMIT (API de sitemaps — no Inspección de URL)
  • SERP de pago: dry_run=true por defecto; confirm=YES-PAY + libro de presupuesto
  • Autoridad de pago (backlink_overview): misma puerta, libro de presupuesto [authority] separado; la ejecución en seco hace cero llamadas al proveedor y el libro registra el costo real informado por el proveedor
  • HTML estático: rendered: false — usa agent-browser para JS

Claves opcionales (v0.7)

ClaveDesbloqueaCosto
authority.open_pagerank_api_keyauthority_snapshot, paso de autoridad en local_audit, veredictos rank_diagnosis, dificultad de palabras clavegratis (domcop)
authority.dataforseo_login / _passwordbrecha de enlaces backlink_overview, keyword_volumespago por uso, con tope de presupuesto
serp.api_keyserp_fetch / rank_watch → fundamenta content_brief, dificultad de palabras clave, comprobaciones de presencia de citas~$0.001/consulta
local.places_api_keycalificación gbp_reviews_snapshot, velocidad de reseñas, brecha de competidoresnivel gratuito + tope mensual de llamadas
gsc.credentials_filegsc_* incl. historial gsc_trends y gsc_opportunitiesgratis

Verifica antes de confiar en los números: el costo de crédito de tu proveedor de SERP para num > 10 (serp.num_100_multiplier), el keywords.location_code de DataForSEO para tu país, y el precio actual de los campos de Places API. Los tres son valores de configuración, no están codificados.

No reimplementar

Usa MCPs hermanos: google-analytics, google-adwords, cloudflare, namecheap, agent-browser.

Clientes

Ya registrado como seo en Grok Build / Claude Code (reinicia los clientes después de recompilar).

Pruebas

cargo test --release
./tests/test-stdio.sh

Plan

Ver PLAN.md (fusionado Grok + Fable + Kimi + enmiendas de crítica).

Diseño de módulos (v0.7)

src/
  bin/seo.rs        # CLI (doctor, tool, audit daily|weekly, mail)
  bin/mcp_server_seo.rs
  server/           # thin MCP tool-router only (no SEO logic)
    params.rs       # all tool input schemas
    dispatch/       # named-tool router + one exec file per handler group
    playbooks.rs    # daily/weekly audits; ok=false on step errors
    mod.rs          # SeoServer, shared helpers, chained tool_router()
    handlers/       # #[tool] wrappers → run_named; one sub-router per file
                    #   (site, page, crawl, pagespeed, gsc, serp, audit,
                    #    findings, content, authority, local)
  tools/            # business logic per concern
    page/           # parse, og probe, structured data, text extraction, audit
    crawl/          # BFS crawl + report builder
    local/          # nap, citations, gbp, local_audit
    gsc/            # client (JWT) + ops (analytics/inspect/sitemaps)
    authority/      # open pagerank (free) + dataforseo (paid) adapters
    audit/          # composites: page, site, verify_live, rank_diagnosis
    source_map.rs   # URL → repo file (convention presets, sandbox)
    serp_evidence.rs# stored-SERP parser shared by briefs/keywords
    html_dom.rs     # shared HTML extract helpers incl. main-text extraction
    …
  rules/            # pure rules (checklist, schema, patterns, intent, relevance, issue)
  storage/          # SQLite split by domain (crawls, snapshots, spend, authority,
                    #   keywords, gsc, rank, places, events,
                    #   findings/{persist,extract,query,family}) over one shared conn
  http.rs / config.rs / site.rs / util.rs

Regla: sin archivos God — la lógica vive bajo tools/* / rules/*; server/ no implementa algoritmos SEO. Los constructores de problemas compartidos viven en rules/issue.rs.