google-ads-manager-mcp
# Google Ads Manager MCP
> Unofficial, community-maintained project. Not affiliated with, endorsed by, or sponsored by
> Google. "Google Ads" is a trademark of Google LLC.
A local MCP (Model Context Protocol) server that lets an AI assistant read and manage a Google Ads
account: run GAQL reports, create campaigns, pause/enable campaigns, and add keywords.
Google also publishes an [official Google Ads MCP server](https://github.com/googleads/google-ads-mcp),
which is **read-only** (reporting/diagnostics only). This project covers the same reporting ground
and adds **write** support — creating and editing campaigns, budgets, ad groups, keywords, and ads —
gated behind a draft/confirm safety layer so nothing changes in your account by accident.
Every write goes through a **draft → confirm** safety flow: the tool that "creates" or "updates"
something only validates the change against Google's API (`validate_only`) and hands back a
`draftId` with a preview. Nothing changes in your Ads account until you call `confirm_write` with
that `draftId`. Drafts expire after 10 minutes.
## Tools
Read-only:
- `list_accessible_customers` — which accounts this refresh token can reach
- `search_gaql` — run any raw GAQL `SELECT` query
- `get_campaigns` — campaigns with status, budget, and core metrics
- `get_ad_groups` — ad groups (optionally filtered to a campaign) with metrics
- `get_keywords` — keyword criteria with match type, status, and metrics
- `get_search_terms` — actual search terms that triggered your ads, for finding negative keyword candidates
Write (draft → confirm):
- `create_campaign` — new campaign + budget, created `PAUSED` unless you say otherwise
- `update_campaign_status` — enable / pause / remove a campaign
- `update_campaign_budget` — change an existing campaign's daily budget
- `add_keywords` — add keyword criteria to an ad group
- `create_ad_group` — new ad group inside an existing campaign
- `update_ad_group_status` — enable / pause / remove an ad group
- `update_keyword_status` — enable / pause / remove a keyword criterion
- `add_negative_keywords` — add negative keyword criteria to an ad group
- `create_responsive_search_ad` — new responsive search ad, created `PAUSED` unless you say otherwise
- `confirm_write` — execute a previously returned `draftId` for real
## Setup
### 1. Google Ads developer token
Google Ads → Tools & Settings → **API Center**. Test-account tokens are issued instantly; a
production-level token requires Google's manual review (roughly 1-2 weeks), so apply for that
early if you'll use this beyond a test account.
### 2. OAuth client
Google Cloud Console → APIs & Services → Credentials → **Create credentials → OAuth client ID**.
Choose application type **Desktop app**. Copy the client ID and client secret.
### 3. Configure environment
```bash
cp .env.example .env
```
Fill in `GOOGLE_ADS_CLIENT_ID`, `GOOGLE_ADS_CLIENT_SECRET`, `GOOGLE_ADS_DEVELOPER_TOKEN`, and
`GOOGLE_ADS_CUSTOMER_ID` (the account this server should manage — 10 digits, dashes optional). If
that account is a client under a manager (MCC) account, also set `GOOGLE_ADS_LOGIN_CUSTOMER_ID` to
the manager account's ID.
### 4. Get a refresh token
```bash
npm install
npm run auth
```
This opens an authorization URL — open it, sign in with the Google account that has access to
your Ads account, approve the `adwords` scope. The script prints a `GOOGLE_ADS_REFRESH_TOKEN`;
add it to `.env`.
### 5. Build
```bash
npm run build
```
### 6. Point your MCP client at it
For Claude Desktop / Claude Code, add to your MCP config:
```json
{
"mcpServers": {
"google-ads-manager": {
"command": "node",
"args": ["/absolute/path/to/google ads manger mcp/build/index.js"],
"env": {
"GOOGLE_ADS_CLIENT_ID": "...",
"GOOGLE_ADS_CLIENT_SECRET": "...",
"GOOGLE_ADS_DEVELOPER_TOKEN": "...",
"GOOGLE_ADS_REFRESH_TOKEN": "...",
"GOOGLE_ADS_CUSTOMER_ID": "..."
}
}
}
}
```
(Or skip the `env` block and just make sure `.env` is populated — the server loads it via
`dotenv` when run directly, e.g. `npm run dev` during local iteration.)
## Notes
- This is scoped to a **single** Google Ads account (`GOOGLE_ADS_CUSTOMER_ID`). To manage several
client accounts under one manager account, either run one instance per customer ID, or extend
`googleAdsClient.ts` to accept a `customerId` argument per tool call.
- New campaigns default to `PAUSED` (`startEnabled: false`) so nothing spends until you explicitly
enable it.
## Contributing
Issues and PRs welcome — new report types, negative-keyword-at-campaign-level support, and
multi-account (MCC) handling are the most useful next additions.
## License
[MIT](LICENSE)
TDQS
Scored across 16 tools
Each tool targets a distinct resource and action: reads (list_accessible_customers, search_gaql, get_campaigns, get_ad_groups, get_keywords, get_search_terms) vs writes (create_campaign, create_ad_group, etc.), with status updates and budget updates cleanly separated. The only potential overlap is search_gaql vs get_* tools, but search_gaql is explicitly for raw GAQL queries beyond the standard retrievers, so ambiguity is minimal.
All tools follow a consistent verb_noun pattern in snake_case (e.g., list_accessible_customers, update_campaign_status, create_responsive_search_ad). Even the special confirm_write uses the same verb-first convention. No mixed styles or unpredictable variations.
16 tools is slightly above the typical 3-15 range but appropriate for a Google Ads manager covering campaigns, ad groups, keywords, ads, search terms, and budgets. The count reflects the breadth of the domain without feeling bloated or redundant.
The surface covers the core lifecycle: listing customers, querying reports, reading and writing campaigns, ad groups, keywords, negative keywords, and responsive search ads, plus status/budget updates and a confirmation mechanism. Minor gaps exist (e.g., editing or removing ads, more ad types), but GAQL search and the existing create/update/remove operations cover most workflows.