Skip to main content
ai22 de febrero de 202616 min de lectura

Servidores MCP: Haciendo que Google Analytics Sea Realmente Útil para Desarrolladores

Cómo los servidores Model Context Protocol convierten Google Analytics de un dashboard de marketing en una fuente de datos amigable para desarrolladores que puedes consultar conversacionalmente.

mcpanalyticsai
Servidores MCP: Haciendo que Google Analytics Sea Realmente Útil para Desarrolladores

Google Analytics siempre ha sido una herramienta de marketing que los desarrolladores toleran. Configuras el tracking, estableces los eventos y luego se lo pasas a alguien que realmente disfruta haciendo clic en dashboards. Cuando necesitas datos tú mismo — tasas de rebote para una página específica, embudos de conversión para una nueva funcionalidad, usuarios activos en tiempo real segmentados por país — terminas haciendo clic en cinco menús anidados, peleando con el constructor de consultas de GA4 y preguntándote por qué cuesta más esfuerzo hacer una pregunta que responderla.

Model Context Protocol cambia esto por completo. Al envolver la API de reportes de GA4 en un servidor MCP, puedes consultar tus datos de analytics conversacionalmente a través de Claude o cualquier asistente de IA compatible con MCP. Sin dashboards. Sin constructores de consultas. Solo pregunta lo que quieres saber.

Qué Es MCP y Por Qué Importa

Model Context Protocol es un estándar abierto creado por Anthropic que define cómo los asistentes de IA interactúan con fuentes de datos y herramientas externas. Piénsalo como un puerto USB-C para IA — una interfaz universal que permite a cualquier asistente compatible conectarse a cualquier fuente de datos compatible sin código de integración personalizado para cada combinación.

Antes de MCP, conectar un asistente de IA a tus datos de analytics significaba construir un pipeline a medida: exportar datos a CSV, pegarlos en un chat, esperar que la ventana de contexto sea suficientemente grande. O construir una integración de API personalizada, escribir plantillas de prompts, manejar la autenticación tú mismo. Cada nueva fuente de datos requería una nueva integración.

MCP estandariza esto en tres conceptos:

  • Resources — datos estructurados que el servidor expone (tus propiedades GA4, reportes, dimensiones, métricas)
  • Tools — acciones que la IA puede invocar (ejecutar un reporte, consultar datos en tiempo real, listar métricas disponibles)
  • Prompts — plantillas de prompts reutilizables que el servidor proporciona (consultas de analytics comunes pre-estructuradas para buenos resultados)

El servidor maneja la autenticación, la obtención de datos y el formato de respuestas. El asistente de IA maneja la comprensión del lenguaje natural y la interpretación de resultados. Ningún lado necesita conocer los detalles de implementación del otro.

Por Qué Esto Importa Específicamente para Analytics

Las plataformas de analytics son ricas en información pero pobres en interacción. GA4 tiene datos extraordinariamente poderosos — rastrea cada sesión de usuario, cada vista de página, cada evento, cada conversión en todo tu producto. Pero acceder a esos datos requiere que pienses en el vocabulario de GA4: dimensiones, métricas, segmentos, rangos de fechas, filtros, comparaciones. Tienes que traducir tu pregunta al modelo de consulta de GA4 antes de poder obtener una respuesta.

Un servidor MCP invierte esto. Haces tu pregunta en lenguaje natural. La IA la traduce a las llamadas API correctas, las ejecuta e interpreta los resultados. La fricción entre "tengo una pregunta" y "tengo una respuesta" se reduce de minutos a segundos.

Construyendo un Servidor MCP para GA4

La implementación involucra tres capas: el framework del servidor MCP, el cliente de la API de Datos de Google Analytics y la lógica de conexión que mapea la intención en lenguaje natural a llamadas API.

Configuración del Proyecto

mkdir ga4-mcp-server
cd ga4-mcp-server
npm init -y
npm install @modelcontextprotocol/sdk @google-analytics/data zod dotenv
npm install -D typescript @types/node

El paquete @modelcontextprotocol/sdk proporciona el framework del servidor. @google-analytics/data es la librería oficial de Google para la API de Datos de GA4 (la API de reportes, no la API de Admin). zod maneja la validación de entrada para los parámetros de las herramientas.

Autenticación con Google

La autenticación de la API de GA4 usa una cuenta de servicio de Google Cloud. Crea una en la Consola de Google Cloud, descarga el archivo JSON de la clave y otórgale acceso de "Viewer" a tu propiedad GA4.

// src/analytics-client.ts
import { BetaAnalyticsDataClient } from "@google-analytics/data";

const analyticsClient = new BetaAnalyticsDataClient({
  keyFilename: process.env.GOOGLE_APPLICATION_CREDENTIALS,
});

const propertyId = process.env.GA4_PROPERTY_ID;

export async function runReport(
  dimensions: string[],
  metrics: string[],
  startDate: string,
  endDate: string,
  dimensionFilter?: Record<string, string>
) {
  const request: any = {
    property: `properties/${propertyId}`,
    dimensions: dimensions.map((d) => ({ name: d })),
    metrics: metrics.map((m) => ({ name: m })),
    dateRanges: [{ startDate, endDate }],
  };

  if (dimensionFilter) {
    const filterKey = Object.keys(dimensionFilter)[0];
    request.dimensionFilter = {
      filter: {
        fieldName: filterKey,
        stringFilter: {
          value: dimensionFilter[filterKey],
          matchType: "EXACT",
        },
      },
    };
  }

  const [response] = await analyticsClient.runReport(request);
  return formatReportResponse(response);
}

function formatReportResponse(response: any) {
  if (!response.rows || response.rows.length === 0) {
    return { data: [], summary: "No data found for the specified query." };
  }

  const headers = [
    ...(response.dimensionHeaders?.map((h: any) => h.name) ?? []),
    ...(response.metricHeaders?.map((h: any) => h.name) ?? []),
  ];

  const rows = response.rows.map((row: any) => {
    const values = [
      ...(row.dimensionValues?.map((v: any) => v.value) ?? []),
      ...(row.metricValues?.map((v: any) => v.value) ?? []),
    ];
    return Object.fromEntries(headers.map((h, i) => [h, values[i]]));
  });

  return {
    data: rows,
    rowCount: response.rowCount,
    summary: `Returned ${rows.length} rows.`,
  };
}

El Servidor MCP

// src/server.ts
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
import { runReport, getRealtimeData, getAvailableMetrics } from "./analytics-client";

const server = new McpServer({
  name: "ga4-analytics",
  version: "1.0.0",
});

// Tool: Run a custom report
server.tool(
  "run_report",
  "Run a Google Analytics 4 report with specified dimensions, metrics, and date range",
  {
    dimensions: z.array(z.string()).describe("GA4 dimensions like 'pagePath', 'country', 'deviceCategory'"),
    metrics: z.array(z.string()).describe("GA4 metrics like 'activeUsers', 'sessions', 'bounceRate'"),
    startDate: z.string().describe("Start date in YYYY-MM-DD format or relative like '7daysAgo'"),
    endDate: z.string().describe("End date in YYYY-MM-DD format or 'today'"),
    filter: z.record(z.string()).optional().describe("Optional dimension filter as key-value pair"),
  },
  async ({ dimensions, metrics, startDate, endDate, filter }) => {
    const result = await runReport(dimensions, metrics, startDate, endDate, filter);
    return {
      content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
    };
  }
);

// Tool: Get real-time active users
server.tool(
  "realtime_users",
  "Get current real-time active users, optionally segmented by a dimension",
  {
    dimension: z.string().optional().describe("Optional dimension to segment by, like 'country' or 'pagePath'"),
  },
  async ({ dimension }) => {
    const result = await getRealtimeData(dimension);
    return {
      content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
    };
  }
);

// Tool: List available metrics and dimensions
server.tool(
  "list_metrics",
  "List all available GA4 metrics and dimensions for the connected property",
  {},
  async () => {
    const result = await getAvailableMetrics();
    return {
      content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
    };
  }
);

// Resource: Property metadata
server.resource(
  "property-info",
  "ga4://property/info",
  async (uri) => ({
    contents: [{
      uri: uri.href,
      mimeType: "application/json",
      text: JSON.stringify({
        propertyId: process.env.GA4_PROPERTY_ID,
        description: "Connected GA4 property for analytics queries",
      }),
    }],
  })
);

async function main() {
  const transport = new StdioServerTransport();
  await server.connect(transport);
}

main().catch(console.error);

Esto le da al asistente de IA tres herramientas: ejecutar reportes arbitrarios, consultar datos en tiempo real y descubrir qué métricas y dimensiones están disponibles. La herramienta de descubrimiento es importante — permite que la IA descubra los nombres de campo correctos sin que tú tengas que recordar si es activeUsers o active_users o totalUsers.

Endpoint de Datos en Tiempo Real

// Added to analytics-client.ts
export async function getRealtimeData(dimension?: string) {
  const request: any = {
    property: `properties/${propertyId}`,
    metrics: [{ name: "activeUsers" }],
  };

  if (dimension) {
    request.dimensions = [{ name: dimension }];
  }

  const [response] = await analyticsClient.runRealtimeReport(request);
  return formatReportResponse(response);
}

Los datos en tiempo real son una de las funcionalidades de mayor valor. En un dashboard, navegarías a la sección de tiempo real, esperarías a que cargue y leerías los números. A través de MCP, escribes "cuántas personas están en el sitio ahora mismo?" y obtienes una respuesta en dos segundos.

Consultas Reales que los Desarrolladores Quieren Ejecutar

Las capacidades teóricas son aburridas. Aquí están las consultas reales que me encuentro ejecutando diariamente, y cómo se ven como solicitudes conversacionales a la IA:

Análisis de Tráfico

"Cuáles son las 10 páginas principales por cantidad de sesiones esta semana, y cómo se compara cada una con la semana pasada?"

La IA traduce esto en dos llamadas runReport — una para la semana actual, otra para la semana anterior — luego calcula el delta y presenta una tabla comparativa. En la interfaz de GA4, esto requiere configurar un rango de fechas de comparación, seleccionar el reporte correcto, agregar la dimensión de página, ordenar por sesiones y limitar a 10. A través de MCP, es una oración.

"Muéstrame el tráfico de búsqueda orgánica de los últimos 30 días, desglosado por página de aterrizaje."

Esto se convierte en un solo reporte con sessionDefaultChannelGroup como filtro de dimensión (filtrado a "Organic Search"), landingPagePlusQueryString como dimensión y sessions más engagedSessions como métricas.

Depuración de Conversiones

"Cuál es la tasa de rebote en /pricing comparada con /features en las últimas dos semanas?"

Dos llamadas de reporte filtradas, resultados comparados lado a lado. Este es el tipo de pregunta que toma 30 segundos formular conversacionalmente y 3 minutos responder a través de la interfaz de GA4.

"Qué países tienen la mayor tasa de conversión para el evento de registro?"

Un solo reporte con dimensión country, métrica eventCount filtrada al evento sign_up y sessions para calcular la tasa de conversión. La IA puede incluso hacer la división y presentar porcentajes directamente.

Monitoreo de Rendimiento

"Cuál es el tiempo promedio de interacción por sesión en móvil vs escritorio este mes?"

Segmentado por deviceCategory, midiendo averageSessionDuration y engagedSessions. Consulta simple, pero una que requiere navegar al reporte correcto y configurar segmentos en GA4.

"Hay alguna página con más de 1000 vistas esta semana pero una tasa de interacción por debajo del 30%?"

Aquí es donde el analytics conversacional realmente brilla. La IA ejecuta el reporte, filtra los resultados programáticamente y devuelve solo las páginas que coinciden con ambos criterios. En GA4, necesitarías exportar a una hoja de cálculo y filtrar manualmente, o construir una exploración personalizada.

Conectando a Claude y Asistentes de IA

Configuración de Claude Desktop

Una vez que tu servidor MCP está construido, conectarlo a Claude Desktop es una edición de archivo de configuración:

{
  "mcpServers": {
    "ga4-analytics": {
      "command": "node",
      "args": ["/path/to/ga4-mcp-server/dist/server.js"],
      "env": {
        "GOOGLE_APPLICATION_CREDENTIALS": "/path/to/service-account-key.json",
        "GA4_PROPERTY_ID": "123456789"
      }
    }
  }
}

En macOS, esto va en ~/Library/Application Support/Claude/claude_desktop_config.json. En Windows, es %APPDATA%\Claude\claude_desktop_config.json.

Después de reiniciar Claude Desktop, las herramientas de GA4 aparecen en el menú de herramientas. Claude ahora puede llamarlas directamente en la conversación.

Integración con Claude Code

Para desarrolladores que trabajan principalmente en la terminal, Claude Code soporta servidores MCP nativamente. Agrega el servidor al .mcp.json de tu proyecto:

{
  "mcpServers": {
    "ga4-analytics": {
      "command": "node",
      "args": ["./mcp-servers/ga4/dist/server.js"],
      "env": {
        "GOOGLE_APPLICATION_CREDENTIALS": "./credentials/ga4-service-account.json",
        "GA4_PROPERTY_ID": "123456789"
      }
    }
  }
}

Ahora puedes consultar datos de analytics sin salir de tu editor. Mientras depuras una regresión de rendimiento, puedes preguntar "cuál es la tasa de rebote en /checkout esta semana vs la semana pasada?" sin cambiar de contexto a un navegador.

Usando con Otros Clientes Compatibles con MCP

La belleza de MCP como estándar es que cualquier cliente compatible funciona. Cursor, Windsurf y otros editores que soportan MCP pueden conectarse al mismo servidor. Construyes el servidor una vez y funciona en todas partes.

Ejemplos Prácticos de Analytics Conversacional

Déjame recorrer un flujo de trabajo real que uso regularmente.

Revisión Matutina

Empiezo el día preguntándole a Claude: "Dame un resumen del tráfico de ayer — sesiones totales, usuarios activos, las 5 páginas principales y cualquier página con tasa de interacción por debajo del 25%."

La IA hace tres llamadas de herramientas: una para métricas generales, una para páginas principales, una para páginas con baja interacción. Regresa con algo como:

Ayer: 2,341 sesiones de 1,892 usuarios únicos. Las páginas principales fueron /home (580 sesiones), /pricing (412), /docs/getting-started (389), /blog/mcp-guide (267), /features (198). Dos páginas tuvieron interacción por debajo del 25%: /legal/terms (12%) y /blog/old-post-2024 (22%).

Esto tomaría 5-10 minutos en la interfaz de GA4. A través de MCP, toma 15 segundos.

Monitoreo de Lanzamiento de Funcionalidades

Cuando lanzo una nueva funcionalidad, quiero saber si la gente la está encontrando y usando. "Compara el tráfico a /features/new-dashboard de los últimos 3 días vs los 3 días antes del lanzamiento, desglosado por canal de adquisición."

La IA ejecuta la comparación, identifica qué canales están impulsando el descubrimiento (generalmente la búsqueda directa y orgánica van por detrás de redes sociales y referidos en los primeros días después del lanzamiento), y resalta cualquier anomalía.

Depuración de Quejas de Usuarios

Cuando los usuarios reportan que "el sitio se siente lento", puedo preguntar: "Cuál es el tiempo promedio de carga de página por página de los últimos 7 días, ordenado de más lento primero?" Si GA4 tiene datos de Web Vitals (a través del measurement protocol o eventos gtag), el servidor MCP puede mostrar esto sin que yo abra un navegador.

Reportes Semanales

"Genera una comparación semana a semana de sesiones, nuevos usuarios, tasa de interacción y tasa de conversión para cada una de nuestras 20 páginas principales."

Esto produce una tabla formateada que puedo insertar directamente en un mensaje de Slack o una actualización de equipo. Sin gimnasia de hojas de cálculo, sin recortar capturas de pantalla.

Construyendo Funcionalidades Avanzadas

Capa de Caché

La API de GA4 tiene límites de tasa (típicamente 10 solicitudes por minuto por propiedad para el nivel gratuito). Para un servidor MCP que podría ser consultado frecuentemente, agrega una capa de caché:

import { createHash } from "crypto";

const cache = new Map<string, { data: any; expiry: number }>();

function getCacheKey(dimensions: string[], metrics: string[], startDate: string, endDate: string): string {
  const input = JSON.stringify({ dimensions, metrics, startDate, endDate });
  return createHash("md5").update(input).digest("hex");
}

export async function cachedRunReport(
  dimensions: string[],
  metrics: string[],
  startDate: string,
  endDate: string
) {
  const key = getCacheKey(dimensions, metrics, startDate, endDate);
  const cached = cache.get(key);

  if (cached && cached.expiry > Date.now()) {
    return cached.data;
  }

  const result = await runReport(dimensions, metrics, startDate, endDate);

  // Cache for 5 minutes (real-time queries get shorter TTL)
  const ttl = startDate === "today" ? 60_000 : 300_000;
  cache.set(key, { data: result, expiry: Date.now() + ttl });

  return result;
}

Las consultas en tiempo real obtienen un TTL de 1 minuto. Las consultas históricas obtienen 5 minutos. Esto te mantiene bien dentro de los límites de tasa durante una sesión conversacional donde la IA podría hacer varias consultas relacionadas en rápida sucesión.

Soporte Multi-Propiedad

Si administras múltiples productos o clientes, extiende el servidor para soportar cambio entre propiedades GA4:

server.tool(
  "switch_property",
  "Switch to a different GA4 property",
  {
    propertyId: z.string().describe("The GA4 property ID to switch to"),
  },
  async ({ propertyId }) => {
    // Validate access
    const properties = await listAccessibleProperties();
    if (!properties.includes(propertyId)) {
      return {
        content: [{ type: "text", text: `No access to property ${propertyId}` }],
      };
    }

    currentPropertyId = propertyId;
    return {
      content: [{ type: "text", text: `Switched to property ${propertyId}` }],
    };
  }
);

Ahora puedes decir "cambia a la propiedad de staging y muéstrame el tráfico de ayer" sin reconfigurar nada.

Consideraciones de Seguridad

Ejecutar un servidor MCP que accede a datos de analytics introduce varias preocupaciones de seguridad que necesitan manejo deliberado.

Gestión de Credenciales

El archivo de clave de la cuenta de servicio es la pieza más sensible. Nunca lo subas al control de versiones. Usa variables de entorno o un gestor de secretos. Si estás ejecutando el servidor MCP localmente (que es el caso común para Claude Desktop), almacena el archivo de clave fuera del directorio de tu proyecto con permisos de archivo restringidos:

chmod 600 /path/to/service-account-key.json

Para entornos de equipo, considera usar Workload Identity Federation de Google Cloud en lugar de un archivo de clave. Elimina la credencial estática por completo usando tokens de corta duración vinculados a la identidad del runtime.

Principio de Menor Privilegio

La cuenta de servicio debería tener acceso de solo lectura a GA4. Específicamente, otorga el rol "Viewer" a nivel de propiedad GA4 — no el rol "Editor" o "Administrator". El servidor MCP nunca necesita modificar tu configuración de analytics, crear audiencias o cambiar configuraciones de medición.

A nivel de proyecto de Google Cloud, otorga solo el scope analyticsdata.readonly. Esto previene que la cuenta de servicio acceda a cualquier otro servicio de Google Cloud incluso si la clave es comprometida.

Alcance de Exposición de Datos

Sé deliberado sobre qué datos puede acceder el servidor MCP. GA4 puede contener PII — IDs de usuario, IDs de cliente, geolocalización derivada de IP. Tu servidor MCP debería eliminar o enmascarar campos que no son necesarios para las consultas que quieres soportar.

const BLOCKED_DIMENSIONS = ["userID", "clientId"];

function validateDimensions(dimensions: string[]) {
  const blocked = dimensions.filter((d) => BLOCKED_DIMENSIONS.includes(d));
  if (blocked.length > 0) {
    throw new Error(`Blocked dimensions for privacy: ${blocked.join(", ")}`);
  }
}

Esto es especialmente importante si otros miembros del equipo pueden interactuar con el servidor MCP. Quieres prevenir consultas casuales que podrían exponer datos individuales de usuarios.

Seguridad de Transporte

MCP actualmente se ejecuta sobre stdio (entrada/salida estándar) cuando se usa con Claude Desktop, lo que significa que la comunicación ocurre dentro de los límites del proceso local. No hay exposición de red. Sin embargo, si despliegas un servidor MCP sobre HTTP (usando el transporte SSE), necesitas TLS, tokens de autenticación y rate limiting — trátalo como cualquier otro endpoint de API.

