Analytics report
run_ga4_reportRuns a custom GA4 report with dimensions, metrics, filters, ordering, paging and comparison periods. Queries the GA4 Data API and flags sampling, thresholding or quota issues that skew results.
Instructions
Run a custom GA4 report with optional filters, ordering, paging and a comparison period.
Returns the property, the date range, the dimension and metric headers, one row per dimension combination (values as strings), row_count and total_row_count (plus next_offset while more rows remain). At least one dimension or metric is required. With compare_start/compare_end the comparison period is a second date range: every row then carries a dateRange value of "current" or "comparison", and date_ranges maps both labels to their dates. Invalid filters or ordering return "Validation failed" with details, before anything is sent. insights[] says when GA4 thresholded or sampled the data, grouped rows into "(other)", or the property is close to its API quota, because each makes numbers differ from the GA4 interface. Reports over time (a date-type dimension) or comparing periods also return the property's annotations in those dates, which often explain a jump in the rows.
Queries the GA4 Data API. Dimensions and metrics: https://developers.google.com/analytics/devguides/reporting/data/v1/api-schema
Tool call template
This tool declares no required parameters. Add optional parameters from the input schema as needed.
{
"id": 1,
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"arguments": {},
"name": "run_ga4_report"
}
}Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of rows returned (positive). | |
| offset | No | Zero-based row offset for paging; pass next_offset from the previous result to get the following page. | |
| metrics | No | GA4 metric API names, e.g. sessions, totalUsers, newUsers, screenPageViews, keyEvents, eventCount, bounceRate. | |
| order_by | No | Sort order as [{"field": <name>, "desc": true|false}]; each field must be one of the requested dimensions or metrics. | |
| dimensions | No | GA4 dimension API names, e.g. date, pagePath, sessionSource, sessionMedium, country, deviceCategory, eventName. Custom ones (customEvent:...) and every valid name are listed by list_ga4_dimensions_and_metrics. | |
| compare_end | No | End of the comparison period. | |
| date_ranges | No | Up to four named periods in one report, replacing date_range_start/end (not combinable with compare_start/end): [{"start": "2026-10-01", "end": "2026-10-31", "name": "october"}, {"start": "2025-10-01", "end": "2025-10-31", "name": "october_last_year"}]. Rows then carry a dateRange value with the name. Names default to range_1, range_2, ... | |
| property_id | No | GA4 property as "properties/123456789" (see get_account_summaries). If empty, uses the default from config. | |
| compare_start | No | Start of the comparison period (same formats as date_range_start). Set together with compare_end. | |
| currency_code | No | ISO 4217 code (e.g. "EUR") to report revenue and cost metrics in that currency instead of the property's own. | |
| metric_filter | No | Conditions on metrics, applied after aggregation, all of which must hold (AND). Each is {"field": <metric>, "op": <op>, "value": <number>}; op is EQUAL, LESS_THAN, LESS_THAN_OR_EQUAL, GREATER_THAN, GREATER_THAN_OR_EQUAL (or =, <, <=, >, >=), or BETWEEN with "value": [from, to]. Optional "not": true. Groups work as in dimension_filter. Example: [{"field": "sessions", "op": ">", "value": 100}]. | |
| date_range_end | No | End date, same formats as date_range_start. | today |
| date_range_start | No | Start date: "today", "yesterday", "NdaysAgo" (e.g. "7daysAgo", "28daysAgo", "90daysAgo"), or "YYYY-MM-DD". | 7daysAgo |
| dimension_filter | No | Conditions on dimensions, all of which must hold (AND). Each is {"field": <dimension>, "op": <match>, "value": <string>}; op is EXACT (default), BEGINS_WITH, ENDS_WITH, CONTAINS, FULL_REGEXP, PARTIAL_REGEXP, or IN_LIST with "values": [<strings>]. Optional keys: "case_sensitive" (default false) and "not": true to exclude matches. Example: [{"field": "sessionDefaultChannelGroup", "op": "EXACT", "value": "Paid Search"}]. For OR, put a group in the list: {"any_of": [<conditions>]} matches when any holds, {"all_of": [...]} when all hold; groups take "not" too and nest up to three levels. Example: [{"any_of": [{"field": "sessionSource", "value": "google"}, {"field": "sessionSource", "value": "bing"}]}]. |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||