Google Ads MCP Unofficial
Provides tools for reading, analyzing, and (gated) acting on a Google Ads account, including managing keywords, campaigns, budgets, and performance data.
google-ads-mcp-unofficial
Unofficial Model Context Protocol server that lets AI agents read, analyze, and (gated) act on a Google Ads account — pause keywords, set bids, adjust budgets — without leaving your stack.
Unofficial. Not affiliated with Google. This is a local-first MCP server that speaks the Google Ads REST API directly. It does NOT include automated financial-account changes beyond what the Google Ads API allows. Always review proposed changes before enabling GOOGLE_ADS_ALLOW_MUTATIONS.
Quick start (30 seconds)
npx -y google-ads-mcp-unofficial setupThe setup wizard collects your developer token + OAuth client, writes ~/.google-ads-mcp/config.json (chmod 600), then walks you through the OAuth dance via a local callback at http://127.0.0.1:3000/callback.
Verify:
npx -y google-ads-mcp-unofficial doctorThen add it to your agent (Claude Desktop, Cursor, Hermes, OpenClaw, Codex — see examples below).
Related MCP server: google-ads-mcp
What it does
22 tools across 6 categories.
Category | Count | Examples |
Meta / diagnostic | 5 |
|
Shared Delx profile | 3 |
|
Auth | 3 |
|
Reads (always safe) | 8 |
|
Workflow | 2 |
|
Mutations (gated) | 6 |
|
Full tool reference: see AGENTS.md.
Setup wizard
npx -y google-ads-mcp-unofficial setup [--allow-mutations] [--client hermes|claude|cursor|...]What it does:
Prompts for: developer token, OAuth client id/secret, optional login_customer_id (MCC), redirect URI, privacy mode.
Writes
~/.google-ads-mcp/config.jsonwithchmod 600.Writes an MCP client config (e.g. merges into
claude_desktop_config.jsonon macOS; writes a Hermes block and skill file for--client hermes).Runs the OAuth dance (unless
--no-auth) by opening Google's consent screen and listening on127.0.0.1:3000.
Mutations are off by default.
--allow-mutationsenables write tools. ASK THE USER before turning this on — it lets agents change campaigns, bids, budgets, and pause/resume keywords.
Auth model
This MCP requires two credentials:
Google Ads Developer Token — from your MCC (Manager) account at https://ads.google.com/aw/apicenter. New tokens start in "Test account access" mode and need approval for production traffic.
Google OAuth 2.0 Client — a "Desktop" or "Web" client created in Google Cloud Console. The single OAuth scope used is
https://www.googleapis.com/auth/adwords.
⚠️ Refresh token gotcha: Google only returns a
refresh_tokenon first consent or after you revoke the prior grant at https://myaccount.google.com/permissions. Ourauthflow usesprompt=consentto maximize the chance Google returns one — but if your code-exchange response is missingrefresh_token, the tool will tell you to revoke and retry.
Variable | Purpose | Stored where | Secret? |
| Approved developer token |
| yes |
| OAuth client id | local or env | no |
| OAuth client secret | local or env | yes |
| MCC id (no dashes) | local or env | no |
| OAuth callback | local or env (default | no |
|
| local or env (default | no |
| Enable write tools | local or env (default | no |
| Override token storage | local or env (default | no |
| Enable SQLite cache | local or env (default off) | no |
| Override cache path | local or env | no |
| Disable retry middleware | env (default off) | no |
Privacy modes
Mode | What you get | Customer id |
| id + name + status fields only | partial-redacted ( |
| flat normalized rows with metrics | partial-redacted |
| full upstream Google Ads REST payload | full |
Pass privacy_mode per call to override the default per response.
Redaction matrix:
Field | summary | structured | raw |
developer_token | n/a | n/a | n/a (never returned) |
access_token, refresh_token, client_secret | [REDACTED] in all errors | [REDACTED] | [REDACTED] |
email addresses in error messages | [REDACTED] | [REDACTED] | [REDACTED] |
customer_id |
|
| full |
metrics (clicks, cost, etc.) | dropped | included | included |
⚠️ Mutation gating — read this
Default: mutations are DISABLED. Six tools are gated:
google_ads_pause_keyword/google_ads_resume_keywordgoogle_ads_set_keyword_bid_microsgoogle_ads_set_campaign_budget_microsgoogle_ads_pause_campaign/google_ads_resume_campaign
If an agent calls any of them without GOOGLE_ADS_ALLOW_MUTATIONS=true, it gets:
Error: Write tools are disabled. To enable: re-run `google-ads-mcp-server setup --allow-mutations`
or set GOOGLE_ADS_ALLOW_MUTATIONS=true. ASK THE USER BEFORE TURNING THIS ON — it lets agents
change campaigns, bids, budgets, and pause/resume keywords.Even with the env enabled, every mutation requires explicit_user_intent: true in the per-call arguments. And every mutation is logged to stderr with the resource name:
[google-ads-mcp] MUTATION pause_keyword {"resource_name":"customers/1234567890/adGroupCriteria/999~111222333"}Read SECURITY.md for the threat model.
Agent client examples
Claude Desktop
~/Library/Application Support/Claude/claude_desktop_config.json (macOS):
{
"mcpServers": {
"google-ads": {
"command": "npx",
"args": ["-y", "google-ads-mcp-unofficial"]
}
}
}Then restart Claude Desktop.
Cursor / Windsurf
~/.cursor/mcp.json (or your IDE equivalent):
{
"mcpServers": {
"google-ads": {
"command": "npx",
"args": ["-y", "google-ads-mcp-unofficial@0.1.0"]
}
}
}Hermes
# ~/.hermes/config.yaml
mcp_servers:
google-ads:
command: npx
args:
- -y
- google-ads-mcp-unofficial@0.1.0
timeout: 120
connect_timeout: 60
sampling:
enabled: falseThen /reload-mcp (do NOT restart the gateway for normal data access).
OpenClaw
~/.openclaw/mcp.servers.json:
{
"google-ads": {
"command": "npx",
"args": ["-y", "google-ads-mcp-unofficial@0.1.0"]
}
}Codex / TOML clients
See examples/codex.toml for the equivalent TOML block.
Workflow examples
1. Daily performance pulse
// Agent asks: "How did my Google Ads do yesterday?"
{
"name": "google_ads_daily_report",
"arguments": {
"customer_id": "1234567890",
"cpc_alert_threshold": 0.15
}
}Returns markdown with yesterday + 7d + 30d aggregates. If yesterday's CPC exceeds 0.15, the output gets an ALERT banner.
2. Identify waste (read-only)
{
"name": "google_ads_find_waste",
"arguments": {
"customer_id": "1234567890",
"date_range": "LAST_30_DAYS",
"min_clicks": 5,
"min_cost_micros": 200000,
"zero_conversions_only": true
}
}Returns a ranked list of keywords matching "spent ≥ $0.20 with ≥5 clicks and 0 conversions" — but never pauses them.
3. Pause a single keyword (mutation, gated)
After the user confirms:
{
"name": "google_ads_pause_keyword",
"arguments": {
"customer_id": "1234567890",
"ad_group_id": "999",
"criterion_id": "111222333",
"explicit_user_intent": true
}
}Troubleshooting
Symptom | Action |
| Run |
| Revoke at https://myaccount.google.com/permissions then re-run |
| Confirm |
| Expected. Ask the user before enabling |
Hermes tools missing after config edit |
|
Token file insecure perms warning |
|
Support
GitHub Issues: https://github.com/davidmosiah/google-ads-mcp-unofficial/issues
Email: support@delx.ai
X: @delx369
Disclaimer
Unofficial integration. Not affiliated with Google. This MCP does not include automated financial-account changes beyond what the Google Ads REST API allows. Always review proposed changes before enabling GOOGLE_ADS_ALLOW_MUTATIONS. The author is not responsible for budget overruns, paused campaigns, or any other consequences of automated changes to your Google Ads account.
MIT-licensed.
This server cannot be installed
Maintenance
Latest Blog Posts
- 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/davidmosiah/google-ads-mcp-unofficial'
If you have feedback or need assistance with the MCP directory API, please join our Discord server