seo-analytics-mcp
Google Search Console, GA4 e IndexNow — como servidor MCP.
Pregunta a Claude sobre tus propios sitios. Qué está posicionando, qué ha cambiado, qué está indexado, qué está convirtiendo.
"Which pages lost the most clicks in the last 28 days versus the 28 before?"
"How is /pricing doing?"
"Is https://example.com/new-post indexed yet?"
"Which pages rank on page one but get almost no clicks?"
"Top 20 queries for the blog last month, and which of them convert in GA4."Autorizas tu propia cuenta de Google contra un cliente OAuth en tu propio proyecto de Google Cloud. Nada de tu acceso pasa por nadie más, este repositorio no contiene ninguna credencial, y cada cuota de Google que gastas es tuya.
Contenido
Instalación · Configuración · El problema de los siete días · Herramientas · Forma de la respuesta · Configuración · Escrituras · Perfiles · Diseño · Solución de problemas · Desarrollo
Related MCP server: GSC Analyst Connector
Instalación
Requiere Python 3.10+ y uv.
uvx seo-analytics-mcp doctor # no install needed — prints your setup steps, in orderdoctor es toda la experiencia de incorporación. Te dice exactamente qué falta y qué
ejecutar a continuación, en cada etapa. Si no lees nada más aquí, ejecuta eso.
Configuración
Seis clics en la consola de Google Cloud, luego un comando. Diez minutos, una vez.
Crea un proyecto de Google Cloud — o reutiliza uno. console.cloud.google.com/projectcreate
Habilita las APIs. Search Console es obligatoria; el par de GA4 es opcional.
searchconsole ·
analyticsdata ·
analyticsadmin
Configura la pantalla de consentimiento y luego pulsa Publicar aplicación. console.cloud.google.com/auth/overview
Elige Externa y publica. Eres el único usuario de tu propia aplicación, así que se aplica la excepción de uso personal de Google y no se necesita verificación. Los usuarios de Workspace pueden elegir Interna en su lugar.
No te saltes el paso de Publicar — ver más abajo.
Crea un cliente OAuth de tipo Desktop app y descarga el JSON.
console.cloud.google.com/auth/clients
Un cliente de Aplicación web no puede hacer la redirección de bucle local que este servidor
necesita. doctor comprueba este error específico, porque es el más fácil de cometer.
Autoriza, una vez, desde una terminal:
uvx seo-analytics-mcp auth --client-secret ~/Downloads/client_secret_*.jsonSe abre tu navegador. Google dice "Google hasn't verified this app" — esperado para tu propio
cliente: Avanzado → Continuar. El token se guarda en tu directorio de perfil con modo 0600.
Comprueba y luego conecta:
uvx seo-analytics-mcp doctor # eleven checks; exit 0 means it will workConéctalo
claude mcp add seo \
-e GSC_DEFAULT_SITE=sc-domain:example.com \
-e GA4_DEFAULT_PROPERTY=properties/123456789 \
-- uvx seo-analytics-mcp{
"mcpServers": {
"seo": {
"command": "uvx",
"args": ["seo-analytics-mcp"],
"env": {
"GSC_DEFAULT_SITE": "sc-domain:example.com",
"GA4_DEFAULT_PROPERTY": "properties/123456789"
}
}
}
}Luego sal de Claude Desktop por completo (⌘Q — cerrar la ventana no es suficiente) y vuelve a abrirlo.
[!NOTE] No hay ninguna ruta de credenciales en esa configuración. El token vive en el directorio de perfil que
seo-mcp authescribió, así que todo el bloque se puede pegar con seguridad en un issue de GitHub.
El problema de los siete días
[!WARNING] Si el servidor funciona y luego se detiene aproximadamente una semana después, esta es la razón.
Google emite tokens de actualización que expiran después de siete días para cualquier aplicación OAuth externa cuyo estado de publicación siga siendo Probando. La ruta de configuración obvia — crear proyecto, crear cliente, añadirte como usuario de prueba — te deja ahí.
La solución es un clic: en la pantalla de consentimiento, establece la audiencia en Externa y pulsa
Publicar aplicación. Luego uvx seo-analytics-mcp auth --reauth.
doctor marca un token lo bastante reciente como para seguir siendo un token de Prueba, y cada error
invalid_grant del servidor explica esto en detalle. No es un error del servidor — pero será el problema
más común reportado contra él.
Herramientas
Trece herramientas: diez se corresponden con operaciones de nivel superior, dos combinan fuentes, y una existe únicamente para que el modelo pueda decirle a un usuario confundido qué hacer.
Herramienta | Qué hace | |
🔎 |
| Propiedades que esta cuenta puede leer, con nivel de permiso |
🔎 |
| Clics, impresiones, CTR, posición por cualquier combinación de dimensiones |
🔎 |
| Dos ventanas comparadas — mayores movimientos, en ambas direcciones |
🔎 |
| Estado de indexación, cobertura, canónica, último rastreo, resultados enriquecidos |
🔎 |
| Sitemaps enviados con avisos y contadores de errores |
✍️ |
| Envía un sitemap — alcance de escritura y confirmación explícita |
📊 |
| Cuentas y propiedades, para resolver un ID de propiedad numérico |
📊 |
|
|
📊 |
| Sesiones, interacción, conversiones por página de destino |
⚡ |
| Comprueba que el archivo de clave está publicado correctamente |
⚡ |
| Envío por lotes — simulación por defecto, confirmación protegida por token |
🔗 |
| Una URL: tendencia de GSC, consultas principales, interacción de GA4, estado de indexación |
🩺 |
| Perfil activo, alcances, qué APIs responden, qué ejecutar a continuación |
Cómo es una respuesta
Cada herramienta de lectura devuelve las mismas cuatro claves. Acotada, autodescriptiva y con sus propias advertencias.
{
"summary": {
"source": "gsc",
"rows_returned": 10, // what you see
"rows_matched": 1847, // what exists upstream
"date_range": "2026-07-29..2026-08-25", // resolved, always echoed
"data_state": "final",
"totals": { "clicks": 4730, "impressions": 512903, "ctr": 0.0092, "position": 12.4 }
},
"rows": [ /* capped at min(row_limit, 1000) */ ],
"notes": [
"Google anonymises rare queries: these rows do NOT sum to property totals.",
"dataState=final excludes the most recent 2-3 days.",
"1837 further rows were not included inline."
],
"export": "~/.../exports/a1b2c3.csv" // only when rows spilled
}Tres convenciones se mantienen en todas partes:
Los totales cubren todas las filas obtenidas, no solo las mostradas — un modelo que ve diez filas y un
total para diez no puede distinguir la truncación de la realidad. Las tasas nunca se promedian: ctr se
recalcula a partir de clics ÷ impresiones, position está ponderada por impresiones, engagementRate es
interacción ÷ sesiones.
Las advertencias viajan con los datos. La capa que conoce la advertencia la añade: el cliente sabe que
se solicitó la dimensión query, shape() sabe cuántas filas descartó, GA4 sabe que la respuesta fue
muestreada. Los docstrings por sí solos las pierden exactamente cuando el modelo está mirando los números.
Los errores nombran la solución. Un 403 te dice qué permiso comprobar y dónde — nunca un cuerpo de error crudo de Google.
The authorised Google account has no access to sc-domain:example.com. Confirm the
account you authorised is the one with access — Search Console grants are per-property
under Settings > Users and permissions, GA4 grants are per-property under Admin >
Property access management. If access was added recently, run `seo-mcp auth --reauth`.Configuración
Cada variable es opcional. Precedencia: argumento de herramienta → entorno → config.json del perfil.
Variable | Propósito |
| Propiedad por defecto, p. ej. |
| Propiedad GA4 por defecto, p. ej. |
| Qué perfil usar (por defecto: |
| Sobrescribe el directorio raíz de perfiles |
| Requeridas solo para IndexNow |
|
|
Fechas
Cada argumento de fecha acepta YYYY-MM-DD, today, yesterday o NdaysAgo. Las respuestas reflejan
el rango absoluto que realmente usaron, porque un modelo que adivina mal la fecha de hoy produce un
resultado vacío que se lee como "el tráfico bajó a cero".
Search Console tiene un desfase de 2–3 días y retiene ~16 meses; los rangos fuera de esos límites se marcan o se rechazan en lugar de devolver silenciosamente nada. GA4 informa en la zona horaria propia de la propiedad, así que sus fechas no coinciden exactamente con las de Search Console — las respuestas lo indican donde importa.
Escrituras
Dos herramientas actúan sobre el mundo fuera de tu máquina. Ambas son deliberadamente incómodas.
| Necesita el alcance de escritura (no concedido por defecto) y |
| Verifica tu archivo de clave y luego devuelve un |
[!IMPORTANT] Un indicador
confirmpor sí solo no es un mecanismo de seguridad — es un argumento que el modelo rellena, y la misma mala lectura que produce las URLs incorrectas produceconfirm=truejunto a ellas.El token es infalsificable sin una simulación, y cambia una URL y deja de coincidir. Ambas herramientas también llevan anotaciones
destructiveHint, de modo que un cliente que protege las herramientas destructivas detrás de su propio aviso de aprobación lo hará.
Los alcances de solo lectura son el valor por defecto. Un desconocido que instala una herramienta SEO que inmediatamente pide permiso para modificar sus propiedades de Search Console razonablemente lo rechazará.
Perfiles
Varias cuentas de Google en una misma máquina — para agencias que gestionan propiedades de clientes en paralelo.
uvx seo-analytics-mcp auth --profile client-a --client-secret ./client-a.json
uvx seo-analytics-mcp auth --profile client-b --client-secret ./client-b.json
uvx seo-analytics-mcp profiles listEstablece SEO_MCP_PROFILE por entrada de servidor MCP. Las claves de caché incluyen el perfil, así que
dos cuentas nunca pueden servirse datos entre sí.
Un perfil es un directorio — lo primero que le pedirás a un usuario que elimine:
uvx seo-analytics-mcp profiles rm client-a --yesViven en ~/Library/Application Support/seo-mcp/ (macOS), $XDG_CONFIG_HOME/seo-mcp/
(Linux) o %APPDATA%\seo-mcp\ (Windows).
Diseño
Cuatro capas, estrictamente descendentes. Si esto se hace mal, el flujo de autenticación termina dentro de una llamada de herramienta, que es el fallo que todo el diseño existe para prevenir.
flowchart TD
subgraph L4["Entry points"]
S[server.py<br/><i>MCPServer, stdio</i>]
C[cli.py<br/><i>auth · doctor · profiles · serve</i>]
end
subgraph L3["Tools — argument surface, docstrings, cache policy"]
T[13 handlers<br/><i>no HTTP, no credentials, no row shaping</i>]
end
subgraph L2["Clients — the only modules that speak HTTP"]
G[gsc.py]
A[ga4.py]
I[indexnow.py]
end
subgraph L1["Leaves — importable by anyone, import nobody"]
LV[shaping · errors · config · cache · auth/store · auth/scopes]
end
F[auth/flow.py<br/><i>loopback + PKCE · opens a browser</i>]
S --> T
C --> T
C -.->|only reachable from here| F
T --> G & A & I
G & A & I --> LVEl flujo del navegador nunca debe ejecutarse dentro de una llamada de herramienta. Una herramienta MCP que se bloquea en stdio esperando a que un humano termine una pantalla de consentimiento parece un servidor colgado, y el modelo no tiene forma de ayudar. Un comando CLI, ejecutado una vez, es toda la diferencia — y una prueba recorre el AST de cada módulo para hacerlo cumplir.
Otras reglas que las pruebas hacen cumplir mecánicamente: shaping.py no importa ninguna librería de Google
(por eso la lógica de filas es totalmente comprobable por unidades sin credenciales), las herramientas no
importan ninguna librería HTTP, y nada en la ruta del servidor llama a print() — en un transporte stdio,
stdout lleva JSON-RPC y un solo print suelto corrompe el flujo.
Solución de problemas
Síntoma | Causa |
Funcionó, luego se detuvo después de una semana | La aplicación OAuth sigue en Testing — ver arriba |
| Crea un cliente OAuth de aplicación de escritorio en su lugar |
| Cuenta de Google incorrecta, o sin permiso en esa propiedad |
| Habilítala en el proyecto que emitió tu cliente OAuth, luego espera un minuto |
GA4 devuelve un 400 | Un par dimensión/métrica incompatible: no todas las dimensiones de GA4 funcionan con todas las métricas |
El servidor nunca aparece en el cliente | Ejecuta |
Cada informe de problema debe incluir seo-mcp doctor --json. No contiene credenciales: solo rutas, versiones, qué comprobaciones pasaron y qué APIs respondieron.
Desarrollo
uv sync --extra dev
uv run pytest -q # 147 tests · no credentials · no network
uv run python scripts/smoke.py # drives the server over real stdio JSON-RPC
uv run ruff check src testspython3 -m venv .venv && ./.venv/bin/pip install -e ".[dev]"
./.venv/bin/python -m pytest -q
./.venv/bin/python scripts/smoke.py ./.venv/bin/seo-mcpscripts/smoke.py inicia el servidor como subproceso, completa el protocolo de enlace MCP, lista las herramientas y llama a varias, usando un directorio de perfil desechable, por lo que tu token real no se toca. Es la forma más rápida de confirmar que el lado del protocolo funciona antes de que exista cualquier credencial de Google.
Para probarlo manualmente, el Inspector MCP no necesita nada más que Node:
npx @modelcontextprotocol/inspector ./.venv/bin/seo-mcp # web UI
npx @modelcontextprotocol/inspector --cli ./.venv/bin/seo-mcp \
--method tools/call --tool-name auth_status # scriptableNo cubierto por pruebas automatizadas: el flujo OAuth en sí y el envío en vivo de IndexNow. Ambos necesitan un humano y un dominio real, y simularlos solo probaría la simulación. Pertenecen a una breve lista de verificación de lanzamiento manual.
Dos cosas que no hará
[!NOTE] IndexNow no llega a Google. Los participantes son Bing, Yandex, Naver, Seznam.cz, Yep y Amazon: un solo endpoint propaga a todos ellos. Google no participa, y la propia API de Indexación de Google solo acepta páginas que contengan datos estructurados
JobPostingoBroadcastEvent. Si instalas esto esperando una indexación más rápida de Google, te decepcionarás.
[!NOTE] Las filas de consulta nunca suman los totales. Google anonimiza las consultas raras, por lo que cualquier desglose por la dimensión
querysubestima. Cada respuesta que lleva esa dimensión repite la advertencia, porque un modelo al que se le dan esas filas calculará de otro modo porcentajes incorrectos con confianza.
Contribuir
Se aceptan problemas y solicitudes de extracción. La suite de pruebas sin credenciales se ejecuta en cada push en Linux, macOS y Windows en Python 3.10 y 3.13: si pasa localmente, pasará en CI.
Renombrar una herramienta o cambiar un argumento rompe cada prompt guardado que tiene un usuario. Esos cambios van en CHANGELOG.md y son un incremento menor antes de 1.0, uno mayor después.
Licencia
MIT.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- FlicenseAqualityDmaintenanceIntegrates with Google Search Console to enable querying search analytics, comparing performance periods, generating visual reports, and identifying SEO optimization opportunities through natural language.59
- FlicenseNot gradedqualityBmaintenanceEnables querying Google Search Console data via natural language, providing tools for site traffic analysis, page changes, and optimization opportunities.
- AlicenseNot gradedqualityCmaintenanceEnables querying Google Search Console and Google Analytics 4 through natural language, with tools for SEO analysis like anomaly detection, cannibalization detection, and opportunity scoring.231MIT
- FlicenseBqualityCmaintenanceEnables natural language querying of marketing analytics across Google Search Console, GA4, Google Ads, HubSpot, and Bing. Provides tools for search queries, traffic, campaign performance, and composite cross-platform rollups.79
Related MCP Connectors
Turn Search Console data into SEO actions, content, publishing, indexing, and AI insights.
SEO research, audits, backlinks, GSC, and content workflow tools for AI agents.
Ask AI about your ads — query Meta, TikTok, and Google Ads performance in natural language.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/zainsive/seo-analytics-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server