google-ads-mcp-plus
Allows reading and writing Google Ads data, including querying accounts with GAQL, auditing accounts with 12 read-only checks, and creating Search campaigns (paused by default) using a configuration-driven YAML file.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@google-ads-mcp-plusaudit account 123-456-7890"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
google-ads-mcp-plus
The official Google Ads MCP (read) + a read-only account auditor + a safe write layer to create Search campaigns — paused-by-default, with a dry-run mode, full docs and examples.
⚠️ Disclaimer. This is NOT an officially supported Google product. It is a community, experimental project. It wraps Google's official, read-only Google Ads MCP server and adds an independent Python write layer that calls the Google Ads API directly. Use at your own risk. You are responsible for every campaign, every euro/dollar spent, and for complying with Google Ads policies and applicable law.
1. The problem this solves
Google's official Google Ads MCP server (googleads/google-ads-mcp,
released April 2026) is strictly read-only. It exposes three tools —
list_accessible_customers, search (GAQL), and get_resource_metadata — and
"cannot modify bids, pause campaigns, or create new assets." Great for
reporting and diagnostics; useless the moment you want an agent to actually
create a campaign.
The hosted, third-party MCPs that do offer write access ask you to hand your account keys to someone else's server. That is a real trust and data-residency decision, not always acceptable for client work.
google-ads-mcp-plus keeps the two concerns separate and local:
Read → use the official read-only MCP (this repo documents and points to it; see
docs/read-mcp.md).Write → a small, auditable, config-driven Python script that runs on your machine with your credentials and creates campaigns paused by default (
docs/write-layer.md).
Related MCP server: Google Ads MCP Server
2. Features
Read (official MCP): GAQL queries, account discovery, resource metadata — all read-only, credentials stay on your machine.
Audit (this repo, read-only):
audit_account.pyruns 12 checks over any account and reports what is costing you money: missing/secondary conversion actions, campaigns spending with zero conversions, budget- and rank-lost impression share, wasteful search terms, low Quality Score keywords, weak RSAs, disapproved ads, missing negatives and sitelinks.Text, Markdown, or JSON output. Exit code 1 on critical findings, so it works as a cron/CI monitor.
Never mutates anything — GAQL queries only. See
docs/audit.md.
Write (this repo):
One YAML config → budget → campaign → criteria (geo presence + language) → ad group → exact keywords (+ negatives) → Responsive Search Ad → assets (call, sitelinks, callouts, structured snippets).
Paused-by-default. Nothing serves until you un-pause it by hand (or pass the discouraged
--enable).--validate-only(offline, no credentials) and--dry-run(checks the account, resolves geo + language, writes nothing) before any--live.Strict text validation — no headline/description/asset is ever silently truncated; the run stops and tells you the exact field and overflow.
Handles the EU political advertising declaration the API now requires.
Best-effort policy-exemption handling for restricted categories (e.g. Local Services).
Idempotent re-runs via an opt-in
--replace(never destructive by surprise).
2b. Scope — what this does and does not do
Be clear about this before you invest time.
Audit is packaged. This repo ships an audit module with 12 read-only
checks (see docs/audit.md), extensible by adding one
function. Beyond those, write your own GAQL.
Read is unlimited. The official MCP exposes GAQL, so every readable resource is reachable: campaigns, ad groups, keywords, ads, assets, audiences, conversions, search terms, Quality Score, change history, recommendations. If you can write the query, you can read it.
Write is deliberately narrow. The write layer creates one new Search campaign from a config file. That is its entire job.
Area | Supported | Not supported |
Campaign type | Search only | Performance Max, Display, Shopping, Video, Demand Gen, App |
Operation | Create (plus delete via | Update, pause, enable, change budgets, edit ads |
Bidding |
| tCPA, tROAS, Maximize conversions, portfolio strategies |
Keywords | Exact match + negatives | Phrase, positive broad, shared sets |
Structure | One ad group, one RSA | Multiple ad groups or ads per run |
Targeting | Geo + language | Audiences, remarketing, Customer Match, demographics, devices, ad schedule |
Assets | Call, sitelinks, callouts, structured snippets | Images, logos, promotions, prices, lead forms, PMax asset groups |
Other | — | Creating conversion actions, drafts/experiments, labels, bid adjustments |
This narrowness is a design choice, not an oversight. Every additional campaign type multiplies the surface area for expensive mistakes in a tool that spends real money. A small, well-tested write path beats a broad, shaky one.
Contributions extending this are welcome — see Contributing — provided they keep the safety model intact.
2c. Audit an account in one command
Once credentials are set up (docs/setup-oauth.md):
python src/audit/audit_account.py --customer-id 1234567890Client-ready Markdown report over 90 days:
python src/audit/audit_account.py --customer-id 1234567890 \
--days 90 --format markdown --output audit.mdFull reference: docs/audit.md.
3. Quick start
Prerequisites
Python 3.10+
A Google Cloud project with the Google Ads API enabled
Your own OAuth Client ID (Desktop type) — the default gcloud client is blocked for the
adwordsscopeA developer token with at least Basic/Explorer access (a test-only token cannot touch production accounts)
An activated Google Ads account (billing/onboarding complete)
The OAuth setup has real, non-obvious pitfalls. They are documented step by step
in docs/setup-oauth.md — read that first.
Install
git clone https://github.com/monsieurgoodmood/google-ads-mcp-plus.git
cd google-ads-mcp-plus
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt # write layer
pip install -r requirements-dev.txt # to run the offline testsCredentials (summary — full guide in docs/setup-oauth.md)
# 1) Create your own OAuth Desktop client in Google Cloud, download CLIENT.json
# 2) Generate ADC with the adwords scope using YOUR client:
gcloud auth application-default login \
--client-id-file=CLIENT.json \
--scopes=https://www.googleapis.com/auth/adwords,https://www.googleapis.com/auth/cloud-platform \
--no-browser
# 3) Export your developer token (never commit it):
export GOOGLE_ADS_DEVELOPER_TOKEN=YOUR_DEVELOPER_TOKEN4. Read with the official MCP
Point your MCP host (Claude Code, Cursor, Gemini CLI, …) at Google's server:
claude mcp add google-ads-mcp -- \
pipx run --spec git+https://github.com/googleads/google-ads-mcp.git google-ads-mcpFull configuration (env vars, manager accounts) in
docs/read-mcp.md.
5. Write a campaign (paused-by-default)
cp config.example.yaml config.yaml # config.yaml is gitignored
# edit config.yaml with YOUR account, budget, keywords, ad copy…
# offline content check (no credentials):
python src/write_layer/create_campaign.py --config config.yaml --validate-only
# dry run (reads the account, resolves geo + language, writes nothing):
python src/write_layer/create_campaign.py --config config.yaml --dry-run
# create everything, PAUSED:
python src/write_layer/create_campaign.py --config config.yaml --liveThen open the Google Ads UI, review, and un-pause when you are ready. See
docs/write-layer.md for every flag.
6. Conversions & auto-tagging
Do not put a campaign live without conversion tracking — it is blind spend. Link
GA4 ↔ Google Ads, import your GA4 key events as primary conversions, and
enable auto-tagging: docs/conversions.md.
7. Policies & exemptions
Some categories are restricted (e.g. Local Services for locksmiths,
plumbers, garage-door, etc.) and may require advertiser verification before
serving. How exemptions work, and what this tool does and does not do, is in
docs/policies.md. This project does not help with
deceptive content or abusive policy circumvention.
8. Security
No secrets in the repo. Everything is a placeholder.
A strict
.gitignoreexcludes.env, ADC files,*credentials*.json,client_secret*.json,google-ads.yaml, and your privateconfig.yaml.The developer token is read from an environment variable, never from a file in the repo.
Verify
.gitignorebefore everygit add. When in doubt,git status --ignored.
9. Tests
The character-limit validators run fully offline (no API, no credentials):
pytest -q10. Who pays for what
Nothing here is a hosted service. There is no server, no backend, no account to create with us, and no usage limit — because there is nothing to limit. You clone the repo and run the code on your own machine.
That means:
Thing | Who provides it |
This code | Free, Apache-2.0, forever. Clone, fork, use commercially. |
Google Cloud project + OAuth client | You (free tier is sufficient). |
Google Ads developer token | You (free, requested from your account). |
Google Ads account + ad spend | You. Every euro/dollar is yours. |
Infrastructure to run this | You — your laptop. |
The author hosts nothing and receives nothing. There is no telemetry, no phone-home, no analytics: the only network calls this code makes are directly from your machine to Google's API, with your credentials. Nobody else can see your data, including the author.
11. License & attribution
Licensed under Apache-2.0 — one of the most permissive licenses there is. You may use, modify, distribute, and sell products built on this, including commercially and in closed-source work.
The one thing Apache-2.0 asks in return is attribution: if you redistribute this code or a derivative of it, keep the copyright headers and include a copy of the NOTICE file. That is the whole obligation.
Author: Arthur Choisnet / ByteBerry Analytics LLC — @monsieurgoodmood Copyright 2026. Originally published at
https://github.com/monsieurgoodmood/google-ads-mcp-plus.
If this saved you time, a ⭐ on the repo or a link back is appreciated but never required.
Third-party components
This project runs alongside, and depends on, Google's official read-only
googleads/google-ads-mcp and
the Google Ads API Python client library.
Those are Google's work, licensed Apache-2.0. This write layer is independent
and is not affiliated with or endorsed by Google. See NOTICE for
the full list.
12. Contributing
Issues and pull requests welcome. Useful contributions: support for other campaign types (Performance Max, Display), additional asset types, more validators, translations of the docs.
Two ground rules: never commit credentials (check git status against
.gitignore before every commit), and keep paused-by-default intact — no PR
that makes writing easier at the cost of the safety model will be merged.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/monsieurgoodmood/google-ads-mcp-plus'
If you have feedback or need assistance with the MCP directory API, please join our Discord server