npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

mcp-ga4-analytics

v1.0.2

Published

Google Analytics Node.js library for easy integration with Google Analytics 4 API

Readme

Google Analytics 4 Node.js Library

A simple and powerful Node.js library for Google Analytics 4 API integration. Works just like nodemailer - easy configuration with maximum functionality.

Features

  • 🔐 Multiple Authentication Methods: Service Account, OAuth2, and Auto-detection
  • 📊 Complete GA4 API Coverage: Real-time data, historical reports, audience insights, conversions
  • 🚀 Simple Setup: Configure once, use everywhere - just like nodemailer
  • 📈 Pre-built Report Functions: Traffic sources, page performance, audience demographics, conversions
  • 🛠️ Full TypeScript Support: Complete type safety and IntelliSense
  • Modern Promise-based API: Clean async/await syntax
  • 🎯 Flexible Custom Reports: Build any report with GA4 metrics and dimensions
  • 📱 Real-time Analytics: Live user data and active sessions

Installation

npm install mcp-ga4-analytics

Quick Start

1. Service Account (Recommended for Production)

const GoogleAnalytics = require('mcp-ga4-analytics');

const analytics = new GoogleAnalytics({
  serviceAccount: {
    keyFilePath: './service-account-key.json'
  }
});

await analytics.initialize();

// Get all properties
const properties = await analytics.listProperties();
console.log('Properties:', properties);

// Get real-time data
const realtimeData = await analytics.getRealtimeReport({
  propertyId: 'your-property-id',
  metrics: ['activeUsers'],
  dimensions: ['country'],
  limit: 10
});

console.log('Active users by country:', realtimeData);

2. OAuth2 (For Client Applications)

const analytics = new GoogleAnalytics({
  oauth: {
    clientId: 'your-client-id',
    clientSecret: 'your-client-secret'
  },
  credentialsPath: './credentials.json'
});

// First time: Get auth URL
const authUrl = await analytics.authenticate();
console.log('Visit:', authUrl);

// After user authorization, set the code
await analytics.setTokens('authorization-code-from-callback');

// Now initialize and use
await analytics.initialize();
const properties = await analytics.listProperties();

3. Auto-detection (Automatic Authentication)

const analytics = new GoogleAnalytics({
  keyFilePath: './gcp-keys.json', // Can be service account or OAuth2 keys
  credentialsPath: './credentials.json' // Only for OAuth2
});

await analytics.initialize();
// Ready to use!

Authentication Setup

Option 1: Service Account (Production Apps)

  1. Go to Google Cloud Console
  2. Create or select a project
  3. Enable Google Analytics Reporting API v1 and Google Analytics Admin API v1
  4. Create Service Account:
    • Navigate to "IAM & Admin" > "Service Accounts"
    • Click "Create Service Account"
    • Download the JSON key file
  5. In Google Analytics, add the service account email as a Viewer to your GA4 property

Option 2: OAuth2 (Client Apps)

  1. Go to Google Cloud Console
  2. Create or select a project
  3. Enable Google Analytics Reporting API v1 and Google Analytics Admin API v1
  4. Create OAuth2 credentials:
    • Go to "APIs & Services" > "Credentials"
    • Create "OAuth client ID"
    • Choose "Web application" or "Desktop application"
    • Add authorized redirect URIs (e.g., http://localhost:3000/callback)
    • Download the credentials JSON file

Core API Methods

Basic Usage

import GoogleAnalytics from 'mcp-ga4-analytics';

const analytics = new GoogleAnalytics({
  keyFilePath: './gcp-keys.json'
});

await analytics.initialize();

// List all available properties
const properties = await analytics.listProperties();
console.log('Properties:', properties);

// Use the first property for reports
const propertyId = properties[0].property;

Real-time Analytics

// Get current active users by location and device
const realtime = await analytics.getRealtimeReport({
  propertyId,
  metrics: ['activeUsers', 'screenPageViews'],
  dimensions: ['country', 'deviceCategory'],
  limit: 10
});

// Display active users right now
if (realtime.rows) {
  realtime.rows.forEach(row => {
    const country = row.dimensionValues[0]?.value;
    const device = row.dimensionValues[1]?.value;
    const users = row.metricValues[0]?.value;
    console.log(`${country} (${device}): ${users} active users`);
  });
}

Pre-built Report Functions

// Traffic sources for last 30 days
const traffic = await analytics.getTrafficSourcesReport(
  propertyId,
  '30daysAgo',
  'today'
);

// Top pages performance
const pages = await analytics.getPageReport(
  propertyId,
  '7daysAgo',
  'today'
);

// Audience demographics and behavior
const audience = await analytics.getAudienceReport(
  propertyId,
  '30daysAgo',
  'today'
);

// Conversion events and revenue
const conversions = await analytics.getConversionReport(
  propertyId,
  '30daysAgo',
  'today'
);

Custom Reports

// Build any custom report with GA4 metrics and dimensions
const customReport = await analytics.getReport({
  propertyId,
  startDate: '2024-01-01',
  endDate: '2024-01-31',
  metrics: ['sessions', 'users', 'screenPageViews', 'bounceRate'],
  dimensions: ['source', 'medium', 'campaign'],
  orderBy: [{ metric: 'sessions', desc: true }],
  limit: 50
});

// Process the results
if (customReport.rows) {
  customReport.rows.forEach((row, index) => {
    const source = row.dimensionValues[0]?.value;
    const sessions = row.metricValues[0]?.value;
    const users = row.metricValues[1]?.value;
    console.log(`${index + 1}. ${source}: ${sessions} sessions, ${users} users`);
  });
}

Property Management

// List all properties you have access to
const properties = await analytics.listProperties();
properties.forEach(prop => {
  console.log(`${prop.displayName} (${prop.property})`);
  console.log(`  Currency: ${prop.currencyCode}`);
  console.log(`  Timezone: ${prop.timeZone}`);
});

// Get available metrics and dimensions for a property
const metadata = await analytics.getMetadata(propertyId);
console.log(`Available: ${metadata.metrics?.length} metrics, ${metadata.dimensions?.length} dimensions`);

TypeScript Support

import GoogleAnalytics, { 
  AnalyticsConfig, 
  ReportRequest, 
  PropertyInfo,
  AnalyticsReport 
} from 'mcp-ga4-analytics';

const config: AnalyticsConfig = {
  keyFilePath: './gcp-keys.json'
};

const analytics = new GoogleAnalytics(config);

// Type-safe API calls
const properties: PropertyInfo[] = await analytics.listProperties();
const report: AnalyticsReport = await analytics.getReport({
  propertyId: properties[0].property,
  metrics: ['sessions'],
  dimensions: ['source']
});

Complete Configuration Options

const analytics = new GoogleAnalytics({
  // Method 1: Service Account (Production)
  serviceAccount: {
    keyFilePath: './service-account-key.json'
  },

  // Method 2: OAuth2 (Client Apps)
  oauth: {
    clientId: 'your-google-client-id',
    clientSecret: 'your-google-client-secret',
    redirectUri: 'http://localhost:3000/callback' // Optional
  },
  credentialsPath: './oauth-credentials.json', // Where to store tokens

  // Method 3: Auto-detect from key file (Easiest)
  keyFilePath: './gcp-keys.json', // Service account or OAuth2 keys
  credentialsPath: './credentials.json' // Only needed for OAuth2
});

Available GA4 Metrics & Dimensions

Core Metrics

  • User Metrics: activeUsers, totalUsers, newUsers
  • Session Metrics: sessions, engagedSessions, averageSessionDuration, bounceRate
  • Page Metrics: screenPageViews, screenPageViewsPerSession
  • Event Metrics: eventCount, conversions
  • Revenue Metrics: totalRevenue, purchaseRevenue
  • Engagement: engagementRate, userEngagementDuration

Core Dimensions

  • Time: date, year, month, week, day, hour
  • Geography: country, city, continent, region
  • Technology: deviceCategory, operatingSystem, browser
  • Traffic: source, medium, campaign, channelGroup
  • Content: pagePath, pageTitle, screenName
  • Events: eventName
  • User: userAgeBracket, userGender

Error Handling & Best Practices

try {
  await analytics.initialize();
  const properties = await analytics.listProperties();
  
  if (properties.length === 0) {
    console.log('No GA4 properties found. Check authentication and permissions.');
    return;
  }
  
  const propertyId = properties[0].property;
  const report = await analytics.getReport({
    propertyId,
    metrics: ['sessions', 'users'],
    dimensions: ['source', 'medium'],
    startDate: '7daysAgo',
    endDate: 'today',
    limit: 20
  });
  
  console.log(`Found ${report.rowCount} results`);
  
} catch (error) {
  if (error.message.includes('authentication')) {
    console.error('❌ Authentication failed. Check your key files and permissions.');
  } else if (error.message.includes('property')) {
    console.error('❌ Property access denied. Ensure the service account has Viewer permissions.');
  } else if (error.message.includes('ENOENT')) {
    console.error('❌ Key file not found. Check your file paths.');
  } else {
    console.error('❌ GA4 API error:', error.message);
  }
}

Advanced Features

Date Range Options

// Use predefined shortcuts
const report = await analytics.getReport({
  propertyId,
  startDate: '30daysAgo',    // Supported: 'today', 'yesterday', '7daysAgo', '30daysAgo'
  endDate: 'today',
  metrics: ['sessions', 'users']
});

// Or use specific dates (YYYY-MM-DD format)
const customDateReport = await analytics.getReport({
  propertyId,
  startDate: '2024-01-01',
  endDate: '2024-01-31',
  metrics: ['sessions', 'users', 'conversions']
});

Advanced Report Building

// Complex report with multiple metrics, dimensions, and sorting
const advancedReport = await analytics.getReport({
  propertyId,
  startDate: '30daysAgo',
  endDate: 'today',
  metrics: [
    'sessions',
    'users', 
    'newUsers',
    'screenPageViews',
    'averageSessionDuration',
    'bounceRate',
    'conversions',
    'totalRevenue'
  ],
  dimensions: [
    'source',
    'medium', 
    'campaign',
    'country',
    'deviceCategory'
  ],
  orderBy: [
    { metric: 'sessions', desc: true },
    { dimension: 'source', desc: false }
  ],
  limit: 100
});

// Process results with type safety
if (advancedReport.rows) {
  advancedReport.rows.forEach(row => {
    const [source, medium, campaign, country, device] = row.dimensionValues.map(d => d.value);
    const [sessions, users, newUsers, pageViews, duration, bounce, conversions, revenue] = row.metricValues.map(m => m.value);
    
    console.log({
      source, medium, campaign, country, device,
      sessions, users, newUsers, pageViews, duration, bounce, conversions, revenue
    });
  });
}

Multi-Property Analytics

// Analyze multiple GA4 properties at once
const properties = await analytics.listProperties();

for (const property of properties) {
  console.log(`\n📊 Analyzing: ${property.displayName}`);
  
  // Get real-time users
  const realtime = await analytics.getRealtimeReport({
    propertyId: property.property,
    metrics: ['activeUsers'],
    limit: 1
  });
  
  // Get traffic summary
  const traffic = await analytics.getTrafficSourcesReport(
    property.property,
    '7daysAgo',
    'today'
  );
  
  const activeUsers = realtime.totals?.[0]?.metricValues?.[0]?.value || '0';
  const topSource = traffic.rows?.[0]?.dimensionValues?.[0]?.value || 'N/A';
  
  console.log(`  🔴 Active users: ${activeUsers}`);
  console.log(`  🚀 Top source: ${topSource}`);
}

OAuth2 Authentication Flow

// Step 1: Get authorization URL
const analytics = new GoogleAnalytics({
  oauth: {
    clientId: 'your-client-id',
    clientSecret: 'your-client-secret'
  },
  credentialsPath: './credentials.json'
});

const authUrl = await analytics.getAuthUrl();
console.log('Visit this URL:', authUrl);

// Step 2: After user grants permission, exchange code for tokens
const authCode = 'code-from-callback-url';
await analytics.setTokens(authCode);

// Step 3: Initialize and use
await analytics.initialize();
const properties = await analytics.listProperties();

Testing Your Setup

# Run the example file
node example.js

# Test specific authentication methods
npm test -- --service-account    # Test service account
npm test -- --oauth             # Test OAuth2
npm test -- --key-file          # Test auto-detection
npm test -- --comprehensive     # Full test suite

Real-world Usage Examples

// Dashboard metrics for your app
async function getDashboardMetrics(propertyId) {
  const analytics = new GoogleAnalytics({ /* your config */ });
  await analytics.initialize();
  
  const [realtime, traffic, pages, audience] = await Promise.all([
    analytics.getRealtimeReport({ propertyId, metrics: ['activeUsers'] }),
    analytics.getTrafficSourcesReport(propertyId, '30daysAgo', 'today'),
    analytics.getPageReport(propertyId, '30daysAgo', 'today'),
    analytics.getAudienceReport(propertyId, '30daysAgo', 'today')
  ]);
  
  return {
    activeUsers: realtime.totals?.[0]?.metricValues?.[0]?.value || '0',
    topTrafficSource: traffic.rows?.[0]?.dimensionValues?.[0]?.value || 'Direct',
    topPage: pages.rows?.[0]?.dimensionValues?.[0]?.value || '/',
    totalSessions: audience.totals?.[0]?.metricValues?.[2]?.value || '0'
  };
}

// Automated reporting
async function generateWeeklyReport(propertyId) {
  const analytics = new GoogleAnalytics({ /* your config */ });
  await analytics.initialize();
  
  const weeklyData = await analytics.getReport({
    propertyId,
    startDate: '7daysAgo',
    endDate: 'yesterday',
    metrics: ['sessions', 'users', 'newUsers', 'screenPageViews', 'conversions'],
    dimensions: ['date'],
    orderBy: [{ dimension: 'date', desc: false }]
  });
  
  return weeklyData.rows?.map(row => ({
    date: row.dimensionValues[0]?.value,
    sessions: row.metricValues[0]?.value,
    users: row.metricValues[1]?.value,
    newUsers: row.metricValues[2]?.value,
    pageViews: row.metricValues[3]?.value,
    conversions: row.metricValues[4]?.value
  }));
}

License

MIT License - see LICENSE file for details.


Made in India with ❤️ by brain.webnexs.com