Google Analytics 4 MCP (OAuth)
README.md
# Google Analytics 4 MCP (OAuth)
[](https://github.com/rafavillaplana/google-analytics-oauth-mcp/actions/workflows/ci.yml)
[](LICENSE)
**English** · [Español](README.es.md)
Local [MCP](https://modelcontextprotocol.io) server that lets Claude query **Google Analytics 4** in plain language, **signing in with your Google account in the browser**:
> *"Which GA4 properties do I have?"*
> *"How many organic sessions did cliente.es get this month vs. last month, and which landing pages lost the most?"*
> *"How much traffic do we get from ChatGPT and Perplexity, and to which pages?"*
**The difference with service-account connectors:** with a service account (`xxx@project.iam.gserviceaccount.com`) you have to add that email as a user to every Analytics account or property, one by one. Here Claude acts **as you**: sign in once and it sees **every account and property your Google account can already access**, including the ones shared with you tomorrow.
- **Runs on your computer.** Talks directly to the official Google Analytics Admin and Data APIs. No servers in between.
- **Your own OAuth client.** Created in your own Google Cloud project. **You can reuse the one from the Search Console connector.**
- **Sign in once.** The refresh token is stored in a local file only your user can read, and access renews itself.
- **Read-only.** `analytics.readonly` scope: it cannot change properties, users, events or settings.
## 1. Set up the OAuth client in Google Cloud (5 minutes, once)
### If you already use [search-console-oauth-mcp](https://github.com/rafavillaplana/search-console-oauth-mcp)
Reuse the same project and client:
1. In [Google Cloud Console](https://console.cloud.google.com/), with the Search Console connector's project selected, go to *APIs & Services → Library* and **enable**:
- **Google Analytics Admin API**
- **Google Analytics Data API**
2. *(Optional)* In *Google Auth Platform → Data access*, add the `.../auth/analytics.readonly` scope.
3. Use the **same Client ID and secret** when installing this extension. Each connector keeps its own token, so they can even use different Google accounts.
### Starting from scratch
1. Open [Google Cloud Console](https://console.cloud.google.com/) and create a project (e.g. *Claude Google*).
2. **Enable the APIs:** *APIs & Services → Library →* enable **Google Analytics Admin API** and **Google Analytics Data API**.
3. **Consent screen** (*Google Auth Platform*):
- *Branding:* app name (e.g. *Claude Analytics*), your support email and, if Google asks for them to publish, your site's home page and privacy policy, adding your domain under *Authorized domains*.
⚠️ **Don't upload a logo:** with a logo Google requires app verification.
- *Audience:*
- **Google Workspace account, only users in your organization →** choose **Internal**. No warnings, no expiry.
- **Gmail account or outside users →** choose **External**, then click **Publish app** to move it to **In production**.
⚠️ If you leave it in *Testing*, sign-in shows *"Access blocked"* (unless you add yourself as a test user), and even then access expires **every 7 days**.
- *Data access (optional):* add the `.../auth/analytics.readonly` scope.
4. **Create the client:** *Clients → Create client →* Application type **Desktop app** → *Create*.
Copy the **Client ID** (`….apps.googleusercontent.com`) and **Client secret** (`GOCSPX-…`).
You don't need Google's app verification to use it yourself (or your team, up to 100 users). Because it's unverified, the first time Google shows *"Google hasn't verified this app"*: click **Advanced → Go to Claude Analytics**. It's your own app in your own project.
## 2. Install
### Claude Desktop, one click (recommended)
1. Download the latest **`google-analytics-oauth-mcp-x.y.z.mcpb`** from [Releases](https://github.com/rafavillaplana/google-analytics-oauth-mcp/releases/latest).
2. Double-click it (or drag it onto Claude Desktop, or *Settings → Extensions → Install extension…*).
3. Paste the **Client ID** and **Client secret** and enable the extension.
Claude Desktop runs the extension with its built-in Node.js, so there's nothing else to install.
### From source (manual config or Claude Code)
You need [Node.js](https://nodejs.org) 20+ and git:
```bash
git clone https://github.com/rafavillaplana/google-analytics-oauth-mcp.git
cd google-analytics-oauth-mcp
npm install # installs and builds dist/index.js
```
**Claude Desktop:** *Settings → Developer → Edit config* (on Windows use `\\` in the path):
```json
{
"mcpServers": {
"google-analytics": {
"command": "node",
"args": ["/path/to/google-analytics-oauth-mcp/dist/index.js"],
"env": {
"GA4_OAUTH_CLIENT_ID": "your-id.apps.googleusercontent.com",
"GA4_OAUTH_CLIENT_SECRET": "GOCSPX-..."
}
}
}
}
```
**Claude Code:**
```bash
claude mcp add google-analytics --scope user \
-e GA4_OAUTH_CLIENT_ID=your-id.apps.googleusercontent.com \
-e GA4_OAUTH_CLIENT_SECRET=GOCSPX-... \
-- node /path/to/google-analytics-oauth-mcp/dist/index.js
```
Instead of the ID and secret you can point to the JSON Google lets you download: `-e GA4_OAUTH_CLIENT_FILE=/path/client_secret_xxx.json`.
## 3. Sign in
Ask Claude anything (e.g. *"list my GA4 properties"*). The first time, your browser opens Google's sign-in page: pick your account and **tick the Google Analytics permission**. You'll see *"Connected to Google Analytics ✔"* and Claude carries on with the answer.
- If no browser opens, Claude gives you the link to open on the same computer.
- From source you can also sign in from a terminal with `node dist/index.js auth` (same environment variables).
- To **switch Google accounts**, ask Claude to sign out (`sign_out`) and ask again.
## Tools
| Tool | What it does |
|---|---|
| `list_properties` | Every GA4 account and property your account can access, searchable by name |
| `get_property` | Time zone, currency, data streams (URL and `G-…` measurement ID) and key events |
| `get_metadata` | Dimension and metric catalog for the property, custom definitions included |
| `get_overview` | Sessions, users, engagement, views, key events and revenue vs. the previous period (or last year), split by channel |
| `run_report` | Free-form report: any dimensions and metrics, filters (regex included), sorting, pagination and a comparison period |
| `get_report_over_time` | Time series by day, ISO week or month, optionally broken down by one dimension (channel, device…) |
| `compare_periods` | Landing pages, pages, sources or any dimension that gained or lost the most between two periods (new and lost included) |
| `get_ai_traffic` | Traffic referred by AI assistants (ChatGPT, Perplexity, Gemini, Copilot, Claude, DeepSeek, Grok…): total, share, trend, split by assistant and the landing pages they send traffic to |
| `run_realtime_report` | Active users in the last 30 minutes by page, country, device, event… |
| `auth_status` · `sign_in` · `sign_out` | See the connected account, sign in, or disconnect it |
By default data covers the **last 28 complete days** (up to yesterday), like the GA4 interface. Dates accept `YYYY-MM-DD`, `today`, `yesterday` or `NdaysAgo`. Rates (`engagementRate`, `bounceRate`…) are 0–1 fractions and durations are seconds. The `channel` shortcut filters by default channel group (e.g. `"Organic Search"`).
> **About `get_ai_traffic`:** it counts visits that arrive with an AI referrer. Many clicks from apps or copied links land as *Direct*, so treat it as a lower bound.
## Security and privacy
- The connector only requests **read** access to Google Analytics (`analytics.readonly`) and your email (to show which account is connected).
- The refresh token is stored at `~/.google-analytics-oauth-mcp/token.json` (on Windows, `C:\Users\<you>\.google-analytics-oauth-mcp\token.json`), readable only by your user. Override with `GA4_TOKEN_PATH`.
- Sign-in uses Google's official desktop-app flow: loopback redirect to `127.0.0.1` + PKCE. The link expires after 10 minutes and works once.
- `sign_out` revokes access at Google and deletes the token. You can also revoke it at [myaccount.google.com/permissions](https://myaccount.google.com/permissions).
- Publishing your OAuth app (*In production*) doesn't expose your data: each person who signs in only authorizes access to **their own** properties. Anyone who downloads this project creates their own OAuth client; neither the code nor the `.mcpb` contain credentials.
- Don't share your client secret or token file. More in [SECURITY.md](SECURITY.md).
## Troubleshooting
| Message | Fix |
|---|---|
| *Google Analytics Admin/Data API has not been used / is disabled* | Enable **both** APIs in the same Google Cloud project as the OAuth client |
| *The saved Google sign-in has expired or was revoked* every week | The app is in *Testing*: publish it (*In production*) or use *Internal* |
| *has no access to this property* | Use the numeric `propertyId` from `list_properties`; your account needs at least the Viewer role |
| *is not a GA4 property ID* | You passed a measurement ID (`G-…`) or a Universal Analytics ID (`UA-…`): use the numeric property ID |
| *Google Analytics permission was not granted* | Sign out and sign in again ticking the Google Analytics box |
| *… is not a valid dimension/metric* or incompatible combination | Check names with `get_metadata`; some user-scoped dimensions can't be mixed with event-scoped metrics |
| *quota reached* | GA4 limits tokens per property per hour: wait, or ask for fewer rows or dimensions |
| *invalid_client* in the browser | ID or secret don't match, or the client isn't a *Desktop app* |
## Development
```bash
npm install
npm run typecheck
npm test # unit tests
npm run test:e2e # full flow against a fake Google (OAuth + Admin API + Data API)
npm run pack # builds the .mcpb
```
[MIT](LICENSE) · Made by [Rafa Villaplana](https://rafavillaplana.com). Companion of [search-console-oauth-mcp](https://github.com/rafavillaplana/search-console-oauth-mcp) and [bing-webmaster-tools-mcp](https://github.com/rafavillaplana/bing-webmaster-tools-mcp).
*Not affiliated with Google. Google Analytics is a trademark of Google LLC.*
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues