Google Analytics 4 MCP Server
Provides read-only tools for querying Google Analytics 4, including listing properties, retrieving property details and metadata, and running historical and realtime reports with dimensions, metrics, filters, sorting, and row limits.
This server does not currently have a deployable release on Glama. Follow the repository's setup instructions to install and configure it for your MCP client, including any required credentials and local dependencies.
Google Analytics 4 MCP Server
A read-only Model Context Protocol server that lets Claude query Google Analytics 4. Deploy it once (for example on Railway), add it to your Claude Team plan as a custom connector, and anyone on the team can ask things like:
"Which channels drove the most sessions and key events last month?"
"Top 20 landing pages from Organic Search in the last 28 days, with engagement rate"
"Compare this month's sessions by device to last month"
"How many people are on the site right now, and from which countries?"
It is read-only: it only ever requests the https://www.googleapis.com/auth/analytics.readonly scope and has no tools that change anything in GA4.
Based on ccsmatt/gsc-mcp-server, a fork of sofianbettayeb/gsc-mcp-server by Sofian Bettayeb (MIT). The HTTP transport and deployment setup come from that project; the Search Console tools were replaced with GA4 tools.
Tools
Tool | What it does |
| Lists GA4 accounts and properties the Google account can read, with property IDs |
| Details for one property: time zone, currency, data streams (website URL, measurement ID) |
| Historical report (Data API |
| Last 30 minutes of activity ( |
| Custom dimensions and metrics on a property (optionally all standard ones too) |
Related MCP server: Delmain GA4 MCP
How it works
One HTTP endpoint,
POST /mcp(stateless streamable HTTP), plusGET /healthzfor health checks.Every
/mcprequest must carryAuthorization: Bearer <MCP_AUTH_TOKEN>. The server refuses to start ifMCP_AUTH_TOKENis not set.The server reads GA4 as one identity: either a service account (a robot Google account) or the Google account that created the refresh token. Everyone who uses the connector sees what that identity can see, so give it Viewer access to exactly the properties your team should query.
All credentials come from environment variables. Nothing is written to disk.
Environment variables
Set either the service account variables or the three OAuth variables. If a service account key is set, it is used and the OAuth variables are ignored.
Variable | Required | Description |
| option A | Service account key JSON, raw or base64-encoded (recommended for Railway) |
| option A | Path to the key JSON file instead (used only if |
| option B | OAuth client ID (Desktop app type) |
| option B | OAuth client secret |
| option B | From |
| yes | Long random string Claude must send as a Bearer token |
| no | Listen port (default 8080; Railway sets this for you) |
Both options use only the read-only scope https://www.googleapis.com/auth/analytics.readonly.
1. Google Cloud setup
Go to Google Cloud Console and create a project (or pick an existing one).
Enable the two APIs (APIs & Services > Library), searching for each:
Google Analytics Data API
Google Analytics Admin API
Then follow either option A or option B.
Which option?
Option A: service account (recommended). No consent screen, no Google app verification, and the key doesn't expire after 7 days. You add the service account's email as a Viewer on each GA4 property, the same way you'd add a person. This is the way to go if your main Google account is a personal Gmail account: there, an unverified OAuth app is either blocked or limited to 7-day tokens.
Option B: OAuth refresh token. Signs in as a real Google account, so it sees every property that account can see without adding anything in GA4. Best if your account is part of a Google Workspace organization (consent screen set to Internal).
2A. Option A: service account
In Google Cloud Console, go to IAM & Admin > Service Accounts > Create service account.
Name: e.g.
ga4-mcp. Click Create and continue.Skip the optional "grant access" steps (it needs no Cloud roles) and click Done.
Copy the service account's email (looks like
ga4-mcp@your-project.iam.gserviceaccount.com).Open the service account > Keys > Add key > Create new key > JSON > Create. A
.jsonkey file downloads.Save it outside this repo folder (e.g. your password manager), never commit it.
If key creation is blocked with an organization policy error (
iam.disableServiceAccountKeyCreation), an organization admin has to allow keys for this project.
Give it access in GA4. For each property (or once per GA4 account to cover all its properties): GA4 Admin > Property access management (or Account access management) > + > Add users, paste the service account email, choose role Viewer, untick Notify new users by email, click Add.
Turn the key into one line for Railway. Base64-encode the file and copy it to the clipboard:
PowerShell (Windows):
[Convert]::ToBase64String([IO.File]::ReadAllBytes("C:\path\to\key.json")) | Set-ClipboardmacOS:
base64 -i /path/to/key.json | tr -d '\n' | pbcopyYou'll paste this as
GOOGLE_SERVICE_ACCOUNT_KEYin step 5. (Raw JSON also works, but base64 avoids problems with the line breaks in the private key.)
Then skip to step 4.
To revoke access later, delete the key (or the whole service account) in Google Cloud, or remove its email from GA4.
2B. Option B: OAuth refresh token
Configure the OAuth consent screen
In Google Auth Platform:
Branding: app name (e.g. "GA4 MCP"), your support email.
Audience:
If your Google account is part of a Google Workspace organization, choose Internal. Tokens don't expire and no verification is needed.
Otherwise choose External, add yourself as a test user, then Publish app (set to In production). Apps left in Testing issue refresh tokens that expire after 7 days. An unverified production app shows an "unverified app" warning during consent; as the owner you can click Advanced > Go to ... (unsafe) to continue. Some personal Gmail accounts instead get a hard "This app is blocked" page; if that happens, use option A.
Data Access: add the scope
https://www.googleapis.com/auth/analytics.readonly(shown as ".../auth/analytics.readonly").
Create the OAuth client
Google Auth Platform > Clients > Create client.
Application type: Desktop app. Give it a name and click Create.
Copy the Client ID and Client secret. Don't download the JSON into this repo (it's git-ignored, but there's no need for it).
Make sure the Google account you'll sign in with has at least Viewer access on each GA4 property (GA4 > Admin > Property access management).
Get a refresh token
You need Node.js 22+ and a copy of this repo.
git clone https://github.com/ccsmatt/ga-mcp-server.git
cd ga-mcp-server
npm installThen run the helper with your client ID and secret as environment variables.
PowerShell (Windows):
$env:GOOGLE_CLIENT_ID = "your-client-id.apps.googleusercontent.com"
$env:GOOGLE_CLIENT_SECRET = "your-client-secret"
npm run setup-authmacOS / Linux:
GOOGLE_CLIENT_ID="your-client-id.apps.googleusercontent.com" GOOGLE_CLIENT_SECRET="your-client-secret" npm run setup-authThe script:
Prints a Google consent URL. Open it in an incognito/private window and sign in with the Google account that has GA4 access.
After you approve, your browser goes to
http://localhost/?code=...and shows a "can't connect" page. That's expected.Copy the full address from the address bar (or just the
codevalue) and paste it into the terminal.The script prints only the refresh token. Copy it somewhere safe for step 5 (e.g. your password manager).
Nothing is written to disk. Close the terminal afterwards so the client secret isn't left in its environment.
If you get invalid_grant, the code expired or was already used; run it again and paste promptly.
4. Choose an MCP auth token
MCP_AUTH_TOKEN is the password Claude uses to call your server. Generate a long random one:
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"5. Deploy to Railway
In Railway, click New Project > Deploy from GitHub repo and pick
ga-mcp-server. Railway finds theDockerfileand builds with it.Open the service > Variables and add:
MCP_AUTH_TOKENOption A:
GOOGLE_SERVICE_ACCOUNT_KEY(the base64 text from step 2A)Option B:
GOOGLE_CLIENT_ID,GOOGLE_CLIENT_SECRET,GOOGLE_REFRESH_TOKEN
Don't set
PORT; Railway provides it. If you switch from option B to A, delete the three OAuth variables so it's clear which one is in use.Settings > Networking > Generate Domain to get a public URL like
https://ga-mcp-server-production.up.railway.app.Optional: Settings > Deploy > Healthcheck Path =
/healthz.Check it: opening
https://<your-domain>/healthzshould show{"status":"ok"}. The deploy logs should sayga-mcp-server listening on port ...andGoogle credentials: service account <email>(orOAuth refresh token). If the logs say a variable is missing, fix it under Variables (Railway redeploys automatically).
Your MCP endpoint is https://<your-domain>/mcp.
6. Add it to Claude (Team plan)
An Owner of the Claude Team organization does this once:
Go to Organization settings > Connectors, select Add, then Custom (choose Web if asked).
Name: e.g. "Google Analytics 4". MCP server URL:
https://<your-domain>/mcp.Authentication: No sign-in.
Request headers: choose header name
authorization, valueBearer <your MCP_AUTH_TOKEN>. Type the wordBearer, a space, then the token; Claude sends the value exactly as entered. Mark it Required.Click Add.
Team members then go to Customize > Connectors, find the connector with the Custom label and click Connect. In a chat, turn it on from the + menu > Connectors.
Request header authentication is in beta for a limited set of organizations. If you don't see Request headers in the dialog, your org doesn't have it yet, and this server (which only accepts the header) can't be added from claude.ai until it does. It still works from Claude Code, which supports headers today.
To change the token later, update MCP_AUTH_TOKEN in Railway, then remove and re-add the connector with the new header (headers can't be edited after saving).
Claude Code (CLI)
claude mcp add --transport http ga4 https://<your-domain>/mcp --header "Authorization: Bearer <your MCP_AUTH_TOKEN>"Local development
cp .env.example .env # fill in real values; .env is git-ignored
npm run build
npm start # or: npm run devnpm start doesn't load .env by itself; export the variables in your shell first (or use your editor's env support). Then check http://localhost:8080/healthz.
Troubleshooting
Message | Fix |
| The Google account or service account email needs Viewer access on that GA4 property, or the property ID is wrong. |
| Service account: its email hasn't been added to any GA4 property or account yet (step 2A.4). |
| Enable both Google Analytics Data API and Google Analytics Admin API in the same Cloud project as the service account or OAuth client. |
|
|
| The key was deleted or disabled. Create a new key and update |
| Refresh token revoked or expired (7-day expiry if the consent screen is External + Testing). Re-run |
"This app is blocked" during | Google blocked the unverified OAuth app for this account. Use option A (service account). |
|
|
| The connector isn't sending |
Server exits at startup | Read the deploy log: it names the missing variable. |
Security notes
Never commit
.env, service account keys, OAuth client JSON or tokens..gitignoreand.dockerignoreblock the usual file names, but keep key files outside the repo folder anyway.The service account key grants read access to every GA4 property its email has been added to. Store it only in Railway variables (and your password manager). Revoke it any time by deleting the key in Google Cloud.
The refresh token grants read access to every GA4 property the Google account can see. Store it only in Railway variables. Revoke it any time at Google Account permissions.
Anyone with
MCP_AUTH_TOKENand the URL can read that GA4 data. Rotate it if it leaks.
Privacy
See PRIVACY.md and TERMS.md.
License
MIT. See LICENSE. Originally derived from gsc-mcp-server by Sofian Bettayeb.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
This server cannot be deployed
Maintenance
Related MCP Connectors
Read-only Google Analytics 4 MCP server for AI assistants.
Read-only Google Ads, GA4 and Search Console data for Claude, with no Google Cloud setup.
Read-only Google Search Console and Google Analytics for AI agents.
GA4, Google Ads and Search Console in Claude. Read-only OAuth, multi-account for agencies.
Related MCP Servers
- AlicenseBqualityDmaintenanceEnables LLM applications to query Google Analytics 4 data through standard MCP interfaces, supporting real-time data, custom reports, and metadata discovery.5107 npm1MIT
- AlicenseAqualityDmaintenanceEnables querying Google Analytics 4 properties using natural language through MCP clients. Supports customizable reports with any dimensions and metrics, listing properties, and real-time data.4MIT
- AlicenseNot gradedqualityCmaintenanceEnables querying Google Analytics 4 data through MCP tools for running reports, listing properties, getting real-time metrics, and exploring metadata.149 npmMIT
- AlicenseAqualityBmaintenanceEnables MCP clients to query Google Analytics 4 reporting and configuration data through 27 read-only tools, including pivots, funnels, realtime reports, Admin API inspection, and diagnostics, with identifiers redacted by default.27394 npmApache 2.0