Google Ads MCP Server - Query and mutate Google Ads data using GAQL
npm install @channel47/google-ads-mcp

MCP server for Google Ads API access via GAQL (Google Ads Query Language).
This is a Model Context Protocol (MCP) server that provides tools for querying and mutating Google Ads data using GAQL. It's designed to work seamlessly with Claude Code and other MCP-compatible clients.
This package is automatically installed when using the google-ads-specialist Claude Code plugin. No manual installation required!
For use with other MCP clients or standalone testing:
``bash`
npx @channel47/google-ads-mcp@latest
Or install globally:
`bash`
npm install -g @channel47/google-ads-mcp
google-ads-mcp
Set these environment variables before running:
| 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 |
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 querylimit
- (integer, optional): Max rows to return (default: 100, max: 10000)
Example:
`javascript`
{
"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 IDoperations
- (array, required): Mutation operationspartial_failure
- (boolean, optional): Enable partial failure mode (default: true)dry_run
- (boolean, optional): Validate without executing (default: true for safety)
Example:
`javascript`
{
"customer_id": "1234567890",
"operations": [
{
"campaignOperation": {
"update": {
"resourceName": "customers/1234567890/campaigns/123",
"status": "PAUSED"
},
"updateMask": "status"
}
}
],
"dry_run": false
}
#### Working with Responsive Search Ads (RSAs)
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'):`javascript`
{
"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'):`javascript`
{
"operations": [{
"entity": "ad_group_ad",
"operation": "update",
"resource": {
"resource_name": "customers/1234567890/adGroupAds/111222333~9876543210",
"status": "PAUSED"
}
}],
"dry_run": false
}
#### Creating Image Assets with File Paths
When creating image assets, you can provide a local file path instead of base64 data:
`javascript`
{
"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.
#### Creating Campaigns
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:
`javascript`
{
"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-clickmaximize_conversions
- - Maximize conversionsmaximize_conversion_value
- - Maximize conversion value (with optional target_roas)target_cpa
- - Target cost-per-acquisitiontarget_spend
- - Maximize clicks (target spend)target_impression_share
- - Target impression sharebidding_strategy
- - Reference to portfolio bidding strategy
The server provides:
- Resources: GAQL reference documentation accessible via MCP resources
- Prompts: Templates for common Google Ads operations
This server is designed to work with the google-ads-specialist plugin, which provides:
- 9 Skill Files: Progressive disclosure of GAQL patterns and best practices
- Atomic skills for focused tasks (campaign performance, search terms, wasted spend, etc.)
- Playbooks for comprehensive workflows (account health audit)
- Troubleshooting guides for common errors
- PreToolUse Hook: Validates skill references before query/mutate operations
- Comprehensive Documentation: Setup guides and OAuth configuration help
The plugin ensures Claude consults domain knowledge before executing queries, preventing hallucinated GAQL.
- Node.js 18 or higher
- Google Ads API access (Developer Token)
- OAuth 2.0 credentials from Google Cloud
`bash`
git clone https://github.com/channel47/google-ads-mcp-server.git
cd google-ads-mcp-server
npm install
`bash`
npm test
`bash``
npm start
Minimal Design:
- ~200 lines of server code
- 3 core tools (list, query, mutate)
- OAuth 2.0 authentication
- Resources for GAQL reference
- Prompts for common patterns
Security:
- Dry-run mode enabled by default for mutations
- Environment-based credential management
- Input validation for all operations
Contributions welcome! Please:
1. Fork the repository
2. Create a feature branch
3. Make your changes with tests
4. Submit a pull request
- NPM Package
- GitHub Repository
- Claude Code Plugin
- Google Ads API Documentation
- GAQL Reference
- Model Context Protocol
MIT - See LICENSE file for details.
For issues or questions:
- Plugin-related: Plugin Repository Issues
- Server-related: Server Repository Issues