Google Ads MCP

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.

Category
Visit Server

README

Google Ads MCP

Manage Google Ads campaigns through an AI assistant — safely, with every write gated behind a preview and an audit log.

CI Python 3.10+ License: MIT

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

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured