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).
This server cannot be deployed
Maintenance
ActivitySlowing
ResponsivenessNo issues