google-ads-write-mcp
An MCP server that enables safe, audited mutation of Google Ads campaigns—creating ads, ad groups, keywords, and assets or adjusting budgets and statuses—with a dry-run default and an optional guarded remove operation, plus read-only Keyword Planner ideas.
README
google-ads-write-mcp
A small, allow-listed write-side MCP server for Google Ads, plus a read-only
Keyword Planner tool. It is the companion to Google's official
google-ads-mcp, which is
read-only by design: use that one to look things up, and this one to change them.
Works with Claude Code (and any MCP client over stdio).
Safety model
- Dry run by default. Every mutating tool sends its request with
validate_only=true— Google checks auth and payload and changes nothing. Passconfirm=trueto apply. - Atomic. Each call is one
MutateGoogleAdsRequestwith partial failure off: either everything in it is created, or nothing is. - Additive. Tools add ads, keywords, assets, ad groups and campaigns, or toggle ENABLED/PAUSED, or tune budget and target CPA. Nothing edits existing ad text. New campaigns are created PAUSED.
- One guarded delete.
remove_entityrefuses anything that does not sit under a campaign carrying the managed label (defaultclaude-managed, whichcreate_search_campaignattaches to every campaign it creates), and verifies that with a read query first. Removal in Google Ads is permanent; there is no restore. - Audited. Every call — dry run or applied, success or rejection — is appended to a local JSONL audit log with timestamp, tool, customer, payload and API result. No secrets are written.
- Local limits. RSA headline/description counts and lengths, sitelink, callout and snippet lengths, image size and aspect ratio are checked before anything is sent.
Tools
| Tool | Purpose |
|---|---|
create_search_campaign |
Build a complete Search campaign in one atomic mutate: budget, campaign, location and language criteria, campaign negatives, the managed label, every ad group with its keywords, optional ad-group negatives, optional final URL suffix (UTMs) and one responsive search ad. Created PAUSED; Google Search only; Maximize conversions (optional target CPA) or Maximize clicks |
add_ad_group |
Add one ad group with keywords, optional negatives, optional final URL suffix and one RSA to an existing campaign |
create_responsive_search_ad |
Add a new RSA to an ad group (existing ads untouched) |
add_keywords |
Add positive keywords to an ad group |
add_negative_keywords |
Add negatives at campaign or ad-group level |
add_sitelinks / add_callouts / add_structured_snippet |
Create the assets and attach them to a campaign; add_sitelinks can attach to one ad group instead (ad_group_id) |
add_image_assets |
Upload PNG/JPEG files and attach them to a Search campaign (AD_IMAGE); validates 1:1 / 1.91:1 shape, minimum size and 5 MB cap |
set_status |
ENABLED / PAUSED on a campaign, ad group, ad or keyword |
set_campaign_daily_budget |
Change a campaign's non-shared daily budget |
set_campaign_target_cpa |
Set tCPA on a Maximize-conversions campaign |
set_final_urls |
Update final URLs (ads, assets) and final URL suffixes (ad groups, ads) in one atomic mutate — e.g. move UTMs into the final URL itself |
set_device_bid_modifiers |
Campaign-level device bid adjustments in percent; −100 excludes a device (mobile-only = desktop −100, tablet −100). Call it after create_search_campaign with the returned campaign id |
remove_entity |
Permanently remove a campaign, ad group, ad, keyword, campaign criterion (e.g. a campaign negative) or an asset link (campaign/ad-group asset) — one resource name or a list of the same kind, atomically — only under a campaign carrying the managed label |
keyword_ideas |
Keyword Planner ideas with monthly volume and bid ranges (read-only, 1 request/second) |
audit_log_tail |
Last N audit-log entries |
Customer ids may contain dashes. Use the read-only MCP first to look up campaign and ad-group ids and resource names.
Prerequisites
You need the same three things the official read-only server needs — this package creates none of them:
- A Google Ads API developer token (from a manager account's API Center).
- An OAuth client in a Google Cloud project, and an Ads ADC file produced by
gcloud auth application-default login --scopes=https://www.googleapis.com/auth/adwords(anauthorized_userJSON with client id, client secret and refresh token). - Edit access on the Google Ads accounts you intend to change. Read-only users can query but every mutate is rejected.
Keep the token and the ADC file out of any repository.
Install
pipx install "git+https://github.com/Luxand/google-ads-write-mcp@v0.5.2"
google-ads-write-mcp --check # shows which credential files it found; no secrets printed
google-ads-write-mcp --list-tools
The install is pinned to a tag, so pipx upgrade will not move it; upgrade
with pipx install --force "git+https://github.com/Luxand/google-ads-write-mcp@<new tag>".
Configuration
Everything is optional if the defaults fit:
| Variable | Meaning | Default |
|---|---|---|
GOOGLE_ADS_DEVELOPER_TOKEN |
the token itself | — |
GOOGLE_ADS_DEVELOPER_TOKEN_FILE |
file holding the token | ~/.config/google-ads-mcp/developer-token |
GOOGLE_APPLICATION_CREDENTIALS |
Ads ADC JSON | ~/.config/google-ads-mcp/gcloud/application_default_credentials.json |
GOOGLE_ADS_LOGIN_CUSTOMER_ID |
manager (MCC) id when the target account sits under one; GOOGLE_ADS_MCP_LOGIN_CUSTOMER_ID is accepted as an alias |
none |
GOOGLE_ADS_WRITE_AUDIT_LOG |
audit log path | ~/.local/share/google-ads-write-mcp/audit.jsonl |
GOOGLE_ADS_WRITE_MANAGED_LABEL |
Google Ads label that marks campaigns remove_entity may touch; created in the account on first use |
claude-managed |
A login customer id applies to the whole client, so register one server entry per manager context you need.
Register in Claude Code
# direct accounts
claude mcp add --scope user google-ads-write -- "$(command -v google-ads-write-mcp)"
# accounts under a manager
claude mcp add --scope user google-ads-write-luxand \
--env GOOGLE_ADS_LOGIN_CUSTOMER_ID=1234567890 \
-- "$(command -v google-ads-write-mcp)"
Then in Claude Code, /mcp should list the server and its tools. A safe first
call is audit_log_tail, then any tool without confirm (a dry run).
Scripted use
--call TOOL ARGS.json runs one tool from a JSON file through the same code
path, same dry-run default and same audit log:
google-ads-write-mcp --call create_search_campaign /abs/path/campaign.json
Useful for pushing a large campaign generated from a spreadsheet, where passing
hundreds of keywords as chat tool arguments is impractical. Add "confirm": true
to the JSON to apply.
Things the API taught us
- Search campaigns accept image assets only as
AD_IMAGE;MARKETING_IMAGE/SQUARE_MARKETING_IMAGEare Performance Max and Display field types and are rejected withFIELD_TYPE_INCOMPATIBLE_WITH_CAMPAIGN_TYPE. contains_eu_political_advertisingis required on campaign creation in current API versions; this server sets it to "does not contain".- Geo and language criteria are plain resource names
(
geoTargetConstants/2840,languageConstants/1000). GenerateKeywordIdeasis limited to 1 request per second per customer id and returnsRESOURCE_EXHAUSTEDabove that;keyword_ideasspaces and retries.- A mutate request may hold at most 10,000 operations; a 20-ad-group Search campaign with ~250 keywords is about 370.
- Device criteria (desktop 30000, mobile 30001, tablet 30002) exist implicitly
on every campaign; set a bid modifier by updating
campaignCriteria/<campaign>~<id>. Namebid_modifierin the update mask explicitly: a field mask built by comparing against defaults drops a 0.0 (−100%) value and the request succeeds while changing nothing.
License
MIT.
Recommended Servers
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.
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.
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.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
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.
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.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
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.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.