Skip to main content
Glama
google-ecommerce-mcp

google-ecommerce-mcp

google-ecommerce-mcp

One MCP server for the data an online shop decides from, for one shop or for many clients: GA4, Search Console, Merchant Center, Tag Manager, Indexing API, PageSpeed, the ad platforms Google Ads, Meta Ads and ChatGPT Ads, and the Meta pixel, catalog, Instagram and Page. It reads by default, and can also prepare controlled changes that you approve (pause a campaign, change a budget, submit a sitemap, add a tag in a workspace).

Ask your AI assistant "how much organic traffic did we get this month?", "which products are disapproved in Merchant Center?", "is GA4 loaded twice on my site?" or "what did each ad platform claim last month, and what does GA4 say?" and it answers from your own accounts. Out of the box it reads and reports and changes nothing. If you turn writing on for a client, the assistant can propose a change as a plan; nothing is sent until you approve it, and anything that costs money needs your approval in a terminal, outside the chat.

Built by MoonEyes, a small French shop selling 3D-printed tabletop terrain, because no existing MCP server covered GA4, Search Console and Merchant Center together.

Writing is off by default and has never been tested on a real account. The write tools exist in this version, but they were checked offline only, against fake answers written from each platform's documentation. Turning them on is opt-in per client and per platform, creations are always paused, and some risks cannot be removed (for example a Google Ads token or a ChatGPT Ads key cannot be limited to reading). Read docs/SECURITY.md and docs/WRITE.md before you turn it on, and try it first on a test account. New here? docs/QUICKSTART.md: your first client in 10 minutes.

The paid media connectors are new and tested offline only. The Google Ads, Meta Ads and ChatGPT Ads tools were checked against fake responses written from each platform's documentation. They have not been run against real ad accounts yet: compare the first figures with each platform's own interface. Details: docs/ADS.md.

tests license python PyPI MCP Registry

Architecture overview

Documentation

Page

What is in it

Quickstart

Your first client in 10 minutes: four commands

Several clients

The client registry clients.json, secrets per client, isolation, an agency example

Reading pilot

A pilot with one client and writing left off: access checklist, steps, how to check writing is off, how to revoke

Writing: plan, approve, apply

Turn writing on in 5 steps, three full examples, every lock, every refusal and its fix

Architecture

Components, the write path, a tool call step by step, design choices, sequence diagrams

Tool reference

Every tool (82): parameters, output, example questions

Setup, one service at a time

Which services you need, access checklist and e-mail template for a client, install order with doctor checks, revocation

Client reporting

Monthly report plan, KPI formulas, the report command and its input contract

Guided install prompts

A prompt to paste into Claude to be guided step by step (French)

Third-party notices

Code ported from OpenGSC (MIT); ideas credited to other open-source projects (no code copied)

Easy setup guide for ad platforms

Google Ads, Meta Ads, ChatGPT Ads: client e-mail, numbered steps, ids, checks, revocation

Paid media guide

Google Ads, Meta Ads, ChatGPT Ads: prerequisites step by step, GAQL rules, errors, what is untested

Google Cloud setup

OAuth client, APIs to enable, where to find each id

Security model

What writing changes, the real guardrails, the known limits, scopes, token storage, how to revoke

Troubleshooting

Every error we have met and its fix

Example prompts

Questions that work well, by use case

Client configs

Claude Desktop (one or two shops), Claude Code

Related MCP server: Google Search Console MCP Server

Why this one

  • One server for the whole picture. Traffic and sales (GA4), organic search (Search Console), the product feed (Merchant Center), the tracking setup (Tag Manager), site speed, and what the ad platforms say they delivered. Other MCP servers cover one or two of these.

  • Several clients, kept apart. An agency registers each client once (ids in a file, secrets in the OS keyring). Every call names its client, a foreign account id is refused, and one server process can be pinned to one client.

  • Read by default, controlled writing on request. Reading uses a per-platform allow-list with no write endpoint. Writing is off until you enable it per client and per platform, and then goes through one path only: plan (diff, dry run, signed token), your approval (in a terminal for anything that costs money, is irreversible or touches personal data), apply, and a journal. Creations are paused; there is no activation, deletion or publishing in this version.

  • Secrets kept out of the way. The Google token goes to your OS keyring (Windows Credential Manager, macOS Keychain or Secret Service). The Google Ads token is a separate keyring entry because its scope can write. Meta and ChatGPT Ads secrets go to the OS keyring from a hidden prompt (an environment variable also works), never on the command line or in a URL.

  • Answers a model can read correctly. Reports return the top rows plus totals over everything, the unit and definition of each metric, dates resolved in the account's timezone with a flag when the last days can still change, and the attribution windows each ad platform used.

  • Honest about what it does not know. Ad platforms count conversions their own way. The tools say so in every answer instead of adding up numbers that should not be added.

  • No third party. Requests go straight from your machine to Google, Meta and OpenAI. Nothing goes through a MoonEyes server.

How it compares

Checked on 2026-10-18 from each project's public page; they change fast, so check before you decide.

Project

License

Scope

Writing

googleanalytics/google-analytics-mcp (official)

Apache-2.0

GA4

reads only

googleads/google-ads-mcp (official)

Apache-2.0

Google Ads

reads only

Meta Ads MCP (official, hosted by Meta, beta)

closed

Meta Ads

yes, hosted by Meta

pipeboard-co/meta-ads-mcp

BUSL

Meta Ads

yes

stape-io/google-tag-manager-mcp-server

Apache-2.0

Tag Manager

read and write

RoyAzran/mcp-ads

MIT

12+ ad and analytics platforms

see its docs

This project

MIT

GA4, Search Console, Merchant Center, Tag Manager, PageSpeed, Google Ads, Meta Ads, ChatGPT Ads

off by default, plan, approval, journal, rollback; never tested on a real account

Where this one fits: you run several shops or clients from one self-hosted server and want every change shown as a diff and approved before it is sent. If you need one Google product only, or a hosted service with nothing to install, the official servers above are the better choice.

What you can ask

Each case gives the question, the tools the assistant usually calls, what you learn, and the decision it supports. The decision stays yours: by default the server shows data and changes nothing, and any change it prepares needs your approval. Ready-to-paste prompts are in examples/PROMPTS.md.

Traffic, search, feed, tracking

  1. Where do visits and sales come from? "Sessions, purchases and revenue by channel, this month vs. last month." Tools: ga4_report. You learn which channels bring revenue and which only bring visits. Decision: where to put the next hour or euro.

  2. Which searches are one push away from page one? "Queries ranking 5 to 15 with more than 100 impressions, and their landing page." Tools: gsc_performance. You learn which pages already earn impressions but few clicks. Decision: which titles, descriptions and internal links to rewrite first.

  3. Which disapproved products still get visits? "Products disapproved in Merchant Center that still receive organic clicks." Tools: merchant_product_issues, gsc_performance. You learn which feed errors hit pages people still visit. Decision: fix those products before the rest.

  4. Is the tracking trustworthy? "Is GA4 loaded twice? Does the purchase tag fire once? Is the workspace the same as the live version?" Tools: gtm_inventory, ga4_realtime. You learn whether purchases or page views may be double counted and whether unpublished changes exist. Decision: publish, remove a duplicate tag, or leave it.

  5. Preparing a redesign. "Which landing pages earn money and organic clicks, which will need a 301, and what is today's speed baseline?" Tools: ga4_report (dimension landingPage), gsc_performance, gsc_moves, gsc_opportunities, gsc_inspect_url, pagespeed. You learn which URLs to preserve, which redirects to plan, and the before-numbers to compare with after. Decision: the redirect map and what must not change.

Paid media (needs the connectors below)

  1. Do the platforms agree with GA4? "Compare the conversions of Google Ads, Meta and ChatGPT Ads with GA4 for last month." Tools: ads_overview, ga4_report. You learn how far each platform's claim is from what GA4 recorded. Decision: which figure to trust less, and which attribution settings to review in that platform's interface.

  2. What does each platform's ROAS look like next to real revenue? "Reported ROAS per platform vs. GA4 revenue for the same days." Tools: ads_overview, ga4_report. You learn the value each platform claims and the revenue GA4 saw. The server does not compute an overall return on ad spend (MER): you compare the two yourself. Decision: whether the claimed values are plausible together.

  3. Which campaigns spend without a recorded purchase? "Campaigns with spend and no purchase attributed, and what GA4 shows for the same campaign names." Tools: gads_performance or meta_insights, ga4_report (dimension sessionCampaignName). You learn which campaigns spend while neither the platform nor GA4 shows a sale. Decision: pause, fix the tracking or wait, done by you in the ad platform.

Why platform numbers differ. Meta defaults to a 7-day click plus 1-day view window, ChatGPT Ads, as this server requests it by default, to 30-day click plus 1-day view, and Google Ads to the setting of each conversion action. Platforms attach a conversion to different dates, count the same order independently, and may report modelled conversions when visitors decline cookies (Consent Mode). GA4 adds its own thresholds. What the tools cannot tell you: whether an ad caused a sale (incrementality), your real number of orders (your shop's back office is not read), or your consent rate.

Real findings

Findings from MoonEyes' own accounts and from one anonymised small-business account. They show the kind of problem the data revealed, not a promised result. Each states its period and how it was measured. They are single cases, not a benchmark, and a fix that coincides with a better number is a correlation, not a guarantee. The repository holds no raw export behind these figures, so they cannot be re-checked from here.

Finding

Period

Measured by

Merchant Center: 2,544 listings, 112 disapproved. 224 "weight too high" refusals came from a grams-to-kilograms unit error in the feed (packs sent as about 2 tonnes), since corrected. One false "alcoholic drink" refusal was caused by a product name and went away after renaming 3 products. A duplicate feed source created by the Google for WooCommerce plugin was removed.

Audit of 1-2 June 2026 (MoonEyes)

Merchant Center product statuses and feed sources (the same kind of data merchant_product_issues and merchant_data_sources return; no export of the audit is kept in this repository)

A purchase counted twice: the same Google Ads conversion id was sent both by a WordPress snippet and by Google Tag Manager. The snippet was disabled and GTM stays the single source. The number of gtag occurrences in the served HTML went from 18 to 12 on one page and from 6 to 3 on another.

2 June 2026 (MoonEyes)

Counting gtag occurrences in the served HTML

GA4 over-counted conversions: 265 conversions for 201 sessions, because phone, e-mail and contact clicks were marked as key events.

The 28 days before the 1-2 June 2026 audit (MoonEyes)

GA4 conversions and sessions (the check ga4_key_event_audit automates)

Search Console: 0 clicks and 708 submitted URLs for 0 indexed, the starting point of an indexing work item.

1 June 2026 (MoonEyes)

Search Console

A Google Ads account showed 96 conversions at EUR 2.16 each for 10 real bookings. Real cost: EUR 207.57 / 10 = about EUR 20.76 per booking, 9.6 times the displayed figure. Cause: page_view and a page event were marked as key events under a target-CPA bid strategy; fixed by keeping only the booking event. Small local-services business, anonymised.

26 August to 22 September 2026

Google Ads console (read in the Ads interface, not with these tools)

Tools

82 tools in total. Full parameters and outputs: docs/TOOLS.md. Most only read. The *_plan_* tools prepare a change and write nothing. Only four tools write, and only for a client where writing is on: gads_apply, meta_apply, openai_ads_apply, google_apply.

Platform

Reads

Prepares a change (plan)

What the plans can do (all behind the locks of WRITE.md)

All

server_status, clients_list, client_profile, client_check, plan_get, plan_list, audit_log, ads_overview

rollback_plan

Undo a plan with a new plan

GA4

ga4_report, ga4_compare, ga4_key_event_audit, ga4_realtime, ga4_properties, ga4_custom_definitions, ga4_key_events

ga4_plan_key_event_create, ga4_plan_custom_dimension_create

Create a key event or a custom dimension

Search Console

gsc_performance, gsc_moves, gsc_opportunities, gsc_inspect_url, gsc_sitemaps, gsc_sites

gsc_plan_sitemap_submit

Submit a sitemap

Merchant Center

merchant_data_sources, merchant_product_issues, merchant_report_query, merchant_products, merchant_account_issues

merchant_plan_product_patch

Change title, description, link, availability or price of a product

Tag Manager

gtm_inventory, gtm_workspace_status, gtm_get_tag, gtm_get_trigger, gtm_get_variable, gtm_versions

gtm_plan_workspace_create, gtm_plan_tag_upsert, gtm_plan_trigger_upsert, gtm_plan_variable_upsert, gtm_plan_quick_preview

Edit a non-default workspace. Nothing goes live: no version, no publish

Indexing, PageSpeed

indexing_status, pagespeed

none

none

Google Ads

gads_accounts, gads_performance, gads_query, gads_conversion_actions

gads_plan_pause_entities, gads_plan_budget_change, gads_plan_add_negatives, gads_plan_create_campaign

Pause, daily budget, negative keywords, one new Search campaign (paused)

Meta ads

meta_ad_accounts, meta_insights, meta_campaigns, meta_adsets, meta_ads_list

meta_plan_pause, meta_plan_budget_change, meta_plan_create_campaign, meta_plan_create_adset, meta_plan_create_ad

Pause, daily budget, new campaign, ad set and ad (paused)

Meta pixel, catalog, Instagram, Page

meta_pixel_health, meta_dataset_quality, meta_catalog_diagnostics, meta_catalog_products, meta_ig_insights, meta_page_insights

meta_eco_plan_catalog_item_update

Price, sale price, availability, stock of one catalog item

ChatGPT Ads

openai_ads_account, openai_ads_insights, openai_ads_conversions, openai_ads_campaigns, openai_ads_ad_groups, openai_ads_ads

openai_ads_plan_pause, openai_ads_plan_budget_change, openai_ads_plan_create_campaign

Pause, daily budget, new campaign (paused)

What the main read tools answer:

Tool

Service

What it answers

ga4_report

GA4

Any report: channels, landing pages, purchases, revenue, by period

ga4_key_event_audit

GA4

Which events are key events, and whether they inflate conversions (more key events than sessions, page_view or contact clicks marked as key)

gsc_performance

Search Console

Clicks, impressions, CTR, position by query, page, country, device, date

gsc_opportunities

Search Console

Queries or pages ranking 5 to 15 with real impressions, and those with impressions but no clicks

gsc_inspect_url

Search Console

Is this URL indexed, which canonical did Google pick, last crawl

merchant_product_issues

Merchant Center

Products with disapprovals or warnings, all pages

gtm_inventory

Tag Manager

Tags, triggers, variables, live version

pagespeed

PageSpeed Insights

Lighthouse performance and SEO scores, Core Web Vitals

gads_performance

Google Ads

Spend, clicks, conversions, value, ROAS by account, campaign or ad group

gads_query

Google Ads

One read-only GAQL SELECT on reporting resources

meta_insights

Meta Ads

Spend, reach, purchases, value, ROAS by level, with breakdowns

openai_ads_insights

ChatGPT Ads

Impressions, clicks, spend, conversions, attributed sales

ads_overview

Google Ads, Meta, ChatGPT Ads

The three platforms side by side for one period

Paid media connectors

Optional. Configure one, two or all three; the others answer not_configured. The table lists the original reading tools; the full list, with the plan tools, is above.

Platform

Tools

You need

Google Ads

gads_accounts, gads_performance, gads_query

A customer id (GADS_CUSTOMER_ID), a manager id if you use one, and a separate authorization: google-ecommerce-mcp setup-ads --client-secret client_secret.json. No developer token (Google ended them on 9 September 2026)

Meta Ads

meta_ad_accounts, meta_insights

A system user token with only ads_read (google-ecommerce-mcp set-secret meta-access-token) and META_AD_ACCOUNT_ID

ChatGPT Ads

openai_ads_account, openai_ads_insights, openai_ads_conversions

An advertiser API key from Ads Manager (google-ecommerce-mcp set-secret openai-ads-key). One key is one account

All

ads_overview

At least one of the above

Step by step, with the GAQL rules, every error and the known limits: docs/ADS.md.

Attribution warning. Each platform attributes conversions independently, with its own windows, dates and model, so the same order can be counted by several of them. The sum of the platforms' conversions is not deduplicated and overstates real orders. ads_overview repeats this in every answer. Read the figures as "what each platform claims", and compare them with GA4 and, outside this server, with your orders.

Reads by default, with one caveat. The Google Ads permission (adwords) can write and Google offers no read-only version. Without writing turned on, the server only sends read requests, but the token itself could write, so it is stored apart from your other Google token. ChatGPT Ads documents no read-only key either, and the same key serves reading and writing. See Security notes.

Tested offline only, reading and writing. All behaviour was checked against fake responses; real-account trials are still to do, and no write has ever been sent to a real account. Not yet confirmed: the timezone ChatGPT Ads returns with time_granularity=none, Meta's longer view windows (7d_view, 28d_view; the tool does not offer them), and whether a ChatGPT Ads key can be limited to reading.

Client reporting

google-ecommerce-mcp report turns the tools' JSON results into one static HTML file in your client's brand (name, logo, accent colour), printable to PDF. It needs no network and no configured service, shows comparisons with the previous month and last year, and never invents a cause: a cause appears only if you supply it.

# the assistant runs the tools for each period and saves their raw JSON; you assemble report.json from them
google-ecommerce-mcp report --input report.json --output report.html --brand-name "Client name" --accent "#1F6F5B" --logo logo.png
# open report.html in a browser, then Ctrl+P > Save as PDF

The plan, the input contract, the colour rules, the KPI formulas and common mistakes are in docs/REPORTING.md; a ready prompt is in examples/PROMPTS.md. Tested on sample data only, not yet on real client accounts. Margin, targets and annotations come from you, and some figures (impression share, Shopping product reports, MER) need extra GAQL or a calculation by the assistant.

Who is it for

  • Shop owner. You want straight answers (what sold, what is broken, which ads spend for nothing) without opening six dashboards. Install, ask in plain language, decide yourself.

  • Agency. You work for several clients. One install, one registry (docs/MULTI-CLIENT.md), the same checks each time, attribution caveats written into the answers you hand to a client, and writing turned on only for the clients and platforms you choose.

  • Developer. You want a small, readable, tested server: plain HTTP calls, per-platform allow-lists, one write path, structured errors. Pull requests welcome (see Contributing).

What it will not do

  • No change without a plan you can read. By default it writes nothing. With writing on for a client, it still cannot activate a paused campaign, delete or archive anything, publish a Tag Manager container, set a bid amount or choose a bidding strategy (a new Google Ads campaign gets a fixed manual CPC with no bid amount), or upload conversions and customer lists in this version. Everything it creates is paused. To do those, use the platform's own interface.

  • No change that costs money without you at a terminal. Budgets, new campaigns and price changes are applied only after you run google-ecommerce-mcp approve yourself. This does not protect you from an assistant that has a shell on your machine (see docs/SECURITY.md).

  • No causal attribution. It reports what each platform and GA4 recorded. It cannot say whether an ad caused a sale (incrementality).

  • No real order count. Your shop's back office (WooCommerce, Shopify...) is not read, so it cannot tell you actual orders, margins or returns. It does not know your consent rate either.

  • No deduplicated conversions, no currency conversion. It will not merge the platforms' conversions into one "true" number, and it adds spends only when they share one currency.

Quick install

Create your Google OAuth client first (step 1 below), then run the installer. It installs uv if needed, asks your ids, opens the Google consent screen and adds the server to Claude Desktop (your previous config is backed up). It installs the exact package version it was released with (google-ecommerce-mcp==0.6.0).

Recommended: download, read, run. The URLs name an exact commit, not a branch, so the script cannot change under you.

Windows (PowerShell):

Invoke-WebRequest https://raw.githubusercontent.com/MoonEyes/google-ecommerce-mcp/54705d4dd1a4b34b387a682c13de164210892352/install.ps1 -OutFile install.ps1
Get-Content .\install.ps1            # read it
(Get-FileHash .\install.ps1 -Algorithm SHA256).Hash   # compare with the SHA-256 below
.\install.ps1

macOS / Linux:

curl -LsSf -o install.sh https://raw.githubusercontent.com/MoonEyes/google-ecommerce-mcp/54705d4dd1a4b34b387a682c13de164210892352/install.sh
cat install.sh                       # read it
shasum -a 256 install.sh             # compare with the SHA-256 below
sh install.sh

SHA-256 of the pinned scripts:

  • install.ps1: aa697734ffcd71fd063ebb5ac6e6996a29572582ac7f18d53566082723265db0

  • install.sh: 3849a64501ed954ec5a79ecaaa29c8c79621bfe0c8bd20c758179feb3fc85aba

One line, if you accept to run it without reading (same pinned commit; this way the SHA-256 is not checked):

irm https://raw.githubusercontent.com/MoonEyes/google-ecommerce-mcp/54705d4dd1a4b34b387a682c13de164210892352/install.ps1 | iex
curl -LsSf https://raw.githubusercontent.com/MoonEyes/google-ecommerce-mcp/54705d4dd1a4b34b387a682c13de164210892352/install.sh | sh

The installer has an optional Paid media step (Google Ads, Meta Ads, ChatGPT Ads); skip it with --skip-ads. It never takes a secret as an argument: Google Ads uses the browser consent (the same OAuth client file, a separate token), and the Meta token and ChatGPT Ads key are typed at a hidden prompt into the OS keyring. The Claude Desktop config only receives non-secret ids. Non-secret options: --gads-customer-id (exactly 10 digits, dashes allowed), --gads-login-customer-id, --meta-account-id (3 to 20 digits), and --corporate-proxy (sets ADS_TRUST_ENV=1; it is enough on its own to add it to an existing entry). All checks run before any consent or secret prompt; a conflicting value stops with exit code 3 and changes nothing, and --force replaces a value but never deletes a variable. With --yes, ChatGPT Ads is skipped (no id to give): add it interactively (install --skip-auth) or with set-secret openai-ads-key. The PageSpeed key is read from --pagespeed-key (not recommended: it stays in your shell history), else PAGESPEED_API_KEY, else a hidden prompt.

Guided install. To be walked through it one step at a time, paste examples/INSTALL-PROMPT.md (English) or INSTALL-PROMPT.fr.md (French) into Claude. Install one service at a time and the access checklist for your client are in docs/SETUP.md.

Then quit Claude Desktop completely and reopen it. To pass options, save the script first, for example .\install.ps1 --ga4 123456789 --gsc sc-domain:example.com --client-secret client_secret.json. Run google-ecommerce-mcp install --help for every option. Maintainers: each release bumps the version in both scripts, then refreshes the commit in these URLs and the checksums (tests/test_installer_scripts.py fails until they match).

Setup, step by step

If you used the quick install, you only need step 1. The steps below are the manual path.

1. Google Cloud (once, about 10 minutes)

Full walkthrough with every click explained: docs/SETUP-GOOGLE-CLOUD.md. Short version:

  1. In Google Cloud Console, create or pick a project.

  2. Enable the APIs you need: Google Analytics Data API, Google Analytics Admin API, Google Search Console API, Merchant API, Tag Manager API, Web Search Indexing API, PageSpeed Insights API.

  3. Configure the OAuth consent screen (External, add yourself as a test user).

  4. Create an OAuth client of type Desktop app and download its JSON file.

  5. Merchant API only: register your Cloud project with your Merchant Center account.

  6. Optional: create an API key restricted to PageSpeed Insights (the anonymous quota is shared and often exhausted).

2. Install and authorize

# with uv (recommended): nothing to install, uvx fetches the package from PyPI
uvx google-ecommerce-mcp setup --client-secret path/to/client_secret.json --with-merchant
# read scopes only by default; --with-merchant / --with-indexing add the write-capable ones you need

# or with pip
pip install google-ecommerce-mcp
google-ecommerce-mcp setup --client-secret path/to/client_secret.json

Latest development version: uvx --from git+https://github.com/MoonEyes/google-ecommerce-mcp google-ecommerce-mcp.

Your browser opens the Google consent screen. The token is then stored in your OS keyring. Check everything with google-ecommerce-mcp check.

Check each service with doctor:

google-ecommerce-mcp doctor                          # offline; without a registry: Service, Set up, Secret, Token, Status, Account; with one: Client, Platform, Ids, Read, Write, On, Status, Account, Next (plus Live with --live)
google-ecommerce-mcp doctor --only gads --live       # one service, plus one minimal read call
google-ecommerce-mcp doctor --live --json            # no secret in the output; ids masked (123***890)

--client <name> limits it to one client of the registry. --only takes ga4,gsc,merchant,gtm,pagespeed,gads,meta,openai (comma-separated). doctor reads this shell's environment and the server entry of your Claude Desktop config (--config and --name point it elsewhere). The table is followed by "To fix" (the exact command for each problem), "Not set up", a Result: line and a Next command:. Exit code 0 means all configured services work, 1 that a configured service fails, 2 that nothing is configured. --live does not test PageSpeed (it is shown as skipped: it needs a page address and about 30 seconds); ask the assistant to run pagespeed instead.

Paid media (optional)

Set up Google Ads with google-ecommerce-mcp setup-ads --client-secret client_secret.json (or install with --gads-customer-id), Meta with google-ecommerce-mcp set-secret meta-access-token plus the ad account id (install --yes --skip-auth --meta-account-id <id>), ChatGPT Ads with google-ecommerce-mcp set-secret openai-ads-key, then check each with doctor --only <service> --live. Prerequisites: docs/ADS.md. Overall procedure, access checklist and an e-mail template for your client: docs/SETUP.md.

3. Add it to your MCP client

Claude Desktop (claude_desktop_config.json):

{
  "mcpServers": {
    "google-ecommerce": {
      "command": "uvx",
      "args": ["google-ecommerce-mcp"],
      "env": {
        "GA4_PROPERTY_ID": "123456789",
        "GSC_SITE_URL": "sc-domain:example.com",
        "MERCHANT_ACCOUNT_ID": "1234567890",
        "GTM_CONTAINER_ID": "GTM-XXXXXXX",
        "PAGESPEED_API_KEY": ""
      }
    }
  }
}

Claude Code:

claude mcp add google-ecommerce -e GA4_PROPERTY_ID=123456789 -e GSC_SITE_URL=sc-domain:example.com \
  -e MERCHANT_ACCOUNT_ID=1234567890 -e GTM_CONTAINER_ID=GTM-XXXXXXX \
  -- uvx google-ecommerce-mcp

Every variable is optional: a tool for a service you did not configure simply answers not_configured. These variables describe one shop (legacy mode). For several clients, create a registry instead and leave the ids out of this config: docs/QUICKSTART.md, docs/MULTI-CLIENT.md. Once a registry exists, the id variables below are ignored. For the ad platforms, put ids in the config (GADS_CUSTOMER_ID, META_AD_ACCOUNT_ID) and secrets in the keyring with the commands below the table.

Variable

Example

Used by

GA4_PROPERTY_ID

123456789 (numeric property id)

GA4 tools

GSC_SITE_URL

sc-domain:example.com or https://www.example.com/

Search Console tools

MERCHANT_ACCOUNT_ID

1234567890

Merchant tools

GTM_CONTAINER_ID

GTM-XXXXXXX

gtm_inventory

PAGESPEED_API_KEY

API key

pagespeed

GOOGLE_TOKEN_FILE

~/.config/google-ecommerce-mcp/token.json

store the token in a file instead of the keyring

GADS_CUSTOMER_ID

1234567890

Google Ads tools

GADS_LOGIN_CUSTOMER_ID

1234567890

manager (MCC) id, only if you reach the account through one

GADS_DEVELOPER_TOKEN

not needed since 9 September 2026; sent only when set

GADS_TOKEN_FILE

~/.config/google-ecommerce-mcp/ads-token.json

store the Google Ads token in a file instead of the keyring (must differ from GOOGLE_TOKEN_FILE)

GADS_API_VERSION

v26 (default)

Google Ads REST version

GADS_ALLOW_SENSITIVE_QUERIES

1

lifts the resource lists of gads_query (personal data possible)

META_ACCESS_TOKEN

Meta token (ads_read only). Prefer set-secret meta-access-token to keep it out of the config

META_AD_ACCOUNT_ID

act_1234567890 or 1234567890

meta_insights

META_API_VERSION

v26.0 (default)

Graph API version

OPENAI_ADS_API_KEY

ChatGPT Ads key. Prefer set-secret openai-ads-key

ADS_TRUST_ENV

1 (exactly)

use HTTPS_PROXY, NO_PROXY and REQUESTS_CA_BUNDLE for the Ads connectors (corporate proxy)

GEM_CLIENT

acme

pin this server process to one client of the registry

GEM_CLIENTS_FILE

a path

use another client registry file than the default clients.json

GEM_WRITE

1 (exactly)

allow writing at all. Unset means every apply is refused. See docs/WRITE.md

GEM_STATE_DIR

a path

where plans, approvals and the journal are kept

GEM_LANG

fr or en

language of the client, quickstart and install messages (default: the system language)

GEM_WRITE_HMAC_KEY

a long random string

signing key for plans and approvals (CI); otherwise keyring entry write-hmac-master, else a file in the state folder

GEM_LIVE_TEST

1

with it, apply works only for a client marked "sandbox": true

GEM_SECRET_<CLIENT>_<KIND>

GEM_SECRET_ACME_META

a client's secret read from the environment instead of the keyring (CI)

Command for the client report: google-ecommerce-mcp report --input report.json --output report.html [--lang fr|en] [--brand-name NAME] [--accent #RRGGBB] [--logo FILE] [--force] (see docs/REPORTING.md).

Commands for the paid media connectors (details in docs/ADS.md):

google-ecommerce-mcp setup-ads --client-secret path/to/client_secret.json [--token-file path]   # Google Ads only, separate token
google-ecommerce-mcp set-secret meta-access-token      # hidden prompt, stored in the OS keyring
google-ecommerce-mcp set-secret openai-ads-key         # hidden prompt, stored in the OS keyring

How a call works

Sequence of one tool call

Security notes

Details, the full list of guardrails and the known limits: docs/SECURITY.md.

  • Reading is read-only, enforced. Every read request is checked against an allow-list before it is sent, and CI fails if a tool tries an endpoint outside it. readOnlyHint is only a hint.

  • Writing is off by default and opt-in. It needs GEM_WRITE=1, enabled for the client and platform, an allowed account, budget caps, paused creations, a field allow-list, a signed single-use token bound to the exact plan, a journal that must be writable, and, for money, personal data, irreversible or high-risk plans, your approval in a terminal. It never activates, deletes or publishes.

  • The limits you must know. The terminal approval does not stop an assistant that has a shell or file access on your machine. A Google Ads token and a ChatGPT Ads key cannot be split into read and write. The write policy is a file you (or anything running as you) can edit. No write was ever verified on a real account.

  • setup requests read scopes only. Google has no read-only scope for Merchant Center (content) or the Indexing API (indexing); they are requested only with --with-merchant / --with-indexing. Write scopes for GA4, Tag Manager, Search Console and Merchant Center live in a separate token created by setup --client <name> --write.

  • Paid media. Each ad platform has its own allow-list (host pinned, a few read endpoints). Google Ads queries go through a GAQL validator before being sent. Redirects are never followed, answers are capped at 20 MB, secrets are masked in every error, and the environment's proxy is used only if you set ADS_TRUST_ENV=1.

  • Google Ads scope caveat. setup-ads requests the adwords scope, which can write and cannot be limited. It is stored in its own keyring entry, apart from the Google read token. ChatGPT Ads documents no read-only key, and a Meta system user token is long-lived: dedicate each credential to this server and revoke it when you stop.

  • Every result carries fetched_at and freshness; report tools return the date_range queried, resolved in the data's timezone, with data_complete.

  • Revoke access at any time from your Google account permissions.

Limitations

  • The Merchant API is recent and Google keeps changing it; the older Content API for Shopping has been shut down, so only the Merchant API is used. Open an issue if a call breaks.

  • Without a client registry (legacy mode): one site, Merchant account and container per server instance, and writing is not available. With a registry: any number of clients, each with its own ids and secrets.

  • GA4 Data API quotas apply to ga4_report. Each ad platform has its own quotas, returned as rate_limited; nothing is retried automatically.

  • Neither the paid media connectors nor any write is tested on real accounts (offline tests only). Platform conversions are attributed independently and are not deduplicated; spends are never converted between currencies.

  • Ad platforms keep changing their APIs (defaults: Google Ads v26, Meta v26.0; both are settable). Open an issue if a call breaks.

  • One Google Ads customer, one Meta ad account and one ChatGPT Ads key per client. With a registry, a property_id, customer_id or account_id that is not the client's own is refused (id_not_owned) for reads and for plans; only in legacy mode (no registry) do these parameters read any account the credential can see.

  • Writing, since 0.5.0: bids are refused (which blocks some creations, for example a Meta ad set whose goal needs a bid cap; a new Google Ads campaign uses a fixed manual CPC with no bid amount), activation, deletion and publishing do not exist, and max_plan_budget_micros is not usable.

Contributing

See CONTRIBUTING.md. Security reports: SECURITY.md.

Development

pip install -e ".[dev]"
pytest

Tests run offline with a fake HTTP session; no Google, Meta or OpenAI account needed. Maintainers: see docs/RELEASING.md.

License

MIT, see LICENSE.

Available Tools

82 tools
ads_overviewAds overview (all platforms)A
Read-onlyIdempotent

Google Ads, Meta and OpenAI Ads totals side by side for one period: spend, impressions, clicks, conversions and conversion value as reported by each platform, the platform's own ROAS, currency, attribution windows and date range. A platform not configured or failing gets its own block without blocking the others (partial). combined adds spends only when every currency is the same (else null with combined_reason; a platform without activity adds zeros and needs no currency) and computes ROAS as total value / total spend. Conversions overlap between platforms: their sum is not deduplicated (warning). Multi-client: one client only (client_id), and only the platforms that client has; never two clients mixed.

Inputs: end_date (required), start_date (required), client_id.

audit_logWrite journalA
Read-onlyIdempotent

Read the write journal of a client (plans, apply intents and results, rollbacks), secrets masked.

Inputs: limit, plan_id, client_id.

client_checkClient checkA
Read-onlyIdempotent

Health of one client: which services are configured, whether its Google token works and which scopes it holds (like server_status), plus whether each of its secrets is stored ("secrets": {kind: true/false}; the values are never read out).

Inputs: client_id.

client_profileClient profileA
Read-onlyIdempotent

One client's profile: label, sandbox flag, the account ids of each platform (GA4 property, Search Console site, Merchant account, GTM container, Google Ads customer, Meta ad account...) and its write policy per platform (enabled, allowed accounts, budget caps). Never a secret value.

Inputs: client_id.

clients_listClients listA
Read-onlyIdempotent

Clients this server can work on, from the client registry (clients.json): client_id, label, sandbox and which platforms are configured. Never a secret. Without a registry there is one implicit client, "default", built from the environment variables. Pass client_id to the other tools when several clients are listed.

Inputs: no named parameters.

ga4_compareGA4 compareA
Read-onlyIdempotent

Compare a GA4 period with an earlier one in ONE call (Data API runReport with two date ranges): this month against last month, the last 7 days against the 7 before, a month against the same month last year. Returns, per row, the current and previous value of each metric with the absolute "change" and "change_pct" (percent; None when the previous value is 0), "totals" over every row, the unit and definition of each metric under "metrics", the currency, both "date_range"s resolved to calendar dates in the property's timezone with "data_complete", and "biggest_moves": the 5 rows whose first metric changed the most in absolute terms. A key present in one range only shows the other as 0 and a "present_in" list. Use ga4_report for a single range.

Inputs: limit, period, metrics, client_id, +3 more.

ga4_custom_definitionsGA4 custom definitionsA
Read-onlyIdempotent

Custom dimensions and custom metrics of a GA4 property (parameter name, display name, scope, unit) and how many slots each scope uses against the standard quotas (50 event, 25 user, 10 item dimensions; 50 metrics). Read only.

Inputs: client_id, property_id.

ga4_key_event_auditGA4 key event auditA
Read-onlyIdempotent

Which GA4 events are marked as key events (conversions), and do they inflate conversions: more key events than sessions, page_view or other engagement events marked as key, contact clicks (phone, e-mail, WhatsApp) marked as key. Two Data API runReport calls: events with eventCount and keyEvents, then the property totals of sessions, keyEvents and ecommercePurchases. Returns "key_events" (event_name, event_count, key_events, share_pct, flags), "totals", "key_events_per_session", "findings" ({code, severity, event_name, detail}), the unit and definition of each metric under "metrics" and a "date_range" with "data_complete". Heuristics: check in GA4 Admin > Events > Key events before changing anything. Run it first on a new property, before reading any conversion rate or ROAS.

Inputs: end_date, client_id, start_date, property_id.

ga4_key_eventsGA4 key eventsB
Read-onlyIdempotent

Key events (formerly conversions) of a GA4 property: event name, counting method, default value, whether it is custom and deletable. Read only.

Inputs: client_id, property_id.

ga4_plan_custom_dimension_createPlan a GA4 custom dimensionA
Read-only

PLAN (nothing is written): register a custom dimension on the client's GA4 property. Warning: parameterName and scope are immutable and the slot counts against the quota (50 event / 25 user / 10 item). Apply with google_apply after the user agreed. No automatic rollback (archiving is not offered).

Inputs: display_name (required), parameter_name (required), scope, client_id, +3 more.

ga4_plan_key_event_createPlan a GA4 key eventA
Read-only

PLAN (nothing is written): mark an event as a key event of the client's GA4 property. Returns the plan with a confirmation_token; apply it with google_apply after the user agreed. No automatic rollback (deleting a key event is not offered in this version: remove it in GA4 Admin > Key events).

Inputs: event_name (required), client_id, property_id, counting_method.

ga4_propertiesGA4 propertiesA
Read-onlyIdempotent

GA4 accounts and properties the authorized Google account can read (Admin API accountSummaries), so the assistant can find a property id itself and pass it as property_id to ga4_report or ga4_realtime. Returns {"properties": [{property_id, property_name, property_type, account_id, account_name, configured}], "configured_property_id"}. Needs the Google Analytics Admin API enabled; no extra OAuth scope. With a client registry each property also says whether it belongs to the client ("owned"): only those can be queried.

Inputs: client_id, max_pages.

ga4_realtimeGA4 realtimeA
Read-onlyIdempotent

GA4 realtime report for the last 30 minutes. Useful to check a tracking change, for example that one page view is counted once and not twice. Returns {"rows": [...], "row_count": n, "totals": {...}, "metrics": {...}}.

Inputs: metrics, client_id, dimensions, property_id.

ga4_reportGA4 reportA
Read-onlyIdempotent

Run a Google Analytics 4 report (Data API runReport): traffic, conversions or revenue split by any dimensions over a date range. Returns the top rows ({"rows": [{dimension: value, metric: number}]}), "totals" over every row, "row_count" and "truncated", the unit and definition of each metric under "metrics", the currency, and a "date_range" resolved to calendar dates in the property's timezone with "data_complete". Use ga4_realtime for the last 30 minutes.

Inputs: limit, metrics, end_date, client_id, +4 more.

gads_accountsGoogle Ads accountsA
Read-onlyIdempotent

Google Ads customer accounts the Google Ads token can read directly (customers:listAccessibleCustomers), with the configured customer (GADS_CUSTOMER_ID, or the client's) and login customer (manager account), to pick a customer_id for gads_performance or gads_query. Returns {"customers": [{"id"}], "configured_customer_id", "login_customer_id", "cached"} (cached: true when the list comes from the 5-minute discovery cache). With a client registry only the client's own customers are listed ("hidden_customers" counts the others).

Inputs: client_id.

gads_applyApply a Google Ads planA
Destructive

WRITE: apply a signed plan for Google Ads, after the user approved it. Pass plan_id, confirmation_token and confirm exactly as the plan_* tool returned them. Every lock is re-checked; ops run in order and stop at the first error; everything is journaled.

Inputs: confirm (required), plan_id (required), confirmation_token (required), client_id.

gads_conversion_actionsGoogle Ads conversion actionsA
Read-onlyIdempotent

Google Ads conversion actions of one customer and the settings that decide what metrics.conversions counts: name, status, type, category, origin, primary_for_goal, include_in_conversions_metric, counting type (one or every conversion per click), attribution model, click-through and view-through lookback windows (days) and default value / currency. Fixed GAQL template on conversion_action (searchStream), sorted by name; REMOVED actions are left out unless include_removed. Use it to explain why conversions differ from another platform.

Inputs: limit, client_id, customer_id, include_removed.

gads_performanceGoogle Ads performanceA
Read-onlyIdempotent

Google Ads performance by account, campaign or ad group over a date range: spend, impressions, clicks, conversions, conversion value, CTR, CPC, CPA and ROAS, optionally split by date, device or network. Built from fixed aggregated GAQL templates (searchStream), highest spend first. Returns "rows", "totals" (ROAS = sum of values / sum of spends) with "totals_complete". start_date and end_date are required (empty -> invalid_dates), the "currency" (looked up when no row), a "date_range" in the account timezone with "data_complete", the unit and definition of each metric, and the "attribution" used.

Inputs: level, limit, segment, end_date, +3 more.

gads_plan_add_negativesPlan: add Google Ads negative keywordsA
Read-only

Plan adding negative keywords (1 to 50 texts given by you, match type EXACT, PHRASE or BROAD) to one campaign (campaign_id) or to one shared negative keyword list (shared_set_id), in one atomic request, dry-run by Google first. Negatives only stop ads from showing (no spend increase). Rollback is manual (remove them in the interface).

Inputs: keywords (required), client_id, match_type, campaign_id, +2 more.

gads_plan_budget_changePlan: change a Google Ads daily budgetA
Read-only

Plan a new daily amount for one Google Ads campaign budget (amountMicros, in micros of the ACCOUNT currency: 12.50 EUR = 12500000). Give budget_id, or campaign_id to change the budget that campaign uses. The current budget and currency are read first; the policy caps it (max_daily_budget_micros in cap_currency, +20 % per 24 h at most) and a human approval is required before gads_apply (financial). A shared budget changes every campaign using it (shown in the plan).

Inputs: daily_budget_micros (required), budget_id, client_id, campaign_id, +1 more.

gads_plan_create_campaignPlan: create a paused Google Ads Search campaignA
Read-only

Plan creating one Google Ads Search campaign, PAUSED, with its own daily budget (amountMicros in micros of the account currency; not shared), Google Search network only, in one atomic request dry-run by Google. No ad group, keyword nor ad is created; the bidding strategy is fixed (manual CPC, no bid amount, not configurable). It stays PAUSED: activate it in the Google Ads interface once it is complete. Financial: human approval before gads_apply.

Inputs: name (required), daily_budget_micros (required), client_id, customer_id.

gads_plan_pause_entitiesPlan: pause Google Ads entitiesA
Read-only

Plan pausing Google Ads campaigns, ad groups or ads (status PAUSED, nothing else). Each entity is read first (current status kept for the rollback) and dry-run by Google (validateOnly). Ad ids are "<ad_group_id>~<ad_id>". Returns the plan (diff, risks, confirmation_token, confirm): show it to the user, then gads_apply. A paused entity stops spending; rollback_plan re-enables it only if allow_activate is set.

Inputs: ids (required), level (required), client_id, customer_id.

gads_queryGoogle Ads GAQL queryA
Read-onlyIdempotent

Run a free read-only Google Ads Query Language (GAQL) SELECT on one customer (searchStream), for fields the fixed gads_performance templates do not cover. Refused without any network call unless it is a single SELECT with no ';' and no '--' or '/' (refused even inside a string literal). The read is bounded: without LIMIT, LIMIT 10001 is added (before PARAMETERS); a larger LIMIT is lowered to 10001; the answer is capped at 20 MB. One SELECT and one FROM only, no JOIN, no backslash, ASCII only outside string literals. FROM and every dotted name prefix in SELECT, WHERE and ORDER BY (besides metrics and segments) must be a reporting resource: customer, campaign, campaign_budget, ad_group, ad_group_ad, ad_group_criterion, keyword_view, shopping_performance_view, product_group_view, asset_group, asset_group_listing_group_filter, asset_group_asset, asset, ad_group_ad_asset_view, campaign_criterion, geographic_view, gender_view, age_range_view, landing_page_view, expanded_landing_page_view, display_keyword_view, topic_view, bidding_strategy, conversion_action, location_view, distance_view, with customer. limited to id, descriptive_name, currency_code, time_zone, status, manager, test_account and resource_name; anything else is refused with resource_not_allowed. Names exposing personal data (change_event, click_view, call_view, search term views, leads, user_*, payments_*, billing_*, customer_user_access, invoices, account links, placements...) are refused anywhere in the query with sensitive_resource. Setting GADS_ALLOW_SENSITIVE_QUERIES=1 in the server env lifts both lists (personal data possible). Rows are flattened to GAQL field names (campaign.name, metrics.clicks); micros fields are converted to currency units: micros renamed without the suffix (metrics.cost_micros -> metrics.cost), metrics.average_cpc, average_cpm, average_cost and cost_per kept under their name.

Inputs: gaql (required), limit, client_id, customer_id.

google_applyApply a GA4, Search Console, Merchant, GTM planA
Destructive

WRITE: apply a signed plan for GA4, Search Console, Merchant, GTM, after the user approved it. Pass plan_id, confirmation_token and confirm exactly as the plan_* tool returned them. Every lock is re-checked; ops run in order and stop at the first error; everything is journaled.

Inputs: confirm (required), plan_id (required), confirmation_token (required), client_id.

gsc_inspect_urlSearch Console URL inspectionA
Read-onlyIdempotent

Google index status of one URL (URL Inspection API): verdict, coverage state, user and Google-selected canonical, robots.txt state, page fetch state and last crawl time. Quota: 2,000 inspections per day.

Inputs: url (required), site_url, client_id.

gsc_movesSearch Console movesA
Read-onlyIdempotent

Search Console week-over-week moves: the queries (or pages) that lost and gained the most clicks, last N days against the N days before, with clicks, impressions, CTR and position for both periods, plus totals and both date ranges. A key absent from one period counts as a full loss or a full gain. Read only.

Inputs: days, limit, site_url, client_id, +1 more.

gsc_opportunitiesSearch Console opportunitiesA
Read-onlyIdempotent

Search Console opportunities: the queries (or pages) ranking between min_position and max_position with at least min_impressions ("striking_distance"), and the ones with impressions but zero clicks ("no_clicks"), each sorted by impressions. One request over the last N days ending 2 days ago. Read only.

Inputs: days, limit, site_url, client_id, +4 more.

gsc_performanceSearch Console performanceA
Read-onlyIdempotent

Google Search Console search performance for the configured property: clicks, impressions, CTR and average position, split by query, page, country, device or date. Returns the top rows, "totals" for the whole period (same filter, no split), "truncated", the unit and definition of each metric under "metrics", and a "date_range" in Pacific Time (Search Console's timezone) with "data_complete".

Inputs: limit, end_date, site_url, client_id, +4 more.

gsc_plan_sitemap_submitPlan a Search Console sitemap submissionA
Read-only

PLAN (nothing is written): submit a sitemap to the client's Search Console property. The sitemap URL must be inside the property (same domain or a subdomain for sc-domain:, same prefix for a URL-prefix property). Low risk. Apply with google_apply after the user agreed. A sitemap that was not listed before can be removed again with rollback_plan (needs write.gsc.allow_delete and a human approval); one that was already listed has no rollback.

Inputs: sitemap_url (required), site_url, client_id.

gsc_sitemapsSearch Console sitemapsB
Read-onlyIdempotent

Sitemaps declared in Search Console, with last submission, last download, errors and warnings.

Inputs: site_url, client_id.

gsc_sitesSearch Console sitesA
Read-onlyIdempotent

Search Console properties the client's Google token can see: address (sc-domain:example.com or a URL prefix), permission level (siteOwner, siteFullUser, siteRestrictedUser, siteUnverifiedUser), whether it is the client's configured site and whether that level may submit sitemaps. With several clients, sites that are not this client's are masked. Read only.

Inputs: client_id.

gtm_get_tagGTM tagA
Read-onlyIdempotent

One tag of a workspace in full (type, parameters, triggers, paused) with its fingerprint, which gtm_plan_tag_upsert needs to update it. Read only.

Inputs: tag_id (required), workspace_id (required), client_id.

gtm_get_triggerGTM triggerA
Read-onlyIdempotent

One trigger of a workspace in full (type, filters) with its fingerprint (needed to update it). Read only.

Inputs: trigger_id (required), workspace_id (required), client_id.

gtm_get_variableGTM variableA
Read-onlyIdempotent

One variable of a workspace in full (type, parameters) with its fingerprint (needed to update it). Read only.

Inputs: variable_id (required), workspace_id (required), client_id.

gtm_inventoryTag Manager inventoryA
Read-onlyIdempotent

Tags (type, paused, firing triggers, parameters), triggers and variables of the configured Google Tag Manager container's default workspace, plus the id of the live published version. Built-in trigger ids are translated, e.g. All Pages. Useful to spot a tag configured twice.

Inputs: client_id.

gtm_plan_quick_previewPreview a GTM workspaceA
Read-only

Preview step of a GTM plan: compile a workspace into a throw-away preview version and report compiler errors, merge conflicts and what it holds. It changes nothing (no version is created, nothing goes live), so there is nothing to apply. Uses the write token (scope tagmanager.edit.containerversions) and needs writes enabled for the client.

Inputs: workspace_id (required), client_id.

gtm_plan_tag_upsertPlan a GTM tag changeA
Read-only

PLAN (nothing is written): create or update a tag in a non-default workspace of the client's GTM container. An update needs the fingerprint from gtm_get_tag. Nothing goes live: publishing stays in the GTM interface. Custom HTML tags are high risk. Apply with google_apply after the user agreed; an update can be undone with rollback_plan.

Inputs: tag (required), workspace_id (required), tag_id, client_id, +1 more.

gtm_plan_trigger_upsertPlan a GTM trigger changeA
Read-only

PLAN (nothing is written): create or update a trigger in a non-default workspace of the client's GTM container (fingerprint from gtm_get_trigger for an update). Apply with google_apply after the user agreed.

Inputs: trigger (required), workspace_id (required), client_id, trigger_id, +1 more.

gtm_plan_variable_upsertPlan a GTM variable changeA
Read-only

PLAN (nothing is written): create or update a variable in a non-default workspace of the client's GTM container (fingerprint from gtm_get_variable for an update). Custom JavaScript variables are high risk. Apply with google_apply after the user agreed.

Inputs: variable (required), workspace_id (required), client_id, fingerprint, +1 more.

gtm_plan_workspace_createPlan a GTM workspaceA
Read-only

PLAN (nothing is written): create a dedicated workspace in the client's GTM container, where the tag, trigger and variable plans can then work (the Default Workspace is never written). Low risk: a workspace changes nothing live. Apply with google_apply after the user agreed. No automatic rollback.

Inputs: name (required), client_id, description.

gtm_versionsGTM versionsA
Read-onlyIdempotent

Container versions of the client's GTM container, newest first (id, name, number of tags, triggers and variables) and which one is live. Read only: publishing is not offered.

Inputs: limit, client_id.

gtm_workspace_statusGTM workspace statusA
Read-onlyIdempotent

Workspaces of the client's GTM container (id, name, whether it is the Default Workspace, whether this server created it) and, for each one, its pending changes (added / updated / deleted tags, triggers, variables) and merge conflicts. Read only; use a non-default workspace for any change.

Inputs: client_id, workspace_id.

indexing_statusIndexing API statusA
Read-onlyIdempotent

Latest Indexing API notifications (URL_UPDATED / URL_DELETED) Google holds for a URL. Read only: nothing is submitted. Most URLs were never notified, which is reported as such.

Inputs: url (required), client_id.

merchant_account_issuesMerchant Center account issuesA
Read-onlyIdempotent

Account-level issues of the client's Merchant Center account (suspensions, policy, shipping, tax, website claim...): title, severity (CRITICAL, ERROR, SUGGESTION), detail, documentation link and impacted destinations per country, with counts by severity. Read only.

Inputs: client_id, account_id, language_code.

merchant_data_sourcesMerchant Center data sourcesB
Read-onlyIdempotent

Merchant Center data sources (feeds): labels, countries, languages, fetch URLs.

Inputs: client_id.

merchant_plan_product_patchPlan a Merchant Center product changeA
Read-only

PLAN (nothing is written): change some attributes of one product of the client's Merchant Center account, with an explicit update mask (an attribute listed without a value is refused: Google would delete it). Title and description are low risk, link and availability medium, price high and financial (needs a human approval; capped by write.merchant.max_daily_budget_micros, max_increase_pct and cap_currency). Only API data sources. Apply with google_apply after the user agreed; changes show after up to 30 minutes; rollback_plan restores the previous values. Product insert, delete and inventories are deliberately not offered.

Inputs: product_id (required), update_mask (required), product_attributes (required), client_id, +2 more.

merchant_product_issuesMerchant Center product issuesA
Read-onlyIdempotent

Merchant Center products with their item-level issues (disapprovals, demotions, warnings) per destination, with the attribute to fix. Scans every page of products up to max_pages. Returns {"products": [{offer_id, feed_label, title, link, issues: [{code, severity, description, attribute, destination}]}], "scanned": n, "truncated": bool}.

Inputs: limit, client_id, max_pages, only_with_issues.

merchant_productsMerchant Center productsA
Read-onlyIdempotent

One page of the client's Merchant Center products (processed view): full product id contentLanguagefeedLabelofferId (the id merchant_plan_product_patch takes), title, link, availability, price, primary data source, number of item issues and status per destination. Pass next_page_token for the next page. Read only.

Inputs: limit, client_id, account_id, page_token.

merchant_report_queryMerchant Center report queryA
Read-onlyIdempotent

Run a Merchant Center report (Merchant API reports:search) with an MCQL query, for example product status or free-listing performance. Returns Google's raw result rows.

Inputs: query, client_id.

meta_ad_accountsMeta ad accountsA
Read-onlyIdempotent

List the Meta ad accounts the access token can read (id act_..., name, status, currency, timezone).

Use it to find the account id for META_AD_ACCOUNT_ID or for the account_id argument of meta_insights. With a client registry only the client's own accounts are listed (not_owned_hidden counts the others).

Inputs: client_id.

meta_adsetsMeta ad setsB
Read-onlyIdempotent

List the ad sets of a Meta ad account (optionally of one campaign): id, name, campaign_id, status, effective_status, daily and lifetime budget (minor units and currency units), optimization goal, billing event, bid strategy, dates. Read-only.

Inputs: limit, statuses, client_id, account_id, +1 more.

meta_ads_listMeta adsA
Read-onlyIdempotent

List the ads of a Meta ad account (optionally of one ad set or campaign): id, name, campaign_id, adset_id, status, effective_status, creative_id, dates. Read-only.

Inputs: limit, adset_id, statuses, client_id, +2 more.

meta_applyApply a Meta (ads, pixel, catalog, Instagram, Page) planA
Destructive

WRITE: apply a signed plan for Meta (ads, pixel, catalog, Instagram, Page), after the user approved it. Pass plan_id, confirmation_token and confirm exactly as the plan_* tool returned them. Every lock is re-checked; ops run in order and stop at the first error; everything is journaled.

Inputs: confirm (required), plan_id (required), confirmation_token (required), client_id.

meta_campaignsMeta campaignsA
Read-onlyIdempotent

List the campaigns of a Meta ad account: id, name, status, effective_status, objective, daily and lifetime budget (minor units and currency units), special_ad_categories, dates. Read-only.

Use the ids with meta_plan_pause / meta_plan_budget_change, or meta_adsets(campaign_id=...).

Inputs: limit, statuses, client_id, account_id.

meta_catalog_diagnosticsMeta catalog diagnosticsB
Read-onlyIdempotent

Meta catalog diagnostics: issues by type and severity (MUST_FIX, WARNING), e.g. catalog not connected to the pixel, invalid content ids, missing attributes, image quality, policy violations, with the number of affected items.

Inputs: types, client_id, catalog_id.

meta_catalog_productsMeta catalog productsA
Read-onlyIdempotent

Products of the client's Meta catalog (bounded list): product item id, retailer_id, name, price, sale_price, currency, availability, inventory, review status, visibility. Use the product item id with meta_eco_plan_catalog_item_update.

Inputs: limit, client_id, catalog_id, retailer_id.

meta_dataset_qualityMeta dataset qualityA
Read-onlyIdempotent

Conversions API / pixel dataset quality per web event: event match quality (composite score, match key feedback), event coverage, dedup feedback, data freshness and additional conversions reported (ACR). Read only: nothing is sent to the dataset.

Inputs: pixel_id, client_id.

meta_eco_plan_catalog_item_updatePlan a Meta catalog item updateA
Read-only

PLAN (writes nothing): update one Meta catalog product item (price, sale price, availability, stock). Reads the item first (complete snapshot, rollback restores it), validates locally, and returns a signed plan with confirmation_token and confirm; apply it with meta_apply after the user agrees (a price change also needs google-ecommerce-mcp approve).

Inputs: product_item_id (required), price, title, client_id, +3 more.

meta_ig_insightsInstagram insightsA
Read-onlyIdempotent

Instagram professional account insights, total over the period: reach, views, accounts engaged, interactions (likes, comments, shares, saves, replies), follows and profile link taps. Deprecated metrics (impressions, plays, video_views) are refused.

Inputs: metrics, end_date, client_id, ig_user_id, +1 more.

meta_insightsMeta Ads insightsA
Read-onlyIdempotent

Meta Ads performance (spend, impressions, clicks, reach, purchases, purchase value, ROAS) by level.

ctr is recomputed as a ratio 0..1, ROAS = purchase value / spend (totals: sum of values / sum of spends), Meta's own purchase_roas is kept raw in meta_reported_roas. Currency is the ad account's, never converted.

Inputs: level, limit, end_date, client_id, +6 more.

meta_page_insightsFacebook Page insightsA
Read-onlyIdempotent

Facebook Page insights per day and in total: media views (page_media_view replaces the deprecated impressions), post engagements, follows and unfollows, total actions. 90 days at most per request.

Inputs: metrics, page_id, end_date, client_id, +1 more.

meta_pixel_healthMeta pixel healthA
Read-onlyIdempotent

Meta pixel health: last fire time, availability, automatic matching, and the events received per name over the last days days (PageView, ViewContent, AddToCart, Purchase...), with plain warnings (never fired, silent for more than 24 h, no Purchase event).

Inputs: days, pixel_id, client_id.

meta_plan_budget_changePlan a Meta budget changeA
Read-only

PLAN (nothing is written): change the daily budget of a Meta campaign or ad set. Financial: capped by the client's policy (max daily budget in its currency, +20 % in 24 h) and applied only after a human approval out of band (google-ecommerce-mcp approve). Rollback restores the previous budget.

Inputs: level (required), entity_id (required), daily_budget_minor (required), client_id.

meta_plan_create_adPlan a Meta adA
Read-only

PLAN (nothing is written): create a Meta ad, always PAUSED, from an existing creative, in an ad set of the client's account (both checked). Dry-run with validate_only; apply with meta_apply. No automatic rollback.

Inputs: name (required), adset_id (required), creative_id (required), client_id.

meta_plan_create_adsetPlan a Meta ad setA
Read-only

PLAN (nothing is written): create a Meta ad set, always PAUSED, in a campaign of the client's account (checked). No bid fields (bid caps are refused by the policy). Dry-run with validate_only; apply with meta_apply. No automatic rollback.

Inputs: name (required), countries (required), campaign_id (required), billing_event (required), +9 more.

meta_plan_create_campaignPlan a Meta campaignA
Read-only

PLAN (nothing is written): create a Meta campaign, always PAUSED. Dry-run with validate_only; apply with meta_apply; activation stays in Ads Manager. No automatic rollback (archive it in Ads Manager).

Inputs: name (required), objective (required), special_ad_categories (required), client_id, +3 more.

meta_plan_pausePlan a Meta pauseA
Read-only

PLAN (nothing is written): pause Meta campaigns, ad sets or ads (status PAUSED). Reads each entity (account first, then status), checks the change locally (nothing is sent to Meta), returns the signed plan; apply it with meta_apply after the user agrees. Rollback restores the previous status.

Inputs: level (required), entity_ids (required), client_id.

openai_ads_accountOpenAI Ads accountA
Read-onlyIdempotent

OpenAI Ads (ChatGPT ads) ad account of the client's key (GET /v1/ad_account): only id, name, status, currency_code (the account currency), timezone when present; every other key is dropped and listed in raw_fields_dropped. Use it as a connection test before openai_ads_insights. Cached 300 s ("cached": true). With a registry, refused (account_mismatch) when the key answers for another account than the client's.

Inputs: client_id.

openai_ads_ad_groupsOpenAI Ads ad groupsA
Read-onlyIdempotent

List the ad groups of one OpenAI Ads (ChatGPT ads) campaign (GET /v1/ad_groups?campaign_id=...): id, name, status, bidding_config (billing_event_type, max_bid_micros in micros of the account currency), created_at / updated_at. Reads up to limit rows (next_after while has_more). Names are third-party text.

Inputs: campaign_id (required), after, limit, order, +2 more.

openai_ads_adsOpenAI Ads adsA
Read-onlyIdempotent

List the ads of one OpenAI Ads (ChatGPT ads) ad group (GET /v1/ads?ad_group_id=...): id, name, status, review_status (in_review, rejected, approved), creative (type, title, body, price, target_url, file_id), created_at / updated_at. Reads up to limit rows (next_after while has_more). Names and creative texts are third-party text.

Inputs: ad_group_id (required), after, limit, order, +2 more.

openai_ads_applyApply a ChatGPT Ads (OpenAI) planA
Destructive

WRITE: apply a signed plan for ChatGPT Ads (OpenAI), after the user approved it. Pass plan_id, confirmation_token and confirm exactly as the plan_* tool returned them. Every lock is re-checked; ops run in order and stop at the first error; everything is journaled.

Inputs: confirm (required), plan_id (required), confirmation_token (required), client_id.

openai_ads_campaignsOpenAI Ads campaignsA
Read-onlyIdempotent

List the OpenAI Ads (ChatGPT ads) campaigns of the client's ad account (GET /v1/campaigns): id, name, status (active, paused, archived), bidding_type, budget (daily_spend_limit_micros or lifetime_spend_limit_micros, micros of the account currency), start_time / end_time (unix seconds), mode, created_at / updated_at. Use the ids with openai_ads_ad_groups, openai_ads_insights or openai_ads_plan_pause. Reads up to limit rows (next_after while has_more). Names are third-party text.

Inputs: after, limit, order, before, +1 more.

openai_ads_conversionsOpenAI Ads conversionsA
Read-onlyIdempotent

OpenAI Ads (ChatGPT ads) conversion insights (POST /v1/conversions/insights, a read query): goal conversions (click-through and view-through) and attributed order value per campaign, ad group or ad (entity_ids), or for the whole account (group_by_entity false), over whole days in the account timezone. Returns "rows" (null kept), recomputed "totals", "currency" (account_currency), "attribution" and "date_range". No pagination: more than 2000 rows answers too_many_rows (fewer entities, shorter period or fewer event_names). Warning: attributed event details may contain order or user identifiers; only documented aggregate fields are kept.

Inputs: end_date (required), start_date (required), account_timezone (required), aggregation_level (required), +11 more.

openai_ads_insightsOpenAI Ads insightsA
Read-onlyIdempotent

OpenAI Ads (ChatGPT ads) performance over a date range: impressions, clicks, spend, ctr, conversions and attributed sales for the ad account or one campaign, ad group or ad. Returns "rows" as reported (flat keys such as campaign_id; null kept, null_means "non calculable"), recomputed "totals" (roas = sum of sales / sum of spend), "currency" (from order_created_attributed_sales_currency, else None), "date_range" in the timezone returned by the API, "next_after" while has_more (reads up to max_rows rows over at most 5 pages), units (spend in major currency units, ctr ratio) and "attribution". No automatic retry.

Inputs: end_date (required), start_date (required), sort, after, +16 more.

openai_ads_plan_budget_changePlan an OpenAI Ads budget changeA
Read-only

PLAN (nothing is written): set the daily budget (daily_spend_limit_micros) of one OpenAI Ads campaign. Financial: the client's cap, currency and +20 %/24 h locks apply and the user must approve it out of band (google-ecommerce-mcp approve). Lifetime budgets are refused. LOCAL dry-run only. Apply with openai_ads_apply; rollback restores the previous daily budget. An OpenAI Ads key cannot be read-only.

Inputs: campaign_id (required), daily_budget_micros (required), client_id.

openai_ads_plan_create_campaignPlan an OpenAI Ads campaign (paused)A
Read-only

PLAN (nothing is written): create one OpenAI Ads campaign, always with an explicit status "paused" and an explicit start_time, and a daily budget (no targeting, no bidding, no product feed). Financial: cap and currency locks plus an out-of-band human approval. LOCAL dry-run only. Apply with openai_ads_apply; activate it in the ChatGPT Ads interface once its ad groups and ads are ready. An OpenAI Ads key cannot be read-only.

Inputs: name (required), start_time (required), daily_budget_micros (required), end_time, +2 more.

openai_ads_plan_pausePlan an OpenAI Ads pauseA
Read-only

PLAN (nothing is written): pause OpenAI Ads (ChatGPT ads) campaigns, ad groups or ads. Reads each entity (archived ones are refused, already paused ones are skipped), checks the client's write policy, runs a LOCAL dry-run (the unit endpoints have no validate_only) and returns the plan with confirmation_token and confirm; apply it with openai_ads_apply after the user agreed. Rollback reactivates what was active (that rollback spends money: allow_activate and a human approval). Note: an OpenAI Ads key cannot be read-only; only this server's policy guards writes.

Inputs: level (required), entity_ids (required), client_id.

pagespeedPageSpeed InsightsA
Read-onlyIdempotent

Lighthouse performance and SEO scores (0 to 100) plus LCP, CLS and TBT for a URL, and the Chrome UX Report field category when Google has real-user data. Set PAGESPEED_API_KEY to avoid the shared anonymous quota.

Inputs: url (required), strategy, client_id.

plan_getShow a write planA
Read-onlyIdempotent

Show a stored write plan (ops, risk, changes, requests masked, status). Never returns its token.

Inputs: plan_id (required), client_id.

plan_listList write plansB
Read-onlyIdempotent

List the newest write plans of a client (id, platform, title, status, expiry).

Inputs: limit, client_id.

rollback_planPlan a rollbackA
Read-only

Build a NEW plan undoing what plan_id applied (nothing is written; apply it like any plan).

Inputs: plan_id (required), client_id.

server_statusServer statusA
Read-onlyIdempotent

Which Google services are configured for this server (or for one client), and whether the stored OAuth token works. Call it first when another tool answers not_configured or not_authenticated. Returns one boolean per service, the token storage (os-keyring or file), "token": "ok" or the error, and the package version.

Inputs: client_id.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.6/5.0

    Scored across 82 tools

    Disambiguation3/5

    Many tools are clearly distinct within a platform, but the set has numerous analogous reporting tools across platforms (e.g. ga4_report/ga4_compare/ga4_realtime, gsc_performance/gsc_opportunities/gsc_moves, multiple *_insights) and many parallel plan tools that an agent must map correctly. Descriptions are detailed and usually disambiguate individual tools, but the sheer breadth and cross-platform parallels create real selection risk.

    Naming Consistency4/5

    Predominantly consistent platform-prefixed snake_case (ga4_, gads_, gsc_, gtm_, meta_, merchant_, openai_ads_) with clear plan_/apply/rollback patterns. Minor inconsistencies exist: google_apply bundles GA4/GSC/Merchant/GTM while Meta and OpenAI have their own apply, and meta_eco_plan_catalog_item_update is an outlier, but overall the convention is predictable.

    Tool Count2/5

    82 tools is far above the healthy 3-15 band and well into the 'too many' range; even for a multi-platform server, the cognitive load is high. Each tool may earn its place logically, but the count is excessive and will strain an agent's tool selection.

    Completeness4/5

    The surface covers read, plan, apply, rollback and audit across GA4, Google Ads, GSC, GTM, Merchant, Meta and OpenAI Ads. Some lifecycle gaps exist (e.g. Meta ad group/creative creation, Google Ads keyword/ad creation, Merchant product insert/delete), but these appear deliberate and workarounds exist (e.g. platform UI, plan tools).

    Maintenance

    ActivityMaintained
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      C
      maintenance
      Enables AI agents to manage Google Tag Manager, Google Search Console, and Google Analytics (GA4) through unified access to tags, search performance data, URL inspection, sitemaps, and analytics reporting.
      7 npm
      ISC
    • A
      license
      A
      quality
      B
      maintenance
      Provides AI agents with read-only access to Google Search Console data, including search analytics, index coverage, and sitemap status. It enables users to query clicks, impressions, and ranking performance or check URL indexing status through natural language.
      4
      124 npm
      9
      MIT
    • A
      license
      B
      quality
      C
      maintenance
      Provides AI agents with hands-on control of Google SEO and analytics tools including Search Console, GA4, Tag Manager, Indexing API, and PageSpeed Insights, with self-configuring OAuth2.
      33
      14 npm
      MIT
    • A
      license
      A
      quality
      D
      maintenance
      Enables AI assistants to analyze Google Search Console SEO data through natural language, including search analytics, URL inspection, sitemap management, and property management.
      21
      MIT