Skip to main content
Glama
ZLeventer

Google Analytics MCP Server

README.md
# Google Analytics MCP

Local MCP server for Google Analytics 4. Wraps the GA4 Data API behind tools focused on **SEO and Paid** reporting.

## Tools

| Tool | Purpose |
|---|---|
| `ga4_organic_search_performance` | SEO: Organic Search sessions/users/engagement/conversions by landing page, source, country, or device |
| `ga4_paid_search_performance` | Paid: Paid Search sessions/conversions/cost/CPC by campaign, landing page, keyword, or source |
| `ga4_all_paid_performance` | Paid: all paid channels (Search + Social + Video + Display) with cost and ROAS |
| `ga4_google_ads_performance` | Paid: Google Ads campaign × ad group × keyword (requires GA4 ↔ Google Ads link) |
| `ga4_landing_page_performance` | Top landing pages by sessions/engagement/conversions (optional channel filter) |
| `ga4_channel_performance` | Default channel group rollup |
| `ga4_campaign_performance` | Campaign × source × medium breakdown |
| `ga4_conversions_by_source` | Conversions and key events by source/medium/channel |
| `ga4_realtime_active_users` | Active users in last 30 min |
| `ga4_run_report` | Flexible escape hatch — any dimensions + metrics |

## Setup

```bash
git clone https://github.com/ZLeventer/google-analytics-mcp-server.git
cd google-analytics-mcp-server
npm install
npm run build
```

## Credentials

Copy `.env.example` to `.env` and fill in:

- `GA4_PROPERTY_ID` — numeric property ID from GA4 Admin → Property Settings (e.g. `123456789`). **Not** the Measurement ID (`G-XXXXXXX`).
- `GOOGLE_APPLICATION_CREDENTIALS` — absolute path to the service account JSON key file.

### Create the service account

1. Go to [console.cloud.google.com](https://console.cloud.google.com) → pick/create a project
2. **APIs & Services → Library** → enable **Google Analytics Data API**
3. **IAM & Admin → Service Accounts** → **Create service account** (name it `ga4-mcp` or similar)
4. On the created account → **Keys** → **Add key** → **Create new key** → **JSON** → download
5. Save the JSON as `service-account.json` in this directory (already in `.gitignore`)
6. In **GA4 → Admin → Property Access Management**, click **+** → paste the service account email (`ga4-mcp@project-id.iam.gserviceaccount.com`) → assign **Viewer**

The Google SDK auto-reads `GOOGLE_APPLICATION_CREDENTIALS` — no code changes needed.

## Install into Claude Code

```bash
claude mcp add google-analytics \
  --env-file "/absolute/path/to/google-analytics-mcp-server/.env" \
  -- node "/absolute/path/to/google-analytics-mcp-server/dist/index.js"
```

Or add to `~/.claude.json` manually:

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

Restart Claude Code after install.

## Date formats

All date args accept GA4 formats:
- `YYYY-MM-DD` (e.g. `2026-04-01`)
- `NdaysAgo` (e.g. `28daysAgo`, `90daysAgo`)
- `yesterday`, `today`

Defaults: `28daysAgo` → `yesterday`.

## Verification

After credentials are in place:

```bash
node -e '
  import("./dist/tools/reports.js").then(m =>
    m.channelPerformance({ start_date: "7daysAgo", end_date: "yesterday", limit: 10 })
  ).then(r => console.log(JSON.stringify(r, null, 2)))
'
```

If that returns rows, everything works. Expected errors:
- `GA4_PROPERTY_ID is not set` — check `.env`
- `PERMISSION_DENIED` — service account isn't granted Viewer on the property
- `403 Google Analytics Data API has not been used` — enable the API in the GCP project

## Roadmap

- [ ] Admin API tools (list custom dimensions, conversion events, audiences) once needed
- [ ] Search Console MCP as sibling server for rankings / impressions / CTR data (complements this one)
- [ ] Pair with Demandbase MCP to join GA4 traffic with firmographics (account-level attribution)

TDQS

A3.7/5.0

Scored across 10 tools

Disambiguation5/5

Each tool targets a distinct area of GA4 data: all paid, specific channels, campaigns, conversions, landing pages, organic/paid search, realtime, and a generic report. No two tools have overlapping purposes that would cause confusion.

Naming Consistency5/5

All tool names consistently follow the 'ga4_<descriptive_name>' format using snake_case. The naming pattern is predictable and uniform across the entire set.

Tool Count5/5

10 tools is well within the ideal 3-15 range for a focused analytics server. Each tool serves a clear purpose, and the count feels neither excessive nor insufficient for covering core GA4 queries.

Completeness4/5

The set covers acquisition, behavior, conversions, and realtime analytics well. Minor gaps exist (e.g., user demographics, event details), but the flexible ga4_run_report tool allows agents to fill these gaps for custom reports.