Google Analytics MCP Server
Allows listing Google Ads links associated with a Google Analytics property.
Provides tools for interacting with Google Analytics Admin and Data APIs, enabling retrieval of account and property information, running core and realtime reports, and accessing custom dimensions and metrics.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Google Analytics MCP ServerShow me page views for the last 7 days"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Google Analytics MCP Server (Experimental)
This repo contains the source code for running a local MCP server that interacts with APIs for Google Analytics.
Join the discussion and ask questions in the 🤖-analytics-mcp channel on Discord.
Tools 🛠️
The server uses the Google Analytics Admin API and Google Analytics Data API to provide several Tools for use with LLMs.
Retrieve account and property information 🟠
get_account_summaries: Retrieves information about the user's Google Analytics accounts and properties.get_property_details: Returns details about a property.list_google_ads_links: Returns a list of links to Google Ads accounts for a property.
Run core reports 📙
run_report: Runs a Google Analytics report using the Data API.get_custom_dimensions_and_metrics: Retrieves the custom dimensions and metrics for a specific property.
Run realtime reports ⏳
run_realtime_report: Runs a Google Analytics realtime report using the Data API.
Related MCP server: Google Analytics MCP Server
Setup instructions 🔧
Setup involves the following steps:
Configure Python.
Configure credentials for Google Analytics.
Configure Gemini.
Configure Python 🐍
Enable APIs in your project ✅
Follow the instructions to enable the following APIs in your Google Cloud project:
Configure credentials 🔑
Configure your Application Default Credentials (ADC). Make sure the credentials are for a user with access to your Google Analytics accounts or properties.
Credentials must include the Google Analytics read-only scope:
https://www.googleapis.com/auth/analytics.readonlyCheck out Manage OAuth Clients for how to create an OAuth client.
Here are some sample gcloud commands you might find useful:
Set up ADC using user credentials and an OAuth desktop or web client after downloading the client JSON to
YOUR_CLIENT_JSON_FILE.gcloud auth application-default login \ --scopes https://www.googleapis.com/auth/analytics.readonly,https://www.googleapis.com/auth/cloud-platform \ --client-id-file=YOUR_CLIENT_JSON_FILESet up ADC using service account impersonation.
gcloud auth application-default login \ --impersonate-service-account=SERVICE_ACCOUNT_EMAIL \ --scopes=https://www.googleapis.com/auth/analytics.readonly,https://www.googleapis.com/auth/cloud-platform
When the gcloud auth application-default command completes, copy the
PATH_TO_CREDENTIALS_JSON file location printed to the console in the
following message. You'll need this for the next step!
Credentials saved to file: [PATH_TO_CREDENTIALS_JSON]Configure Gemini
Install Gemini CLI or Gemini Code Assist.
Create or edit the file at
~/.gemini/settings.json, adding your server to themcpServerslist.Replace
PATH_TO_CREDENTIALS_JSONwith the path you copied in the previous step.We also recommend that you add a
GOOGLE_CLOUD_PROJECTattribute to theenvobject. ReplaceYOUR_PROJECT_IDin the following example with the project ID of your Google Cloud project.{ "mcpServers": { "analytics-mcp": { "command": "pipx", "args": [ "run", "analytics-mcp" ], "env": { "GOOGLE_APPLICATION_CREDENTIALS": "PATH_TO_CREDENTIALS_JSON", "GOOGLE_PROJECT_ID": "YOUR_PROJECT_ID" } } } }
Try it out 🥼
Launch Gemini Code Assist or Gemini CLI and type /mcp. You should see
analytics-mcp listed in the results.
Here are some sample prompts to get you started:
Ask what the server can do:
what can the analytics-mcp server do?Ask about a Google Analytics property
Give me details about my Google Analytics property with 'xyz' in the namePrompt for analysis:
what are the most popular events in my Google Analytics property in the last 180 days?Ask about signed-in users:
were most of my users in the last 6 months logged in?Ask about property configuration:
what are the custom dimensions and custom metrics in my property?
Contributing ✨
Contributions welcome! See the Contributing Guide.
Available Tools
6 toolsget_account_summariesB
Retrieves information about the user's Google Analytics accounts and properties.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description bears full responsibility for behavioral disclosure. It merely states 'retrieves information,' which implies a read operation, but omits details about permissions, rate limits, data scope, or whether the result includes summaries or raw data. This leaves an agent with an incomplete behavioral picture.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence that immediately states the verb and object. Every word adds value, and there is no redundancy or filler. Perfectly concise for its purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity (no parameters, has output schema), the description covers the core functionality. However, it does not hint at the output structure or data fidelity (e.g., 'returns a list of accounts with their properties'), reducing completeness slightly. An output schema exists, so return value details are not required, but some additional context would improve agent understanding.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so the input schema is trivially complete (100% coverage). The description does not need to add parameter details. Per guidelines, a baseline of 4 is appropriate for zero-parameter tools.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses the specific verb 'retrieves' and names the resource ('user's Google Analytics accounts and properties'), making the purpose clear. It implicitly distinguishes from sibling tools like get_property_details (narrower scope) and run_report (different purpose), though it could be more explicit about the summarization aspect.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description offers no guidance on when to use this tool versus alternatives such as get_property_details or run_report. An agent would have to infer usage context solely from the tool name and sibling names, which is insufficient for clear decision-making.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_custom_dimensions_and_metricsRetrieves the custom Core Reporting dimensions and metrics for a specific propertyB
Returns the property's custom dimensions and metrics.
Args: property_id: The Google Analytics property ID. Accepted formats are: - A number - A string consisting of 'properties/' followed by a number
| Name | Required | Description | Default |
|---|---|---|---|
| property_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description must carry the full burden of behavioral disclosure. It only states that the tool returns custom dimensions and metrics, but does not mention any side effects, authentication requirements, rate limits, or whether the operation is read-only. For a simple read operation, this is minimally acceptable but lacking.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is short and front-loaded with the main purpose. It includes an 'Args' section for the parameter. However, it could be slightly more compact or structured, but it is efficient and avoids unnecessary words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool is simple with one required parameter and an output schema exists, the description adequately covers the parameter format. However, it does not mention what the output contains (e.g., a list of objects) or any prerequisites, though the output schema may cover return values. It is minimally complete but leaves some context unexplored.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema coverage is 0%, meaning the schema itself provides no description for property_id. The description compensates by explaining accepted formats (number or 'properties/' string), which adds meaning beyond the schema's type definition.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The title and description clearly state the tool retrieves custom dimensions and metrics for a specific property. It uses a specific verb ('returns') and resource ('custom dimensions and metrics'), and it is easily distinguished from sibling tools like get_account_summaries or run_reports.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is provided on when to use this tool versus alternatives. For example, it does not explain how it differs from get_property_details or when a user should choose this over other tools. The description only states what it does without context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_property_detailsGets details about a propertyA
Returns details about a property. Args: property_id: The Google Analytics property ID. Accepted formats are: - A number - A string consisting of 'properties/' followed by a number
| Name | Required | Description | Default |
|---|---|---|---|
| property_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description must disclose behavioral traits. It only states it returns details without explaining the nature of details, error handling, or side effects. The parameter format is explained, but overall transparency is minimal.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is extremely concise with two sentences, front-loading the purpose and then detailing the parameter. No unnecessary words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the presence of an output schema (though not shown), the description is adequate for a simple one-parameter tool. However, it lacks context on what 'details' includes and does not differentiate usage from siblings.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description adds meaningful semantics beyond the schema by describing both accepted formats (number or string with 'properties/' prefix) for property_id. Schema coverage is 0%, so this addition is valuable.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description 'Returns details about a property' clearly states the verb and resource. The context of the tool name and sibling tools (e.g., get_account_summaries, run_report) makes the specific domain (Google Analytics) obvious, distinguishing it effectively.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool versus alternatives like get_account_summaries or run_report. It does not specify scenarios or exclusions, leaving the agent without selection criteria.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_google_ads_linksList links to Google Ads accountsB
Returns a list of links to Google Ads accounts for a property.
Args: property_id: The Google Analytics property ID. Accepted formats are: - A number - A string consisting of 'properties/' followed by a number
| Name | Required | Description | Default |
|---|---|---|---|
| property_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries full burden. It only mentions returning a list, without disclosing side effects, read-only nature, authentication requirements, or behavior when no links exist.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Extremely concise: two sentences plus a clear args section. Purpose is front-loaded, no redundant information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the simplicity (one param, output schema exists), the description covers the basic purpose and parameter format, but lacks usage context and behavioral details, leaving some gaps for a complete agent understanding.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Although schema coverage is 0%, the description adds value by explaining accepted formats for 'property_id' (number or 'properties/' prefix), which is not obvious from the schema's 'anyOf' definition.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool returns a list of links to Google Ads accounts for a property, using specific verb 'Returns' and resource. It is distinguishable from siblings, which cover other aspects like account summaries or reports.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this tool over alternatives, nor any prerequisites or exclusions. The description only states what it does, missing context for agent decision-making.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
run_realtime_reportRun a Google Analytics realtime report using the Data APIA
Runs a Google Analytics Data API realtime report.See https://developers.google.com/analytics/devguides/reporting/data/v1/realtime-basics for more information.
Args:
property_id: The Google Analytics property ID. Accepted formats are:
- A number
- A string consisting of 'properties/' followed by a number
dimensions: A list of dimensions to include in the report. Dimensions must be realtime dimensions.
metrics: A list of metrics to include in the report. Metrics must be realtime metrics.
dimension_filter: A Data API FilterExpression
(https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1beta/FilterExpression)
to apply to the dimensions. Don't use this for filtering metrics. Use
metric_filter instead. The field_name in a dimension_filter must
be a dimension, as defined in the get_standard_dimensions and
get_dimensions tools.
For more information about the expected format of this argument, see
the run_report_dimension_filter_hints tool.
metric_filter: A Data API FilterExpression
(https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1beta/FilterExpression)
to apply to the metrics. Don't use this for filtering dimensions. Use
dimension_filter instead. The field_name in a metric_filter must
be a metric, as defined in the get_standard_metrics and
get_metrics tools.
For more information about the expected format of this argument, see
the run_report_metric_filter_hints tool.
order_bys: A list of Data API OrderBy
(https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1beta/OrderBy)
objects to apply to the dimensions and metrics.
For more information about the expected format of this argument, see
the run_report_order_bys_hints tool.
limit: The maximum number of rows to return in each response. Value must
be a positive integer <= 250,000. Used to paginate through large
reports, following the guide at
https://developers.google.com/analytics/devguides/reporting/data/v1/basics#pagination.
offset: The row count of the start row. The first row is counted as row
0. Used to paginate through large
reports, following the guide at
https://developers.google.com/analytics/devguides/reporting/data/v1/basics#pagination.
return_property_quota: Whether to return realtime property quota in the response.
## Hints for arguments
Here are some hints that outline the expected format and requirements
for arguments.
### Hints for `dimensions`
The `dimensions` list must consist solely of either of the following:
1. Realtime standard dimensions defined in the HTML table at
https://developers.google.com/analytics/devguides/reporting/data/v1/realtime-api-schema#dimensions.
These dimensions are available to *every* property.
2. User-scoped custom dimensions for the `property_id`. Use the
`get_custom_dimensions_and_metrics` tool to retrieve the list of
custom dimensions for a property, and look for the custom
dimensions with an `apiName` that begins with "customUser:".
### Hints for `metrics`
The `metrics` list must consist solely of the Realtime standard
metrics defined in the HTML table at
https://developers.google.com/analytics/devguides/reporting/data/v1/realtime-api-schema#metrics.
These metrics are available to *every* property.
Realtime reports can't use custom metrics.
### Hints for `date_ranges`:
Example date_range arguments:
1. A single date range:
[ {"start_date": "2025-01-01", "end_date": "2025-01-31", "name": "Jan2025"} ]
2. A relative date range using 'yesterday' and 'today':
[ {"start_date": "yesterday", "end_date": "today", "name": "YesterdayAndToday"} ]
3. A relative date range using 'NdaysAgo' and 'today':
[ {"start_date": "30daysAgo", "end_date": "yesterday", "name": "Previous30Days"}]
4. Multiple date ranges:
[ {"start_date": "2025-01-01", "end_date": "2025-01-31", "name": "Jan2025"}, {"start_date": "2025-02-01", "end_date": "2025-02-28", "name": "Feb2025"} ]
### Hints for `dimension_filter`:
Example dimension_filter arguments:
1. A simple filter:
{"filter": {"field_name": "eventName", "string_filter": {"match_type": 2, "value": "add", "case_sensitive": false}}}
2. A NOT filter:
{"not_expression": {"filter": {"field_name": "eventName", "string_filter": {"match_type": 2, "value": "add", "case_sensitive": false}}}}
3. An empty value filter:
{"filter": {"field_name": "source", "empty_filter": {}}}
4. An AND group filter:
{"and_group": {"expressions": [{"filter": {"field_name": "sourceMedium", "string_filter": {"match_type": 1, "value": "google / cpc", "case_sensitive": false}}}, {"filter": {"field_name": "eventName", "in_list_filter": {"values": ["first_visit", "purchase", "add_to_cart"], "case_sensitive": true}}}]}}
5. An OR group filter:
{"or_group": {"expressions": [{"filter": {"field_name": "sourceMedium", "string_filter": {"match_type": 1, "value": "google / cpc", "case_sensitive": false}}}, {"filter": {"field_name": "eventName", "in_list_filter": {"values": ["first_visit", "purchase", "add_to_cart"], "case_sensitive": true}}}]}} Notes:
The API applies the dimension_filter and metric_filter
independently. As a result, some complex combinations of dimension and
metric filters are not possible in a single report request.
For example, you can't create a `dimension_filter` and `metric_filter`
combination for the following condition:
(
(eventName = "page_view" AND eventCount > 100)
OR
(eventName = "join_group" AND eventCount < 50)
)
This isn't possible because there's no way to apply the condition
"eventCount > 100" only to the data with eventName of "page_view", and
the condition "eventCount < 50" only to the data with eventName of
"join_group".
More generally, you can't define a `dimension_filter` and `metric_filter`
for:
(
((dimension condition D1) AND (metric condition M1))
OR
((dimension condition D2) AND (metric condition M2))
)
If you have complex conditions like this, either:
a) Run a single report that applies a subset of the conditions that
the API supports as well as the data needed to perform filtering of the
API response on the client side. For example, for the condition:
(
(eventName = "page_view" AND eventCount > 100)
OR
(eventName = "join_group" AND eventCount < 50)
)
You could run a report that filters only on:
eventName one of "page_view" or "join_group"
and include the eventCount metric, then filter the API response on the
client side to apply the different metric filters for the different
events.
or
b) Run a separate report for each combination of dimension condition and
metric condition. For the example above, you'd run one report for the
combination of (D1 AND M1), and another report for the combination of
(D2 AND M2).
Try to run fewer reports (option a) if possible. However, if running
fewer reports results in excessive quota usage for the API, use option
b. More information on quota usage is at
https://developers.google.com/analytics/blog/2023/data-api-quota-management.
### Hints for `metric_filter`:
Example metric_filter arguments:
1. A simple filter:
{"filter": {"field_name": "eventCount", "numeric_filter": {"operation": 4, "value": {"int64_value": "10"}}}}
2. A NOT filter:
{"not_expression": {"filter": {"field_name": "eventCount", "numeric_filter": {"operation": 4, "value": {"int64_value": "10"}}}}}
3. An empty value filter:
{"filter": {"field_name": "purchaseRevenue", "empty_filter": {}}}
4. An AND group filter:
{"and_group": {"expressions": [{"filter": {"field_name": "eventCount", "numeric_filter": {"operation": 4, "value": {"int64_value": "10"}}}}, {"filter": {"field_name": "purchaseRevenue", "between_filter": {"from_value": {"double_value": 10.0}, "to_value": {"double_value": 25.0}}}}]}}
5. An OR group filter:
{"or_group": {"expressions": [{"filter": {"field_name": "eventCount", "numeric_filter": {"operation": 4, "value": {"int64_value": "10"}}}}, {"filter": {"field_name": "purchaseRevenue", "between_filter": {"from_value": {"double_value": 10.0}, "to_value": {"double_value": 25.0}}}}]}} Notes:
The API applies the dimension_filter and metric_filter
independently. As a result, some complex combinations of dimension and
metric filters are not possible in a single report request.
For example, you can't create a `dimension_filter` and `metric_filter`
combination for the following condition:
(
(eventName = "page_view" AND eventCount > 100)
OR
(eventName = "join_group" AND eventCount < 50)
)
This isn't possible because there's no way to apply the condition
"eventCount > 100" only to the data with eventName of "page_view", and
the condition "eventCount < 50" only to the data with eventName of
"join_group".
More generally, you can't define a `dimension_filter` and `metric_filter`
for:
(
((dimension condition D1) AND (metric condition M1))
OR
((dimension condition D2) AND (metric condition M2))
)
If you have complex conditions like this, either:
a) Run a single report that applies a subset of the conditions that
the API supports as well as the data needed to perform filtering of the
API response on the client side. For example, for the condition:
(
(eventName = "page_view" AND eventCount > 100)
OR
(eventName = "join_group" AND eventCount < 50)
)
You could run a report that filters only on:
eventName one of "page_view" or "join_group"
and include the eventCount metric, then filter the API response on the
client side to apply the different metric filters for the different
events.
or
b) Run a separate report for each combination of dimension condition and
metric condition. For the example above, you'd run one report for the
combination of (D1 AND M1), and another report for the combination of
(D2 AND M2).
Try to run fewer reports (option a) if possible. However, if running
fewer reports results in excessive quota usage for the API, use option
b. More information on quota usage is at
https://developers.google.com/analytics/blog/2023/data-api-quota-management.
### Hints for `order_bys`:
Example order_bys arguments:
1. Order by ascending 'eventName':
[ {"dimension": {"dimension_name": "eventName", "order_type": 1}, "desc": false} ]
2. Order by descending 'eventName', ignoring case:
[ {"dimension": {"dimension_name": "campaignName", "order_type": 2}, "desc": true} ]
3. Order by ascending 'audienceId':
[ {"dimension": {"dimension_name": "audienceId", "order_type": 3}, "desc": false} ]
4. Order by descending 'eventCount':
[ {"metric": {"metric_name": "eventValue"}, "desc": true} ]
5. Order by ascending 'eventCount':
[ {"metric": {"metric_name": "eventCount"}, "desc": false} ]
6. Combination of dimension and metric order bys:
[
{"dimension": {"dimension_name": "eventName", "order_type": 1}, "desc": false},
{"metric": {"metric_name": "eventValue"}, "desc": true},
]
7. Order by multiple dimensions and metrics:
[
{"dimension": {"dimension_name": "eventName", "order_type": 1}, "desc": false},
{"dimension": {"dimension_name": "audienceId", "order_type": 3}, "desc": false},
{"metric": {"metric_name": "eventValue"}, "desc": true},
]
The dimensions and metrics in order_bys must also be present in the report
request's "dimensions" and "metrics" arguments, respectively.| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| offset | No | ||
| metrics | Yes | ||
| order_bys | No | ||
| dimensions | Yes | ||
| property_id | Yes | ||
| metric_filter | No | ||
| dimension_filter | No | ||
| return_property_quota | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full burden. It discloses that the report is realtime, includes pagination, filter independence limitations, and optional quota return. However, it does not explicitly state whether the tool is read-only or any authentication requirements, though these are implicit.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is very long and includes repeated notes (e.g., the same filter limitation appears for both dimension_filter and metric_filter). While well-structured, it could be more concise. Every sentence adds some value, but the length impacts readability.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the complexity of 9 parameters, nested objects, and filter limitations, the description is thorough. It covers parameter formats, constraints, examples, API limitations, and links to external resources. The presence of an output schema does not reduce the need for description, and it meets that need fully.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate with detailed parameter explanations. It provides format, constraints, examples, and links for all parameters, including dimensions, metrics, filters, order_bys, and pagination. This fully compensates for the lack of schema documentation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states that the tool runs a Google Analytics Data API realtime report, specifying the resource (realtime report) and the type of data (realtime). It distinguishes itself from sibling tools like 'run_report', which handles non-realtime reports.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
While the description does not explicitly state 'use this for realtime data only' or provide alternatives, the name and title make it clear. The extensive hints and notes about filter limitations guide appropriate usage. The lack of explicit when-not guidance slightly reduces the score.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
run_reportRun a Google Analytics Data API report using the Data APIA
Runs a Google Analytics Data API report.Note that the reference docs at https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1beta all use camelCase field names, but field names passed to this method should be in snake_case since the tool is using the protocol buffers (protobuf) format. The protocol buffers for the Data API are available at https://github.com/googleapis/googleapis/tree/master/google/analytics/data/v1beta.
Args:
property_id: The Google Analytics property ID. Accepted formats are:
- A number
- A string consisting of 'properties/' followed by a number
date_ranges: A list of date ranges
(https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1beta/DateRange)
to include in the report.
dimensions: A list of dimensions to include in the report.
metrics: A list of metrics to include in the report.
dimension_filter: A Data API FilterExpression
(https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1beta/FilterExpression)
to apply to the dimensions. Don't use this for filtering metrics. Use
metric_filter instead. The field_name in a dimension_filter must
be a dimension, as defined in the get_standard_dimensions and
get_dimensions tools.
metric_filter: A Data API FilterExpression
(https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1beta/FilterExpression)
to apply to the metrics. Don't use this for filtering dimensions. Use
dimension_filter instead. The field_name in a metric_filter must
be a metric, as defined in the get_standard_metrics and
get_metrics tools.
order_bys: A list of Data API OrderBy
(https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1beta/OrderBy)
objects to apply to the dimensions and metrics.
limit: The maximum number of rows to return in each response. Value must
be a positive integer <= 250,000. Used to paginate through large
reports, following the guide at
https://developers.google.com/analytics/devguides/reporting/data/v1/basics#pagination.
offset: The row count of the start row. The first row is counted as row
0. Used to paginate through large
reports, following the guide at
https://developers.google.com/analytics/devguides/reporting/data/v1/basics#pagination.
currency_code: The currency code to use for currency values. Must be in
ISO4217 format, such as "AED", "USD", "JPY". If the field is empty, the
report uses the property's default currency.
return_property_quota: Whether to return property quota in the response.
## Hints for arguments
Here are some hints that outline the expected format and requirements
for arguments.
### Hints for `dimensions`
The `dimensions` list must consist solely of either of the following:
1. Standard dimensions defined in the HTML table at
https://developers.google.com/analytics/devguides/reporting/data/v1/api-schema#dimensions.
These dimensions are available to *every* property.
2. Custom dimensions for the `property_id`. Use the
`get_custom_dimensions_and_metrics` tool to retrieve the list of
custom dimensions for a property.
### Hints for `metrics`
The `metrics` list must consist solely of either of the following:
1. Standard metrics defined in the HTML table at
https://developers.google.com/analytics/devguides/reporting/data/v1/api-schema#metrics.
These metrics are available to *every* property.
2. Custom metrics for the `property_id`. Use the
`get_custom_dimensions_and_metrics` tool to retrieve the list of
custom metrics for a property.
### Hints for `date_ranges`:
Example date_range arguments:
1. A single date range:
[ {"start_date": "2025-01-01", "end_date": "2025-01-31", "name": "Jan2025"} ]
2. A relative date range using 'yesterday' and 'today':
[ {"start_date": "yesterday", "end_date": "today", "name": "YesterdayAndToday"} ]
3. A relative date range using 'NdaysAgo' and 'today':
[ {"start_date": "30daysAgo", "end_date": "yesterday", "name": "Previous30Days"}]
4. Multiple date ranges:
[ {"start_date": "2025-01-01", "end_date": "2025-01-31", "name": "Jan2025"}, {"start_date": "2025-02-01", "end_date": "2025-02-28", "name": "Feb2025"} ]
### Hints for `dimension_filter`:
Example dimension_filter arguments:
1. A simple filter:
{"filter": {"field_name": "eventName", "string_filter": {"match_type": 2, "value": "add", "case_sensitive": false}}}
2. A NOT filter:
{"not_expression": {"filter": {"field_name": "eventName", "string_filter": {"match_type": 2, "value": "add", "case_sensitive": false}}}}
3. An empty value filter:
{"filter": {"field_name": "source", "empty_filter": {}}}
4. An AND group filter:
{"and_group": {"expressions": [{"filter": {"field_name": "sourceMedium", "string_filter": {"match_type": 1, "value": "google / cpc", "case_sensitive": false}}}, {"filter": {"field_name": "eventName", "in_list_filter": {"values": ["first_visit", "purchase", "add_to_cart"], "case_sensitive": true}}}]}}
5. An OR group filter:
{"or_group": {"expressions": [{"filter": {"field_name": "sourceMedium", "string_filter": {"match_type": 1, "value": "google / cpc", "case_sensitive": false}}}, {"filter": {"field_name": "eventName", "in_list_filter": {"values": ["first_visit", "purchase", "add_to_cart"], "case_sensitive": true}}}]}} Notes:
The API applies the dimension_filter and metric_filter
independently. As a result, some complex combinations of dimension and
metric filters are not possible in a single report request.
For example, you can't create a `dimension_filter` and `metric_filter`
combination for the following condition:
(
(eventName = "page_view" AND eventCount > 100)
OR
(eventName = "join_group" AND eventCount < 50)
)
This isn't possible because there's no way to apply the condition
"eventCount > 100" only to the data with eventName of "page_view", and
the condition "eventCount < 50" only to the data with eventName of
"join_group".
More generally, you can't define a `dimension_filter` and `metric_filter`
for:
(
((dimension condition D1) AND (metric condition M1))
OR
((dimension condition D2) AND (metric condition M2))
)
If you have complex conditions like this, either:
a) Run a single report that applies a subset of the conditions that
the API supports as well as the data needed to perform filtering of the
API response on the client side. For example, for the condition:
(
(eventName = "page_view" AND eventCount > 100)
OR
(eventName = "join_group" AND eventCount < 50)
)
You could run a report that filters only on:
eventName one of "page_view" or "join_group"
and include the eventCount metric, then filter the API response on the
client side to apply the different metric filters for the different
events.
or
b) Run a separate report for each combination of dimension condition and
metric condition. For the example above, you'd run one report for the
combination of (D1 AND M1), and another report for the combination of
(D2 AND M2).
Try to run fewer reports (option a) if possible. However, if running
fewer reports results in excessive quota usage for the API, use option
b. More information on quota usage is at
https://developers.google.com/analytics/blog/2023/data-api-quota-management.
### Hints for `metric_filter`:
Example metric_filter arguments:
1. A simple filter:
{"filter": {"field_name": "eventCount", "numeric_filter": {"operation": 4, "value": {"int64_value": "10"}}}}
2. A NOT filter:
{"not_expression": {"filter": {"field_name": "eventCount", "numeric_filter": {"operation": 4, "value": {"int64_value": "10"}}}}}
3. An empty value filter:
{"filter": {"field_name": "purchaseRevenue", "empty_filter": {}}}
4. An AND group filter:
{"and_group": {"expressions": [{"filter": {"field_name": "eventCount", "numeric_filter": {"operation": 4, "value": {"int64_value": "10"}}}}, {"filter": {"field_name": "purchaseRevenue", "between_filter": {"from_value": {"double_value": 10.0}, "to_value": {"double_value": 25.0}}}}]}}
5. An OR group filter:
{"or_group": {"expressions": [{"filter": {"field_name": "eventCount", "numeric_filter": {"operation": 4, "value": {"int64_value": "10"}}}}, {"filter": {"field_name": "purchaseRevenue", "between_filter": {"from_value": {"double_value": 10.0}, "to_value": {"double_value": 25.0}}}}]}} Notes:
The API applies the dimension_filter and metric_filter
independently. As a result, some complex combinations of dimension and
metric filters are not possible in a single report request.
For example, you can't create a `dimension_filter` and `metric_filter`
combination for the following condition:
(
(eventName = "page_view" AND eventCount > 100)
OR
(eventName = "join_group" AND eventCount < 50)
)
This isn't possible because there's no way to apply the condition
"eventCount > 100" only to the data with eventName of "page_view", and
the condition "eventCount < 50" only to the data with eventName of
"join_group".
More generally, you can't define a `dimension_filter` and `metric_filter`
for:
(
((dimension condition D1) AND (metric condition M1))
OR
((dimension condition D2) AND (metric condition M2))
)
If you have complex conditions like this, either:
a) Run a single report that applies a subset of the conditions that
the API supports as well as the data needed to perform filtering of the
API response on the client side. For example, for the condition:
(
(eventName = "page_view" AND eventCount > 100)
OR
(eventName = "join_group" AND eventCount < 50)
)
You could run a report that filters only on:
eventName one of "page_view" or "join_group"
and include the eventCount metric, then filter the API response on the
client side to apply the different metric filters for the different
events.
or
b) Run a separate report for each combination of dimension condition and
metric condition. For the example above, you'd run one report for the
combination of (D1 AND M1), and another report for the combination of
(D2 AND M2).
Try to run fewer reports (option a) if possible. However, if running
fewer reports results in excessive quota usage for the API, use option
b. More information on quota usage is at
https://developers.google.com/analytics/blog/2023/data-api-quota-management.
### Hints for `order_bys`:
Example order_bys arguments:
1. Order by ascending 'eventName':
[ {"dimension": {"dimension_name": "eventName", "order_type": 1}, "desc": false} ]
2. Order by descending 'eventName', ignoring case:
[ {"dimension": {"dimension_name": "campaignName", "order_type": 2}, "desc": true} ]
3. Order by ascending 'audienceId':
[ {"dimension": {"dimension_name": "audienceId", "order_type": 3}, "desc": false} ]
4. Order by descending 'eventCount':
[ {"metric": {"metric_name": "eventValue"}, "desc": true} ]
5. Order by ascending 'eventCount':
[ {"metric": {"metric_name": "eventCount"}, "desc": false} ]
6. Combination of dimension and metric order bys:
[
{"dimension": {"dimension_name": "eventName", "order_type": 1}, "desc": false},
{"metric": {"metric_name": "eventValue"}, "desc": true},
]
7. Order by multiple dimensions and metrics:
[
{"dimension": {"dimension_name": "eventName", "order_type": 1}, "desc": false},
{"dimension": {"dimension_name": "audienceId", "order_type": 3}, "desc": false},
{"metric": {"metric_name": "eventValue"}, "desc": true},
]
The dimensions and metrics in order_bys must also be present in the report
request's "dimensions" and "metrics" arguments, respectively.| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| offset | No | ||
| metrics | Yes | ||
| order_bys | No | ||
| dimensions | Yes | ||
| date_ranges | Yes | ||
| property_id | Yes | ||
| currency_code | No | ||
| metric_filter | No | ||
| dimension_filter | No | ||
| return_property_quota | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so the description carries full burden. It discloses: snake_case field name requirement, pagination behavior, independent application of filters, limitations on complex filter combos, and quota considerations. It does not explicitly mention error handling or authentication, but these are less critical for a report tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is very long and contains redundancy (the Notes on filter limitations appear twice). While well-structured with sections and examples, it could be more concise. The sheer length may overwhelm, though justified for a complex tool with 11 parameters.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the complexity (11 params, 4 required, nested objects) and the presence of an output schema, the description covers parameter details, usage, limitations, alternatives, and provides examples. It does not detail return values (covered by output schema) but could mention relationship to run_realtime_report. Overall, very complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, yet the description provides extensive parameter documentation for all 11 parameters, including formats, constraints, examples, and links to external references. This fully compensates for the lack of schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it runs a Google Analytics Data API report. The title specifies 'Data API', distinguishing it from real-time reporting (sibling run_realtime_report). However, it does not explicitly contrast with other siblings like get_account_summaries or list_google_ads_links, which have different purposes.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description includes explicit guidance: 'Don't use this for filtering metrics. Use metric_filter instead.' and vice versa. It provides alternatives for complex filter combinations (options a and b) and references sibling tools for custom dimensions/metrics. It also explains pagination with limit/offset and references external guides.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
6 tool updates
v0.1.1- First observed
get_account_summaries - First observed
get_custom_dimensions_and_metrics - First observed
get_property_details - First observed
list_google_ads_links - First observed
run_realtime_report - First observed
run_report
TDQS
Each tool has a clearly distinct purpose: account summaries, custom dimensions/metrics, property details, Google Ads links, realtime reports, and standard reports. No overlap or confusion between tools.
All tools use consistent snake_case naming with appropriate verbs (get_, list_, run_) followed by specific nouns, making the pattern predictable and easy to understand.
With 6 tools, the server is well-scoped for Google Analytics operations, covering account/ property metadata, custom dimensions/metrics, Ads links, and both standard and realtime reporting.
While the core reporting and metadata tools are present, the server lacks tools to list standard dimensions and metrics, which are referenced in the report tool descriptions, creating a discoverability gap for agents.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
SEO & marketing toolkit for AI agents: GA4, Search Console, AdSense, GTM, PageSpeed, Trends.
Connect Google Analytics to ChatGPT. Query GA4 data in plain English and get instant insights.
Read and edit GA4, Search Console and Google Tag Manager from any MCP client. 29 tools.
Query your Betterlytics web analytics from AI agents: traffic, funnels, journeys, errors, uptime.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables interaction with Google Analytics APIs to fetch reports, manage properties, data streams, conversion events, and custom dimensions/metrics through OAuth2 authentication.636MIT
- AlicenseNot gradedqualityDmaintenanceEnables AI agents to interact with Google Analytics 4 data, providing tools for historical reporting, real-time activity monitoring, and property management. It supports secure service account authentication to access metrics like traffic summaries, user acquisition, and custom dimensions.MIT
- AlicenseAqualityCmaintenanceEnables LLMs to interact with Google Analytics Admin and Data APIs to retrieve account summaries, property details, and custom metrics. It allows users to run core and real-time reports to analyze website performance and configuration via natural language.71Apache 2.0
- AlicenseNot gradedqualityFmaintenanceEnables LLMs to interact with Google Analytics 4 data through the Google Analytics Data API, supporting standard reports, real-time data, and metadata retrieval.19MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/iclaudiumihaila/google-analytics-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server