A comprehensive Google Ads MCP server providing ~47 tools for full read/write access to Google Ads accounts. Built for Claude Desktop, Claude Code, and other MCP-compatible clients.
- Accounts — list accessible accounts, get account info, MCC hierarchy
- Campaigns — full CRUD for Search, Display, Video, Demand Gen campaigns
- Ad Groups — create, update, list, and manage ad groups
- Ads — RSA, Responsive Display, Video, and Demand Gen ad creation
- Keywords — add, remove, update bids, get performance
- Performance Max — complete PMax support: asset groups, assets, audience signals
- Budgets — create, update, list, and check utilization
- Reporting — flexible GAQL queries, campaign/ad group/keyword performance
- Utilities — GAQL resource discovery, field metadata, micros conversion
- Python 3.12+
- uv for dependency management
- Google Ads API credentials (developer token, GCP service account JSON key)
git clone https://github.com/bertramdev/GoogleAdsMCP.git
cd GoogleAdsMCP
uv syncCopy .env.example to .env and fill in your credentials:
cp .env.example .envRequired environment variables:
GOOGLE_ADS_DEVELOPER_TOKEN— your API developer tokenGOOGLE_ADS_SERVICE_ACCOUNT_PATH— path to GCP service account JSON key fileGOOGLE_ADS_LOGIN_CUSTOMER_ID— MCC customer ID (if using MCC)
Optional:
GOOGLE_ADS_IMPERSONATED_EMAIL— Workspace user email for domain-wide delegationGOOGLE_ADS_CUSTOMER_ID— default customer ID for operations
uv run google-ads-mcpAdd to claude_desktop_config.json:
{
"mcpServers": {
"google-ads": {
"command": "uv",
"args": ["run", "--directory", "/path/to/GoogleAdsMCP", "google-ads-mcp"],
"env": {
"GOOGLE_ADS_DEVELOPER_TOKEN": "...",
"GOOGLE_ADS_SERVICE_ACCOUNT_PATH": "/path/to/service-account.json",
"GOOGLE_ADS_LOGIN_CUSTOMER_ID": "...",
"GOOGLE_ADS_IMPERSONATED_EMAIL": "user@yourdomain.com"
}
}
}
}Add to .mcp.json in the project root:
{
"mcpServers": {
"google-ads": {
"command": "uv",
"args": ["run", "--directory", "/path/to/GoogleAdsMCP", "google-ads-mcp"],
"env": {
"GOOGLE_ADS_DEVELOPER_TOKEN": "...",
"GOOGLE_ADS_SERVICE_ACCOUNT_PATH": "/path/to/service-account.json",
"GOOGLE_ADS_LOGIN_CUSTOMER_ID": "...",
"GOOGLE_ADS_IMPERSONATED_EMAIL": "user@yourdomain.com"
}
}
}
}All tools include MCP tool annotations (readOnlyHint, destructiveHint, etc.) so clients can make informed permission decisions. However, Claude Code requires explicit allow rules — annotations alone don't auto-approve tools.
Within this project: The project-level .claude/settings.json auto-allows read-only tools (get_*, list_*, execute_gaql, convert_micros). Write tools require approval on each use.
From other projects: Project-level permissions don't apply. To allow all tools globally, add to ~/.claude/settings.json:
{
"permissions": {
"allow": [
"mcp__google-ads__*"
]
}
}Or for read-only tools only:
{
"permissions": {
"allow": [
"mcp__google-ads__get_*",
"mcp__google-ads__list_*",
"mcp__google-ads__execute_gaql",
"mcp__google-ads__convert_micros"
]
}
}This MCP server cannot modify account access, user permissions, login credentials, billing, or payment methods. There are no tools for account administration — a compromised server cannot lock anyone out of their account.
Worst-case impact if credentials are compromised:
| Risk | Details |
|---|---|
| Financial | Creating campaigns/budgets or increasing keyword bids could spend money |
| Disruption | Pausing/removing campaigns, keywords, or ad groups |
| Data exposure | Reading account performance, search terms, and campaign details. execute_gaql can also read sensitive resources like customer_user_access and billing_setup (read-only — no mutations possible via GAQL) |
Removal tools (remove_campaign, remove_keyword, remove_asset_from_group) require confirm_removal=True as a server-side safety guard. The set_*_status tools execute immediately without a confirmation parameter.
uv run pytestlist_accessible_accounts— List accounts accessible via credentialsget_account_info— Account details (name, currency, timezone)get_account_hierarchy— MCC hierarchy tree
list_campaigns— List campaigns with optional status filterget_campaign— Single campaign detailscreate_campaign— Create Search/Display campaign with budgetupdate_campaign— Update name, bidding strategy, etc.set_campaign_status— Enable/pause/removeremove_campaign— Soft delete with confirm
list_ad_groups— List ad groups in campaignget_ad_group— Ad group detailscreate_ad_group— Create ad group with bidupdate_ad_group— Update name, bid, statusset_ad_group_status— Enable/pause/remove
list_ads— List ads in ad groupcreate_responsive_search_ad— RSA for Search campaignscreate_responsive_display_ad— Responsive display adcreate_video_ad— Video ad for YouTubecreate_demand_gen_ad— Demand Gen adset_ad_status— Enable/pause/removeget_ad_details— Full ad details
list_keywords— List keywords in ad groupadd_keywords— Add keywords with match types (batch)remove_keyword— Remove keywordupdate_keyword_bid— Update CPC bidget_keyword_performance— Keyword metrics
create_performance_max_campaign— Full PMax campaign creationlist_asset_groups— List asset groups in PMax campaignget_asset_group_details— Asset group details with linked assetsadd_assets_to_group— Add assets to asset groupremove_asset_from_group— Remove asset from asset groupadd_audience_signal— Add audience/search theme signalsget_asset_performance— Asset-level performance labelsget_pmax_placement_performance— Channel breakdown
list_budgets— List campaign budgetscreate_budget— Create shared budgetupdate_budget— Update budget amountget_budget_utilization— Budget vs actual spend
execute_gaql— Flexible GAQL query executionget_campaign_performance— Campaign metricsget_ad_group_performance— Ad group metricsget_search_terms_report— Search terms reportget_keyword_performance_report— Keyword metricsget_account_performance_summary— Account daily summary
list_gaql_resources— Available GAQL resourcesget_field_metadata— Field metadata for a resourceconvert_micros— Micros to currency conversion
Apache 2.0 — see LICENSE.