Skip to main content
Glama
WEYERSK

Google Ads MCP Server

by WEYERSK
README.md
# Google Ads MCP Server

A local [MCP](https://modelcontextprotocol.io) server for reading and writing the
Google Ads API. Full campaign management with a dry-run/confirm safety flow on every
write.

## Prerequisites

1. **Google Ads Manager (MCC) account** with a **developer token**.
   Check its access level: Google Ads UI -> Tools & Settings -> Setup -> API Center.
   - **Test**: can only call test accounts. Apply for **Basic access** to touch live
     accounts (approval can take a few days).
   - **Basic/Standard**: ready for live accounts.
2. A **Google Cloud project** with the Google Ads API enabled and an **OAuth2 client**
   of type *Desktop app* (gives you a client ID and client secret).

## Setup

```bash
python -m venv .venv
. .venv/Scripts/activate      # Windows PowerShell: .venv\Scripts\Activate.ps1
pip install -e ".[dev]"

# Mint a refresh token (one-off browser consent):
python scripts/generate_refresh_token.py --client-id XXX --client-secret YYY

cp .env.example .env          # then fill in every value
```

If your OAuth consent screen is still in *testing* mode, add the Google account you
sign in with as a **test user** first (Cloud Console -> APIs & Services -> OAuth
consent screen -> Audience), otherwise consent fails with a verification error.

Once `.env` holds the client ID and secret, `python scripts/remint_refresh_token.py`
re-mints an expired or revoked refresh token and rewrites `.env` in place, without
printing the secret.

Never commit `.env`; it is gitignored, and it is the only place real credentials
should ever live.

`.env` keys: `GOOGLE_ADS_DEVELOPER_TOKEN`, `GOOGLE_ADS_CLIENT_ID`,
`GOOGLE_ADS_CLIENT_SECRET`, `GOOGLE_ADS_REFRESH_TOKEN`,
`GOOGLE_ADS_LOGIN_CUSTOMER_ID` (your MCC ID, dashes optional, shown
top-right in the Google Ads UI when logged into the manager account).

## Run the tests

```bash
pip install -e ".[dev]"
pytest -v
```

## Register with Claude Code

Use the venv's absolute python path so registration works regardless of which
directory Claude Code is launched from (the server also resolves `.env` from the
project root, not the cwd):

```bash
# Windows
claude mcp add google-ads -- "<REPO_PATH>\.venv\Scripts\python.exe" -m google_ads_mcp.server

# macOS / Linux
claude mcp add google-ads -- "<REPO_PATH>/.venv/bin/python" -m google_ads_mcp.server
```

Add `--scope user` to make the tools available in every project rather than just this one.

## Write safety

Every write tool defaults to a **preview**: it validates the change with the API's
`validate_only` and returns a `confirmation_token`. To apply, call the same tool again
with `commit=true` and that token. The committed operation is byte-for-byte what was
previewed. Nothing spends money until you confirm.

## Tools

**Read:** `list_accounts`, `run_gaql`, `get_campaigns`, `get_ad_groups`,
`get_keywords`, `get_performance`.

**Write (preview -> confirm):** `create_campaign_budget`, `create_campaign`,
`update_budget`, `update_campaign_status`, `create_ad_group`,
`update_ad_group_status`, `create_responsive_search_ad`, `add_keywords`,
`add_negative_keywords`, `apply_mutate`.