Automaticé GA4 con YAML. Ahora Me Señala Qué Revisar en SEO.
Una CLI + servidor MCP que configura GA4 y Search Console desde YAML, y señala qué revisar en tu SEO por impacto. Determinista: las decisiones las tomas tú. →
Óscar Gallego
Desarrollador Web
En este artículo
Empecé a construir esto para no perder 40 minutos clicando en la UI de GA4 cada vez que arrancaba un proyecto. Lo que no esperaba es dónde acabaría: ahora la herramienta no solo configura analytics, me señala qué mirar en mi SEO, ordenado por cuántos clics me está costando. No decide por mí. Me pone los datos delante, priorizados, y yo elijo qué tocar.
En esa distinción está la clave, y vuelvo a ella más abajo. Esta es la historia de cómo pasó, qué hace hoy, y qué salió cuando le solté la suite entera a este mismo blog, incluido el momento en que la herramienta se equivocó (y por qué eso me dio más confianza, no menos).
El problema original: clicar como un mono
Tengo varios side projects. Este portfolio, WealthSim, y unos cuantos más pequeños. Cada uno necesita analytics, y cada vez que arrancaba uno nuevo el ritual era el mismo: crear la propiedad GA4 (fácil), y luego clicar. Conversiones, diez clics cada una. Dimensiones, más clics. Métricas, más. Retención de datos, ¿dónde estaba eso? Enhanced measurement, otro menú.
Treinta o cuarenta minutos de clics repetitivos. Y lo peor: si quería la misma config en otro proyecto, a repetirlo todo desde cero. GA4 no tiene “exportar configuración”. No puedes copiar setup entre propiedades.
Después de configurar el tercer proyecto en una semana pensé lo que piensas tú ahora: esto es exactamente el tipo de trabajo que debería automatizarse.
La premisa: analytics as code
Defino mi infra como código. Mi CI/CD como código. ¿Por qué no mi analytics?
Esa fue toda la idea. Un YAML que describe cómo quiero GA4, y un comando que lo aplica:
project:
name: "Mi Proyecto"
ga4:
property_id: "123456789"
tier: standard
conversions:
- name: newsletter_signup
counting_method: ONCE_PER_SESSION
dimensions:
- parameter: article_category
scope: EVENT
ga4 setup --config mi-proyecto.yaml
Boom. Config aplicada. Sin clics, sin typos, versionable en git junto a tu código. De 40 minutos a menos de uno. Eso fue GA4 Manager v1.
El giro: dejó de enseñarme datos y empezó a señalarme dónde mirar
Aquí es donde la herramienta se volvió interesante de verdad.
La primera mitad de su vida fue configuración: aplica este YAML, crea estas conversiones, envía este sitemap. Útil, pero pasivo. La segunda mitad, lo que de verdad cambió cómo trabajo, es diagnóstico. Hoy, en la v2.3.1, el servidor MCP expone 20 herramientas, y las más nuevas no te enseñan datos: te dicen por dónde empezar.
La que más uso es gsc_opportunities. Busca queries donde ya estás en página 1-2 (posición 5-20) pero con un CTR por debajo de la mediana de su franja, y las ordena por potential_clicks: los clics extra al mes que ganarías solo con llegar al CTR mediano. Las mayores ganancias primero.
¿En este blog? Encontró exactamente una. Y encima en posición ~18, página 2, donde un retoque de title no la mueve. La herramienta no la infló: me dijo la verdad, que aquí no había una mina de oro. En un sitio con tráfico de verdad, esta es la tool que te paga el café; en uno pequeño, te confirma que no hay atajos. Las dos respuestas me valen.
Las otras tres del grupo nuevo siguen la misma filosofía de “qué primero”:
gsc_cannibalization: queries donde dos o más páginas tuyas se reparten impresiones y se comen la autoridad entre ellas; te señala la candidata a canónica.gsc_ctr_anomaly: pares (query, página) donde la posición casi no se movió pero el CTR se desplomó. Traducción: tu snippet dejó de convertir. A reescribir.gsc_health: informe de indexación que diffea el estado de cada URL contra el snapshot anterior, así unnoindexaccidental sale en días, no en semanas. Silencioso si todo está verde. Pensado para un cron.
Y algo que para mí es lo que separa esto del montón: nada de esto es la IA adivinando SEO. Son queries deterministas contra la API de Search Console (un CLI en Go, output estructurado). El LLM solo orquesta las llamadas y me resume el resultado; la interpretación y el “esto sí, esto no” son míos. Si te da urticaria el vibe coding (a mí me la da), esa es justo la línea que importa: la herramienta saca, tú juzgas.
Qué pasó cuando lo solté sobre este blog
Este blog es uno de mis side projects y corre sobre un sitio que usa GA4 Manager vía MCP, así que la semana pasada me senté con Claude y le solté la suite entera sobre oscargallegoruiz.com. Esperaba encontrar desastres. La realidad fue más aburrida, y más interesante de lo que parece.
43 de 43 páginas indexadas. gsc_ctr_anomaly: vacío. seo_page_audit en las páginas top: limpias, cero errores. En resumen: el sitio estaba sano. Y que una herramienta te diga “está todo bien” en vez de inventarte un problema para justificarse ya es una señal de la que me fío.
Pero hubo un susto. gsc_sitemaps_list me devolvió una lista vacía, como si nunca hubiera enviado el sitemap. El reflejo fácil habría sido reenviarlo y pasar página. En vez de eso lo verifiqué con gsc_sitemaps_get… y ahí estaba, enviado y descargado por Google sin problema. La lista vacía era un bug en mi propia herramienta, no un fallo de SEO.
Y esa es la moraleja que me importa, la que conecta con todo lo de arriba: no me fié del output a ciegas. Si llego a actuar sobre el falso positivo, habría “arreglado” algo que no estaba roto. Verificar me ahorró el ridículo y, de paso, la herramienta que escribí para cazar problemas me cazó un bug en sí misma. Lo arreglé. Esa es la relación sana con un tool así: te da pistas, tú las confirmas. De la que no me fío nunca es de la que te promete que no hace falta confirmar nada.
Lo que aprendí construyendo esto
Google tiene dos APIs de GA4. La Data API (consultar datos) y la Admin API (configurar). GA4 Manager usa la Admin, que va en v1alpha. Sí, alpha. Algunos endpoints cambian sin avisar, y ciertos tipos de métrica (como CURRENCY) tienen restricciones mal documentadas. Te enteras por las malas.
Los límites son reales y los valida antes de tocar nada. En el tier gratuito: 30 conversiones, 50 dimensiones, 50 métricas. Si te acercas, te avisa antes de comerte un 400 de la API.
Los nombres de parámetros son para siempre. Una vez creas una dimensión o métrica, el nombre del parámetro queda reservado de forma permanente. Aunque la archives. Mi solución es fea pero funciona: versionar los nombres (reading_time_v3).
Úsalo desde tu asistente (MCP)
La pieza que lo cambió todo fue el servidor MCP. Expone las 20 herramientas a Claude Desktop, Claude CLI, VS Code, Cursor y Cline, así que puedo decir en lenguaje normal:
“Compara el tráfico de la última semana vs la anterior, pasa una auditoría a la home y al post peor posicionado, y dime qué revisar.”
Y Claude orquesta las llamadas y junta los resultados. Pero ojo, mismo principio de siempre: me devuelve una lista priorizada, no un git push. Las decisiones siguen siendo mías.
Y aquí está la conexión que me tiene enganchado: gsc_health está hecho para un cron. O sea, no es solo una tool que invoco, sino un loop que puedo dejar corriendo: un agente que cada lunes mira la indexación, compara el tráfico, y solo me molesta si algo se rompió. Ese es el siguiente escalón. Dejas de preguntar y montas el bucle que pregunta por ti.
Lo que NO hace (seamos honestos)
- Audiencias: la herramienta no las crea. Genera la documentación para que las montes a mano en la UI (la Admin API sí permite crear audiencias; simplemente aún no lo he metido en la herramienta).
- BigQuery linking: automatizado.
ga4 link --service bigquerycrea el enlace de exportación vía Admin API. - Search Console linking: manual. La herramienta imprime una guía de setup; el enlace lo terminas tú en la UI.
- Datos históricos: esto configura GA4, no migra datos. La recolección empieza después del setup.
Instalación: un solo script
git clone https://github.com/garbarok/ga4-manager.git
cd ga4-manager
./scripts/setup.sh
El script verifica prerequisitos (gcloud, jq, curl), elige contigo la ruta de auth (ADC para uso personal, service-account key para CI), activa las APIs necesarias, hace smoke-test de cada endpoint, y te imprime qué permisos manuales te quedan. Es idempotente: lo relanzas sin miedo.
Preguntas rápidas
¿Es gratis? Sí, open source con licencia MIT. El código está en GitHub.
¿Necesito saber Go? No. Bajas el binario y escribes YAML.
¿Puede borrar mis datos? No. Solo usa la Admin API para configuración; no toca tus datos de analytics. Lo peor sería crear o borrar recursos de config, que siempre puedes recrear. Y --dry-run te deja previsualizar todo antes de aplicar.
¿Las auditorías SEO necesitan una API key de pago? Solo si quieres Core Web Vitals dentro de seo_page_audit. Sin key, PageSpeed Insights limita a una request cada ~100s y la auditoría se salta los CWV. Con una key gratuita tienes la cuota normal.
¿gsc_analytics_run vs gsc_traffic_compare? La primera es una foto de un periodo (top queries, páginas, CTR, posición). La segunda compara dos periodos y te da caídas y subidas por URL. Una para ver lo que tienes, la otra para ver qué cambió.
Si tienes un par de side projects que rara vez tocas, probablemente no lo necesitas. Si llevas tres o más y estás harto de clicar la misma UI por enésima vez: pruébalo, dale una estrella si te sirve, y abre un issue si algo se rompe (o si encuentras otro bug como el de la lista de sitemaps).
Lectura relacionada: por qué gsc_health en un cron es el siguiente paso natural: deja de promptear a tu agente, escribe loops.
P.D. Si lo pruebas, cuéntame qué te encontró en Twitter/X. Ahora, si me disculpas, tengo un cron que montar.
Última actualización:


