Skip to main content
Glama
wonyoungseong

GA4 MCP Server

ga4_run_realtime_report

Retrieve real-time Google Analytics data from the last 30 minutes for immediate insights into user activity and website performance.

Instructions

Runs a Google Analytics Data API realtime report. Returns real-time analytics data for the last 30 minutes.

Hints for arguments

Hints for dimensions

Use realtime dimensions from https://developers.google.com/analytics/devguides/reporting/data/v1/realtime-api-schema#dimensions Or user-scoped custom dimensions (apiName starting with "customUser:")

Hints for metrics

Use realtime metrics from https://developers.google.com/analytics/devguides/reporting/data/v1/realtime-api-schema#metrics Note: Realtime reports cannot use custom metrics.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
propertyIdYesThe Google Analytics property ID
dimensionsYesList of realtime dimension names (e.g., 'country', 'city', 'deviceCategory')
metricsYesList of realtime metric names (e.g., 'activeUsers', 'screenPageViews')
dimensionFilterNoFilter expression for dimensions
metricFilterNoFilter expression for metrics
orderBysNoList of order by specifications
limitNoMaximum number of rows to return
returnPropertyQuotaNoWhether to return realtime property quota information

Implementation Reference

  • The main handler function runRealtimeReport that executes the Google Analytics Data API realtime report request. It constructs the request body with dimensions, metrics, and optional filters, then calls client.properties.runRealtimeReport() and returns the response.
    export async function runRealtimeReport(params: RunRealtimeReportParams): Promise<ToolResponse> { try { const client = await getAnalyticsDataClient(); const propertyName = constructPropertyResourceName(params.propertyId); // Build the request body const requestBody: Record<string, unknown> = { property: propertyName, dimensions: params.dimensions.map(name => ({ name })), metrics: params.metrics.map(name => ({ name })), }; if (params.dimensionFilter) { requestBody.dimensionFilter = params.dimensionFilter; } if (params.metricFilter) { requestBody.metricFilter = params.metricFilter; } if (params.orderBys && params.orderBys.length > 0) { requestBody.orderBys = params.orderBys; } if (params.limit !== undefined) { requestBody.limit = params.limit; } if (params.returnPropertyQuota !== undefined) { requestBody.returnPropertyQuota = params.returnPropertyQuota; } const response = await client.properties.runRealtimeReport({ property: propertyName, requestBody: requestBody, }); return createSuccessResponse(response.data); } catch (error) { return createErrorResponse(`Failed to run realtime report for ${params.propertyId}`, error); } }
  • Tool schema definition for ga4_run_realtime_report including the name, description with hints for realtime dimensions and metrics, and inputSchema with propertyId, dimensions, metrics, dimensionFilter, metricFilter, orderBys, limit, and returnPropertyQuota properties.
    name: "ga4_run_realtime_report", description: `Runs a Google Analytics Data API realtime report. Returns real-time analytics data for the last 30 minutes. ## Hints for arguments ### Hints for dimensions Use realtime dimensions from https://developers.google.com/analytics/devguides/reporting/data/v1/realtime-api-schema#dimensions Or user-scoped custom dimensions (apiName starting with "customUser:") ### Hints for metrics Use realtime metrics from https://developers.google.com/analytics/devguides/reporting/data/v1/realtime-api-schema#metrics Note: Realtime reports cannot use custom metrics.`, inputSchema: { type: "object" as const, properties: { propertyId: { type: "string", description: "The Google Analytics property ID", }, dimensions: { type: "array", items: { type: "string" }, description: "List of realtime dimension names (e.g., 'country', 'city', 'deviceCategory')", }, metrics: { type: "array", items: { type: "string" }, description: "List of realtime metric names (e.g., 'activeUsers', 'screenPageViews')", }, dimensionFilter: { type: "object", description: "Filter expression for dimensions", }, metricFilter: { type: "object", description: "Filter expression for metrics", }, orderBys: { type: "array", items: { type: "object" }, description: "List of order by specifications", }, limit: { type: "number", description: "Maximum number of rows to return", }, returnPropertyQuota: { type: "boolean", description: "Whether to return realtime property quota information", }, }, required: ["propertyId", "dimensions", "metrics"], }, },
  • Tool call routing that handles the ga4_run_realtime_report case by extracting arguments from the args object and calling the runRealtimeReport handler function.
    case "ga4_run_realtime_report": return await runRealtimeReport({ propertyId: args.propertyId as string, dimensions: args.dimensions as string[], metrics: args.metrics as string[], dimensionFilter: args.dimensionFilter as Record<string, unknown> | undefined, metricFilter: args.metricFilter as Record<string, unknown> | undefined, orderBys: args.orderBys as Array<Record<string, unknown>> | undefined, limit: args.limit as number | undefined, returnPropertyQuota: args.returnPropertyQuota as boolean | undefined, });
  • TypeScript interface defining the RunRealtimeReportParams type with all the parameters required for the realtime report handler.
    interface RunRealtimeReportParams { propertyId: string; dimensions: string[]; metrics: string[]; dimensionFilter?: FilterExpression; metricFilter?: FilterExpression; orderBys?: OrderBy[]; limit?: number; returnPropertyQuota?: boolean; }
  • Helper function constructPropertyResourceName used by runRealtimeReport to format property IDs into the required 'properties/ID' format for GA4 API calls.
    export function constructPropertyResourceName(propertyId: string | number): string { let propertyNum: number | null = null; if (typeof propertyId === "number") { propertyNum = propertyId; } else if (typeof propertyId === "string") { const trimmed = propertyId.trim(); if (/^\d+$/.test(trimmed)) { propertyNum = parseInt(trimmed, 10); } else if (trimmed.startsWith("properties/")) { const numericPart = trimmed.split("/")[1]; if (numericPart && /^\d+$/.test(numericPart)) { propertyNum = parseInt(numericPart, 10); } } } if (propertyNum === null) { throw new Error( `Invalid property ID: ${propertyId}. ` + "A valid property value is either a number or a string starting " + "with 'properties/' and followed by a number." ); } return `properties/${propertyNum}`; }

Latest Blog Posts

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/wonyoungseong/ga4-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server