Skip to main content
Glama
clientskatbi

Google Ads Campaign MCP

by clientskatbi
README.md
# Google Ads Campaign MCP

MCP server for **managing Google Ads campaigns** through the official Google Ads API — accounts, campaigns, budgets, keywords, search terms, and keyword ideas — exposed as MCP tools for any MCP client (Claude, Cursor, Hermes, ...).

> ⚠️ **Read/write server.** Tools like `set_campaign_status`, `update_campaign_budget`, `add_keywords`, and `update_keyword_bid` mutate your live ads account. Test against a dev/test account first.

## Features

| Category | Tools |
|---|---|
| Accounts | `list_accounts` — enumerate MCC + child accounts |
| Campaigns | `list_campaigns`, `get_campaign_stats`, `set_campaign_status` (pause/enable), `update_campaign_budget`, `create_search_campaign` |
| Ad groups & keywords | `list_ad_groups`, `list_keywords`, `add_keywords`, `set_keyword_status`, `remove_keyword`, `update_keyword_bid` |
| Reports & research | `get_search_terms`, `get_keyword_ideas` (Keyword Planner) |

## Requirements

- Python 3.10+
- Google Ads API access: a **developer token**, and an OAuth2 client with the `https://www.googleapis.com/auth/adwords` scope
- At least one Google Ads customer account (or MCC) the token can access

## Setup

### 1. Install

```bash
pip install -e .
# or via pipx (recommended for MCP stdio servers)
pipx install .
```

### 2. Provide credentials

Set environment variables **or** provide a `google-ads.yaml` file (see `examples/google-ads.example.yaml`):

```bash
export GOOGLE_ADS_DEVELOPER_TOKEN="YOUR_DEV_TOKEN"
export GOOGLE_ADS_CLIENT_ID="YOUR_CLIENT_ID"
export GOOGLE_ADS_CLIENT_SECRET="YOUR_CLIENT_SECRET"
export GOOGLE_ADS_REFRESH_TOKEN="YOUR_REFRESH_TOKEN"
export GOOGLE_ADS_LOGIN_CUSTOMER_ID="MCC_ID_IF_ANY"   # optional
```

Or point at a YAML file:

```bash
export GOOGLE_ADS_CONFIG_PATH=/path/to/google-ads.yaml
```

> Never commit real credentials. `google-ads.yaml` is gitignored.

### 3. Configure your MCP client

Claude Desktop / Claude Code:

```json
{
  "mcpServers": {
    "google-ads-campaign": {
      "command": "google-ads-campaign-mcp",
      "env": {
        "GOOGLE_ADS_DEVELOPER_TOKEN": "...",
        "GOOGLE_ADS_CLIENT_ID": "...",
        "GOOGLE_ADS_CLIENT_SECRET": "...",
        "GOOGLE_ADS_REFRESH_TOKEN": "..."
      }
    }
  }
}
```

Hermes (`~/.hermes/config.yaml`):

```yaml
mcp:
  servers:
    google-ads-campaign:
      command: "google-ads-campaign-mcp"
      env:
        GOOGLE_ADS_DEVELOPER_TOKEN: "..."
        GOOGLE_ADS_CLIENT_ID: "..."
        GOOGLE_ADS_CLIENT_SECRET: "..."
        GOOGLE_ADS_REFRESH_TOKEN: "..."
```

### 4. Smoke test

```bash
# Verify the server boots and tools are listed
python -m google_ads_campaign_mcp --help
# or run a manual JSON-RPC handshake
```

## Usage examples

```text
list_accounts
list_campaigns(customer_id="1234567890")
get_campaign_stats(customer_id="1234567890")
set_campaign_status(customer_id="1234567890", campaign_id="9876543210", status="PAUSED")
update_campaign_budget(customer_id="1234567890", campaign_id="9876543210", daily_budget=50)
list_keywords(customer_id="1234567890", campaign_id="9876543210")
add_keywords(customer_id="1234567890", ad_group_id="555000111", keywords=["car repair sharjah"], match_type="PHRASE")
get_search_terms(customer_id="1234567890")
get_keyword_ideas(customer_id="1234567890", keywords=["car repair"], url="https://example.com")
```

## Notes & known limitations

- `get_keyword_ideas` geo defaults to the UAE region constant (`2764`); override with `GOOGLE_ADS_GEO_ID`.
- Arabic keyword seeds often return empty from the Keyword Planner — use an English seed or a URL seed.
- Keyword Planner requires API v21+; the SDK must be `google-ads>=31.1.0`.
- Mutations are batched in groups of 50 (Google API limit).

## Development

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

## License

MIT — see [LICENSE](LICENSE). Maintained by [Katbi Digital Solutions](https://katbi.net).