Google Ads MCP
Enables managing Google Ads campaigns through an AI assistant with read-only reporting, recommendations, and gated write operations for bids, budgets, and statuses, all backed by preview and audit logging.
README
Google Ads MCP
Manage Google Ads campaigns through an AI assistant — safely, with every write gated behind a preview and an audit log.
A Model Context Protocol server that exposes Google Ads API v24 operations as tools for Claude (or any MCP client). Read campaign metrics, search terms, and recommendations; make controlled changes to bids, budgets, statuses, and creative — all from a single conversation.
Features
31 tools across five capability layers:
Read-only reporting
| Tool | What it does |
|---|---|
list_accessible_customers |
List all accounts under the MCC |
get_campaigns |
List campaigns with status and channel type |
get_campaign_performance |
Clicks, impressions, cost, conversions, CTR |
get_ad_groups |
List ad groups with status |
get_keywords |
Keywords with match type and status |
get_search_terms |
Actual search queries with performance metrics |
get_change_events |
Account change history |
run_gaql_query |
Execute any read-only GAQL query (up to 10k rows) |
get_segments_metadata |
Available GAQL segments |
get_metrics_metadata |
Available GAQL metrics |
get_resource_metadata |
Fields for any GAQL resource |
Recommendations & planning
| Tool | What it does |
|---|---|
get_recommendations |
Active Google Ads recommendations for an account or campaign |
generate_keyword_ideas |
Keyword ideas from seed keywords or a URL |
get_forecast_metrics |
Bid simulations and forecast data |
apply_recommendation |
Apply a recommendation (gated) |
dismiss_recommendation |
Dismiss a recommendation (gated) |
Status writes (gated)
| Tool | What it does |
|---|---|
pause_campaign / enable_campaign |
Toggle campaign status |
pause_ad_group / enable_ad_group |
Toggle ad group status |
pause_keyword / enable_keyword |
Toggle keyword status |
pause_ad / enable_ad |
Toggle ad status |
Bid & budget writes (gated + capped)
| Tool | What it does |
|---|---|
update_keyword_bid |
Set keyword max CPC — capped at ±25% by default |
update_ad_group_bid |
Set ad group default CPC — capped |
update_campaign_budget |
Set daily budget — capped at ±20% by default |
Entity creation (gated)
| Tool | What it does |
|---|---|
create_campaign |
Create campaign + shared budget atomically (starts paused) |
create_ad_group |
Create ad group under a campaign |
create_keyword |
Add keyword to an ad group |
create_ad |
Create a responsive search ad (starts paused) |
Safety model
Every write passes through four sequential gates:
1. Allowlist — customer_id must be in GOOGLE_ADS_MUTATE_ALLOWLIST (default: deny all)
2. Cap — bid/budget changes exceeding the configured % are blocked outright
3. Preview — confirm=False (default) runs validate_only; nothing changes in the account
4. Audit — confirmed mutations are appended to an append-only JSONL log (chmod 0600)
New entities (campaigns, ad groups, keywords, ads) always start paused.
Transient quota errors (RESOURCE_TEMPORARILY_EXHAUSTED) are retried automatically with exponential back-off and jitter (configurable via GOOGLE_ADS_MAX_RETRIES, default 3).
Setup
Prerequisites
- Python 3.10+
- uv
- A Google Ads developer token and manager account (MCC)
Install
git clone https://github.com/LucasSantana-Dev/google-ads-mcp
cd google-ads-mcp
uv sync --extra dev
Credentials
cp .env.example .env
| Variable | Description |
|---|---|
GOOGLE_ADS_CLIENT_ID |
OAuth 2.0 Desktop App client ID |
GOOGLE_ADS_CLIENT_SECRET |
OAuth 2.0 Desktop App client secret |
GOOGLE_ADS_DEVELOPER_TOKEN |
Your Google Ads developer token |
GOOGLE_ADS_LOGIN_CUSTOMER_ID |
MCC account ID (digits only, no hyphens) |
GOOGLE_ADS_REFRESH_TOKEN |
Long-lived OAuth refresh token (see below) |
GOOGLE_ADS_MUTATE_ALLOWLIST |
Comma-separated customer IDs that may receive writes |
GOOGLE_ADS_AUDIT_LOG |
Audit log path (default: audit-log.jsonl) |
GOOGLE_ADS_MAX_BID_CHANGE_PCT |
Max bid change fraction (default: 0.25) |
GOOGLE_ADS_MAX_BUDGET_CHANGE_PCT |
Max budget change fraction (default: 0.20) |
GOOGLE_ADS_MAX_RETRIES |
Quota retry attempts (default: 3) |
Mint a refresh token
GOOGLE_ADS_CLIENT_ID=... GOOGLE_ADS_CLIENT_SECRET=... \
uv run python scripts/get_refresh_token.py
A browser opens for OAuth consent. Copy the printed refresh token into .env.
Claude Desktop integration
Add to ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"google-ads": {
"command": "/Users/<you>/.local/bin/uv",
"args": [
"run",
"--directory", "/path/to/google-ads-mcp",
"--env-file", "/path/to/google-ads-mcp/.env",
"python", "-m", "google_ads_mcp.server"
]
}
}
}
Restart Claude Desktop. The 31 tools appear automatically.
Example conversations
# Reporting
"Show me all campaigns for account 123-456-7890 with spend > $100 this week"
"What search terms triggered our branded keywords in the last 7 days?"
"Any keyword ideas for 'project management software'?"
"What recommendations does Google have for my account?"
# Writes — always previews first; apply with confirm=true
"Pause campaign 9876543, it's burning budget"
"Set the CPC bid for keyword 111 in ad group 222 to $1.50"
"Create a new Search campaign 'Brand Q3' with a $20/day budget"
"Apply the 'add keyword' recommendation for campaign 555"
Development
uv run pytest # 102 tests, 89% coverage
uv run ruff check src/ tests/ # lint
uv run mypy src/ # type check
CI runs on every push and pull request.
Architecture
src/google_ads_mcp/
├── server.py # FastMCP entrypoint, tool registration
├── config.py # GoogleAdsClient factory (reads .env)
├── gaql.py # GAQL execution, validators, row serialization, retry
├── mutate.py # Write-safety harness (allowlist → cap → preview → audit)
├── retry.py # Exponential back-off for quota errors
├── errors.py # tool_handler wrapper → {success, error} for any exception
├── testing.py # FakeGoogleAdsClient — unit tests without network or credentials
└── tools/
├── accounts.py # list_accessible_customers
├── campaigns.py # get_campaigns, get_campaign_performance
├── adgroups.py # get_ad_groups
├── keywords.py # get_keywords, get_search_terms
├── changes.py # get_change_events
├── query.py # run_gaql_query
├── metadata.py # get_*_metadata (3 tools)
├── writes_status.py # pause/enable campaign/ad_group/keyword/ad (8 tools)
├── writes_value.py # update keyword bid, ad group bid, campaign budget (3 tools)
├── creates.py # create campaign, ad group, keyword, ad (4 tools)
└── planning.py # recommendations, keyword ideas, forecast (5 tools)
Transport: stdio only — no HTTP port, no public exposure.
Auth: OAuth 2.0 Desktop App + refresh token. Credentials stay on the local machine.
License
MIT
推荐服务器
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 模型以安全和受控的方式获取实时的网络信息。