MCP server for Google Ads API access via GAQL (Google Ads Query Language). Built by a practitioner managing 25+ ad accounts daily — not a demo.
Part of channel47, the open-source ecosystem of profession plugins for Claude Code. Get the newsletter for weekly skill breakdowns from production use.
- List accounts accessible under your MCC or individual credentials
- Query anything with raw GAQL — campaigns, ad groups, keywords, search terms, assets, any resource
- Mutate entities — campaigns, ad groups, ads, keywords, budgets, assets with dry-run safety
- Resources and prompts — bundled GAQL reference docs and operation templates
Bundled with the media-buyer plugin. No manual install required.
npx @channel47/google-ads-mcp@latestOr install globally:
npm install -g @channel47/google-ads-mcp
google-ads-mcp| Variable | Description |
|---|---|
GOOGLE_ADS_DEVELOPER_TOKEN |
Your Google Ads API Developer Token |
GOOGLE_ADS_CLIENT_ID |
OAuth 2.0 Client ID from Google Cloud |
GOOGLE_ADS_CLIENT_SECRET |
OAuth 2.0 Client Secret |
GOOGLE_ADS_REFRESH_TOKEN |
OAuth 2.0 Refresh Token |
| Variable | Description |
|---|---|
GOOGLE_ADS_LOGIN_CUSTOMER_ID |
MCC Account ID (10 digits, no dashes) |
GOOGLE_ADS_DEFAULT_CUSTOMER_ID |
Default account ID for queries |
GOOGLE_ADS_READ_ONLY |
Set to true to hide the mutate tool entirely — query and list only |
{
"mcpServers": {
"google-ads": {
"command": "npx",
"args": ["-y", "@channel47/google-ads-mcp@latest"],
"env": {
"GOOGLE_ADS_DEVELOPER_TOKEN": "your-developer-token",
"GOOGLE_ADS_CLIENT_ID": "your-client-id",
"GOOGLE_ADS_CLIENT_SECRET": "your-client-secret",
"GOOGLE_ADS_REFRESH_TOKEN": "your-refresh-token",
"GOOGLE_ADS_LOGIN_CUSTOMER_ID": "1234567890",
"GOOGLE_ADS_READ_ONLY": "true"
}
}
}
}Remove GOOGLE_ADS_READ_ONLY or set to false to enable the mutate tool.
List all accessible Google Ads accounts.
Returns: Array of account objects with ID, name, currency, and status.
Execute any GAQL SELECT query. Returns clean JSON results.
Parameters:
-
customer_id(string, optional): Account ID (10 digits, no dashes) -
query(string, required): GAQL SELECT query -
limit(integer, optional): Max rows to return (default: 100, max: 10000)
Example:
{
"customer_id": "1234567890",
"query": "SELECT campaign.name, campaign.status FROM campaign WHERE campaign.status = 'ENABLED'",
"limit": 50
}Execute write operations using GoogleAdsService.Mutate.
Parameters:
-
customer_id(string, optional): Account ID -
operations(array, required): Mutation operations -
partial_failure(boolean, optional): Enable partial failure mode (default: true) -
dry_run(boolean, optional): Validate without executing (default: true for safety)
Example:
{
"customer_id": "1234567890",
"operations": [
{
"campaignOperation": {
"update": {
"resourceName": "customers/1234567890/campaigns/123",
"status": "PAUSED"
},
"updateMask": "status"
}
}
],
"dry_run": false
}RSAs have two different resource types with different mutability:
| Resource | Entity | Use Case |
|---|---|---|
customers/{id}/ads/{ad_id} |
ad |
Update ad content (headlines, descriptions, URLs) |
customers/{id}/adGroupAds/{ad_group_id}~{ad_id} |
ad_group_ad |
Change ad status (pause, enable, remove) |
Update RSA headlines/descriptions (use entity: 'ad'):
{
"operations": [{
"entity": "ad",
"operation": "update",
"resource": {
"resource_name": "customers/1234567890/ads/9876543210",
"responsive_search_ad": {
"headlines": [
{"text": "New Headline 1"},
{"text": "New Headline 2"},
{"text": "New Headline 3"}
],
"descriptions": [
{"text": "New Description 1"},
{"text": "New Description 2"}
]
},
"final_urls": ["https://example.com"]
}
}],
"dry_run": false
}Change RSA status (use entity: 'ad_group_ad'):
{
"operations": [{
"entity": "ad_group_ad",
"operation": "update",
"resource": {
"resource_name": "customers/1234567890/adGroupAds/111222333~9876543210",
"status": "PAUSED"
}
}],
"dry_run": false
}When creating image assets, you can provide a local file path instead of base64 data:
{
"operations": [{
"entity": "asset",
"operation": "create",
"resource": {
"name": "My Image Asset",
"image_file_path": "/path/to/image.png"
}
}]
}The server will automatically read the file and convert it to the required base64 format.
Campaign creation requires specific fields since Google Ads API v19.2 (September 2025):
| Field | Required | Description |
|---|---|---|
name |
Yes | Campaign name |
advertising_channel_type |
Yes | Campaign type (SEARCH, DISPLAY, etc.) |
campaign_budget |
Yes | Reference to budget resource |
bidding strategy |
Yes | One of: manual_cpc, maximize_conversions, target_cpa, etc. |
contains_eu_political_advertising |
Auto | Auto-defaults to DOES_NOT_CONTAIN_EU_POLITICAL_ADVERTISING
|
Complete campaign creation example:
{
"operations": [
// 1. Create budget first (with temp ID for atomic creation)
{
"entity": "campaign_budget",
"operation": "create",
"resource": {
"resource_name": "customers/1234567890/campaignBudgets/-1",
"name": "My Budget",
"amount_micros": 10000000,
"delivery_method": "STANDARD"
}
},
// 2. Create campaign referencing the budget
{
"entity": "campaign",
"operation": "create",
"resource": {
"name": "My Search Campaign",
"advertising_channel_type": "SEARCH",
"status": "PAUSED",
"campaign_budget": "customers/1234567890/campaignBudgets/-1",
"manual_cpc": { "enhanced_cpc_enabled": false },
"network_settings": {
"target_google_search": true,
"target_search_network": true
}
}
}
],
"dry_run": false
}Supported bidding strategies:
-
manual_cpc- Manual cost-per-click -
maximize_conversions- Maximize conversions -
maximize_conversion_value- Maximize conversion value (with optionaltarget_roas) -
target_cpa- Target cost-per-acquisition -
target_spend- Maximize clicks (target spend) -
target_impression_share- Target impression share -
bidding_strategy- Reference to portfolio bidding strategy
git clone https://github.com/channel47/mcps.git
cd mcps
npm install # workspaces — installs all servers
npm test # runs all server tests3 core tools. Dry-run by default. OAuth 2.0 with environment-based credentials.
Pairs with the media-buyer plugin, which adds skills, mutation validation hooks, and GAQL reference docs on top of this server.
- channel47 — open-source profession plugins for Claude Code
- Build Notes — weekly skill breakdowns from production use
- Media Buyer Plugin — the paid-search toolkit this MCP powers
- NPM Package
- Google Ads API / GAQL Reference
- X / LinkedIn / GitHub
MIT