How to use the Google Analytics MCP in OpenCode to query GA4
13 min readWritten by: Jonathan Reis on
GA4 in the browser is excellent for exploring reports, but repetitive questions become tedious quickly. This guide configures Google's official Analytics MCP in OpenCode and shows how to query properties, events, funnels, and realtime data without copying numbers from screens.

Opening Google Analytics in the browser is a good way to answer one question. You choose an account, find the right property, open a report, change the date range, add dimensions, adjust metrics, and copy the numbers somewhere you can compare them with last week. When the question changes slightly, the sequence starts again.
The problem is not the interface. It is useful for visual exploration. The friction starts when the same question must be answered repeatedly, explained to somebody else, or combined with context that lives outside GA4: a release, a campaign, an acquisition experiment, or a product change. A click sequence is not a query specification. Two people can open similar reports and leave with different numbers because they selected different properties, filters, or time zones.
That was the situation while configuring the official Google Analytics MCP Server for OpenCode. The benefit was not turning GA4 into a magical conversation. It was giving the agent tools that call the official APIs, discover the available properties, and run reports with explicit dimensions, metrics, and date ranges.
What changes when GA4 becomes a tool
The Model Context Protocol connects a client such as OpenCode to a server that exposes structured operations. Google’s official Analytics server uses the Admin API to discover accounts, properties, and configuration, and the Data API to run reports.
In the browser, a question usually becomes a chain of interactions. Through MCP, it can become a checkable sequence:
- Discover the accessible accounts and properties.
- Confirm the details of the selected property.
- Define the date range, dimensions, and metrics.
- Run the report.
- Interpret the response without losing the parameters that produced it.
That creates four practical gains:
- Repeatability: ask the same question tomorrow with the same criteria.
- Less context switching: do not copy data from the browser into a conversation or spreadsheet before analyzing it.
- Explicit scope: property, period, dimensions, and metrics remain visible in the request.
- Composition: compare the result with documentation, releases, campaigns, or other sources available to the agent.
MCP does not fix missing instrumentation, grant access to properties, or remove GA4 processing delay. It improves the boundary between the question and the API. If the app never sent page_view, MCP cannot invent that event. If the account lacks permission on the property, the report will still fail.
Understand the architecture before configuring it
The Google Cloud project used for OAuth is not the Analytics property. It hosts the OAuth client and enabled APIs. The authenticated identity determines which accounts and properties appear:
Authorized Google account
|
+-- Google Analytics account
+-- App property
+-- Website property
+-- Another shared property
A single authorization can query every property that the account is allowed to access. Adding another GA4 property tomorrow does not require another MCP server or OAuth client. The new property only needs to be accessible to the identity that is already authorized.
The server is local. OpenCode starts a Python process on your machine, and that process uses Application Default Credentials (ADC) to call Google. The OpenCode configuration does not need to contain a refresh token, client secret, or real property ID.
Step 1: install a local runner
The official repository publishes the analytics-mcp package to PyPI and documents pipx. This setup used uvx, which runs the package in an isolated environment and uses a local cache:
uvx --from analytics-mcp analytics-mcp
If you want to follow the project README exactly, use:
pipx run analytics-mcp
The important part is that the command can start an MCP server over stdin and stdout. You do not need to clone the repository or install the package inside every code project whose analytics you want to inspect.
The server is experimental. Tool names and configuration details can change. Pinning the package version can make sense for a team, while the example above follows the current PyPI package. After an upgrade, repeat the startup check and query one property again.
Step 2: prepare the Google Cloud project
Create or choose a Google Cloud project dedicated to the OpenCode client. A name such as mcp-google-analytics is enough; it does not need to match any app or property name.
Enable these APIs in the project:
These APIs belong to the project making the calls. They do not add that project as an administrator of your GA4 properties. Permissions still come from the Google account authenticated through OAuth.
Step 3: create a Desktop OAuth client
In the OAuth client configuration, configure the consent screen and create a client of type Desktop app.
For personal use with an external app in testing mode:
- Use an application name that identifies the local client.
- Add the Google account that actually has Analytics access as a test user.
- Download the client JSON and keep it outside the repository.
- Never paste that JSON into OpenCode, an issue, or a public post.
The scope needed for read-only reports is:
https://www.googleapis.com/auth/analytics.readonly
The project README shows gcloud auth application-default login with both analytics.readonly and cloud-platform. The second scope is used by the gcloud flow for quota and Google API authentication, but it is broader than Analytics read access. The consent screen makes the difference visible: it can appear as permission to view, edit, configure, and delete Google Cloud resources.
That distinction deserves an explicit decision. For a simple setup, follow the documented command and review the permissions shown before accepting. If least privilege is a requirement, do not approve a broader scope without your organization’s approval: use an OAuth runner approved by your team that produces ADC with the Analytics scope only, or ask an administrator for a service-identity alternative. The MCP does not need GA4 administration permission to run read-only reports.
With the documented gcloud path, the shape is:
gcloud auth application-default login \
--client-id-file=<your-client-json-file> \
--scopes=https://www.googleapis.com/auth/analytics.readonly,https://www.googleapis.com/auth/cloud-platform
The command writes credentials to the default ADC location. If you use a different file, set GOOGLE_APPLICATION_CREDENTIALS in the environment that starts OpenCode. The refresh token is a secret: restrict the file permissions and never commit it.
One authentication trap is specific to remote login. Do not paste the partial URL printed by --no-browser or --remote-bootstrap directly into a browser. That URL does not yet contain every redirect parameter and can return Missing required parameter: redirect_uri. The flow must be run by the gcloud helper process or by an OAuth tool that preserves the state and local redirect.
Step 4: add the server to OpenCode
In the global opencode.json or opencode.jsonc, add an entry under mcp:
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"google-analytics": {
"type": "local",
"command": ["uvx", "--from", "analytics-mcp", "analytics-mcp"],
"enabled": true,
"timeout": 60000,
},
},
}
If uvx is not on the PATH used by OpenCode, replace the first item with the executable’s absolute path. Preserve the other servers and existing fields. The shape matters: command is an argument array, and every server must declare type: "local".
Do not add GOOGLE_APPLICATION_CREDENTIALS just because the README shows that variable for another client. When ADC is in its default location, Google’s libraries discover it automatically. Use environment only when the credential lives at another path:
"environment": {
"GOOGLE_APPLICATION_CREDENTIALS": "{env:GOOGLE_APPLICATION_CREDENTIALS}"
}
After saving the configuration, quit and restart OpenCode. MCP configuration is loaded when the session starts; editing the file does not restart a server that is already running.
Make the first query in the right order
Start with discovery, not a report. A useful instruction is:
Use the Google Analytics MCP to list my accessible accounts and properties.
Show each property name and property ID. Do not guess IDs.
This calls get_account_summaries. Then confirm the property by name and request get_property_details to check its time zone, currency, and type. The display name is for humans; the property_id is the stable identifier used by reports.
After selecting the property, run a narrow report:
Use run_report for property <your-property-id>.
Query the two most recent calendar days available.
Dimensions: date and eventName.
Metrics: totalUsers, sessions, and eventCount.
Sort by ascending date and descending eventCount.
Show the parameters used and a short result table.
During this setup’s validation, an equivalent query returned one session, one user, one page view, and three events from a test property. The response also included the property’s configured time zone and currency. That is stronger evidence than merely seeing the server listed in OpenCode: the process started, authenticated, located the property, and received data from the Data API.
Use realtime and funnels for different questions
run_report is for historical periods. For people who are on the site now, request run_realtime_report and make it clear that the query must use realtime dimensions and metrics. Realtime does not accept exactly the same dimension set as a historical report.
For a journey, use run_funnel_report. Describe the events in order and ask for a breakdown by device, country, or another supported dimension. An acquisition funnel can be described like this:
Build a funnel for property <your-property-id> with these steps:
1. session_start
2. page_view
3. sign_up
4. purchase
Show users at each step and the drop-off rate between steps.
Do not ask the agent to invent a custom dimension. First call get_custom_dimensions_and_metrics and use only the names returned for that property. A dimension registered on another property is not automatically valid here.
Limits that still exist
MCP does not change GA4 behavior. Three limits should appear in any serious analysis:
- The last 48 hours: the Data API normally works with calendar dates. An exact rolling 48-hour window has an hourly boundary that the standard report may not express.
- Ingestion delay: recent events may not be visible in historical reports yet. Realtime and standard reports answer different questions.
- Permissions: the OAuth account needs access to the property. The Cloud project hosting the client does not grant that access.
Do not automatically treat a small number as a technical failure. A report with zero users can mean zero traffic, an incorrect filter, processing delay, or the wrong property. Ask the agent to rerun the query without filters, confirm the property, and show its parameters before concluding that instrumentation is broken.
Browser and MCP failure modes
The browser has an operational trap: it is easy to switch properties without noticing, especially when several properties have similar names. MCP reduces that risk when the flow starts with get_account_summaries, but it cannot remove the ambiguity from a prompt that only says “my website.” Include the name and confirm the ID.
MCP has a different trap: letting the agent choose dimensions and metrics without specifying them. A request such as “what happened recently?” can produce a polished answer that is difficult to reproduce. State the period, dimensions, metrics, ordering, and the time zone to use when presenting dates.
Authentication also benefits from separation. OAuth defines which account is acting. ADC defines where client libraries find the token. opencode.jsonc defines how the server starts. Putting all three, including secrets, in one configuration file makes the setup harder to debug and easier to leak.
The complete workflow
Adapt the placeholders to your environment:
# 1. Check the runner
uvx --from analytics-mcp analytics-mcp
# 2. Create ADC through the OAuth flow approved by your team
gcloud auth application-default login \
--client-id-file=<your-client-json-file> \
--scopes=https://www.googleapis.com/auth/analytics.readonly,https://www.googleapis.com/auth/cloud-platform
# 3. Set the project used for API configuration
gcloud config set project <your-cloud-project-id>
Then configure mcp.google-analytics, restart OpenCode, list the properties, confirm the details, and only then run the first run_report. This order keeps authentication, property selection, metric validity, and data interpretation from collapsing into one vague failure.
Checklist
- Create a Cloud project for the client without confusing it with a GA4 property.
- Enable the Admin API and Data API.
- Create a Desktop OAuth client and add the right account as a test user when required.
- Review the scopes before accepting consent.
- Keep ADC and the refresh token outside the repository.
- Use
uvxorpipxto start the official package. - Configure the server as a local MCP in OpenCode.
- Restart OpenCode after editing configuration.
- Start with
get_account_summariesand confirm theproperty_id. - Declare dimensions, metrics, date range, and ordering in every report.
- Distinguish historical data from Realtime.
- Validate a real API call before considering the setup complete.
The point of MCP is not to replace the GA4 interface. It removes repeated questions from the click path and puts them into a tool that the agent can call with explicit parameters. The browser remains the best place for visual exploration; MCP is better when a question needs to be repeated, compared, and explained without starting from zero.
Related postHow to validate Firebase DebugView events in a React Native release build9 min readWritten by: Jonathan Reis on