Tools Reference
You don't call these tools yourself: your AI client picks them from your question. This page helps you phrase questions, and explains what the answers are based on. All 12 tools are read-only.
| Tool | What it does |
|---|---|
get_account_summaries |
Lists the GA4 accounts and properties you can read, with property IDs |
get_property_details |
Property settings and data streams |
list_google_ads_links |
Linked Google Ads accounts |
list_property_annotations |
Reporting annotations |
get_custom_dimensions_and_metrics |
Custom (and optionally standard) dimensions and metrics |
run_report |
Standard GA4 report: dimensions, metrics, date ranges, filters |
run_realtime_report |
The last 30 minutes |
run_funnel_report |
Funnels from event steps |
check_duplicate_transactions |
Tag Pilot check: duplicated purchases |
check_traffic_attribution |
Tag Pilot check: Unassigned, (not set) and Direct traffic |
connect |
Connects this computer: returns a link and a code to approve |
connection_status |
Whether this computer is connected |
Property IDs are the numeric GA4 IDs, such as 123456789 (properties/123456789 works too). Measurement IDs like G-XXXXXXX don't work. get_account_summaries lists the IDs, so you can just name the property in your question.
Connection tools
Your AI client uses these to connect the computer to your free Tag Pilot account and Google. You don't need a terminal: just say "connect GA4", or ask a data question.
connect
Starts connecting (or reuses a connect already in progress) and returns a clickable link and a code like ABCD-1234. Open the link in any browser, check the code, approve, and allow Google access. Clients that support MCP URL elicitation also offer to open the link for you. If the computer is already connected, it says so. No parameters.
connection_status
Whether this computer is connected:
| Answer | Meaning |
|---|---|
connected |
Connected, with the device name shown on the GA4 MCP page |
waiting |
A sign-in is open; shows the link and code again |
not_connected |
Not connected yet; the AI client calls connect |
error |
Something failed, with the next step |
| Parameter | Type | Default | |
|---|---|---|---|
wait |
boolean | true |
Wait up to 25 seconds for an open sign-in to finish before answering |
Data tools called before the computer is connected return the same link and code, and the AI client retries your question once you've approved.
Property and setup tools
get_account_summaries
Every GA4 account and property the signed-in Google account can read: account ID and name, and for each property its ID, name and type. Your AI client usually calls this first. No parameters.
"Which GA4 properties do I have access to?"
get_property_details
A property's time zone, currency, industry, service level (standard or 360), create and update times, and its data streams with their web measurement IDs (G-…), default URLs or app IDs.
| Parameter | Type | |
|---|---|---|
property_id |
string or number | Required |
"What currency and time zone is the Shop property set to, and which measurement ID does its web stream use?"
list_google_ads_links
Google Ads accounts linked to a property: customer ID, whether ads personalization is on, and who created the link and when.
| Parameter | Type | |
|---|---|---|
property_id |
string or number | Required |
"Is Google Ads linked to this property? Which customer IDs?"
list_property_annotations
Reporting annotations: notes on dates or date ranges, such as releases, tracking changes or campaigns, including ones Google added. Handy to explain a jump in the data.
| Parameter | Type | |
|---|---|---|
property_id |
string or number | Required |
"Sessions dropped in early October. Are there any annotations around that time?"
get_custom_dimensions_and_metrics
The property's custom dimensions (with scope: event, user or item) and custom metrics, with the API names to use in reports, such as customEvent:payment_type or customUser:plan.
| Parameter | Type | Default | |
|---|---|---|---|
property_id |
string or number | Required | |
include_standard |
boolean | false |
Also list GA4's built-in dimensions and metrics (a long list: combine with search) |
search |
string | Case-insensitive filter on API name, UI name and category, e.g. item or revenue |
"Which custom dimensions does this property have? Is there one for the logged-in user type?"
Report tools
run_report
The main GA4 report (Data API runReport): metrics broken down by dimensions over one or more date ranges.
| Parameter | Type | Default | |
|---|---|---|---|
property_id |
string or number | Required | |
metrics |
list of strings | Required, 1–10. E.g. sessions, activeUsers, eventCount, keyEvents, ecommercePurchases, purchaseRevenue, engagementRate |
|
dimensions |
list of strings | none | Up to 9. E.g. date, eventName, sessionSourceMedium, sessionDefaultChannelGroup, pagePath, landingPage, country, deviceCategory, transactionId, itemName |
date_ranges |
list | last 28 days | Up to 4 ranges, see Dates below |
dimension_filter |
filter | Filters rows before aggregation, see Filters below | |
metric_filter |
filter | Filters rows after aggregation, e.g. only rows with more than 100 sessions | |
order_bys |
list | Sorting, see Sorting below | |
limit |
integer | 100 |
Rows to return, 1–100,000 |
offset |
integer | 0 |
Paging: pass next_offset from the previous result |
metric_aggregations |
list | Any of total, maximum, minimum, returned across all rows |
|
keep_empty_rows |
boolean | false |
Include rows whose metrics are all 0 |
currency_code |
string | property currency | ISO 4217 code, e.g. EUR |
return_property_quota |
boolean | false |
Include the property's remaining GA4 quota |
Standard dimension and metric names are in Google's API schema. Custom ones come from get_custom_dimensions_and_metrics.
"Top 10 landing pages by sessions in the last 7 days, with engagement rate."
run_realtime_report
Active users and events in the last 30 minutes (60 on GA4 360). Useful to check that a tracking change is live.
| Parameter | Type | Default | |
|---|---|---|---|
property_id |
string or number | Required | |
metrics |
list of strings | Required: activeUsers, eventCount, keyEvents, screenPageViews |
|
dimensions |
list of strings | none | Realtime dimensions only, e.g. eventName, unifiedScreenName, country, city, deviceCategory, platform, minutesAgo (full list) |
minute_ranges |
list | last 30 minutes | Up to 2 ranges of start_minutes_ago and end_minutes_ago (0–29 on standard properties, 0–59 on 360), e.g. last 5 vs last 30 minutes |
dimension_filter, metric_filter, order_bys, limit, return_property_quota |
As in run_report |
"I just published the GTM container. Are add_to_cart events coming in right now?"
run_funnel_report
How many users reach each step of a funnel and where they drop off (Data API runFunnelReport). Google's funnel API is still in alpha, so it can change or fail more often than other reports.
| Parameter | Type | Default | |
|---|---|---|---|
property_id |
string or number | Required | |
steps |
list | Required, 2–10 steps in order | |
date_ranges |
list | last 28 days | As in run_report |
open_funnel |
boolean | false |
Open funnel: users can enter at any step. Closed: everyone starts at step 1 |
breakdown_dimension |
string | Split each step by a dimension, e.g. deviceCategory or sessionDefaultChannelGroup |
|
breakdown_limit |
integer | 5 |
Max breakdown values, 1–15 |
next_action_dimension |
string | What users did after each step: eventName, pagePath, pageTitle, unifiedScreenName and a few more |
|
trended |
boolean | false |
Also return the funnel day by day |
dimension_filter |
filter | Limit the funnel to users matching these conditions, e.g. a country | |
limit, return_property_quota |
As in run_report |
Each step has:
| Field | |
|---|---|
name |
Label in the result, e.g. 1. View item |
event_name |
Event that completes the step, e.g. view_item, add_to_cart, begin_checkout, purchase |
event_params |
Conditions on that event's parameters: {"param": "payment_type", "op": "exact", "value": "card"}. Add "item_param": true for item parameters such as item_category |
conditions |
Conditions on dimensions, e.g. {"field": "pagePath", "op": "begins_with", "value": "/checkout"} |
directly_followed_by |
true: the next step must come directly after this one |
within_seconds |
This step must happen within N seconds of the previous one |
A step needs event_name, conditions or both. The empty operator isn't available in funnel steps. Each step in the result has activeUsers, funnelStepCompletionRate, funnelStepAbandonments and funnelStepAbandonmentRate.
"Show the funnel view_item → add_to_cart → begin_checkout → purchase for the last 30 days, split by device."
Tag Pilot tracking-health checks
These two checks are opinionated rules of thumb built from a few run_report calls. Every result shows what it measured, and the thresholds below are Tag Pilot's suggestions, not GA4 rules. They use the same GA4 quota as the equivalent reports.
check_duplicate_transactions
Counts purchase events per transaction_id to find purchases tracked more than once (usually thank-you page reloads, or the same order sent by both a browser tag and a server-side or Measurement Protocol tag), and purchases with no transaction_id at all. Uses 3 report calls.
| Parameter | Type | Default | |
|---|---|---|---|
property_id |
string or number | Required | |
date_range |
one date range | last 28 days | {"start_date": "…", "end_date": "…"} |
top |
integer | 20 |
How many duplicated transaction IDs to list, 1–200 |
The result has a summary (purchase events, distinct and duplicated transaction IDs, extra purchase events, duplicate rate, purchases without an ID), findings in plain words, and top_duplicates with each ID's purchase event count and revenue. It flags a duplicate rate of 2% or more, and 1% or more of purchases without an ID.
"Do we have duplicate purchases in GA4 this month?"
check_traffic_attribution
How sessions split by default channel group, with the attribution problems flagged. Uses 4 report calls.
| Parameter | Type | Default | |
|---|---|---|---|
property_id |
string or number | Required | |
date_range |
one date range | last 28 days | {"start_date": "…", "end_date": "…"} |
The result has total_sessions, the shares in percent, findings with likely causes, sessions per channel, and the top source / medium pairs of Unassigned sessions. It flags:
| Share of sessions | Flagged at | Usual causes |
|---|---|---|
| Unassigned | 5% or more | UTM mediums GA4 doesn't recognise, events without session source data |
(not set) source |
2% or more | Server-side or Measurement Protocol events without a matching browser session, missing client_id / session_id, consent mode cookieless pings |
(not set) landing page |
2% or more | Sessions that start without a page_view: events firing before the config tag, sessions restarted by a late event, server-side events |
| Direct | 40% or more | Redirects that strip UTMs or referrers, payment gateway self-referrals, missing cross-domain linking |
"Check traffic attribution on the Shop property for September and explain the Unassigned traffic."
Report inputs
Dates
A date is YYYY-MM-DD, today, yesterday or NdaysAgo (e.g. 7daysAgo, 28daysAgo). The default range is the last 28 full days: 28daysAgo to yesterday. Dates are in the property's time zone.
[{"start_date": "2026-09-01", "end_date": "2026-09-30"}]
Pass up to 4 ranges to compare periods. Each row then gets a dateRange column with the range's name (or date_range_0, date_range_1, … when unnamed):
[
{"start_date": "7daysAgo", "end_date": "yesterday", "name": "this_week"},
{"start_date": "14daysAgo", "end_date": "8daysAgo", "name": "last_week"}
]
Filters
A filter is a list of conditions that must all match. {"any": [...]} groups conditions where at least one must match, and "not": true negates a condition:
[
{"field": "eventName", "op": "exact", "value": "purchase"},
{"field": "country", "op": "in_list", "values": ["Poland", "Germany"], "not": true},
{"any": [
{"field": "pagePath", "op": "begins_with", "value": "/shop"},
{"field": "pagePath", "op": "partial_regex", "value": "product"}
]}
]
| Operators | Use |
|---|---|
exact, contains, begins_with, ends_with |
Text, with value |
full_regex, partial_regex |
Regular expression (RE2) matching the whole value or a part of it, with value |
in_list |
One of values (a list) |
eq, lt, lte, gt, gte |
Numbers, with a numeric value |
between |
Numbers from from to to, both included |
empty |
Value is empty or not set |
Text matching ignores case unless you add "case_sensitive": true. Dimension filters (dimension_filter) and metric filters (metric_filter) are separate, as in GA4: a metric filter such as [{"field": "sessions", "op": "gt", "value": 100}] applies after aggregation.
Sorting
[{"field": "sessions", "desc": true}]
The field must be one of the request's dimensions or metrics. For dimensions you can add "dimension_order": alphanumeric, case_insensitive_alphanumeric or numeric (for number-like dimensions stored as text).
Results
Reports come back as JSON your AI client reads for you:
{
"row_count": 214,
"returned": 100,
"next_offset": 100,
"rows": [{"date": "20261026", "sessionDefaultChannelGroup": "Organic Search", "sessions": 321}],
"currency_code": "EUR",
"time_zone": "Europe/Warsaw",
"notes": ["Subject to thresholding: …"]
}
next_offsetappears when more rows exist; the next call passes it asoffset.totals,maximumsandminimumsappear when requested withmetric_aggregations.notesexplain caveats: thresholding, sampling, values grouped into(other), or why a result is empty. See Troubleshooting.property_quotaappears withreturn_property_quota: true.