ga4-overview
GA4 Overview
Read the Google Analytics 4 property linked to one Search Console site and present a traffic overview, the organic channel's share and trend, conversions, error pages and recommendations. The user's request may contain a property, a date range, a key event name (for example "form_submit"), a dimension to break down by, or a custom dimension name; honor what is given and resolve the rest below.
Workflow
-
Resolve the property. If the user's request or the conversation names a property, use it. Site URLs use GSC formats:
sc-domain:example.comorhttps://www.example.com/. Otherwise calllist_sitesand pick the obvious match. If several plausible properties exist, ask the user which one before continuing. Use the last 28 days compared with the previous period unless the user specifies dates. Every GA4 tool here defaults to the same settled window as the Search Console tools (the last 28 days ending about 3 days back), so omittingstartDateandendDateis the safe choice; when the user asks for explicit dates that reach into the last day or two, say that GA4 may still be processing them and treat the newest day as incomplete rather than as a drop. -
Confirm the GA4 link. Call
list_ga4_properties(no arguments). Readconnected:falsemeans the Google Analytics consent has not been granted in the GSC Wizard app for this account (accountnames it), andconnected: falsewithreauthRequired: truemeans it was granted but Google now rejects every Google account carrying it, so the user has to reconnect it on the Account page of the app. Find the property whoselinkedSiteUrlscontains the resolved site; linking happens in the app, not through the MCP, so if no property lists the site, say so and tell the user to link one in GSC Wizard.linkedSiteUrlsonly covers the GSC Wizard account this connection is authenticated as, so a link made from another account of the user shows as empty here. Readerrorsfor Google accounts whose properties are missing from the list and relay eachmessage. -
Traffic overview. Call
get_ga4_overviewwithsiteUrl; it always compares against the same-length period immediately before unless bothcomparisonStartDateandcomparisonEndDateare passed. ReadsummaryandprevSummary: sessions, active, total and new users, page views,engagementRate,averageSessionDuration(seconds),bounceRate, event count and key events. The two rates are 0-1 fractions, so multiply them by 100 for display and say so. WhencomparisonHasDatais false,prevSummaryis null because the data stream did not exist yet; report the current period alone instead of a change. SetincludeTimeseries: trueonly when the user wants the daily shape (timeseries, oldest day first). If the response carriessiteScope, the GA4 property is shared by several sites and every number is limited to this site's hostnames; say that once. -
Channel mix and the organic share. Call
query_ga4_reportwithdimension: "channel",comparisonStartDateandcomparisonEndDateset to the previous period (this tool only compares when both are given; without them theprev*fields are 0 andhasComparisonis false) andlimit: 25. Rows carry the metric names listed inmetrics(sessions, activeUsers, engagementRate and keyEvents for this dimension), sorted by sessions. Derive the organic share as the "Organic Search" row's sessions divided bysummary.sessionsfrom step 3, label it as derived, and report the change in organic sessions against the comparison. For the trend over days, call the tool again withdimension: "date"andfilters: { channel: ["Organic Search"] }; date breakdowns take no comparison range. Rows stop atlimit(truncatedandnotesay when more exist), so never sum rows to reach a total;get_ga4_overviewowns the totals. -
One more breakdown when the question asks for it.
query_ga4_reporttakes one dimension per call andsecondaryDimension(dateorhostName, different fromdimension) splits each row further, for exampledimension: "event"withsecondaryDimension: "date"shows on which days an event fired.filtersnarrow bychannel,sourceMedium,pagePath,landingPage,country,device,eventorhostName; to follow one event passfilters: { event: ["<eventName>"] }. Keeplimitat 25 unless the user wants more (max 1000). Pick the dimension from the question: