google-ads-write-mcp
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| GOOGLE_ADS_DEVELOPER_TOKEN | No | The developer token itself | |
| GOOGLE_ADS_WRITE_AUDIT_LOG | No | Audit log path | ~/.local/share/google-ads-write-mcp/audit.jsonl |
| GOOGLE_ADS_LOGIN_CUSTOMER_ID | No | Manager (MCC) id when the target account sits under one | |
| GOOGLE_ADS_WRITE_MANAGED_LABEL | No | Google Ads label that marks campaigns remove_entity may touch; created in the account on first use | claude-managed |
| GOOGLE_APPLICATION_CREDENTIALS | No | Ads ADC JSON | ~/.config/google-ads-mcp/gcloud/application_default_credentials.json |
| GOOGLE_ADS_DEVELOPER_TOKEN_FILE | No | File holding the developer token | ~/.config/google-ads-mcp/developer-token |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": false
} |
| prompts | {
"listChanged": false
} |
| resources | {
"subscribe": false,
"listChanged": false
} |
| experimental | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| create_responsive_search_adA | Create a NEW responsive search ad in an ad group (existing ads are untouched). headlines: 3-15 items, each <=30 chars; descriptions: 2-4 items, each <=90 chars. An item may be a string or {"text": "...", "pin": "HEADLINE_1|HEADLINE_2|HEADLINE_3|DESCRIPTION_1|DESCRIPTION_2"}. status: ENABLED or PAUSED. Dry run unless confirm=true. |
| add_keywordsA | Add positive keywords to an ad group. keywords: [{"text": "photo to pdf", "match_type": "PHRASE|EXACT|BROAD"}]. Dry run unless confirm=true. |
| add_negative_keywordsA | Add NEGATIVE keywords at campaign level (campaign_id) or ad-group level (ad_group_id). match_type: PHRASE (default) | EXACT | BROAD. Dry run unless confirm=true. |
| add_sitelinksA | Create sitelink assets and attach them to a campaign, or to one ad group when ad_group_id is given (ad-group sitelinks override the campaign's for that ad group). sitelinks: [{"link_text": <=25 chars, "final_url": "https://...", "description1": <=35, "description2": <=35}, ...] Link text must be unique and URLs should differ (Google will not serve two sitelinks with the same URL together). Dry run unless confirm=true. |
| add_calloutsA | Create callout assets (each <=25 chars) and attach them to a campaign. Dry run unless confirm=true. |
| add_structured_snippetA | Create one structured-snippet asset (header e.g. "Types", "Services"; 3-10 values, each <=25 chars) and attach it to a campaign. Dry run unless confirm=true. |
| set_statusA | Set ENABLED or PAUSED on a campaign, ad group, ad (adGroupAds/... |
| set_campaign_target_cpaA | Set the target CPA (in account currency, e.g. 9.5) of a campaign that uses Maximize Conversions. Dry run unless confirm=true. |
| set_campaign_cpc_ceilingA | Set the max CPC bid ceiling (account currency, e.g. 5.0) of a campaign that uses Maximize Clicks (Campaign.target_spend). Pass 0 to remove the ceiling. Dry run unless confirm=true. |
| set_campaign_daily_budgetA | Set a campaign's daily budget (account currency). Refuses if the budget is shared with other campaigns. Dry run unless confirm=true. |
| create_search_campaignA | Create a complete Search campaign in ONE atomic mutate: budget, campaign, location and language criteria, campaign negatives, and every ad group with its keywords and one RSA. The campaign gets the managed label (default "claude-managed"; created in the account on first use) so remove_entity can later act on it. It is created PAUSED; enable it with set_status. locations: geo target constant ids (United States = 2840); location targeting is created presence-only (positive and negative geo_target_type = PRESENCE). languages: language constant ids (English = 1000); an empty list means "all languages" (no language criterion is created). bidding: MAXIMIZE_CONVERSIONS (optional target_cpa) or MAXIMIZE_CLICKS (optional cpc_bid_ceiling in account currency; omitted = uncapped). Headlines/descriptions accept plain strings or {"text", "pin": "H1".."H3" | "D1" | "D2"}. Network: Google Search only (no partners, no Display). ad_groups: [{"name", "final_url", "keywords": [{"text","match_type"}], "headlines": [...], "descriptions": [...], "path1", "path2", "status", "final_url_suffix", "negative_keywords": [...]}, ...] negative_keywords: [{"text", "match_type"}] at campaign level. Device bid adjustments (e.g. mobile-only) are a follow-up call to set_device_bid_modifiers with the returned campaign id: the device criteria only exist once the campaign does. Extensions (sitelinks, callouts, snippets, images) are separate tools - call them with the returned campaign id. Dry run unless confirm=true. |
| add_ad_groupA | Add one ad group - with its keywords, optional ad-group negatives, optional final URL suffix and one responsive search ad - to an EXISTING campaign, atomically. Same argument shapes as create_search_campaign's ad_groups entries. Dry run unless confirm=true. |
| add_image_assetsA | Upload image files as image assets and attach them to a Search campaign as AD_IMAGE. images: [{"path": "/absolute/file.png", "field_type": "SQUARE_MARKETING_IMAGE"|"MARKETING_IMAGE", "name": optional asset name}, ...] field_type here declares the SHAPE (1:1 or 1.91:1) and drives local validation; the link itself is always AD_IMAGE, which is the only image field type Search campaigns accept (MARKETING_IMAGE / SQUARE_MARKETING_IMAGE are Performance Max and Display field types). or, to attach an image already in the account: {"asset_resource_name": "customers/../assets/..", "field_type": ...}. PNG or JPEG, <=5 MB, 1:1 >=300x300 or 1.91:1 >=600x314; the file's aspect ratio must match the field_type. Google rejects an image identical to an existing asset (DUPLICATE_ASSET) - pass its asset_resource_name instead. Dry run unless confirm=true. |
| add_business_assetsA | Attach a business name and/or business logo to a Search campaign. business_name (<=25 chars, Google's limit) is created as a TEXT asset and linked as BUSINESS_NAME. For the logo pass logo_path (absolute PNG/JPEG, square within 2%,
|
| remove_entityA | PERMANENTLY remove a campaign, ad group, ad (adGroupAds/...), keyword (adGroupCriteria/...), campaign criterion such as a campaign negative keyword (campaignCriteria/...), or an asset LINK (campaignAssets/..., adGroupAssets/... - the asset itself stays in the account's asset library). resource_name may be one resource name or a list of names of the SAME kind; a list is removed in one atomic mutate. Refuses unless every entity sits under a campaign carrying the managed label (default "claude-managed") - i.e. one created by this server. Google Ads has no restore for removed entities; historical data stays in reports but the entity cannot be re-enabled. Dry run unless confirm=true. |
| set_final_urlsA | Update final URLs and/or final URL suffixes in one atomic mutate. targets: [{"resource_name": <ad (adGroupAds/..~..) | ad group (adGroups/..) | asset (assets/..)>, "final_url": "https://..." (ads and assets), "final_url_suffix": "utm_..." or "" to clear (ad groups and ads)}, ...] Ads keep their text and history: Google allows changing an ad's final URLs in place. Typical use: move UTMs from an ad-group suffix into the final URL itself, or retag a campaign. Dry run unless confirm=true. |
| update_responsive_search_adA | Edit an EXISTING responsive search ad in place (AdService update): the ad keeps its id and reporting history, goes back through policy review, and its asset performance labels / Ad Strength reset. Every argument left None is unchanged. headlines / descriptions, when given, REPLACE the whole list (3-15 headlines <=30 chars, 2-4 descriptions <=90 chars; items are strings or {"text", "pin": "HEADLINE_1|HEADLINE_2|HEADLINE_3|DESCRIPTION_1|DESCRIPTION_2"}). path1 / path2: "" clears. ad_id: the numeric ad id or an adGroupAds/~ resource name. Dry run unless confirm=true. |
| set_campaign_final_url_suffixA | Set the CAMPAIGN-level final URL suffix, or clear it with "". Google appends the suffix to every final URL in the campaign at click time and substitutes ValueTrack tokens, e.g. "utm_term={keyword}&kw_match={matchtype}&device={device}". An ad-group or ad suffix overrides the campaign's, so keep the suffix at one level. Ads, their text and history are untouched. Dry run unless confirm=true. |
| set_device_bid_modifiersA | Set campaign-level device bid adjustments in percent (-100 to +900). -100 excludes the device: a mobile-only Search campaign is desktop=-100, tablet=-100. Smart Bidding strategies honour only the -100 case; other values are advisory under Maximize conversions / tCPA. Leave a device None to keep it unchanged. Dry run unless confirm=true. |
| set_location_bid_modifiersA | Set campaign-level LOCATION bid adjustments in percent (-90 to +900) on locations the campaign already targets. modifiers maps a geo target constant id (2840 = US, 2344 = Hong Kong; also accepts "geoTargetConstants/2840") to the adjustment: {"2840": 30, "2344": -30}. 0 removes an adjustment. Honoured by Manual CPC and Maximize clicks; Smart Bidding (tCPA / Maximize conversions) ignores location adjustments. Targeting is never changed: a geo the campaign does not target is rejected. One atomic mutate; dry run unless confirm=true. |
| keyword_ideasA | Keyword Planner ideas with US-style monthly search volume and bid ranges. READ-ONLY: creates nothing, so there is no confirm flag. Costs one API operation per call, rate-limited to 1/second. seeds: up to 20 seed keywords; url: a landing page to seed from (either or both).
geo_target_ids: geo target constant ids (default [2840] = United States); language_id: language
constant id (default 1000 = English). Google Search network only (no partners).
Returns ideas sorted by avg_monthly_searches desc, up to |
| audit_log_tailA | Return the last n entries of this server's local audit log (dry runs and applied changes). |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/Luxand/google-ads-write-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server