Registro de Auditoría

Registra cada consulta que el servidor MCP procesa. No solo por seguridad — por responsabilidad. Cuando alguien pregunte "quién consultó nuestros datos de analytics y cuándo," deberías tener una respuesta.

function logQuery(tool: string, params: Record<string, unknown>) {
  console.log(JSON.stringify({
    timestamp: new Date().toISOString(),
    tool,
    params,
    propertyId: currentPropertyId,
  }));
}

Compensaciones y Limitaciones

Lo Que Funciona Bien

El analytics conversacional elimina la curva de aprendizaje de GA4 para desarrolladores. No necesitas conocer los nombres de dimensiones y métricas de GA4, los tipos de reportes o la sintaxis de filtros. La IA maneja la traducción. Para preguntas ad-hoc — del tipo que haces una vez y nunca repites — esto es dramáticamente más rápido que el dashboard.

Combinar analytics con contexto de desarrollo es poderoso. Cuando estás depurando en Claude Code y puedes simultáneamente consultar datos de analytics, el ciclo de retroalimentación se estrecha. Ves el código, los logs de errores y el impacto en usuarios en un solo lugar.

Lo Que No Funciona Bien

Las exploraciones complejas que requieren refinamiento iterativo siguen siendo más rápidas en la interfaz Explore de GA4. Si estás construyendo un análisis de embudo con múltiples etapas, segmentos personalizados y grupos de comparación, el constructor visual te da retroalimentación inmediata que una interfaz conversacional no puede igualar.

Los dashboards en tiempo real que se auto-refrescan están fuera del modelo actual de MCP. MCP es solicitud-respuesta — preguntas, responde. Para un dashboard que se actualiza en vivo mostrando usuarios en tiempo real, una herramienta dedicada como la vista en tiempo real de GA4 o un panel personalizado de Grafana es mejor.

El volumen de datos es una restricción. La API de Datos de GA4 devuelve hasta 100,000 filas por solicitud. Para propiedades con millones de eventos diarios, puede que necesites ser específico sobre dimensiones y rangos de fechas para evitar alcanzar este límite. La API también tiene comportamiento de muestreo para conjuntos de datos grandes — los resultados pueden ser estimaciones en lugar de exactos para consultas de alta cardinalidad.

MCP vs. Integración Directa con la API

Si estás construyendo una funcionalidad de producto que necesita datos de analytics (como un dashboard de administración para tu SaaS), usa la API de GA4 directamente. MCP es para consultas con humano en el ciclo, no para pipelines de datos programáticos. La sobrecarga de traducción de lenguaje natural e interpretación de IA es innecesaria cuando sabes exactamente qué consulta ejecutar.

MCP brilla cuando la pregunta no está estructurada, cuando no sabes exactamente qué estás buscando, o cuando el esfuerzo de construir una integración adecuada no se justifica para una pregunta puntual. Es el equivalente en analytics de abrir un REPL en lugar de escribir un script.

Para Empezar

Si quieres probar esto tú mismo, el camino mínimo es:

  1. Crear un proyecto de Google Cloud y habilitar la API de Datos de Google Analytics.
  2. Crear una cuenta de servicio con acceso Viewer a tu propiedad GA4.
  3. Descargar el JSON de la clave de cuenta de servicio.
  4. Clonar o construir el servidor MCP como se describió arriba.
  5. Agregar el servidor a tu configuración de Claude Desktop o Claude Code.
  6. Empezar a hacer preguntas.

Toda la configuración toma alrededor de 30 minutos si ya tienes una propiedad GA4. El retorno es inmediato — la primera vez que obtienes una respuesta a una pregunta de analytics en 5 segundos en lugar de 5 minutos, no querrás volver al dashboard.

Los datos de analytics son uno de los activos más subutilizados en la mayoría de los equipos de desarrollo. No porque no sean valiosos, sino porque acceder a ellos siempre ha sido lo suficientemente inconveniente como para desalentar la consulta casual. MCP elimina esa fricción. Los datos son los mismos. Las preguntas son las mismas. El tiempo para responder es lo que cambia.

DU

Danil Ulmashev

Full Stack Developer

Interesado en trabajar juntos?