google-analytics-mcp 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
ga4_mcp_server.py
ADDED
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
from fastmcp import FastMCP
|
|
2
|
+
from google.analytics.data_v1beta import BetaAnalyticsDataClient
|
|
3
|
+
from google.analytics.data_v1beta.types import (
|
|
4
|
+
DateRange, Dimension, Metric, RunReportRequest
|
|
5
|
+
)
|
|
6
|
+
import os
|
|
7
|
+
import sys
|
|
8
|
+
import json
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
|
|
11
|
+
# Configuration from environment variables
|
|
12
|
+
CREDENTIALS_PATH = os.getenv("GOOGLE_APPLICATION_CREDENTIALS")
|
|
13
|
+
GA4_PROPERTY_ID = os.getenv("GA4_PROPERTY_ID")
|
|
14
|
+
|
|
15
|
+
# Validate required environment variables
|
|
16
|
+
if not CREDENTIALS_PATH:
|
|
17
|
+
print("ERROR: GOOGLE_APPLICATION_CREDENTIALS environment variable not set", file=sys.stderr)
|
|
18
|
+
print("Please set it to the path of your service account JSON file", file=sys.stderr)
|
|
19
|
+
sys.exit(1)
|
|
20
|
+
|
|
21
|
+
if not GA4_PROPERTY_ID:
|
|
22
|
+
print("ERROR: GA4_PROPERTY_ID environment variable not set", file=sys.stderr)
|
|
23
|
+
print("Please set it to your GA4 property ID (e.g., 123456789)", file=sys.stderr)
|
|
24
|
+
sys.exit(1)
|
|
25
|
+
|
|
26
|
+
# Validate credentials file exists
|
|
27
|
+
if not os.path.exists(CREDENTIALS_PATH):
|
|
28
|
+
print(f"ERROR: Credentials file not found: {CREDENTIALS_PATH}", file=sys.stderr)
|
|
29
|
+
print("Please check the GOOGLE_APPLICATION_CREDENTIALS path", file=sys.stderr)
|
|
30
|
+
sys.exit(1)
|
|
31
|
+
|
|
32
|
+
# Initialize FastMCP
|
|
33
|
+
mcp = FastMCP("Google Analytics 4")
|
|
34
|
+
|
|
35
|
+
# Load dimensions and metrics from JSON files
|
|
36
|
+
def load_dimensions():
|
|
37
|
+
"""Load available dimensions from JSON file"""
|
|
38
|
+
try:
|
|
39
|
+
script_dir = Path(__file__).parent
|
|
40
|
+
with open(script_dir / "ga4_dimensions.json", "r") as f:
|
|
41
|
+
return json.load(f)
|
|
42
|
+
except FileNotFoundError:
|
|
43
|
+
print("Warning: ga4_dimensions.json not found", file=sys.stderr)
|
|
44
|
+
return {}
|
|
45
|
+
|
|
46
|
+
def load_metrics():
|
|
47
|
+
"""Load available metrics from JSON file"""
|
|
48
|
+
try:
|
|
49
|
+
script_dir = Path(__file__).parent
|
|
50
|
+
with open(script_dir / "ga4_metrics.json", "r") as f:
|
|
51
|
+
return json.load(f)
|
|
52
|
+
except FileNotFoundError:
|
|
53
|
+
print("Warning: ga4_metrics.json not found", file=sys.stderr)
|
|
54
|
+
return {}
|
|
55
|
+
|
|
56
|
+
@mcp.tool()
|
|
57
|
+
def list_dimension_categories():
|
|
58
|
+
"""
|
|
59
|
+
List all available GA4 dimension categories with descriptions.
|
|
60
|
+
|
|
61
|
+
Returns:
|
|
62
|
+
Dictionary of dimension categories and their available dimensions.
|
|
63
|
+
"""
|
|
64
|
+
dimensions = load_dimensions()
|
|
65
|
+
result = {}
|
|
66
|
+
for category, dims in dimensions.items():
|
|
67
|
+
result[category] = {
|
|
68
|
+
"count": len(dims),
|
|
69
|
+
"dimensions": list(dims.keys())
|
|
70
|
+
}
|
|
71
|
+
return result
|
|
72
|
+
|
|
73
|
+
@mcp.tool()
|
|
74
|
+
def list_metric_categories():
|
|
75
|
+
"""
|
|
76
|
+
List all available GA4 metric categories with descriptions.
|
|
77
|
+
|
|
78
|
+
Returns:
|
|
79
|
+
Dictionary of metric categories and their available metrics.
|
|
80
|
+
"""
|
|
81
|
+
metrics = load_metrics()
|
|
82
|
+
result = {}
|
|
83
|
+
for category, mets in metrics.items():
|
|
84
|
+
result[category] = {
|
|
85
|
+
"count": len(mets),
|
|
86
|
+
"metrics": list(mets.keys())
|
|
87
|
+
}
|
|
88
|
+
return result
|
|
89
|
+
|
|
90
|
+
@mcp.tool()
|
|
91
|
+
def get_dimensions_by_category(category):
|
|
92
|
+
"""
|
|
93
|
+
Get all dimensions in a specific category with their descriptions.
|
|
94
|
+
|
|
95
|
+
Args:
|
|
96
|
+
category: Category name (e.g., 'time', 'geography', 'ecommerce')
|
|
97
|
+
|
|
98
|
+
Returns:
|
|
99
|
+
Dictionary of dimensions and their descriptions for the category.
|
|
100
|
+
"""
|
|
101
|
+
dimensions = load_dimensions()
|
|
102
|
+
if category in dimensions:
|
|
103
|
+
return dimensions[category]
|
|
104
|
+
else:
|
|
105
|
+
available_categories = list(dimensions.keys())
|
|
106
|
+
return {"error": f"Category '{category}' not found. Available categories: {available_categories}"}
|
|
107
|
+
|
|
108
|
+
@mcp.tool()
|
|
109
|
+
def get_metrics_by_category(category):
|
|
110
|
+
"""
|
|
111
|
+
Get all metrics in a specific category with their descriptions.
|
|
112
|
+
|
|
113
|
+
Args:
|
|
114
|
+
category: Category name (e.g., 'user_metrics', 'ecommerce_metrics', 'session_metrics')
|
|
115
|
+
|
|
116
|
+
Returns:
|
|
117
|
+
Dictionary of metrics and their descriptions for the category.
|
|
118
|
+
"""
|
|
119
|
+
metrics = load_metrics()
|
|
120
|
+
if category in metrics:
|
|
121
|
+
return metrics[category]
|
|
122
|
+
else:
|
|
123
|
+
available_categories = list(metrics.keys())
|
|
124
|
+
return {"error": f"Category '{category}' not found. Available categories: {available_categories}"}
|
|
125
|
+
|
|
126
|
+
@mcp.tool()
|
|
127
|
+
def get_ga4_data(
|
|
128
|
+
dimensions=["date"],
|
|
129
|
+
metrics=["totalUsers", "newUsers", "bounceRate", "screenPageViewsPerSession", "averageSessionDuration"],
|
|
130
|
+
date_range_start="7daysAgo",
|
|
131
|
+
date_range_end="yesterday"
|
|
132
|
+
):
|
|
133
|
+
"""
|
|
134
|
+
Retrieve GA4 metrics data broken down by the specified dimensions.
|
|
135
|
+
|
|
136
|
+
Args:
|
|
137
|
+
dimensions: List of GA4 dimensions (e.g., ["date", "city"]) or a string
|
|
138
|
+
representation (e.g., "[\"date\", \"city\"]" or "date,city").
|
|
139
|
+
metrics: List of GA4 metrics (e.g., ["totalUsers", "newUsers"]) or a string
|
|
140
|
+
representation (e.g., "[\"totalUsers\"]" or "totalUsers,newUsers").
|
|
141
|
+
date_range_start: Start date in YYYY-MM-DD format or relative date like '7daysAgo'.
|
|
142
|
+
date_range_end: End date in YYYY-MM-DD format or relative date like 'yesterday'.
|
|
143
|
+
|
|
144
|
+
Returns:
|
|
145
|
+
List of dictionaries containing the requested data, or an error dictionary.
|
|
146
|
+
"""
|
|
147
|
+
try:
|
|
148
|
+
# Handle cases where dimensions might be passed as a string from the MCP client
|
|
149
|
+
parsed_dimensions = dimensions
|
|
150
|
+
if isinstance(dimensions, str):
|
|
151
|
+
try:
|
|
152
|
+
# Attempt to parse as JSON array first (e.g., "[\"date\", \"city\"]")
|
|
153
|
+
parsed_dimensions = json.loads(dimensions)
|
|
154
|
+
# Ensure it's a list after parsing; if json.loads gives a single string, wrap it in a list
|
|
155
|
+
if not isinstance(parsed_dimensions, list):
|
|
156
|
+
parsed_dimensions = [str(parsed_dimensions)]
|
|
157
|
+
except json.JSONDecodeError:
|
|
158
|
+
# If not a valid JSON string, treat as comma-separated (e.g., "date,city" or "date")
|
|
159
|
+
parsed_dimensions = [d.strip() for d in dimensions.split(',')]
|
|
160
|
+
|
|
161
|
+
# Ensure all elements are non-empty strings after potential parsing
|
|
162
|
+
parsed_dimensions = [str(d).strip() for d in parsed_dimensions if str(d).strip()]
|
|
163
|
+
|
|
164
|
+
# Handle cases where metrics might be passed as a string
|
|
165
|
+
parsed_metrics = metrics
|
|
166
|
+
if isinstance(metrics, str):
|
|
167
|
+
try:
|
|
168
|
+
parsed_metrics = json.loads(metrics)
|
|
169
|
+
if not isinstance(parsed_metrics, list):
|
|
170
|
+
parsed_metrics = [str(parsed_metrics)]
|
|
171
|
+
except json.JSONDecodeError:
|
|
172
|
+
parsed_metrics = [m.strip() for m in metrics.split(',')]
|
|
173
|
+
|
|
174
|
+
parsed_metrics = [str(m).strip() for m in parsed_metrics if str(m).strip()]
|
|
175
|
+
|
|
176
|
+
# Proceed if we have valid dimensions and metrics after parsing
|
|
177
|
+
if not parsed_dimensions:
|
|
178
|
+
return {"error": "Dimensions list cannot be empty after parsing."}
|
|
179
|
+
if not parsed_metrics:
|
|
180
|
+
return {"error": "Metrics list cannot be empty after parsing."}
|
|
181
|
+
|
|
182
|
+
# GA4 API Call
|
|
183
|
+
client = BetaAnalyticsDataClient()
|
|
184
|
+
|
|
185
|
+
# Convert dimensions and metrics to GA4 API format
|
|
186
|
+
dimension_objects = [Dimension(name=d) for d in parsed_dimensions]
|
|
187
|
+
metric_objects = [Metric(name=m) for m in parsed_metrics]
|
|
188
|
+
|
|
189
|
+
# Build the request
|
|
190
|
+
request = RunReportRequest(
|
|
191
|
+
property=f"properties/{GA4_PROPERTY_ID}",
|
|
192
|
+
dimensions=dimension_objects,
|
|
193
|
+
metrics=metric_objects,
|
|
194
|
+
date_ranges=[DateRange(start_date=date_range_start, end_date=date_range_end)]
|
|
195
|
+
)
|
|
196
|
+
|
|
197
|
+
# Execute the request
|
|
198
|
+
response = client.run_report(request)
|
|
199
|
+
|
|
200
|
+
# Format the response into a more usable structure
|
|
201
|
+
result = []
|
|
202
|
+
for row_idx, row in enumerate(response.rows):
|
|
203
|
+
data_row = {}
|
|
204
|
+
|
|
205
|
+
# Extract dimension values
|
|
206
|
+
for i, dimension_header in enumerate(response.dimension_headers):
|
|
207
|
+
# Check if dimension_values has enough elements
|
|
208
|
+
if i < len(row.dimension_values):
|
|
209
|
+
data_row[dimension_header.name] = row.dimension_values[i].value
|
|
210
|
+
else:
|
|
211
|
+
data_row[dimension_header.name] = None
|
|
212
|
+
|
|
213
|
+
# Extract metric values
|
|
214
|
+
for i, metric_header in enumerate(response.metric_headers):
|
|
215
|
+
# Check if metric_values has enough elements
|
|
216
|
+
if i < len(row.metric_values):
|
|
217
|
+
data_row[metric_header.name] = row.metric_values[i].value
|
|
218
|
+
else:
|
|
219
|
+
data_row[metric_header.name] = None
|
|
220
|
+
|
|
221
|
+
result.append(data_row)
|
|
222
|
+
|
|
223
|
+
return result
|
|
224
|
+
except Exception as e:
|
|
225
|
+
error_message = f"Error fetching GA4 data: {str(e)}"
|
|
226
|
+
print(error_message, file=sys.stderr)
|
|
227
|
+
# Include more details if available, e.g. from e.details() for gRPC errors
|
|
228
|
+
if hasattr(e, 'details'):
|
|
229
|
+
error_message += f" Details: {e.details()}"
|
|
230
|
+
return {"error": error_message}
|
|
231
|
+
|
|
232
|
+
# Start the server when run directly
|
|
233
|
+
if __name__ == "__main__":
|
|
234
|
+
# Use stdio transport ONLY - this is critical for MCP with Claude
|
|
235
|
+
print("Starting GA4 MCP server...", file=sys.stderr)
|
|
236
|
+
mcp.run(transport="stdio")
|
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: google-analytics-mcp
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Google Analytics 4 MCP Server for Claude, Cursor, Windsurf etc
|
|
5
|
+
Author-email: Surendran Balakrishnan <surendran.balakrishnan@example.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/surendranb/google-analytics-mcp
|
|
8
|
+
Project-URL: Repository, https://github.com/surendranb/google-analytics-mcp
|
|
9
|
+
Project-URL: Issues, https://github.com/surendranb/google-analytics-mcp/issues
|
|
10
|
+
Keywords: google-analytics,mcp,claude,ai,analytics,ga4
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Requires-Python: >=3.8
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
Requires-Dist: fastmcp>=0.1.0
|
|
23
|
+
Requires-Dist: google-analytics-data>=0.16.0
|
|
24
|
+
|
|
25
|
+
# Google Analytics MCP Server for Claude
|
|
26
|
+
|
|
27
|
+
Connect Google Analytics 4 data directly to Claude AI conversations. Ask questions about your website traffic, user behavior, and analytics data in natural language with access to 200+ GA4 dimensions and metrics.
|
|
28
|
+
|
|
29
|
+
## Prerequisites
|
|
30
|
+
|
|
31
|
+
**Check your Python setup first:**
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
# Check Python version (need 3.8+)
|
|
35
|
+
python --version
|
|
36
|
+
python3 --version
|
|
37
|
+
|
|
38
|
+
# Check pip
|
|
39
|
+
pip --version
|
|
40
|
+
pip3 --version
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
**What you need:**
|
|
44
|
+
- Python 3.8 or higher
|
|
45
|
+
- Google Analytics 4 property with data
|
|
46
|
+
- Service account with Analytics Reporting API access
|
|
47
|
+
|
|
48
|
+
## Installation
|
|
49
|
+
|
|
50
|
+
Choose either route:
|
|
51
|
+
|
|
52
|
+
### Route 1: pip install (Recommended)
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
pip install google-analytics-mcp
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Route 2: GitHub download
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
git clone https://github.com/surendranb/google-analytics-mcp.git
|
|
62
|
+
cd google-analytics-mcp
|
|
63
|
+
pip install -r requirements.txt
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Setup
|
|
67
|
+
|
|
68
|
+
### Step 1: Get GA4 Credentials
|
|
69
|
+
|
|
70
|
+
**Part A: Create Service Account in Google Cloud Console**
|
|
71
|
+
|
|
72
|
+
1. Go to [Google Cloud Console](https://console.cloud.google.com/)
|
|
73
|
+
2. **Create or select a project**:
|
|
74
|
+
- If new: Click "New Project" → Enter project name → Create
|
|
75
|
+
- If existing: Select your project from the dropdown
|
|
76
|
+
3. **Enable the Analytics Reporting API**:
|
|
77
|
+
- Go to "APIs & Services" → "Library"
|
|
78
|
+
- Search for "Google Analytics Reporting API"
|
|
79
|
+
- Click on it → Click "Enable"
|
|
80
|
+
4. **Enable the Analytics Data API**:
|
|
81
|
+
- Search for "Google Analytics Data API"
|
|
82
|
+
- Click on it → Click "Enable"
|
|
83
|
+
5. **Create Service Account**:
|
|
84
|
+
- Go to "APIs & Services" → "Credentials"
|
|
85
|
+
- Click "Create Credentials" → "Service Account"
|
|
86
|
+
- Enter a name (e.g., "ga4-mcp-server")
|
|
87
|
+
- Click "Create and Continue"
|
|
88
|
+
- Skip role assignment for now → Click "Done"
|
|
89
|
+
6. **Download JSON Key**:
|
|
90
|
+
- Click on your newly created service account
|
|
91
|
+
- Go to "Keys" tab → "Add Key" → "Create New Key"
|
|
92
|
+
- Select "JSON" → Click "Create"
|
|
93
|
+
- **Save this file securely** - you'll need the path to it
|
|
94
|
+
|
|
95
|
+
**Part B: Add Service Account to GA4**
|
|
96
|
+
|
|
97
|
+
1. **Copy the service account email**:
|
|
98
|
+
- From the downloaded JSON file, find the `client_email` field
|
|
99
|
+
- Copy this email address (looks like: `ga4-mcp-server@your-project.iam.gserviceaccount.com`)
|
|
100
|
+
|
|
101
|
+
2. **Add to GA4 property**:
|
|
102
|
+
- Go to [Google Analytics](https://analytics.google.com/)
|
|
103
|
+
- Select your GA4 property
|
|
104
|
+
- Click "Admin" (gear icon in bottom left)
|
|
105
|
+
- Under "Property" column → Click "Property access management"
|
|
106
|
+
- Click "+" → "Add users"
|
|
107
|
+
- Paste the service account email
|
|
108
|
+
- Select "Viewer" role (sufficient for reading data)
|
|
109
|
+
- Uncheck "Notify new users by email"
|
|
110
|
+
- Click "Add"
|
|
111
|
+
|
|
112
|
+
### Step 2: Find Your GA4 Property ID
|
|
113
|
+
|
|
114
|
+
1. In [Google Analytics](https://analytics.google.com/), select your property
|
|
115
|
+
2. Click "Admin" (gear icon)
|
|
116
|
+
3. Under "Property" column → Click "Property details"
|
|
117
|
+
4. Copy the **Property ID** (numeric, e.g., `1234567890`)
|
|
118
|
+
- **Note**: This is different from the "Measurement ID" (starts with G-)
|
|
119
|
+
|
|
120
|
+
### Step 3: Test Your Setup (Optional)
|
|
121
|
+
|
|
122
|
+
Before configuring Claude, verify your credentials work:
|
|
123
|
+
|
|
124
|
+
1. **Install Google Analytics Data library**:
|
|
125
|
+
```bash
|
|
126
|
+
pip install google-analytics-data
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
2. **Test script** (save as `test_ga4.py`):
|
|
130
|
+
```python
|
|
131
|
+
import os
|
|
132
|
+
from google.analytics.data_v1beta import BetaAnalyticsDataClient
|
|
133
|
+
|
|
134
|
+
# Set your credentials
|
|
135
|
+
os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = "/path/to/your/service-account-key.json"
|
|
136
|
+
|
|
137
|
+
# Test connection
|
|
138
|
+
client = BetaAnalyticsDataClient()
|
|
139
|
+
print("✅ GA4 credentials working!")
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
3. **Run test**:
|
|
143
|
+
```bash
|
|
144
|
+
python test_ga4.py
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
If you see "✅ GA4 credentials working!" you're ready to proceed.
|
|
148
|
+
|
|
149
|
+
### Step 4: Configure Claude
|
|
150
|
+
|
|
151
|
+
Add this to your Claude MCP configuration:
|
|
152
|
+
|
|
153
|
+
**For Route 1 (pip install):**
|
|
154
|
+
```json
|
|
155
|
+
{
|
|
156
|
+
"mcpServers": {
|
|
157
|
+
"ga4-analytics": {
|
|
158
|
+
"command": "ga4-mcp-server",
|
|
159
|
+
"env": {
|
|
160
|
+
"GOOGLE_APPLICATION_CREDENTIALS": "/path/to/your/service-account-key.json",
|
|
161
|
+
"GA4_PROPERTY_ID": "346085905"
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
**For Route 2 (GitHub download):**
|
|
169
|
+
```json
|
|
170
|
+
{
|
|
171
|
+
"mcpServers": {
|
|
172
|
+
"ga4-analytics": {
|
|
173
|
+
"command": "/full/path/to/ga4-mcp-server/venv/bin/python",
|
|
174
|
+
"args": ["/full/path/to/ga4-mcp-server/ga4_mcp_server.py"],
|
|
175
|
+
"env": {
|
|
176
|
+
"GOOGLE_APPLICATION_CREDENTIALS": "/path/to/your/service-account-key.json",
|
|
177
|
+
"GA4_PROPERTY_ID": "346085905"
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
**Replace:**
|
|
185
|
+
- `/path/to/your/service-account-key.json` with your actual credential file path
|
|
186
|
+
- `346085905` with your actual GA4 Property ID
|
|
187
|
+
- `/path/to/ga4-mcp-server/` with your actual download path (Route 2 only)
|
|
188
|
+
|
|
189
|
+
## Usage
|
|
190
|
+
|
|
191
|
+
Once configured, ask Claude questions like:
|
|
192
|
+
|
|
193
|
+
### **Discovery & Exploration:**
|
|
194
|
+
- "What GA4 dimension categories are available?"
|
|
195
|
+
- "Show me all ecommerce metrics"
|
|
196
|
+
- "What dimensions can I use for geographic analysis?"
|
|
197
|
+
|
|
198
|
+
### **Traffic Analysis:**
|
|
199
|
+
- "What's my website traffic for the past week?"
|
|
200
|
+
- "Show me user metrics by city for last month"
|
|
201
|
+
- "Compare bounce rates between different date ranges"
|
|
202
|
+
|
|
203
|
+
### **Multi-Dimensional Analysis:**
|
|
204
|
+
- "Show me revenue by country and device category for last 30 days"
|
|
205
|
+
- "Analyze sessions and conversions by campaign and source/medium"
|
|
206
|
+
- "Compare user engagement across different page paths and traffic sources"
|
|
207
|
+
|
|
208
|
+
### **E-commerce Analysis:**
|
|
209
|
+
- "What are my top-performing products by revenue?"
|
|
210
|
+
- "Show me conversion rates by traffic source and device type"
|
|
211
|
+
- "Analyze purchase behavior by user demographics"
|
|
212
|
+
|
|
213
|
+
## Available Tools
|
|
214
|
+
|
|
215
|
+
The server provides 5 main tools:
|
|
216
|
+
|
|
217
|
+
1. **`get_ga4_data`** - Retrieve GA4 data with custom dimensions and metrics
|
|
218
|
+
2. **`list_dimension_categories`** - Browse available dimension categories
|
|
219
|
+
3. **`list_metric_categories`** - Browse available metric categories
|
|
220
|
+
4. **`get_dimensions_by_category`** - Get dimensions for a specific category
|
|
221
|
+
5. **`get_metrics_by_category`** - Get metrics for a specific category
|
|
222
|
+
|
|
223
|
+
## Dimensions & Metrics
|
|
224
|
+
|
|
225
|
+
Access to **200+ GA4 dimensions and metrics** organized by category:
|
|
226
|
+
|
|
227
|
+
### **Dimension Categories:**
|
|
228
|
+
- **Time**: date, hour, month, year, etc.
|
|
229
|
+
- **Geography**: country, city, region
|
|
230
|
+
- **Technology**: browser, device, operating system
|
|
231
|
+
- **Traffic Source**: campaign, source, medium, channel groups
|
|
232
|
+
- **Content**: page paths, titles, content groups
|
|
233
|
+
- **E-commerce**: item details, transaction info
|
|
234
|
+
- **User Demographics**: age, gender, language
|
|
235
|
+
- **Google Ads**: campaign, ad group, keyword data
|
|
236
|
+
- **And 10+ more categories**
|
|
237
|
+
|
|
238
|
+
### **Metric Categories:**
|
|
239
|
+
- **User Metrics**: totalUsers, newUsers, activeUsers
|
|
240
|
+
- **Session Metrics**: sessions, bounceRate, engagementRate
|
|
241
|
+
- **E-commerce**: totalRevenue, transactions, conversions
|
|
242
|
+
- **Events**: eventCount, conversions, event values
|
|
243
|
+
- **Advertising**: adRevenue, returnOnAdSpend
|
|
244
|
+
- **And more specialized metrics**
|
|
245
|
+
|
|
246
|
+
## Troubleshooting
|
|
247
|
+
|
|
248
|
+
### Command not found (Route 1)
|
|
249
|
+
If `google-analytics-mcp` command not found, try:
|
|
250
|
+
```json
|
|
251
|
+
{
|
|
252
|
+
"command": "python3",
|
|
253
|
+
"args": ["-m", "ga4_mcp_server"]
|
|
254
|
+
}
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
### Python version issues
|
|
258
|
+
- Use `python3` instead of `python` if you have both Python 2 and 3
|
|
259
|
+
- Use `pip3` instead of `pip` if needed
|
|
260
|
+
|
|
261
|
+
### Permission errors
|
|
262
|
+
```bash
|
|
263
|
+
# Try user install instead of system-wide
|
|
264
|
+
pip install --user google-analytics-mcp
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
### Credentials not working
|
|
268
|
+
1. **Verify the JSON file path** is correct and accessible
|
|
269
|
+
2. **Check that the service account has Analytics Reporting API access**:
|
|
270
|
+
- Go to Google Cloud Console → IAM & Admin → IAM
|
|
271
|
+
- Find your service account → Check it has necessary permissions
|
|
272
|
+
3. **Ensure the service account email is added as a viewer in GA4**:
|
|
273
|
+
- GA4 → Admin → Property access management
|
|
274
|
+
- Look for your service account email in the list
|
|
275
|
+
4. **Verify you're using the Property ID, not Measurement ID**:
|
|
276
|
+
- Property ID: numeric (e.g., `1234567890`) ✅
|
|
277
|
+
- Measurement ID: starts with G- (e.g., `G-XXXXXXXXXX`) ❌
|
|
278
|
+
|
|
279
|
+
### API quota/rate limit errors
|
|
280
|
+
- GA4 has daily quotas and rate limits
|
|
281
|
+
- Try reducing the date range in your queries
|
|
282
|
+
- Wait a few minutes between large requests
|
|
283
|
+
|
|
284
|
+
## Project Structure
|
|
285
|
+
|
|
286
|
+
```
|
|
287
|
+
google-analytics-mcp/
|
|
288
|
+
├── ga4_mcp_server.py # Main MCP server
|
|
289
|
+
├── ga4_dimensions.json # All available GA4 dimensions
|
|
290
|
+
├── ga4_metrics.json # All available GA4 metrics
|
|
291
|
+
├── requirements.txt # Python dependencies
|
|
292
|
+
├── pyproject.toml # Package configuration
|
|
293
|
+
├── README.md # This file
|
|
294
|
+
└── claude-config-template.json # MCP configuration template
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
## License
|
|
298
|
+
|
|
299
|
+
MIT License
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
ga4_mcp_server.py,sha256=NZaj0Uu49ORRLAnieKBDN50F5tECpjp5R3YKAl1ithA,9040
|
|
2
|
+
google_analytics_mcp-1.0.0.dist-info/METADATA,sha256=p6bZhBG-UycziKXbd0GFHrLQwoI5U-k5SeDn0TQLPZI,9577
|
|
3
|
+
google_analytics_mcp-1.0.0.dist-info/WHEEL,sha256=zaaOINJESkSfm_4HQVc5ssNzHCPXhJm0kEUakpsEHaU,91
|
|
4
|
+
google_analytics_mcp-1.0.0.dist-info/entry_points.txt,sha256=FxiRVVgKqoXvfu9vxgborulOKJibcsIQ0YLomlNbMCQ,61
|
|
5
|
+
google_analytics_mcp-1.0.0.dist-info/top_level.txt,sha256=nhVl9yD14a_BIFxv0qrslrX6lzGr3h40ifIGlLR2xFg,15
|
|
6
|
+
google_analytics_mcp-1.0.0.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ga4_mcp_server
|