google-ads-write-mcp

google-ads-write-mcp

MCP server that exposes write operations on Google Ads, enabling management of campaigns, ad groups, keywords, RSA ads, sitelinks, images, Customer Match audiences, and recommendations.

Category
Visit Server

README

google-ads-write-mcp

MCP server that exposes write operations on Google Ads: campaigns, ad groups, keywords, RSA ads, sitelinks, images, Customer Match audiences and recommendations.

Complements the official google-ads MCP (read-only). Use the official one (or google-ads-kw-mcp) to read data, this one to write.

Tools (26)

Campaigns

Tool What it does
update_campaign_status Pause, enable or remove a campaign
update_campaign_budget Change the daily budget (locates the budget entity automatically)

Ad groups

Tool What it does
update_ad_group_status Pause, enable or remove an ad group
update_ad_group_cpc_bid Change the ad group's max CPC bid

Keywords

Tool What it does
add_keywords Add keywords to an ad group (BROAD/PHRASE/EXACT, optional bid)
update_keyword_status Pause, enable or remove a keyword
update_keyword_bid Change a keyword's CPC bid
add_negative_keywords Add negative keywords at campaign level

RSA ads

Tool What it does
update_rsa_headlines Replace headlines (and optionally descriptions) of an RSA

Sitelinks

Tool What it does
create_sitelink_asset Create a sitelink asset
link_sitelink_to_campaign Link the sitelink to a campaign

Ad assets

Tool What it does
create_callout_asset Create a callout text (max 25 chars)
create_call_asset Create a call extension with a phone number
create_structured_snippet_asset Create a structured snippet (header + list of values)
link_asset_to_campaign Link any asset to a campaign (SITELINK, CALLOUT, CALL, STRUCTURED_SNIPPET, MARKETING_IMAGE…)

Images

Tool What it does
upload_image_asset Download an image from a URL and upload it as an asset (Display/PMax)

Audiences / Customer Match

Tool What it does
list_user_lists List all audiences (remarketing + Customer Match)
create_customer_match_list Create a new Customer Match list
upload_customer_match_emails Upload emails to a list (SHA-256 hashing done automatically)

Create full campaigns

Tool What it does
create_campaign Create a Search or Performance Max campaign (budget, bid, country, language, EU political-ads flag)
create_ad_group Create an ad group inside a Search campaign
create_rsa Create a full RSA ad (3–15 headlines, 2–4 descriptions, URL, display paths)
create_asset_group Create a PMax asset group (headlines, long headlines, descriptions, images, logo)

Recommendations

Tool What it does
list_recommendations List pending recommendations (optional type filter)
apply_recommendation Apply a recommendation
dismiss_recommendation Dismiss a recommendation

Setup

Same credentials as google-ads-kw-mcp — you can point both at the same credentials.json.

python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

MCP client configuration

{
  "mcpServers": {
    "google-ads-write": {
      "command": "/path/to/.venv/bin/python3",
      "args": ["/path/to/google-ads-write-mcp/server.py"],
      "env": {
        "GOOGLE_ADS_CREDENTIALS_PATH": "~/.config/google-ads-mcp/credentials.json",
        "GOOGLE_ADS_DEVELOPER_TOKEN": "<your developer token>",
        "GOOGLE_ADS_LOGIN_CUSTOMER_ID": "<your MCC customer id, no dashes>"
      }
    }
  }
}

Confirmation required for critical operations

These tools require confirmed=True. Called without it, they return a JSON with requires_confirmation: true that the calling agent MUST show to the user and wait for a response before repeating the call with confirmed=True.

Tool When it asks for confirmation
update_campaign_status status = PAUSED or REMOVED
update_campaign_budget always
update_ad_group_status status = REMOVED
# 1. First call — no confirmed
update_campaign_status(customer_id="1234567890", campaign_id="111222333", status="PAUSED")
# → returns requires_confirmation: true → show it to the user

# 2. Second call — after the user confirms
update_campaign_status(customer_id="1234567890", campaign_id="111222333", status="PAUSED", confirmed=True)

Gotchas found in production use

Auth

  • Never use gcloud auth print-access-token — that token doesn't carry the adwords scope → 403. The only valid source is the refresh_token against oauth2.googleapis.com/token, which this server already does correctly.

Negatives vs. positives

  • Adding a negative EXACT keyword to an ad group where the same keyword already exists as a positive EXACT match returns IMMUTABLE_FIELD. The fix is to pause the positive instead of adding the negative.

Resource names

  • adGroupCriteria resource names always need a ~ between the ad group ID and the criterion ID: customers/{cid}/adGroupCriteria/{ag_id}~{crit_id}.

GAQL field limits

  • ad_group_criterion doesn't accept metrics (clicks, cost, conversions) in the same query — query search_term_view separately for performance data.
  • Filter ad_group_criterion by campaign with WHERE ad_group.campaign = 'customers/{cid}/campaigns/{campaign_id}', not campaign_id directly.

Budgets

  • The budget is a separate entity (CampaignBudget). If a campaign shares a budget with others, changing it affects all of them.

contains_eu_political_advertising

  • This is an enum (EuPoliticalAdvertisingStatus), not a bool. False serializes as UNSPECIFIED, which the API rejects as "not present". Use DOES_NOT_CONTAIN_EU_POLITICAL_ADVERTISING explicitly.

PMax with Brand Guidelines

  • If the account has Brand Guidelines enabled, PMax campaigns need a business_name and a logo (min. 128×128px, square) linked as CampaignAsset at creation time — not after.

RSA headline updates

  • Use AdService.mutate_ads() with field mask "responsive_search_ad.headlines". Using AdGroupAdService with "ad.responsive_search_ad.headlines" gives IMMUTABLE_FIELD.

Removing a keyword

  • Use the remove operation on AdGroupCriterionOperation. Trying an update with status = REMOVED gives INVALID_ENUM_VALUE.

REMOVED resources are immutable

  • No write operation works on ad groups, keywords or ads whose parent campaign has status = REMOVED (OPERATION_NOT_PERMITTED_FOR_REMOVED_RESOURCE).

Customer Match allowlist

  • upload_customer_match_emails fails with CUSTOMER_NOT_ALLOWLISTED_FOR_THIS_FEATURE unless your developer token has explicit Customer Match access. create_customer_match_list works without it — only the email upload needs the allowlist.

Notes

  • Monetary amounts are passed in the account's currency units and converted to micros internally (1 unit = 1,000,000 micros).
  • customer_id is always passed without dashes.
  • update_rsa_headlines replaces ALL current headlines — pass the full desired list, not just the new ones.
  • Customer Match lists can take up to 48h to process on Google's side.

License

MIT — see LICENSE.

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured