Skip to main content
Glama
Shin-sibainu

GA4 MCP Server

by Shin-sibainu

run_realtime_report

Execute real-time reports to retrieve current active user counts and other immediate metrics from Google Analytics 4 properties for instant performance monitoring.

Instructions

リアルタイムレポートを実行し、現在のアクティブユーザー数などを取得します。

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
propertyIdNoGA4プロパティID(省略時は環境変数を使用)
dimensionsNoディメンション(デフォルト: ["country", "deviceCategory"])
metricsNoメトリクス(デフォルト: ["activeUsers"])

Implementation Reference

  • The main handler function that implements the run_realtime_report tool logic. It executes a GA4 realtime report using the provided dimensions and metrics, processes the response into rows and totals.
    export async function runRealtimeReport(
      input: RunRealtimeReportInput
    ): Promise<RealtimeReportOutput> {
      const propertyId = getPropertyId(input.propertyId);
      const property = formatPropertyPath(propertyId);
    
      // デフォルト値の設定
      const dimensions = input.dimensions || ["country", "deviceCategory"];
      const metrics = input.metrics || ["activeUsers"];
    
      // レポート実行
      const response = await executeRealtimeReport({
        property,
        dimensions: dimensions.map((name) => ({ name })),
        metrics: metrics.map((name) => ({ name })),
      });
    
      // 結果を整形
      const rows: ReportRow[] = [];
      const dimensionHeaders = response.dimensionHeaders || [];
      const metricHeaders = response.metricHeaders || [];
    
      for (const row of response.rows || []) {
        const dimensionValues: Record<string, string> = {};
        const metricValues: Record<string, number | string> = {};
    
        // ディメンション値を取得
        (row.dimensionValues || []).forEach((value, index) => {
          const header = dimensionHeaders[index];
          if (header?.name) {
            dimensionValues[header.name] = value.value || "";
          }
        });
    
        // メトリクス値を取得
        (row.metricValues || []).forEach((value, index) => {
          const header = metricHeaders[index];
          if (header?.name) {
            const rawValue = value.value || "0";
            const numValue = parseFloat(rawValue);
            metricValues[header.name] = isNaN(numValue) ? rawValue : numValue;
          }
        });
    
        rows.push({ dimensions: dimensionValues, metrics: metricValues });
      }
    
      // 合計値の取得
      let totals: Record<string, number | string> | undefined;
      if (response.totals && response.totals.length > 0) {
        totals = {};
        const totalRow = response.totals[0];
        (totalRow.metricValues || []).forEach((value, index) => {
          const header = metricHeaders[index];
          if (header?.name) {
            const rawValue = value.value || "0";
            const numValue = parseFloat(rawValue);
            totals![header.name] = isNaN(numValue) ? rawValue : numValue;
          }
        });
      }
    
      return {
        rows,
        rowCount: rows.length,
        totals,
      };
    }
  • src/server.ts:162-187 (registration)
    Tool registration in the tools array, defining the name, description, and input schema for listTools response.
    {
      name: "run_realtime_report",
      description:
        "リアルタイムレポートを実行し、現在のアクティブユーザー数などを取得します。",
      inputSchema: {
        type: "object" as const,
        properties: {
          propertyId: {
            type: "string",
            description: "GA4プロパティID(省略時は環境変数を使用)",
          },
          dimensions: {
            type: "array",
            items: { type: "string" },
            description:
              'ディメンション(デフォルト: ["country", "deviceCategory"])',
          },
          metrics: {
            type: "array",
            items: { type: "string" },
            description: 'メトリクス(デフォルト: ["activeUsers"])',
          },
        },
        required: [],
      },
    },
  • src/server.ts:607-612 (registration)
    Tool dispatcher in handleToolCall switch statement that calls the runRealtimeReport handler with parsed arguments.
    case "run_realtime_report":
      return await runRealtimeReport({
        propertyId: args.propertyId as string | undefined,
        dimensions: args.dimensions as string[] | undefined,
        metrics: args.metrics as string[] | undefined,
      });
  • TypeScript interfaces defining the input (RunRealtimeReportInput) and output (RealtimeReportOutput) types for the tool.
    // run_realtime_report
    export interface RunRealtimeReportInput extends PropertyId {
      dimensions?: string[];
      metrics?: string[];
    }
    
    export interface RealtimeReportOutput {
      rows: ReportRow[];
      rowCount: number;
      totals?: Record<string, number | string>;
    }
  • Re-export of the runRealtimeReport function for convenient import in server.ts.
    export { runRealtimeReport } from "./runRealtimeReport.js";
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It mentions the tool executes reports and retrieves data like active user counts, but doesn't disclose important behavioral traits such as authentication requirements, rate limits, data freshness, or whether this is a read-only operation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, efficient sentence in Japanese that conveys the core purpose. It's appropriately sized and front-loaded with the main action, though it could be slightly more structured for clarity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the complexity of a real-time reporting tool with no annotations and no output schema, the description is insufficient. It doesn't explain what data is returned, the format of results, error conditions, or performance characteristics that would help an agent use it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all three parameters thoroughly. The description doesn't add any additional semantic context about the parameters beyond what's in the schema descriptions, maintaining the baseline score.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: 'execute real-time reports' and 'get current active user count etc.' It specifies the verb (execute/get) and resource (real-time reports), though it doesn't explicitly distinguish it from sibling tools like 'run_report' or 'get_daily_trend'.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives. It doesn't mention when real-time reporting is appropriate compared to historical reports, nor does it reference any sibling tools for different use cases.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

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

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