google-ads-mcp-plus
Extends the official Google Ads MCP with a safe write layer for creating paused-by-default Search campaigns and an account auditor, all running locally with no hosted dependencies.
README
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).
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 --replace) |
Update, pause, enable, change budgets, edit ads |
| Bidding | maximize_clicks, manual_cpc |
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 1234567890
Client-ready Markdown report over 90 days:
python src/audit/audit_account.py --customer-id 1234567890 \
--days 90 --format markdown --output audit.md
Full 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
adwordsscope - A 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 tests
Credentials (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_TOKEN
4. 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-mcp
Full 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 --live
Then 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 -q
10. 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.
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。