mcpbeat Sign in

Ads MCP Server

answering

Ads is answering right now. Last checked 11 min ago. It exposes 234 tools. Last commit 13 Sep 2026.

Manage Google, Meta, Amazon, TikTok, LinkedIn & ChatGPT ads. 430 tools for campaigns & analytics.

Uptime history 47 days of history
47 days agonow
100.0%
Uptime 24h
91 of 91 checks
234
Tools
read from the server
340 ms
Response time
average over 24h
93
Stars
last commit 13 Sep 2026

Nothing serious here today

Today is the operative word: we check Ads every 15 minutes and re-read its code on every release. Watch it and you find out the day that stops being true.

Three servers free · no card

Connect this server

Endpoint below is the one we actually reach during checks — not the one copied from a README. Last verified 11 min ago.

run in your terminal
claude mcp add ads --transport http https://mcp.adspirer.com/mcp
~/Library/Application Support/Claude/claude_desktop_config.json
{
  "mcpServers": {
    "ads": {
      "url": "https://mcp.adspirer.com/mcp"
    }
  }
}
~/.codex/config.toml
[mcp_servers.ads]
url = "https://mcp.adspirer.com/mcp"
.cursor/mcp.json
{
  "mcpServers": {
    "ads": {
      "url": "https://mcp.adspirer.com/mcp"
    }
  }
}
.vscode/mcp.json
{
  "mcpServers": {
    "ads": {
      "url": "https://mcp.adspirer.com/mcp"
    }
  }
}

This endpoint answered with an authorization challenge. The server is running, but you need an API key from its owner to call it.

Available tools 234

Read directly from the server with tools/list, grouped by what they act on. If a tool disappears, we record the date.

meta
add_meta_ad
User wants to add another ad/creative variation to an EXISTING ad set. DO NOT USE to create a new campaign. For new campaigns: - Video campaign - `create_meta_video_campaign` - Image campaign - `create_meta_image_campaign` - Carousel campaign - `create_meta_carousel_campaign` Common scenarios: - A/B test ad copy: Different headlines, primary text, or CTAs for the same audience - A/B test creatives: Different images or videos for the same audience - Format testing within one audience: Image vs video ad in the same ad set - Dynamic Creative (DCO): Multiple images + text variations in one ad — Meta auto-optimizes KEY DISTINCTION — add_meta_ad vs add_meta_ad_set: - Same audience, different creative/copy - use THIS tool (add_meta_ad) - Different audience/targeting - use `add_meta_ad_set` instead (creates a new ad set) Ads in the same ad set SHARE: targeting, budget, schedule, pixel tracking. Each ad has its OWN: creative (image/video/carousel), headline, primary text, CTA, landing page. IMPORTANT: You need an ad_set_id from a previously created ad set. Use `list_meta_ad_sets` first if you don't have the ad_set_id. Supports all 3 ad types + Dynamic Creative: - `image`: Different image + copy variation - `video`: Different video + copy variation - `carousel`: Different card set + copy variation - **Dynamic Creative (DCO)**: Pass `image_urls` (2-10 images), `headlines` (up to 5), `primary_texts` (up to 5), `descriptions` (up to 5). Meta tests ALL combinations and optimizes delivery automatically. Dynamic Creative Optimization (DCO) workflow: 1. Create ad set with `is_dynamic_creative=true` via `add_meta_ad_set` 2. Call this tool with `image_urls` (list of 2-10 image URLs), plus optional `headlines`, `primary_texts`, `descriptions` arrays 3. Meta will test all image × headline × text combinations and optimize 4. DCO ad sets support only 1 ad — if the ad set already has is_dynamic_creative enabled, this tool auto-detects it Note: Cannot mix image_urls (DCO) with image_url (single image) or placement-specific images. Standard workflow: 1. Get ad_set_id from prior campaign creation or `list_meta_ad_sets` 2. Write variant ad copy (different headline/primary_text/image) 3. Call this tool with ad_set_id + new creative + copy
add_meta_ad_set
User wants to add a new ad set to an EXISTING campaign. Common scenarios: - Audience testing: Same ad format, different targeting/interests per ad set (e.g., "4 ad sets with different interests") - Multi-format: Different ad types (image + video + carousel) under one campaign - Budget split: Same creative, different budgets per audience segment - Scaling: Adding new audiences/markets to an existing campaign WhatsApp campaigns (destination_type='WHATSAPP'): if the customer's Page has more than one WhatsApp number, ASK WHICH ONE should receive conversations and pass whatsapp_phone_number. Leave it out and Meta picks a number itself, which may not be the one they expect. - Geographic split: Same ad, different locations per ad set - Dynamic Creative (DCO): Set is_dynamic_creative=true, then use add_meta_ad with image_urls/headlines/primary_texts CRITICAL: Each `create_meta_*_campaign` creates a NEW campaign. To add more ad sets to the SAME campaign, you MUST use this tool. NEVER call create_meta_*_campaign again for the same campaign. IMPORTANT: You need a campaign_id from a previously created campaign. Use `get_meta_campaign_details` first if you don't have the campaign_id. Supports all 3 ad types: - `image`: Provide image_url, existing_image_hash, or asset_bundle_id - `video`: Provide video_url or existing_video_id - `carousel`: Provide cards array (2-10 cards) Dynamic Creative Optimization (DCO): - Set `is_dynamic_creative=true` when creating the ad set - Then use `add_meta_ad` with `image_urls` (2-10), `headlines` (up to 5), `primary_texts` (up to 5) to add a DCO ad - Meta automatically tests all asset combinations and optimizes delivery - DCO ad sets support only 1 ad — one ad with multiple asset variations Each ad set has INDEPENDENT: targeting, budget, schedule, pixel/conversion tracking. Shared from campaign: objective, campaign name. **CBO (Advantage Campaign Budget) campaigns:** If the campaign uses CBO (campaign_budget_optimization=true when created), you MUST: - Set `campaign_budget_optimization: true` on this tool call - Do NOT set `budget_daily` (budget is managed at campaign level) - Optionally set `daily_min_spend_target` and `daily_spend_cap` to control spend distribution If the campaign does NOT use CBO, `budget_daily` is required as usual. Workflow: 1. Create initial campaign with `create_meta_*_campaign` - get campaign_id 2. Call this tool with the campaign_id for each additional ad set 3. Use `add_meta_ad` to add more ad copies/creatives within any ad set
add_meta_catalog_ad
User wants to add ANOTHER catalog ad to an existing catalog ad set — e.g. to test multiple creatives (different copy, CTA, or product set on the creative) within one ad set. Adds the ad PAUSED.
add_meta_catalog_ad_set
User wants to add ANOTHER ad set to an existing Advantage+ Catalog campaign — e.g. one campaign running multiple strategies in parallel: ad set A = prospecting, ad set B = viewed-not-purchased retargeting, ad set C = a different product set or budget. Each catalog ad set independently controls its product set, audience strategy, budget, targeting, and retention window. The catalog is inherited from the parent campaign. Use this AFTER create_meta_catalog_campaign to layer on more ad sets. Adds the ad set + its first catalog ad, PAUSED.
create_meta_carousel_campaign
User wants to create a Meta (Facebook/Instagram) carousel ad campaign with multiple images. REQUIRED: You MUST call `select_meta_campaign_type` first and complete ALL phases it describes (audience targeting research via `search_meta_targeting`/`browse_meta_targeting`, asset discovery via `discover_meta_assets`, and user approval) BEFORE calling this tool. IMPORTANT: This tool creates REAL campaigns that will spend money once activated. Campaign is created in PAUSED status for review. DO NOT USE for single image - use `create_meta_image_campaign` instead. DO NOT USE for video - use `create_meta_video_campaign` instead. This tool creates a complete Meta carousel campaign with: 1. Campaign (objective, budget) 2. Ad Set (targeting, placements, schedule) 3. Multiple Image Uploads (one per card) 4. Ad Creative (carousel with child_attachments) 5. Ad (linking creative to ad set) When to use this tool: - "Create a Facebook carousel ad" - "Launch an Instagram carousel campaign" - "Create a multi-product ad" - "Set up an ad with multiple images" WhatsApp campaigns (destination_type='WHATSAPP'): if the customer's Page has more than one WhatsApp number, ASK WHICH ONE should receive conversations and pass whatsapp_phone_number. Leave it out and Meta picks a number itself, which may not be the one they expect. Required Parameters: - campaign_name: Name for the campaign - budget_daily: Daily budget in the account's own currency, NOT cents, NOT USD (for 20/day send 20, not 2000; min 1, recommend 5-20 for testing) - primary_text: Main ad text (recommended 125 chars for optimal display, longer text shows with "See More") - cards: Array of 2-10 cards (see card structure below) Card Structure (each card requires): - image_url OR image_hash: Image source (one required) - landing_page_url: Where users go when clicking this card - headline: Card headline (max 45 chars) - description: Optional card description (max 20 chars) - call_to_action: Optional per-card CTA override Optional Parameters: - facebook_page_id: Auto-detected from connected account - instagram_account_id: Enable Instagram placements - call_to_action: Default CTA for all cards (LEARN_MORE by default) - objective: OUTCOME_TRAFFIC (default), OUTCOME_SALES, OUTCOME_LEADS - locations: Country codes (default: ['US']) - age_min/age_max: Age targeting (18-65) - genders: ['male'], ['female'], or null for all - multi_share_optimized: Let Meta optimize card order (default: true) - pixel_id: Meta Pixel ID for conversion tracking (required for OUTCOME_SALES) - pixel_event_name: Conversion event (PURCHASE, LEAD, etc.) After Creation — IMPORTANT: - This tool created 1 campaign + 1 ad set + 1 ad. - To add MORE ad sets (different targeting, audiences, or formats), use `add_meta_ad_set` with the returned campaign_id - To add MORE ads to the same ad set (A/B test copy/creative), use `add_meta_ad` with the returned ad_set_id - NEVER call this create tool again for the same campaign — that creates a SEPARATE campaign
create_meta_catalog_campaign
User wants to create an Advantage+ Catalog ad / Dynamic Product Ad (DPA) — ads that automatically show products from their Meta product catalog. Keywords: "catalog ad", "dynamic product ads", "DPA", "advantage+ catalog", "shopping ads", "retarget products", "show my products". Meta renders each product's image, name and price from the catalog at delivery — the user does NOT upload images. Always OUTCOME_SALES. Two audience strategies: - **prospecting** — broad audience to find new buyers (no pixel needed) - **retargeting** — show products to people who engaged via the Pixel (REQUIRES pixel_id). Presets: viewed_not_purchased, carted_not_purchased, all_engaged_not_purchased, cross_sell_purchasers, or custom. REQUIRED FIRST: run `validate_catalog_readiness` (confirms the catalog has products with images and whether retargeting is viable), and resolve catalog_id + product_set_id via `list_meta_catalogs` / `list_meta_product_sets`. For retargeting, get pixel_id from `list_meta_pixels`. The campaign is created **PAUSED** so the user can review it in Ads Manager before spending.
create_meta_dco_ad
User wants Meta to automatically TEST MULTIPLE IMAGES and find the best combination. This is Dynamic Creative Optimization (DCO). Meta tests all combinations of images × headlines × primary texts and optimizes delivery automatically. USE THIS TOOL when the user says ANY of these: - "test these images" / "test multiple images" - "let Meta find the winner" / "let Meta optimize" - "Dynamic Creative" / "DCO" - "which image performs best" - Provides multiple images and wants Meta to choose the best - "test combinations" / "mix and match" - "10 images × 5 headlines" DO NOT USE add_meta_ad multiple times for this — that creates separate ads (A/B test). DCO is ONE ad with multiple assets that Meta mixes and optimizes. Prerequisites: 1. You need an ad_set_id with is_dynamic_creative=true 2. If the user doesn't have one, first call `add_meta_ad_set` with `is_dynamic_creative=true` 3. Then call this tool with the image_urls and text variations Asset limits (from Meta): - Images: 2-10 (required) - Headlines: up to 5 (optional) - Primary texts: up to 5 (optional) - Descriptions: up to 5 (optional) - Total assets: max 30 DCO ad sets support only 1 ad — do NOT add more ads to a DCO ad set. Example: 5 images × 3 headlines × 2 primary texts = 30 combinations, Meta finds the winner.
create_meta_image_campaign
User wants to create a Meta (Facebook/Instagram) single-image ad campaign. REQUIRED: You MUST call `select_meta_campaign_type` first and complete ALL phases it describes (audience targeting research via `search_meta_targeting`/`browse_meta_targeting`, asset discovery via `discover_meta_assets`, and user approval) BEFORE calling this tool. IMPORTANT: This tool creates REAL campaigns that will spend money once activated. Campaign is created in PAUSED status for review. DO NOT USE for video ads - use `create_meta_video_campaign` instead. DO NOT USE for carousel/multi-image - use `create_meta_carousel_campaign` instead. This tool creates a complete Meta campaign with: 1. Campaign (objective, budget) 2. Ad Set (targeting, placements, schedule) 3. Ad Creative (image, text, CTA) 4. Ad (linking creative to ad set) When to use this tool: - "Create a Facebook ad campaign" - "Launch an Instagram image ad" - "Set up a Meta traffic campaign" - "Create an ad with this image" Required Parameters: - campaign_name: Name for the campaign - budget_daily: Daily budget in the account's own currency, NOT cents, NOT USD (for 20/day send 20, not 2000; min 1, recommend 5-20 for testing) - primary_text: Main ad text (recommended 125 chars for optimal display, longer text shows with "See More") - headline: Headline below image (max 255 chars, recommended 40) - landing_page_url: Where users go when clicking Image Source (choose ONE): - asset_bundle_id: From `validate_and_prepare_meta_assets` (recommended for new images) - existing_image_hash: From `discover_meta_assets` (for reusing existing images) - image_url: Direct URL (uploaded during creation - use validate_and_prepare for better error handling) Optional Parameters: - facebook_page_id: Auto-detected from connected account. Only provide if multiple pages. - instagram_account_id: Auto-detected if linked. Enable Instagram placements. - WhatsApp campaigns (destination_type='WHATSAPP'): if the customer's Page has more than one WhatsApp number, ASK WHICH ONE should receive conversations and pass whatsapp_phone_number. Leave it out and Meta picks a number itself, which may not be the one they expect. - objective: OUTCOME_TRAFFIC (default), OUTCOME_SALES, OUTCOME_LEADS, OUTCOME_AWARENESS - call_to_action: LEARN_MORE (default), SHOP_NOW, SIGN_UP, etc. - locations: Country codes (default: ['US']) or location objects from search_meta_targeting - age_min/age_max: Age targeting (18-65) - genders: ['male'], ['female'], or null for all - pixel_id: Meta Pixel ID for conversion tracking (required for OUTCOME_SALES) - pixel_event_name: Conversion event (PURCHASE, LEAD, etc.) - story_image_url: Different image for Stories/Reels (9:16, 1080x1920px). Uses asset_feed_spec. - right_column_image_url: Different image for Right Column (1.91:1, 1200x628px). Uses asset_feed_spec. Multi-Placement Creatives: If the user wants different images for different placements (Feed, Stories, Right Column), provide story_image_url and/or right_column_image_url. The main image will be used for Feed. This uses Meta's asset_feed_spec with asset_customization_rules instead of object_story_spec. After Creation — IMPORTANT: - This tool created 1 campaign + 1 ad set + 1 ad. - To add MORE ad sets (different targeting, audiences, or formats), use `add_meta_ad_set` with the returned campaign_id - To add MORE ads to the same ad set (A/B test copy/creative), use `add_meta_ad` with the returned ad_set_id - NEVER call this create tool again for the same campaign — that creates a SEPARATE campaign
create_meta_product_set
User wants to advertise a SUBSET of their catalog — "boost just these items / these SKUs", "promote my sale items", "make a set of my new arrivals". Creates a product SET (a filtered grouping of EXISTING catalog products) — it does NOT create or upload products (those come from Shopify / Commerce Manager). Provide either: - retailer_ids: a list of SKUs to include (simplest — "boost just these items"), or - filter: an advanced raw Meta product-set filter When to use: - "Boost these 3 products", "create a set of my sale items" - Before a catalog ad when the user wants a specific subset, not the whole catalog
create_meta_video_campaign
User wants to create a Meta (Facebook/Instagram) video ad campaign. REQUIRED: You MUST call `select_meta_campaign_type` first and complete ALL phases it describes (audience targeting research via `search_meta_targeting`/`browse_meta_targeting`, asset discovery via `discover_meta_assets`, and user approval) BEFORE calling this tool. IMPORTANT: This tool creates REAL campaigns that will spend money once activated. Campaign is created in PAUSED status for review. DO NOT USE for image ads - use `create_meta_image_campaign` instead. DO NOT USE for carousel - use `create_meta_carousel_campaign` instead. This tool creates a complete Meta video campaign with: 1. Campaign (objective, budget) 2. Ad Set (targeting, placements, schedule) 3. Video Upload (handles large files with chunked upload) 4. Ad Creative (video, text, CTA) 5. Ad (linking creative to ad set) When to use this tool: - "Create a Facebook video ad campaign" - "Launch an Instagram video ad" - "Set up a Meta Reels campaign" - "Create an ad with this video" WhatsApp campaigns (destination_type='WHATSAPP'): if the customer's Page has more than one WhatsApp number, ASK WHICH ONE should receive conversations and pass whatsapp_phone_number. Leave it out and Meta picks a number itself, which may not be the one they expect. Required Parameters: - campaign_name: Name for the campaign - budget_daily: Daily budget in the account's own currency, NOT cents, NOT USD (for 20/day send 20, not 2000; min 1, recommend 5-20 for testing) - primary_text: Main ad text (recommended 125 chars for optimal display, longer text shows with "See More") - landing_page_url: Where users go when clicking Video Source (choose ONE): - video_url: Public video URL (will be uploaded during creation) - existing_video_id: Existing Meta video ID (for reusing previously uploaded videos) Optional Parameters: - facebook_page_id: Auto-detected from connected account - instagram_account_id: Enable Instagram placements - thumbnail_url: Custom thumbnail image (Meta auto-generates if not provided) - headline: Headline below video (optional for video ads) - description: Description text (max 255 chars, recommended 30) - call_to_action: WATCH_MORE (default), LEARN_MORE, SHOP_NOW, etc. - objective: OUTCOME_TRAFFIC (default), OUTCOME_SALES, OUTCOME_LEADS, OUTCOME_AWARENESS - locations: Country codes (default: ['US']) - age_min/age_max: Age targeting (18-65) - genders: ['male'], ['female'], or null for all - optimize_for_reels: true for vertical (9:16) videos - pixel_id: Meta Pixel ID for conversion tracking (required for OUTCOME_SALES) - pixel_event_name: Conversion event (PURCHASE, LEAD, etc.) Video Specifications: - Formats: MP4, MOV (recommended: MP4 H.264) - Max size: 4GB (recommended under 1GB) - Duration: 1 sec - 240 min (recommended 15-60 sec) - Feed: 1:1 or 4:5 aspect ratio - Stories/Reels: 9:16 aspect ratio After Creation — IMPORTANT: - This tool created 1 campaign + 1 ad set + 1 ad. - To add MORE ad sets (different targeting, audiences, or formats), use `add_meta_ad_set` with the returned campaign_id - To add MORE ads to the same ad set (A/B test copy/creative), use `add_meta_ad` with the returned ad_set_id - NEVER call this create tool again for the same campaign — that creates a SEPARATE campaign
get_meta_ad_creatives
User wants to see their Meta ad creatives, ad copy, media URLs, or creative performance. Returns ad-level data including full creative content and media URLs alongside performance metrics. When to use this tool: - "Show me my Meta ad creatives" - "What ads are running and how are they performing?" - "Show me the headlines and images for my ads" - "Which ad creatives are performing best?" - "What's the creative content for campaign X?" - "Show me ad performance with creative details" - "Get me the image URLs for my ads" - "Export my ad copy" - "What images and videos are my ads using?" Returns per ad — ALWAYS display ALL of these fields when present: - Ad copy: headline, primary_text, description, call_to_action_type - Media URLs: image_url (direct CDN link to ad image), thumbnail_url, video_url (playable video source), video_id - Landing page: landing_page_url - Carousel cards: carousel_cards array with per-card image_url, headline, description, landing_page_url - Performance: spend, impressions, clicks, CTR, CPC, reach, frequency - Video engagement: 25%, 50%, 75%, 100% watched (for video ads) - Creative metadata: creative_type (image/video/carousel/dynamic_creative), first_seen_date IMPORTANT: Always show the full image_url, thumbnail_url, video_url, and landing_page_url values — these are direct CDN links users need to download/export their creative media. Do not summarize or omit URLs. Parameters: - lookback_days: Number of days to analyze (7, 14, 30, 60, 90). Default: 30 - campaign_id: Optional filter to specific campaign - ad_set_id: Optional filter to specific ad set - ad_account_id: Required for multi-account users. Get from list_connected_accounts - start_date/end_date: Optional custom date range (overrides lookback_days) - limit: Max ads per page (default 20, max 50). Use for pagination. - offset: Number of ads to skip (default 0). Use with limit to page through results. Pagination: Results are paginated. Response includes total_ads count and has_more flag. To get next page, increase offset by limit. Execution time: 1-3 seconds Data source: Cached database (collected daily)
get_meta_adset_performance
User wants ad-set-level Meta performance — the middle layer between campaigns and individual ads. Use this when the user asks about ad set performance, has accounts with one campaign and many ad sets, or wants to compare audiences/budgets at the ad set level. This tool fills the gap between `get_meta_campaign_performance` (campaign rollups) and `analyze_meta_ad_performance` (per-ad creatives). Returns: - Per-ad-set metrics: spend, impressions, CTR, frequency, conversions, CPA, ROAS, reach - Top performing ad sets (ranked by ROAS when conversions exist, else CTR) - Underperforming ad sets (high spend, zero conversions, or ROAS < 1) - Frequency fatigue alerts (frequency ≥ 3.0) - Recommendations for budget reallocation and creative refresh When to use this tool: - "How are my Meta ad sets performing?" - "Which ad sets in this campaign are best?" - "Compare ad set performance across audiences" - "Find ad sets with high frequency" - "Which ad sets should I scale or pause?" - Any question about ad-set-level (ad group / audience-level) Meta performance Parameters: - lookback_days: 7, 14, 30 (default), 60, or 90 days - date_range: preset alternative to lookback_days / start_date / end_date. One of: 'last_7_days', 'last_14_days', 'last_30_days', 'last_60_days', 'last_90_days'. (Both 'last_30_days' and 'last_30d' / 'last_month' aliases accepted.) - start_date: Optional start date (YYYY-MM-DD). Overrides lookback_days when used with end_date. - end_date: Optional end date (YYYY-MM-DD). Overrides lookback_days when used with start_date. ⚠️ DATE CLARIFICATION: If the user's date request is vague or ambiguous (e.g., "March to June" without a year, "last quarter", "recently"), ask the user to specify exact dates before calling this tool. - campaign_id: Optional - filter to a single campaign (recommended when one campaign has many ad sets) - include_video_metrics: true (default) or false - include_recommendations: true (default) or false - limit: max ad sets to return (default 100, max 200) - offset: pagination offset (default 0) - ad_account_id: Required for multi-account users. Get from get_connections_status. Execution time: 1-3 seconds (cached database query) Data source: ad_group_daily_metrics table (Meta ad sets stored as ad groups)
get_meta_app_adsets
User wants PER-AD-SET install cost for app-promotion (AEO) campaigns — drill into a campaign's ad sets to see which audiences/placements deliver the cheapest installs. Keywords: "CPI by ad set", "which ad set / audience has the cheapest installs", "ad set install cost". Pass campaign_id (from get_meta_app_campaigns) to scope to one campaign. Each ad set shows installs, CPI, and a self-relative comparison to the account average. Reads cached nightly metrics. When to use: "Which ad set in this campaign has the lowest CPI?", "Cost per install by audience".
get_meta_app_campaigns
User wants PER-CAMPAIGN install cost for their app-promotion (AEO) campaigns. Keywords: "CPI by campaign", "which campaign has the cheapest/most expensive installs", "per-campaign cost per install", "compare install cost across app campaigns". Lists each app campaign's installs and CPI, with a self-relative comparison to the account average CPI (e.g. "+105% vs account" = pricier installs). Honest CPI severity is applied to the top spenders; the rest show install/CPI facts. Run get_meta_app_summary first for the account headline, then this to find the cheap and expensive campaigns. Reads cached nightly metrics. When to use: "Which app campaign has the lowest CPI?", "Break down cost per install by campaign".
get_meta_app_creatives
User wants PER-CREATIVE (per-ad) install cost for app-promotion (AEO) campaigns — which creatives/videos drive the cheapest installs. Keywords: "CPI by creative/ad", "best/worst creative for installs", "which ad has the cheapest installs", "creative install cost". Ranks creatives cheapest-install-first. Pass campaign_id or ad_group_id (from the campaigns/ad-sets tools) to scope. Reads cached nightly metrics. When to use: "Which creative has the lowest CPI?", "Best-performing ad for installs".
get_meta_app_summary
User wants their mobile-APP-promotion (AEO / App Installs / OUTCOME_APP_PROMOTION) performance — INSTALLS and COST PER INSTALL (CPI). Keywords: "CPI", "cost per install", "how many installs", "app installs", "install cost", "AEO performance", "mobile game/app campaign performance", "UA performance", "cost per registration/purchase in-app". The account headline for app campaigns: total installs, CPI (cost per install) graded against the account's OWN goal or 90-day average (never an invented benchmark — abstains honestly if there's no goal/history), and the in-app-event FUNNEL cost ladder (install → activate → registration → add-to-wishlist → checkout → level → purchase) with the cost per event. This is the fast entry point — then drill into per-campaign / ad-set / creative install cost. Reads cached nightly metrics (never calls Meta live). When to use: "What's my CPI?", "How are my app install campaigns doing?", "Cost per install this month?", "Show my install funnel / cost per in-app event".
get_meta_audience_insights
User asks about audience demographics, which placements perform best, device breakdown, or targeting optimization for Meta ads. This tool provides audience and placement analysis for Meta campaigns. Returns: - Age group performance (18-24, 25-34, 35-44, 45-54, 55-64, 65+) - Gender performance breakdown - Placement breakdown (Facebook Feed, Instagram Feed, Stories, Reels, Messenger) - Device breakdown (Mobile, Desktop, Tablet) - Best performing audience segments - Targeting recommendations When to use this tool: - "What age group performs best for my Meta ads?" - "Should I target men or women?" - "Which placements should I use?" - "Do my Instagram Stories ads perform well?" - "Mobile vs desktop performance on Facebook?" Parameters: - lookback_days: 7, 14, 30 (default), 60, or 90 days - date_range: preset alternative to lookback_days / start_date / end_date. One of: 'last_7_days', 'last_14_days', 'last_30_days', 'last_60_days', 'last_90_days'. (Both 'last_30_days' and 'last_30d' / 'last_month' aliases accepted.) - start_date: Optional start date (YYYY-MM-DD). Overrides lookback_days when used with end_date. - end_date: Optional end date (YYYY-MM-DD). Overrides lookback_days when used with start_date. ⚠️ DATE CLARIFICATION: If the user's date request is vague or ambiguous (e.g., "March to June" without a year, "last quarter", "recently", "a few months ago"), ask the user to specify exact dates before calling this tool. Do not assume or guess dates. - breakdown_type: 'age', 'gender', 'placement', 'device', or 'all' (default) - ad_account_id: Required for multi-account users. Get from list_connected_accounts Execution time: 1-3 seconds (cached database query) Data source: Cached database (aggregate metrics only - detailed breakdown requires live API) Common insights: - Meta audiences typically skew mobile (70-85%) - Instagram tends to perform better with 18-34 age groups - Facebook Feed often has highest reach but Stories may have better engagement - Reels placement growing rapidly in 2024-2025
get_meta_campaign_details
User wants to see detailed information about a specific Meta campaign, including its full structure (ad sets, ads, targeting, budgets). This tool retrieves comprehensive details about a single campaign. With `include_hierarchy=true`, it shows the complete campaign tree: Campaign - Ad Sets - Ads. Returns: - Campaign settings (name, status, objective, budget, bid strategy, schedule) - Performance summary (impressions, clicks, spend, reach, CTR, CPC) - Ads Manager URL - When include_hierarchy=true: Full structure with all ad sets and their ads, targeting details, hierarchy stats When to use this tool: - "Show me details for campaign [ID]" - "What's the structure of my campaign?" - "How many ad sets and ads does this campaign have?" - "What targeting is set on my campaign?" - "Show me the full campaign hierarchy" - After `list_meta_campaigns` when user wants to drill into a specific campaign Parameters: - campaign_id: The Meta Campaign ID (required) - include_hierarchy: Include ad sets and ads (default: false, set true for full view) Execution time: 3-10 seconds (longer with hierarchy due to multiple API calls) Data source: Meta Marketing API (live) Workflow: 1. Use `list_meta_campaigns` to find campaign IDs 2. Use `get_meta_campaign_details` with `include_hierarchy=true` to see everything 3. Use `update_meta_ad_set` or `update_meta_ad` to make changes to specific items
get_meta_campaign_performance
User asks about Meta/Facebook/Instagram ad performance, campaign metrics, ROAS, spend analysis, or wants to understand how their Meta ads are performing. This tool retrieves comprehensive campaign performance metrics from Meta Ads. Returns: - Account summary (total spend, impressions, reach, conversions, ROAS) - Campaign breakdown with status and objectives - Top performing campaigns by ROAS - Meta-specific metrics (reach, frequency, reach/impressions ratio) - Optimization recommendations When to use this tool: - "How are my Meta ads performing?" - "What's my Facebook campaign ROAS?" - "Show me Instagram ad performance" - "Which Meta campaigns are doing best?" - "Analyze my Meta ad spend" Parameters: - lookback_days: 7, 14, 30 (default), 60, or 90 days - date_range: preset alternative to lookback_days / start_date / end_date. One of: 'last_7_days', 'last_14_days', 'last_30_days', 'last_60_days', 'last_90_days'. (Both 'last_30_days' and 'last_30d' / 'last_month' aliases accepted.) - start_date: Optional start date (YYYY-MM-DD). Overrides lookback_days when used with end_date. - end_date: Optional end date (YYYY-MM-DD). Overrides lookback_days when used with start_date. ⚠️ DATE CLARIFICATION: If the user's date request is vague or ambiguous (e.g., "March to June" without a year, "last quarter", "recently", "a few months ago"), ask the user to specify exact dates before calling this tool. Do not assume or guess dates. - include_recommendations: true (default) or false - ad_account_id: Required for multi-account users. Get from list_connected_accounts Execution time: 1-3 seconds (cached database query) Data source: campaign_daily_metrics table (updated nightly) Note: Unlike Google Ads, Meta does not have keyword or search term data. Meta uses interest-based targeting.
get_meta_lead_form_submissions
User wants to see lead submissions, lead data, or leads collected from a Meta lead form. Retrieves individual lead submissions for a specific lead form, including contact details and associated ad/campaign information. When to use this tool: - "Show me the leads from form X" - "Get my lead form submissions" - "Download my Meta leads" - "Show lead data from my campaign" - "How many leads did I get?" Returns per lead: - Submission timestamp - Field data (name, email, phone, etc. — varies by form) - Source: organic or paid (with campaign name and ad name) - Lead ID Parameters: - form_id: Lead form ID (required — get from list_meta_lead_forms) - ad_account_id: Required for multi-account users. Get from list_connected_accounts - limit: Maximum leads to return (default: 100) Permission: Requires 'leads_retrieval' scope. If the user gets a permission error, they need to disconnect and reconnect their Meta account to grant the updated permissions. Execution time: 2-5 seconds Data source: Meta Marketing API (live)
get_meta_pixel_stats
User wants to set up RETARGETING catalog ads, or check whether a pixel is firing product events. Returns pixel health (last fired time, availability) and recent event breakdown. Use to confirm ViewContent / AddToCart / Purchase are firing before building a retargeting catalog campaign; if they aren't, recommend prospecting instead. When to use: - Before a retargeting catalog ad - "Is my pixel working?", "what events is my pixel getting?"
get_meta_product_performance
User wants to drill into ONE specific catalog product's performance over time — its daily spend/ROAS trend and full funnel (views → carts → checkouts → purchases). Get the product_id from analyze_meta_catalog_performance first. When to use: "How is product X doing?", "Show me the trend for this SKU", "What's the funnel for this product?"
list_meta_ad_sets
User wants to see the ad sets within a specific Meta campaign, including their targeting, budgets, and optimization settings. This tool retrieves ad sets for a given campaign with their status, budget, optimization goal, and billing event. Returns: - Ad set list with name, ID, status, budget, optimization goal, billing event - Next step guidance for editing ad sets or viewing ads When to use this tool: - "Show me the ad sets in campaign [ID]" - "What ad sets are running in my campaign?" - "List the ad groups for this campaign" - "Which ad sets are active/paused?" - Before using `update_meta_ad_set` when user doesn't know the ad set ID Parameters: - campaign_id: Campaign ID to list ad sets for (required) - status: Filter by status (optional) - limit: Max ad sets to return (default: 100) - ad_account_id: Optional Execution time: 2-5 seconds Data source: Meta Marketing API (live) Workflow: 1. Use `list_meta_campaigns` to find campaign IDs 2. Use `list_meta_ad_sets` with campaign_id to see ad sets 3. Use `update_meta_ad_set` to edit targeting, budget, or placements 4. Use `list_meta_ads` with ad_set_id to see individual ads
list_meta_ads
User wants to see the individual ads within a specific Meta ad set, including their status and creative information. This tool retrieves ads for a given ad set with their name, status, and creative ID. Returns: - Ad list with name, ID, status, creative ID - Next step guidance for editing ads When to use this tool: - "Show me the ads in ad set [ID]" - "What ads are running in this ad set?" - "List the individual ads" - "Which ads are active/paused?" - Before using `update_meta_ad` when user doesn't know the ad ID Parameters: - ad_set_id: Ad Set ID to list ads for (required for direct listing) - campaign_id: Campaign ID (will guide user to use ad_set_id) - status: Filter by status (optional) - limit: Max ads to return (default: 100) Execution time: 2-5 seconds Data source: Meta Marketing API (live) Workflow: 1. Use `list_meta_ad_sets` to find ad set IDs 2. Use `list_meta_ads` with ad_set_id to see ads 3. Use `update_meta_ad` to pause/resume or swap creative Alternative: Use `get_meta_campaign_details` with `include_hierarchy=true` to see the full campaign tree at once.
list_meta_campaigns
User wants to see their existing Meta/Facebook/Instagram campaigns, browse campaign structure, or find a campaign ID. This tool retrieves all campaigns in the connected Meta ad account with their status, objective, budget, and creation date. Returns: - Campaign list with name, ID, status, objective, budget - Status summary (how many ACTIVE, PAUSED, etc.) - Next step guidance for drilling into campaign details When to use this tool: - "Show me my Meta campaigns" - "List my Facebook ad campaigns" - "What campaigns do I have running?" - "Which campaigns are active?" - "Find my campaign for [product/brand]" - "I need to find a campaign ID" - Before using update/pause/resume tools when user doesn't know the campaign ID Parameters: - status: Filter by status (comma-separated: 'ACTIVE', 'PAUSED', 'DELETED', 'ARCHIVED') - effective_status: Filter by effective status (includes inherited states like 'CAMPAIGN_PAUSED') - objective: Filter by objective (OUTCOME_TRAFFIC, OUTCOME_SALES, OUTCOME_LEADS, OUTCOME_AWARENESS) - limit: Max campaigns to return (default: 100) - ad_account_id: Required for multi-account users. Get from list_connected_accounts Execution time: 2-5 seconds Data source: Meta Marketing API (live) Workflow: 1. Use `list_meta_campaigns` to find campaigns 2. Use `get_meta_campaign_details` with a campaign ID to see full structure 3. Use `update_meta_campaign` or `update_meta_ad_set` to make changes
list_meta_catalogs
User wants to browse product catalogs for catalog / dynamic product ads (DPA / Advantage+ Catalog), or before creating a catalog campaign. Returns all product catalogs attached to the business behind the ad account (id, name, product_count, vertical). Workflow: 1. Call this to discover catalogs 2. Pass a catalog ID to list_meta_product_sets / list_meta_products / create_meta_product_set When to use: - "Show my product catalogs", "list my Shopify catalog" - Before creating a catalog / dynamic product / Advantage+ Catalog ad
list_meta_custom_audiences
User wants to browse, list, or select Custom Audiences for targeting — DB lists, lookalike audiences, remarketing segments, website visitors, engagement audiences. Returns all Custom Audiences for the ad account with ID, name, type (subtype), approximate size, and delivery status. Workflow: 1. Call this tool to discover available custom audiences 2. Use audience IDs with campaign creation tools via `custom_audiences` parameter 3. Optionally use `excluded_custom_audiences` to exclude specific audiences When to use: - Before creating campaigns that need custom audience targeting - When user asks "which audiences do I have?" or "show me my lookalike audiences" - When setting up remarketing or DB-list campaigns
list_meta_instagram_accounts
User wants to run ads on Instagram, asks about Instagram accounts, or you need to find the instagram_account_id before campaign creation. Returns Instagram accounts that are: 1. Authorized for ads on the ad account (from Business Manager) 2. Linked to Facebook Pages (from Page settings) Workflow: 1. Call this tool to discover available Instagram accounts 2. Use the Instagram account ID with campaign creation tools via `instagram_account_id` parameter When to use: - Before any campaign creation to enable Instagram placements - When user asks "which Instagram accounts can I use?" - When an Instagram association fails and user needs to find the right account
list_meta_lead_forms
User wants to see their Meta lead generation forms, list lead forms, or find a lead form ID. Lists all lead generation forms for a Facebook Page associated with the ad account. When to use this tool: - "Show me my Meta lead forms" - "List my Facebook lead generation forms" - "What lead forms do I have?" - "Find my lead form ID" - "Show lead forms for my page" Returns per form: - Form name, status (ACTIVE/ARCHIVED), leads count - Creation date - Form questions (field names and types) - Form ID (needed for get_meta_lead_form_submissions and campaign creation with lead_form_id) Parameters: - page_id: Facebook Page ID (optional — auto-resolved from ad account if not provided) - ad_account_id: Required for multi-account users. Get from list_connected_accounts - limit: Maximum forms to return (default: 50) Note: Lead forms belong to Facebook Pages, not ad accounts. If you don't have the page_id, just omit it and the tool will auto-resolve from the ad account's promotable pages. Permission: Requires 'leads_retrieval' scope. If the user gets a permission error, they need to disconnect and reconnect their Meta account to grant the updated permissions. Execution time: 2-5 seconds Data source: Meta Marketing API (live)
list_meta_pages
User wants to know which Facebook Page an ad will run from, or a create/add tool reported the account has 2+ Pages and you need to pick one. Returns every Facebook Page that can run ads on the ad account (id + name + any linked Instagram account). Workflow: 1. Call this tool to discover the account's promotable Pages. 2. Pass the chosen page's id to any Meta create/add tool via the `facebook_page_id` parameter. When to use: - When a create/add tool returns `needs_page_disambiguation` (the account has 2+ Pages and Meta has no default). - When the user asks "which Facebook Page will this run from?" or wants a specific Page. - Before creating a campaign on an account you know has multiple Pages, to choose deliberately rather than let it ask.
list_meta_pixels
User wants conversion tracking, asks about Meta Pixels, or before creating OUTCOME_SALES campaigns. Returns all Meta Pixels for the ad account with their status and last fired time. Workflow: 1. Call this tool to discover available pixels 2. Use the pixel ID with campaign creation tools via `pixel_id` parameter 3. Optionally specify `pixel_event_name` (default: PURCHASE) When to use: - Before creating OUTCOME_SALES campaigns (pixel_id is required for conversion tracking) - When user asks "which pixels do I have?" - When setting up conversion tracking for campaigns
list_meta_product_sets
User wants to see the product sets (groupings) inside a catalog, to choose which products a catalog ad should advertise. Returns product sets (id, name, product_count) for a catalog. The default 'All Products' set always exists. When to use: - "What product sets do I have?", "show the groups in my catalog" - After list_meta_catalogs, before creating a catalog ad
list_meta_products
User wants to inspect the individual products in a catalog or product set (to confirm what will be advertised). Returns products (SKU/retailer_id, name, price, availability). Optionally scoped to a product set. When to use: - "What products are in my catalog?", "show items in the Footwear set" - To verify products before running a catalog ad
list_meta_promotable_apps
User wants to run a Meta app-install / app-promotion campaign, or asks which mobile apps they can advertise. Returns the apps this ad account is allowed to promote, each with its numeric Facebook App ID and the App Store / Google Play URLs Meta already holds. ALWAYS call this BEFORE creating an OUTCOME_APP_PROMOTION campaign. The `app_id` Meta requires is the numeric FACEBOOK App ID — NOT an iOS bundle ID (com.example.app) or Android package name. Customers routinely guess it wrong and the campaign fails. Workflow: 1. Call this tool to discover promotable apps 2. Pass the returned `app_id` + matching `app_store_url` to a campaign creation tool with objective OUTCOME_APP_PROMOTION 3. OS targeting is derived from the store URL automatically — Meta rejects an ad set whose OS targeting disagrees with the promoted app When to use: - Before ANY app campaign creation (app_id + app_store_url are both required) - When the user asks "which apps can I advertise?" - When an app campaign failed with a promoted-object, app-setup, or "Mobile Targeting Mismatch" error Apps that have no App Store / Google Play listing are returned separately with an explanation — Meta cannot run an app campaign for a web-only or canvas app.
search_meta_targeting
User wants to find targeting options for their Meta (Facebook/Instagram) ad campaigns. This tool searches the Meta Marketing API to find targeting options including interests, behaviors, demographics, locations, and more. Returns: - List of targeting options with IDs, names, and audience sizes - Category/path information for interests and behaviors - Location details including country, region for geo-targeting When to use this tool: - "Find interests related to fitness" - "What targeting options are available for travel?" - "Search for locations in California" - "Find behaviors for online shoppers" - "What demographics can I target?" - "Find job titles for marketing professionals" - "Search for schools like Harvard" Search Types Available: - interest: Topics and activities (e.g., 'fitness', 'cooking', 'travel') - behavior: User behaviors (e.g., 'frequent travelers', 'online shoppers') - demographic: Demographics (e.g., 'new parents', 'college educated') - life_event: Life events (e.g., 'recently moved', 'newly engaged') - location: Geo-targeting (e.g., 'New York', 'California', '90210') - locale: Language targeting (e.g., 'Spanish', 'French') - employer: Employer targeting (e.g., 'Google', 'Microsoft') - job_title: Job title targeting (e.g., 'Software Engineer') - school: Education school targeting (e.g., 'Harvard', 'Stanford') - major: Education major targeting (e.g., 'Computer Science') Parameters: - search_type: Type of targeting to search (required) - query: Search query string (required) - limit: Maximum results (1-100, default: 50) - locale: Locale for results (default: en_US) - location_types: For location search - filter by types (country, region, city, zip) - country_code: For location search - filter by country (e.g., 'US') - ad_account_id: Required for multi-account users. Get from list_connected_accounts Execution time: 1-3 seconds Data source: Meta Marketing API Targeting Search
update_meta_ad
User wants to update an individual Meta ad — pause/resume it, rename it, or swap its creative. IMPORTANT: This tool modifies REAL ads in Meta Ads Manager. Changes take effect immediately. Returns: - Confirmation of updates applied - Summary of changes - Ads Manager URL for the ad When to use this tool: - "Pause this ad" - "Resume ad [ID]" - "Rename this ad" - "Swap the creative on this ad" - "Change the image on this ad" (via creative swap) - "Turn off the underperforming ad" Parameters: - ad_id: The Meta Ad ID to update (required) - status: ACTIVE, PAUSED, DELETED, ARCHIVED (optional) - name: New ad name (optional) - creative_id: New creative ID for creative swap (optional) At least one update field must be provided. Execution time: 2-5 seconds Modifies: Real ad in Meta Ads Workflow for creative swap: 1. Use `discover_meta_assets` to find existing images/creatives 2. Get the creative ID you want to use 3. Use `update_meta_ad` with `creative_id` to swap Workflow for pausing underperformers: 1. Use `analyze_meta_ad_performance` to identify underperforming ads 2. Use `list_meta_ads` to get ad IDs 3. Use `update_meta_ad` with `status=PAUSED`
update_meta_ad_set
User wants to edit an existing Meta ad set's targeting, budget, bid, placements, schedule, or optimization settings. IMPORTANT: This tool modifies REAL ad sets in Meta Ads Manager. Changes take effect immediately. This is the primary tool for: - Changing audience targeting (age, gender, interests, locations) - Excluding placements (e.g., remove Audience Network) - Adjusting budgets at the ad set level - Changing bid amounts - Pausing/resuming specific ad sets - Modifying optimization goals Returns: - Confirmation of updates applied - Summary of all changes made - Ads Manager URL for the ad set When to use this tool: - "Change the targeting on my ad set" - "Exclude Audience Network from placements" - "Update the budget on this ad set to $50/day" - "Pause this ad set" - "Change the age range to 25-45" - "Add interest targeting for fitness" - "Exclude custom audience from this ad set" - "Change bid to $5" - "Update the optimization goal" Parameters: - ad_set_id: The Meta Ad Set ID to update (required) - status: ACTIVE, PAUSED, DELETED, ARCHIVED (optional) - name: New ad set name (optional) - daily_budget: New daily budget in the account's own currency, NOT cents, NOT USD (for 20/day send 20, not 2000; optional, min 1). DO NOT use for CBO campaigns. - lifetime_budget: New lifetime budget in the account's own currency, NOT cents, NOT USD (optional). DO NOT use for CBO campaigns. - daily_min_spend_target: CBO only — minimum daily spend for this ad set (use INSTEAD of daily_budget) - daily_spend_cap: CBO only — maximum daily spend cap for this ad set (use INSTEAD of daily_budget) - lifetime_min_spend_target: CBO only — minimum lifetime spend (for lifetime budget CBO) - lifetime_spend_cap: CBO only — maximum lifetime spend cap (for lifetime budget CBO) - bid_amount: New bid amount in the account's own currency, NOT cents, NOT USD (for a 2.50 bid send 2.5, not 250) (optional) - targeting: New targeting spec as JSON (optional) — for placements, audiences, demographics - start_time: New start time ISO format (optional) - end_time: New end time ISO format (optional) - optimization_goal: REACH, LINK_CLICKS, LANDING_PAGE_VIEWS, OFFSITE_CONVERSIONS, VALUE, etc. (optional) **CBO (Advantage Campaign Budget) campaigns:** For ad sets under CBO campaigns, do NOT set daily_budget or lifetime_budget. Use daily_min_spend_target / daily_spend_cap to control spend distribution. Setting daily_budget on a CBO ad set will cause Meta to reject with an error. At least one update field must be provided. Targeting Spec Examples: *Exclude Audience Network:* ```json { "publisher_platforms": ["facebook", "instagram"], "facebook_positions": ["feed", "stories", "reels"], "instagram_positions": ["stream", "story", "reels"] } ``` *Change age and gender:* ```json { "age_min": 25, "age_max": 45, "genders": [1] } ``` (genders: 1=male, 2=female, omit for all) *Add interest targeting:* ```json { "flexible_spec": [{"interests": [{"id": "6003139266461", "name": "Fitness"}]}] } ``` *Exclude custom audience:* ```json { "excluded_custom_audiences": [{"id": "AUDIENCE_ID"}] } ``` Execution time: 2-5 seconds Modifies: Real ad set in Meta Ads Workflow: 1. Use `list_meta_ad_sets` or `get_meta_campaign_details` to find the ad set ID 2. Use `update_meta_ad_set` with the changes you want to make 3. Verify changes in Ads Manager
update_meta_campaign
User wants to update an existing Meta campaign's status, budget, name, or schedule. IMPORTANT: This tool modifies REAL campaigns in Meta Ads Manager. Changes take effect immediately. Returns: - Confirmation of updates applied - Updated campaign details - Ads Manager URL When to use this tool: - "Update my Meta campaign budget" - "Change my Facebook campaign name" - "Pause my Instagram campaign" - "Resume my paused campaign" - "Set a new budget for campaign X" - "Change the end date for my campaign" Parameters: - campaign_id: The Meta Campaign ID to update (required) - status: New status - 'ACTIVE', 'PAUSED' (optional) - name: New campaign name (optional) - daily_budget: New daily budget in the account's own currency, NOT cents, NOT USD (for 20/day send 20, not 2000) (optional) - lifetime_budget: New lifetime budget in the account's own currency, NOT cents, NOT USD (optional) - start_time: New start time in ISO format (optional) - stop_time: New stop time in ISO format (optional) - bid_strategy: Campaign bidding strategy (optional) — 'LOWEST_COST_WITHOUT_CAP', 'LOWEST_COST_WITH_BID_CAP', 'COST_CAP', or 'LOWEST_COST_WITH_MIN_ROAS'. The capped strategies need a bid cap on the ad sets (`bid_amount` via update_meta_ad_set) — set that first or Meta rejects the change. At least one update field must be provided. Execution time: 2-5 seconds Modifies: Real campaign in Meta Ads
update_meta_catalog_ad
User wants to edit/change an existing catalog AD — rename, pause/activate, swap to another creative, or change the copy/headline/description/CTA/landing/product-set (Meta rebuilds the creative since creatives are immutable). Only the fields you pass change.
update_meta_catalog_ad_set
User wants to edit/change an existing catalog AD SET — deep control: budget, bid amount/strategy, optimization goal, full targeting (geo/age/gender/interests/behaviors/custom audiences/placements), schedule/dayparting, frequency caps, attribution, destination. PLUS catalog-specific: swap the product set, change the conversion event, or change the RETARGETING window/events (rebuilds the product audience). Only the fields you pass change.
update_meta_catalog_campaign
User wants to edit/change an existing Advantage+ Catalog CAMPAIGN — rename, pause/activate/archive, change budget (CBO), spend cap, bid strategy, schedule, special ad categories, or swap the catalog. Only the fields you pass are changed.
display
add_display_ad
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Add another Responsive Display Ad (RDA) to an EXISTING Display ad group. **When to use:** - User wants to A/B test multiple creatives in the same ad group - User asks to "add another ad" to an existing Display ad group **Required:** - ad_group_id - headlines (1-5 @ 30ch), long_headline (1 @ 90ch), descriptions (1-5 @ 90ch), business_name (≤25ch), final_url - At least one landscape AND one square marketing image (new or via existing_images) **Character limits (strict):** - Headlines: MAX 30 chars each - Long headline: MAX 90 chars - Descriptions: MAX 90 chars each - Business name: MAX 25 chars **Execution time:** 4-8 seconds
add_display_ad_group
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Add a new DISPLAY_STANDARD ad group (with its own targeting + a Responsive Display Ad) to an EXISTING Display campaign. **When to use:** - User wants another ad group inside a Display campaign (different targeting + different creative) - User asks to "add an ad group to my Display campaign" **Each ad group can have:** - Its own audience_segments, topics, managed_placements, display_keywords, demographics - Its own responsive display ad (creative + assets) - Optional manual CPC/CPM bid (inherits campaign bidding otherwise) **Required:** - campaign_id (Display campaign from list_campaigns) - ad_group_name - Full RDA payload: headlines (1-5 @ 30ch), long_headline (1 @ 90ch), descriptions (1-5 @ 90ch), business_name (≤25ch), final_url - At least one landscape AND one square marketing image (new URL or reuse via existing_images) **Execution time:** 8-15 seconds
add_display_audiences
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Add audience targeting to a Display ad group. **audience_segments** keys: - `user_interests` — list of affinity/in-market category IDs (from `search_audiences`) - `custom_audiences` — list of resource names like `"customers/123/customAudiences/456"` - `user_lists` — list of remarketing list resource names like `"customers/123/userLists/789"` - `combined_audiences` — list of combined audience resource names **CRITICAL:** Only use IDs returned by `search_audiences`. NEVER fabricate — wrong IDs waste budget on unrelated audiences. **Example:** ``` audience_segments: { "user_interests": ["80517", "80520"], "user_lists": ["customers/123/userLists/111"] } ``` **Execution time:** 2-5 seconds.
add_display_keywords
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Add contextual display keywords to a Display ad group. Display keywords are ALWAYS BROAD-match (Google ignores match_type for Display). Each keyword tells Google what context to show ads in — NOT what users are searching. **Example:** ``` display_keywords: [ {"text": "running shoes"}, {"text": "cheap knockoff", "negative": true} ] ``` **Execution time:** 2-5 seconds.
add_display_placements
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Add managed placements (websites, mobile apps, YouTube channels, YouTube videos) to a Display ad group. **Placement types:** - `website` — value is a domain or URL (e.g., "nytimes.com") - `mobile_app` — value is an app ID in format "mobileapp::1-com.example.app" - `youtube_channel` — value is a channel ID (e.g., "UCxxxxx") - `youtube_video` — value is a video ID (e.g., "dQw4w9WgXcQ") **Example:** ``` placements: [ {"type":"website","value":"nytimes.com"}, {"type":"youtube_video","value":"dQw4w9WgXcQ"} ] ``` **Execution time:** 2-5 seconds.
add_display_topics
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Add topic targeting to a Display ad group. **topics** is a list of topic IDs or `topicConstants/<id>` resource names. Example: `["topicConstants/1017", "1020"]` (the bare form gets auto-prefixed). Topic IDs are published by Google at https://developers.google.com/google-ads/api/data/codes-formats#verticals **Execution time:** 2-5 seconds.
create_display_campaign
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Create a Google **Display** campaign with a Responsive Display Ad on the Google Display Network (GDN). 🛑 **STOP — IMAGES ARE MANDATORY. ASK THE USER FIRST.** 🛑 A Display campaign cannot be created without images. Before calling this tool you MUST have: - At least 1 landscape image URL (1.91:1 aspect ratio, min 600×314, max 5 MB) - At least 1 square image URL (1:1 aspect ratio, min 300×300, max 5 MB) If the user has not provided image URLs, **ASK THEM** — do not invent URLs, do not guess Wikipedia/stock-photo URLs (they 403 to server fetches), do not pass `marketing_images: null`. Suggest the user upload to a host like postimages.org and paste the direct .jpg/.png URLs. ✅ **STRONGLY RECOMMENDED — pre-validate first**: call `validate_and_prepare_assets` with the user's image URLs BEFORE calling this tool. It checks aspect ratio, dimensions, file size, and content-type, then returns an `asset_bundle_id` you can pass here. This avoids a Google Ads API rejection mid-create (e.g., "aspect ratio doesn't match expected"). **When to use this tool:** - User explicitly asks for "Display campaign", "Google Display Network", "GDN", "banner ads", or "display ads" - User wants visual/banner placements across millions of websites, mobile apps, YouTube, and Gmail (display slots only) - User wants Smart Display (Google-managed automation): pass smart_display=true and bidding_strategy='TARGET_CPA' **When NOT to use:** - User wants text ads in Google Search → use create_search_campaign - User wants cross-channel (YouTube + Discover + Gmail + Display together) → use create_demandgen_campaign - User wants a PMax-like multi-channel approach → use create_pmax_campaign **Step-by-step workflow:** 1. Ask user for: budget, landing URL, business name, **AT LEAST 1 LANDSCAPE + 1 SQUARE IMAGE URL**, headlines (1-5 @ 30 chars), long headline (1 @ 90 chars), descriptions (1-5 @ 90 chars) 2. Resolve any free-text locations via `resolve_google_locations` first (returns exact `geoTargetConstants/<id>` to avoid ambiguity) 3. Pre-validate the image URLs with `validate_and_prepare_assets` → use the returned `asset_bundle_id` (recommended) OR pass the URLs directly as `marketing_images` / `square_marketing_images` (we'll validate before upload, but the API may still reject for subtle aspect-ratio mismatches) 4. Optional: logos, YouTube videos, audience/topic/placement targeting 5. Call `create_display_campaign` with the full payload (must include images one way or another) 6. After success, add extensions: `add_sitelinks`, `add_callout_extensions`, `add_structured_snippets` **Targeting surfaces supported (ad-group level, ignored for Smart Display):** - audience_segments: user_interests (affinity/in-market via search_audiences), custom_audiences, user_lists, combined_audiences - topics: topic constants - managed_placements: specific websites/apps/YouTube channels/videos - display_keywords: contextual keywords (always BROAD match on Display) - demographics: age/gender/parental/income (exclude-the-inverse pattern) **Bidding strategies:** - MAXIMIZE_CLICKS (default, works without conversion tracking) - MAXIMIZE_CONVERSIONS (needs conversion tracking) - TARGET_CPA (needs target_cpa + conversion tracking) - TARGET_ROAS (needs target_roas + conversion tracking) - MANUAL_CPC (enhanced CPC, needs cpc_bid in account currency) - MANUAL_CPM (viewable CPM, needs cpm_bid in account currency) **Smart Display (smart_display=true):** - sub_type=DISPLAY_SMART_CAMPAIGN (Google-managed) - Bidding MUST be TARGET_CPA - Manual audience/topic/placement/keyword/demographic inputs are REJECTED - Account needs conversion tracking with enough history (≥50 Display conversions or ≥100 Search conversions in last 30 days) **Character limits (strictly enforced — validation will reject before hitting the API):** - Headlines: MAX 30 chars each (1-5) - Long headline: MAX 90 chars (exactly 1) - Descriptions: MAX 90 chars each (1-5) - Business name: MAX 25 chars - Price prefix: MAX 10 chars - Promo text: MAX 20 chars **Image requirements:** - Landscape (1.91:1): min 600x314, max 5MB, 1-15 images - Square (1:1): min 300x300, max 5MB, 1-15 images - Landscape logo (4:1): min 512x128, up to 5 (optional) - Square logo (1:1): min 128x128, up to 5 (optional) **Safety:** - Campaigns always start PAUSED (user must review + enable manually in Google Ads UI) - Never retry on failure — surface the error to the user **Execution time:** 10-20 seconds (atomic mutate: budget + campaign + ad group + all criteria + assets + ad)
get_display_ad_group_settings
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Read every editable setting on a Display ad group. Returns: id, name, status, type (DISPLAY_STANDARD), campaign resource, current cpc_bid + cpm_bid (both in account currency AND micros), ad_rotation_mode, optimized_targeting_enabled, exclude_demographic_expansion. **Use this before update_display_ad_group** so you can show the user the current state and ask for which fields to change. **Execution time:** 1-3 seconds (read-only).
get_display_audiences
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link List audience targeting on a Display campaign's ad groups. Returns entries with type ∈ {USER_LIST, CUSTOM_AUDIENCE, USER_INTEREST, COMBINED_AUDIENCE}. **Execution time:** 1-3 seconds (read-only).
get_display_demographics
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link List demographic targeting (age, gender, parental status, income) on a Display campaign's ad groups. Each entry has a `negative` flag — Google targets via exclude-the-inverse: to target MALE only, everything else is listed as negative criteria. **Execution time:** 1-3 seconds (read-only).
get_display_frequency_caps
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Read the frequency caps currently configured on a Display campaign. Returns a list of `{level, event_type, time_unit, time_length, cap}` entries. **Execution time:** 1-3 seconds (read-only).
get_display_keywords
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link List contextual display keywords on a Display campaign's ad groups. Display keywords are always BROAD-match (Google ignores match_type on Display). **Execution time:** 1-3 seconds (read-only).
get_display_placements
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link List all managed placements (websites, mobile apps, YouTube channels, YouTube videos) on a Display campaign's ad groups. **Returns** list of placements with ad_group_id, criterion_id, type, value, status. Use `criterion_id` + ad_group_id to construct a resource name for `remove_display_criteria`: `customers/{customer_id}/adGroupCriteria/{ad_group_id}~{criterion_id}` **Execution time:** 1-3 seconds (read-only).
get_display_topics
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link List topic targeting on a Display campaign's ad groups. Topics are Google's content categories (e.g., Finance, Travel, Technology). See Google's topic taxonomy at https://developers.google.com/google-ads/api/data/codes-formats#verticals **Execution time:** 1-3 seconds (read-only).
remove_display_ad
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Remove (soft-delete) a Responsive Display Ad. Sets the AdGroupAd status=REMOVED. The ad stops serving but historical reporting is preserved. Cannot be undone via the API. **Parameters:** ad_group_id (REQUIRED), ad_id (REQUIRED) **Execution time:** 2-4 seconds.
remove_display_ad_group
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Remove (soft-delete) a Display ad group. Google's API does not support hard deletion — this sets status=REMOVED, which stops serving but preserves historical data for reporting. Cannot be undone via the API. **Parameters:** ad_group_id (REQUIRED) **Execution time:** 2-4 seconds.
remove_display_criteria
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Remove one or more AdGroupCriteria from a Display ad group by resource name. Works for ANY criterion type — placements, topics, audiences, display keywords, demographic exclusions. **How to get resource names:** use any of the `get_display_*` tools — each entry has `ad_group_id` and `criterion_id`. Construct the resource name as: `customers/{customer_id}/adGroupCriteria/{ad_group_id}~{criterion_id}` **Example:** ``` criterion_resource_names: [ "customers/5835090207/adGroupCriteria/197350763433~123456789" ] ``` **Execution time:** 2-5 seconds (destructive — cannot be undone).
update_display_ad_creative
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Edit any combination of CREATIVE fields on a Responsive Display Ad. Complements `update_ad_content` (which handles headlines / descriptions / long_headline / final_urls). This tool handles EVERYTHING ELSE on the RDA. **Text fields:** - `business_name` (max 25) - `main_color` / `accent_color` (hex e.g. '#FFAABB') - `allow_flexible_color` (bool) - `price_prefix` (max 10) - `promo_text` (max 20) - `call_to_action` (enum label like SHOP_NOW, LEARN_MORE, or free-form ≤30 chars) - `format_setting` (ALL_FORMATS | NATIVE | NON_NATIVE) **Image + video fields** (REPLACE the entire list when provided — you may supply both URL objects to upload AND existing asset resource names to reuse; they're merged): - `marketing_images`: landscape 1.91:1 URLs to upload - `square_marketing_images`: square 1:1 URLs - `logo_images`: landscape 4:1 logos - `square_logo_images`: square 1:1 logos - `youtube_video_ids`: list of YouTube IDs - `existing_*_images`: reuse existing asset resource names (from discover_existing_assets) **Workflow tip** — to add images WITHOUT replacing: first call `get_campaign_structure` or `discover_existing_assets` to get the current resource names, then pass them as `existing_*_images` AND your new ones as `marketing_images`. The service merges them. **At least one field must be provided.** Any omitted field is not touched. **Execution time:** 4-10 seconds (includes image uploads if any).
update_display_ad_group
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Update one or more editable settings on a Display ad group in a single API call. At least one of the following must be provided. Any field omitted is not touched. **Fields:** - `name`: New ad group name (string) - `status`: ENABLED | PAUSED | REMOVED (REMOVED is a soft-delete — use `remove_display_ad_group` for clarity) - `cpc_bid`: Max CPC in account currency (MANUAL_CPC campaigns) - `cpm_bid`: Max viewable CPM in account currency (MANUAL_CPM campaigns) - `ad_rotation_mode`: OPTIMIZE (Google picks best ad) | ROTATE_FOREVER (even rotation) - `optimized_targeting_enabled`: Let Google expand targeting beyond your chosen audiences Note: `exclude_demographic_expansion` is Search-only and not editable on Display. **Execution time:** 2-4 seconds.
update_display_campaign_schedule
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Update a Display campaign's start_date and/or end_date. Pass either or both dates as 'YYYY-MM-DD' (or compact 'YYYYMMDD'). You must provide at least one. Notes: - Google does NOT support un-setting start/end dates via the API. To effectively run "forever", set end_date to a far-future date (e.g., 2099-12-31). - Updating start_date after the campaign has already started is a no-op. **Execution time:** 2-4 seconds.
update_display_demographics
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Update demographic targeting on a Display ad group via the exclude-the-inverse pattern. This tool adds NEGATIVE criteria for every demographic value NOT in your target list. It does NOT remove prior negative criteria — use `remove_display_criteria` if you want to clear old exclusions first. **Input keys** (all optional — only groups you pass are modified): - `age_ranges`: subset of `AGE_RANGE_18_24, AGE_RANGE_25_34, AGE_RANGE_35_44, AGE_RANGE_45_54, AGE_RANGE_55_64, AGE_RANGE_65_UP, AGE_RANGE_UNDETERMINED` - `genders`: subset of `MALE, FEMALE, UNDETERMINED` - `parental_statuses`: subset of `PARENT, NOT_A_PARENT, UNDETERMINED` - `income_ranges`: subset of `INCOME_RANGE_0_50, INCOME_RANGE_50_60, INCOME_RANGE_60_70, INCOME_RANGE_70_80, INCOME_RANGE_80_90, INCOME_RANGE_90_UP, INCOME_RANGE_UNDETERMINED` **Example — target women aged 25-44 only:** ``` demographics: { "age_ranges": ["AGE_RANGE_25_34","AGE_RANGE_35_44"], "genders": ["FEMALE"] } ``` **Execution time:** 2-5 seconds.
update_display_frequency_caps
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link REPLACE all frequency caps on a Display campaign. Google requires sending the full desired set each time — partial updates are not supported. Pass [] to remove ALL caps. **Each entry:** - `level`: CAMPAIGN | AD_GROUP | AD_GROUP_AD - `event_type`: IMPRESSION | VIDEO_VIEW - `time_unit`: DAY | WEEK | MONTH - `time_length`: 1-365 (number of time_unit periods) - `cap`: ≥ 1 (max events per user in that window) **Examples:** - 3 impressions/day: `[{level:CAMPAIGN, event_type:IMPRESSION, time_unit:DAY, time_length:1, cap:3}]` - 10 impressions/week + 2/day: two entries in the list - Clear all caps: `[]` **Execution time:** 2-5 seconds.
campaign
add_campaign_label
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Attach an existing label to a campaign. Get the label_id from list_labels (or create_label first). This tags the campaign for filtering and reporting; it does not change delivery. **Required:** campaign_id + label_id.
add_campaign_proximity
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Add proximity (radius) targeting to a campaign — target everyone within N miles/km of an address. **When to use:** - "Target people within 10 miles of downtown San Francisco" - Local businesses wanting a radius around a store, not a whole city/state **Different from city/state targeting:** for country/state/city/postal geo_target_constant targeting, use `update_campaign` (locations_to_add) instead. Proximity is a RADIUS around a point. **Each proximity needs:** - radius + radius_units (MILES | KILOMETERS) - an address: any of city_name, province_name/province_code, postal_code, country_code, street_address - optional bid_modifier (1.2 = +20%) **Required:** campaign_id + 1+ proximities.
add_search_campaign_image
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Upload + link an image asset at the SEARCH campaign level. For PMax campaigns use `add_pmax_asset_group_image` instead (PMax links at asset-group level). This tool is for Search campaigns where image assets attach at campaign level via CampaignAssetService. Valid `field_type` values (Search campaigns only): - AD_IMAGE — promotional image extension (used by default; always works) - BUSINESS_LOGO — brand logo (requires an identity-verified advertiser) The MARKETING_IMAGE family and LOGO/LANDSCAPE_LOGO are Performance Max / asset-group image types — Google REJECTS them on a Search campaign. For those, use `add_pmax_asset_group_image` on a PMax campaign instead. **Parameters:** - campaign_id: The Search campaign ID - image_url: http(s) URL OR `data:image/...;base64,...` URI - field_type: AD_IMAGE (default) or BUSINESS_LOGO — omit to use AD_IMAGE - asset_name: optional display name in the Asset Library - customer_id: Optional (uses connected account if omitted) **Execution time:** 3-8 seconds (image fetch + Google Ads mutate) **Example:** User: "Upload this image (https://...) to campaign 23847465076" Agent: add_search_campaign_image(campaign_id="23847465076", image_url="https://...") # defaults to AD_IMAGE
create_search_campaign
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link 🔄 LONG-RUNNING TOOL: Creates a Google Ads Search campaign with full structure. Emits MCP progress updates during authentication and campaign creation (typically 5-10 seconds). Progress stages: validate → commit. ⚠️ CRITICAL WARNING ⚠️ - Call this tool ONLY ONCE per campaign - Creates REAL campaigns that cost REAL money - Do NOT retry automatically if errors occur - Report errors to user instead of retrying ⚠️ GOOGLE ADS POLICY NOTE: Avoid keywords related to health conditions, medical treatments, financial hardship, or political topics. These may trigger policy violations. Use general service terms instead. Example: Use "senior care services" not "nursing care", "home services" not "medical services" YOUR ROLE: Expert Google Ads Campaign Strategist BEFORE calling this tool, YOU MUST: 1. **Research the business thoroughly:** - Understand products/services, target audience, value propositions - Analyze competitive landscape and market positioning - Review website messaging and offers - Consider seasonal factors and current trends 2. **🔍 KEYWORD RESEARCH (CRITICAL - Call research_keywords tool FIRST):** Do NOT use generic SEO keywords. Get HIGH-INTENT keywords with real CPC data! **YOU MUST call the research_keywords tool BEFORE this tool:** Steps: a) Call the research_keywords tool: ``` Tool: research_keywords Arguments: { "business_description": "Emergency plumbing services for homeowners", "website_url": "https://example.com", "target_location": "New York, NY" } ``` b) The tool will return: - Keyword table with dynamic CPC thresholds (adapts to industry) - HIGH/MEDIUM/LOW intent keywords - Budget recommendations (Conservative/Moderate/Aggressive) - Top 15-20 recommended keywords c) Show the keyword table to the user d) Ask user if they want to modify keyword selection: - Can add/remove specific keywords - Can use only HIGH intent keywords - Default: use recommended keywords e) Extract keyword texts from the research_keywords result - Use the recommended keywords for this tool's 'keywords' parameter - Max 15-20 keywords per ad group - Will use BROAD match automatically (Google's 2025 recommendation) 3. **Analyze Target Demographics:** For each ad group, consider who the ideal customer is: - **Age**: What age groups are most likely to buy? (e.g., luxury products → 35-54, gaming → 18-34) - **Gender**: Is the product/service gender-specific? (e.g., women's fashion → FEMALE) - **Income**: What income level can afford this? (e.g., luxury → TOP_10/80_90, budget → 0_50/50_60) **Examples:** - Luxury watches: Males 35-54, income top 20% - Budget fashion: Females 18-34, all income levels - Senior services: Age 65+, income 50%+ - Gaming products: 18-34, all genders, middle income If unclear, leave demographics empty for broad reach. 3. **Generate complete campaign structure with ALL details:** **Required Fields (all mandatory):** 1. **campaign_name** - Unique descriptive name 2. **business_description** - What the business sells 3. **website_url** - Landing page URL 4. **budget_daily** - Daily budget in the account's native currency (do NOT convert — pass user's amount as-is) 5. **target_locations** - Geographic targets (cities/states/countries) 6. **ad_groups** - Array of 2-4 ad groups, each containing: - name: Ad group theme (e.g., "Premium Care Services") - keywords: 15-20 keywords from Keyword Planner research (will use BROAD match - Google's 2025 recommendation) - headlines: Exactly 15 headlines (MAXIMUM 30 chars each - NO EXCEPTIONS) - descriptions: Exactly 4 descriptions (MAXIMUM 80 chars each - NO EXCEPTIONS) - final_url: Landing page for this ad group - sitelinks (optional): 2-4 additional links below ad - audiences (optional): Demographics and audience targeting - demographics: {age_ranges: [...], genders: [...], income_ranges: [...]} - custom_audiences: [...], in_market_audiences: [...], affinity_audiences: [...] 7. **negative_keywords** (optional) - Terms to exclude **🚨 CRITICAL CHARACTER LIMITS - COUNT BEFORE CALLING 🚨** - **Headlines:** MAXIMUM 30 characters (NO EXCEPTIONS - will be rejected!) - **Descriptions:** MAXIMUM 80 characters (NO EXCEPTIONS - will be rejected!) - **Long Headlines (PMAX):** MAXIMUM 90 characters (NO EXCEPTIONS - will be rejected!) - Generate ALL content BEFORE calling this tool - COUNT the characters in each headline and description - If ANY exceed limits, you MUST shorten them BEFORE calling - Do NOT rely on retry - fix it the first time! - ✅ Commas ARE ALLOWED and encouraged for natural language - ❌ Do NOT use pipes (|) as separators - they will appear literally in ads - ❌ Do NOT send comma-delimited strings - use proper JSON arrays - Example: ["Expert Care, 24/7 Support", "Premium Service Available"] - Do NOT call this tool multiple times - it creates REAL campaigns - If errors occur, show them to the user - do NOT retry automatically - Each call costs money and creates actual Google Ads campaigns **SITELINK RULES (if using):** ⚠️ Google will REJECT sitelinks that violate these rules: - ALL sitelink URLs MUST be same domain as final_url ✅ Good: final_url='https://example.com' → sitelink='https://example.com/shipping' ❌ Bad: final_url='https://example.com' → sitelink='https://different-site.com' - Each sitelink must link to a UNIQUE, WORKING page (no duplicates, no 404s) - Link text must be DESCRIPTIVE (not "Click Here", "Learn More") - If you add description1, you MUST also add description2 - Only add sitelinks if you've verified the URLs exist and work **Execution Time:** 15-30 seconds **What happens:** - Campaign created immediately in Google Ads - Real money will be spent on the campaign - Returns campaign_id for tracking **Use for:** - Launching new advertising campaigns - Testing new market segments - Scaling successful products
get_campaign_dates
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Read a campaign's start and end dates. Returns start_date and end_date (YYYY-MM-DD). An end_date far in the future (e.g. 2037-12-30) or empty means the campaign has no scheduled end. Works on any campaign type. **Required:** campaign_id (from list_campaigns).
get_campaign_frequency_caps
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Read a campaign's frequency caps (how often a user can see the ads). Returns the list of caps, each with level, event_type, time_unit, time_length, and cap. An empty list means no frequency capping is configured. Works on any campaign type. **Required:** campaign_id (from list_campaigns).
get_campaign_labels
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link List the labels currently attached to a campaign. Returns each attached label's id, name, and description. Use remove_campaign_label with a label id to detach it. **Required:** campaign_id (from list_campaigns).
get_campaign_performance
Analyze Google Ads campaign performance with comprehensive insights and recommendations. ⚠️ IMPORTANT: This tool retrieves READ-ONLY data. Safe to call multiple times. **Returns detailed analysis:** - Campaign structure and ad group organization - Keyword performance with quality scores and match types - Ad group performance breakdown - Performance metrics (CTR, conversions, CPC, cost, ROAS) - Optimization recommendations with actionable insights - Performance trends (last 7 days) **Parameters:** - lookback_days: 7, 30, 60, 90, or 120 days (default: 30) - start_date: Optional start date (YYYY-MM-DD). Overrides lookback_days when used with end_date. - end_date: Optional end date (YYYY-MM-DD). Overrides lookback_days when used with start_date. ⚠️ DATE CLARIFICATION: If the user's date request is vague or ambiguous (e.g., "March to June" without a year, "last quarter", "recently", "a few months ago"), ask the user to specify exact dates before calling this tool. Do not assume or guess dates. - customer_id: Optional (uses connected account if omitted) - campaign_id: Optional. When provided, scopes the analysis to a single campaign (all metrics, ad groups, keywords, and trends reflect that campaign only). Omit for account-wide analysis. Use `list_campaigns` first to find the campaign ID. **Execution time:** 2-5 seconds (direct backend API call) **Data source:** Cached database (updated nightly via metrics collection) **Use this tool to:** - Review current campaign performance - Identify optimization opportunities - Get data-driven recommendations - Analyze keyword and ad effectiveness - Understand what's working and what needs improvement 📊 **AFTER calling this tool, provide these insights to the user:** **How to Interpret Metrics:** - **CTR (Click-Through Rate):** Industry average is 3-5% for search ads - Above 5%: Excellent ad relevance - Below 2%: Consider improving ad copy or targeting - **Conversion Rate:** Industry average is 2-5% - Low CR + High CTR = Landing page issue - Low CR + Low CTR = Ad/targeting issue - **CPA (Cost Per Acquisition):** Compare to your target CPA - Track the trend over time - Adjust bids if CPA is consistently too high 💡 **Optimization Tips:** - Wait at least 2 weeks before making major changes (learning phase) - Focus on high-performing keywords and pause low performers - Test different ad copy variations (A/B testing) - Adjust bids based on device/location performance - Review search terms report for negative keyword opportunities 💬 **Community**: For optimization discussions and tips, visit our Discord: https://discord.gg/dH3Qt4YS
get_campaign_structure
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Get campaign structure with ad groups, keywords, ads, and extensions. Supports pagination for large campaigns. This tool retrieves READ-ONLY data. Safe to call multiple times. **Returns campaign hierarchy (paginated by ad groups):** - Campaign details (name, status, budget, bidding strategy) - Ad groups with their settings (paginated — default 5 per page) - Keywords per ad group (including match types, bids, status) - Ads per ad group (including RSA headlines/descriptions, ad strength) - Negative keywords per ad group - Campaign-level extensions and negative keywords (on page 1 only) - Pagination metadata (page, total_pages, has_more) - Summary counts (total ad groups, keywords, ads across ALL pages) **Parameters:** - campaign_id: The campaign ID (REQUIRED - get from list_campaigns) - customer_id: Optional (uses connected account if omitted) - page: Page number, 1-based (default: 1) - page_size: Ad groups per page, 1-50 (default: 5) - ad_group_id: Optional — fetch only this single ad group (bypasses pagination) - include: What detail per ad group: 'all' (default), 'summary' (counts only), 'keywords', 'ads' **⚡ PAGINATION CONTRACT (IMPORTANT FOR AI AGENTS):** - The response includes `pagination.has_more` — if true, you MUST call again with `page` incremented - Continue calling until `has_more` is false - Then consolidate all pages and present the complete campaign structure to the user - The `summary` section is always included and shows total counts across ALL ad groups (not just the current page) - Extensions and campaign-level negative keywords are only returned on page 1 - Use `ad_group_id` to drill into a single ad group when the user asks about a specific one - Use `include='summary'` for a quick overview without nested keyword/ad data **Execution time:** 3-8 seconds per page (multiple API queries) **Use this tool when:** - User wants to update an existing campaign - User wants to see current keywords/ads - User wants to add extensions to existing campaign - User says "show me what's in this campaign" - Before making any updates to a campaign **Important IDs returned:** - campaign.id - For campaign-level updates (budget, status) - ad_groups[].id - For adding keywords/ads - keywords[].id - For keyword updates (status, bids) - ads[].id - For ad content updates **Example flow:** 1. User: "I want to update my campaign" 2. Agent: Uses list_campaigns to show all campaigns 3. User: Selects campaign "Summer Sale 2025" 4. Agent: Uses get_campaign_structure with that campaign_id 5. If has_more=true, agent calls again with page=2, page=3, etc. 6. Agent: Shows consolidated structure and asks what to update 7. User: "Change the headlines" 8. Agent: Uses update_ad_headlines with the ad_id from structure
get_campaign_targeting
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Full targeting view for a Google Ads campaign — locations, languages, demographics, audiences, devices, ad schedule, topics, placements, keywords, AND negative variants of each. This tool retrieves READ-ONLY data via 2 GAQL queries (cached 15 min in Redis). Safe to call multiple times. **Returns sections (only the ones with data are rendered):** - 📍 **Locations** — geo target constants + bid modifiers - 🌐 **Languages** — language constants - 👥 **Demographics** — gender, age range, parental status, income range (campaign or ad-group level, with bid modifiers) - 🎯 **Audiences** — user lists (remarketing), user interests (in-market/affinity), custom audiences, combined audiences, AUDIENCE resource - 📱 **Devices** — device type + bid modifier - ⏰ **Ad Schedule** — day of week + hour window + bid modifier - 📺 **Topics** — topic constants (Display) - 🌐 **Placements** — managed placement URLs (Display) - 🔑 **Keywords** — keyword text + match type - 🚫 **Negatives** — exclusion list across the same dimensions **Parameters:** - campaign_id: The campaign ID (REQUIRED — get from list_campaigns) - customer_id: Optional (uses connected account if omitted) **Execution time:** 2-5 seconds (2 GAQL queries, then cached 15 min) **Use this tool when:** - User asks "what is this campaign targeting?" — covers ALL targeting axes - User asks "what audiences/demographics/devices does this campaign target?" - User wants ad schedule, placement, or topic exclusions - Before recommending targeting changes - To audit targeting setup post-creation **Out of scope (tracked separately):** - PMax `asset_group_signals` (different resource) - Customer-level negative criterion lists (account-wide negatives) - Shared negative keyword lists (separate resource) - 3rd-party brand safety / IVT services
get_campaign_tracking
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Read a campaign's URL tracking settings. Returns the campaign-level `tracking_url_template` (click-measurement/redirect URL), `final_url_suffix` (query params appended to the landing page), and `url_custom_parameters` (the {key,value} params usable as `{_key}` in the template). Use this to see or verify what `update_campaign` set. Reads/writes of these tracking fields are campaign-level and apply to all ads in the campaign. **Required:** campaign_id (from list_campaigns).
list_campaign_extensions
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link List all campaign-level assets for a campaign: sitelinks, callouts, structured snippets, call assets, business names, and images. Returns a summary of every asset type configured on the campaign, each with its status (ENABLED/PAUSED) and resource name. **Parameters:** - campaign_id: The campaign ID (REQUIRED). Get from list_campaigns. - customer_id: Optional Google Ads customer ID **Returns:** - Sitelinks, Callouts, Structured Snippets - Call assets (phone number + country + status) - Business names - Images (field type + status) **Execution time:** 1-2 seconds (read-only) **When to use:** - User asks "what extensions/assets do I have?" - BEFORE adding an asset — check what already exists (avoids duplicates) - Auditing campaign setup / finding a duplicate to clean up **Example:** User: "Show me the extensions on my campaign" Agent: 1. Uses list_campaigns to get campaign_id 2. Uses list_campaign_extensions to see all assets
remove_campaign
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Permanently remove (delete) a campaign — sets its status to REMOVED. ⚠️ This is PERMANENT and CANNOT be undone (a removed campaign cannot be re-enabled — use pause_campaign if you only want to stop it temporarily). All of the campaign's ad groups and ads are removed with it. **Required:** campaign_id (from list_campaigns). **When to use:** the user explicitly wants to delete / get rid of / permanently remove a campaign. For "stop"/"turn off"/"pause", use pause_campaign instead.
remove_campaign_label
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Detach a label from a campaign (removes the tag; the label itself is not deleted). Get the label_id from get_campaign_labels. **Required:** campaign_id + label_id.
set_campaign_ad_schedule
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Add ad-schedule (day/hour) targeting to a campaign — control WHEN ads run. ⚠️ Adding any schedule restricts ads to ONLY the windows you specify (all other times are off). Add every window you want ads to run in. **Each window:** - day_of_week: MONDAY..SUNDAY - start_hour (0-23) + end_hour (0-24; 24 = midnight) - start_minute/end_minute: ZERO | FIFTEEN | THIRTY | FORTY_FIVE (optional) - bid_modifier (optional, 1.2 = +20%) **Example:** business hours = [{day_of_week:'MONDAY',start_hour:9,end_hour:17}, ...Tue-Fri]. **Note:** this APPENDS schedule windows (re-adding the same window errors). To fully replace a schedule, remove the existing ad-schedule criteria first. **Required:** campaign_id + 1+ schedules.
set_campaign_device_bid_modifiers
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Set device bid modifiers on a campaign — bid up/down per device. Campaigns automatically have MOBILE/DESKTOP/TABLET criteria; this updates their bid adjustments (creates CONNECTED_TV/OTHER if you target them). **Each entry:** - device: MOBILE | TABLET | DESKTOP | CONNECTED_TV | OTHER - bid_modifier: 1.2 = +20%, 0.8 = -20%, 1.0 = no change **Required:** campaign_id + 1+ devices.
update_campaign
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Update an existing campaign's settings. **Can update:** - name: Campaign name - status: ENABLED or PAUSED - budget_amount: Daily budget in dollars - target_search_network: Search Partners toggle (Search campaigns) - target_content_network: Display Network expansion (Search campaigns) - language_codes: Replace language targeting (e.g. ["en"] for English-only). As of Sept 2026 this no longer applies to SEARCH campaigns (Google matches on ad language); still honored for Performance Max. A safe no-op on Search — nothing changes and you get a note explaining why. - locations_to_add: Append locations to geo targeting (free text or geoTargetConstants/<id>) - locations_to_remove: Remove locations by criterion resource name (get from get_campaign_targeting) - audience_targeting_mode: OBSERVATION vs TARGETING for audience signals - ai_max_enabled: Google AI Max toggle on Search campaigns **IMPORTANT:** - Confirm with user BEFORE making changes - Use list_campaigns first to get campaign_id - At least one update field is required - For locations_to_remove, you MUST call get_campaign_targeting first to obtain the criterion resource names — free-text location names will not work for removal. **Parameters:** - campaign_id: The campaign ID (REQUIRED - get from list_campaigns) - name: New campaign name (optional) - status: ENABLED or PAUSED (optional) - budget_amount: Daily budget in dollars, e.g., 50.00 for $50/day (optional) - target_search_network / target_content_network: bools (optional) - language_codes: list[str] (optional, REPLACES current set) - locations_to_add / locations_to_remove: list[str] (optional) - audience_targeting_mode: OBSERVATION | TARGETING (optional) - ai_max_enabled: bool (optional) - customer_id: Optional (uses connected account if omitted) **Execution time:** 2-6 seconds depending on number of targeting changes **Example:** User: "Increase the budget to $100/day and target English-only" Agent: 1. Uses list_campaigns to find the campaign 2. Confirms: "I'll update 'Summer Sale' budget to $100/day and set language to English-only. Proceed?" 3. Uses update_campaign(campaign_id=..., budget_amount=100.00, language_codes=["en"])
update_campaign_dates
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Set a campaign's start and/or end date. Works on ANY campaign type (Search, PMax, Demand Gen, Display). Dates are 'YYYY-MM-DD'. Pass either or both. Setting an end_date stops the campaign after that day; omit end_date to leave it open-ended. Use get_campaign_dates to see current values first. **Required:** campaign_id + at least one of start_date / end_date.
update_campaign_frequency_caps
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Set a campaign's frequency caps — limit how often a user sees the ads. Works on ANY campaign type. This REPLACES the full set of caps (send the complete desired list; pass [] to remove all caps). Each cap: {level: CAMPAIGN|AD_GROUP|AD_GROUP_AD, event_type: IMPRESSION|VIDEO_VIEW, time_unit: DAY|WEEK|MONTH, time_length: 1-365, cap: >=1}. Use get_campaign_frequency_caps first. Example — cap at 3 impressions per user per day: [{"level":"CAMPAIGN","event_type":"IMPRESSION","time_unit":"DAY","time_length":1,"cap":3}] **Required:** campaign_id + frequency_caps (list).
pmax
add_pmax_asset_group
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Add a NEW asset group to an EXISTING Performance Max campaign. Takes the same asset-group shape as create_pmax_campaign and builds the group atomically (assets + links + search themes + audience signals in one call). The new group is created **PAUSED** — enable it with update_pmax_asset_group. **Required in asset_group:** name, final_urls, headlines (3-15), descriptions (2-5), business_name, logo_images, marketing_images (landscape), square_marketing_images. Google rejects groups missing required asset types. **Optional:** long_headlines, portrait_marketing_images, youtube_video_ids, search_themes (auto-derived from headlines if omitted), audience_signals. **Parameters:** - campaign_id: The PMax campaign ID (REQUIRED) - asset_group: The group config object (REQUIRED — see shape above) - auto_truncate: Auto-fix text over character limits (default: true) - customer_id: Optional (uses connected account if omitted) **Execution time:** 10-30 seconds (uploads images, atomic mutate)
add_pmax_asset_group_asset
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Add ONE text or video asset to a Performance Max asset group. Text slots (pass `text`): HEADLINE (≤30 chars), LONG_HEADLINE (≤90), DESCRIPTION (≤90), BUSINESS_NAME (≤25). Video (pass `youtube_video_id`): YOUTUBE_VIDEO. Over-limit text is auto-truncated. Per-group maxima are enforced (15 headlines / 5 long headlines / 5 descriptions / 1 business name / 5 videos) — you'll get a clear error if the slot is full. **Use when:** - "Add a headline 'Summer Sale' to the PMax group" → field_type=HEADLINE, text=... - "Attach this YouTube video to the asset group" → field_type=YOUTUBE_VIDEO, youtube_video_id=... **Parameters:** - campaign_id: The PMax campaign ID (REQUIRED) - field_type: The slot (REQUIRED — see list above) - text: For text slots (REQUIRED for those) - youtube_video_id: For YOUTUBE_VIDEO (REQUIRED for that) - asset_group_id: Required if the campaign has 2+ groups - customer_id: Optional (uses connected account if omitted) **Execution time:** 2-5 seconds
add_pmax_asset_group_image
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Upload a new image and link it to a PMax asset group. Accepts http(s) URLs OR base64 data URIs (`data:image/...;base64,...`). Per-group caps are enforced BEFORE upload: 20 marketing images per group (across MARKETING_IMAGE / SQUARE_MARKETING_IMAGE / PORTRAIT_MARKETING_IMAGE / TALL_PORTRAIT_MARKETING_IMAGE), 5 of each logo type (LOGO / LANDSCAPE_LOGO / BUSINESS_LOGO). If the campaign has exactly one asset group, `asset_group_id` is optional — otherwise it is required. Image bytes are uploaded only after cap validation passes, so a doomed call doesn't burn bandwidth. **Parameters:** - campaign_id: The PMax campaign ID - image_url: http(s) URL or `data:image/...;base64,...` URI - field_type: which PMax image slot to fill (see list of accepted values) - asset_group_id: required for multi-group campaigns - asset_name: optional display name in the Asset Library **Execution time:** 3-8 seconds (image fetch + Google Ads mutate)
add_pmax_audience_signal
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Add an audience signal to an existing Performance Max campaign. Audience signals hint Google AI about who your ideal customers are. Uses in-market segments (actively researching), affinity segments (long-term interests), and custom audiences (remarketing lists, customer match). Use search_audiences tool first to discover relevant audience segment IDs. **Parameters:** - campaign_id: The PMax campaign ID - audience_config: Dict with segment IDs **Execution time:** 2-5 seconds
add_pmax_search_themes
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Add search themes to an existing Performance Max campaign. Search themes hint Google AI about what customers search for. Max 50 per asset group. NOT keywords — no match types, no bids, no quality scores. **Best practices:** - Derive from keyword research results, business profile, or user input - Keep themes specific but not too narrow (2-5 words ideal) - Avoid generic themes like "buy stuff" or overly specific ones like "buy red nike air max 97 size 12" **Parameters:** - campaign_id: The PMax campaign ID - search_themes: List of theme strings to add **Execution time:** 2-5 seconds
create_pmax_campaign
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link 🔄 LONG-RUNNING TOOL: Creates a Google Performance Max campaign with validated images. Emits MCP progress updates during authentication, asset upload, and campaign creation (typically 15-30 seconds). Progress stages: validate → commit. ⚠️ CRITICAL PREREQUISITES: 1. MUST have valid asset_bundle_id from validate_and_prepare_assets tool OR existing_image_ids from discover_existing_assets 2. MUST have all campaign text details from user 3. Creates REAL campaigns that cost REAL money 4. Call ONLY ONCE per campaign - do NOT retry automatically 🎥 **VIDEOS ARE OPTIONAL BUT RECOMMENDED:** - Videos significantly improve PMAX performance (higher CTR, better engagement) - **Always ask the user**: "Would you like to add YouTube videos to this campaign?" - If yes: validate with `validate_video` tool, then include `youtube_video_ids` parameter - If no: proceed without videos (campaigns work fine either way) - See STEP 3.5 below for complete video guidance ⚠️ GOOGLE ADS POLICY NOTE: Avoid keywords related to health conditions, medical treatments, financial hardship, or political topics. These may trigger policy violations. Use general service terms instead. Example: Use "senior care services" not "nursing care", "home services" not "medical services" 📋 **YOUR CRITICAL ROLE: Campaign Strategist & Text Creator** **STEP 1: Verify Prerequisites** Before calling this tool, ensure you have: - ✅ Valid asset_bundle_id from validate_and_prepare_assets (max 1 hour old) - ✅ All required campaign details from user (see below) If asset_bundle_id is missing or expired: - Guide user to re-upload images - Call validate_and_prepare_assets again - Get new asset_bundle_id **STEP 2: Collect Campaign Details from User** YOU MUST collect these from the user (ask if not provided): **REQUIRED Fields:** 1. **Campaign Name** - Example: "Premium Watches Summer 2025" - Make it descriptive and unique 2. **Daily Budget** - Google recommends ~$50/day USD equivalent for Performance Max - IMPORTANT: Accept the user's budget in their stated currency — do NOT convert to USD - Ask: "What's your daily advertising budget?" 3. **Final URL** (Landing Page) - Must match verified domain in Google Ads - Example: "https://example.com/watches" - Ask: "What's the landing page URL for this campaign?" 4. **Business Name** - Maximum 25 characters - Example: "Luxury Watch Co" - Will appear in ads **STEP 3: Generate High-Quality Ad Copy** As an expert copywriter, you MUST create compelling ad text: **🚨 BEFORE GENERATING TEXT - READ CHARACTER LIMITS 🚨** **Headlines (3-15 required):** - **STRICT LIMIT: 30 characters maximum per headline** - Count characters BEFORE calling this tool! - Examples: - "Premium Luxury Watches" (22 chars) ✅ - "Free Shipping" (13 chars) ✅ - "Certified Authentic" (19 chars) ✅ **Descriptions (2-4 required):** - **STRICT LIMIT: 80 characters maximum per description** - Count characters BEFORE calling this tool! - Examples: - "Shop authentic luxury timepieces with free worldwide shipping." (63 chars) ✅ - "Expert-curated Swiss watches. Certified authentic. Shop now." (61 chars) ✅ **Long Headlines (1-5 REQUIRED):** - **STRICT LIMIT: 90 characters maximum per long headline** - At least 1 is REQUIRED for Performance Max - Count characters BEFORE calling this tool! - Example: "Premium Swiss Watches - Certified Authentic, Free Worldwide Shipping" (70 chars) ✅ **⚠️ WILL BE REJECTED IF YOU EXCEED LIMITS - NO RETRIES!** **⚠️ COUNT CHARACTERS CAREFULLY - VALIDATION IS STRICT!** **How to Count Characters:** - Use extended thinking to count each text element - Double-check your character counts before calling - If close to limit, shorten it to be safe - Do NOT assume backend will fix it - it won't! - Use clear, concise language - Focus on user benefits **OPTIONAL Fields (use defaults if not provided):** - target_locations: Defaults to ["United States"] - target_languages: Defaults to ["English"] **🎥 STEP 3.5: YouTube Videos (OPTIONAL but Highly Recommended)** **⚠️ IMPORTANT: Always ask the user about videos!** Videos significantly improve Performance Max campaign performance: - **Higher CTR**: Video ads stand out more than static images - **Better engagement**: Users watch videos longer - **Wider reach**: Serves on YouTube, Display, Discover, Gmail, Search - **Lower CPA**: Video ads often convert better **When to Ask:** - AFTER discovering existing assets - AFTER user uploads images - BEFORE calling create_pmax_campaign **What to Say:** "I've prepared your images. Would you like to add YouTube videos to this campaign? Videos can significantly improve performance (higher CTR and engagement). They're optional but recommended. If yes: - You'll need videos uploaded to YouTube (public or unlisted) - Minimum 10 seconds duration - I can validate them for you If no: - We can proceed with images only - You can add videos later if needed" **How to Include Videos:** 1. **User provides YouTube video URL or ID** - Example: "https://youtu.be/eIZtladpm6c" - Example: "eIZtladpm6c" 2. **You validate it** ``` Call: validate_video Arguments: { "video_url_or_id": "eIZtladpm6c", "platform": "pmax" } ``` 3. **Include in campaign** - Add `youtube_video_ids` parameter: `["eIZtladpm6c"]` - Can include up to 5 videos **Video Specifications:** - **Aspect Ratios**: Landscape (16:9), Square (1:1), Vertical (9:16) - **Duration**: Minimum 10 seconds (no maximum) - **Maximum**: 5 videos per campaign - **Source**: Must be on YouTube (public or unlisted, NOT private) - **Validation**: Happens via Google Ads API during campaign creation **If user doesn't have videos:** - Proceed without them (campaigns work fine without videos) - Mention they can add videos later - Note: Google may auto-generate videos from images if none provided **STEP 4: Call create_pmax_campaign** After you have ALL details: - Validate character counts yourself BEFORE calling - Call create_pmax_campaign with complete payload - Wait for response (may take 15-30 seconds) **STEP 5: Handle Response** **If SUCCESS:** - Celebrate with user! 🎉 - Show campaign ID, name, budget, status - Explain campaign starts PAUSED for safety - 🔴 **IMMEDIATELY proceed to STEP 6 (Extensions)** — do NOT stop here! **If FAILURE:** 1. **Asset Bundle Expired:** - Error: "Asset bundle not found or expired" - Action: Guide user to re-upload images - Call validate_and_prepare_assets again 2. **Character Limit Errors:** - Error: "Headline exceeds 30 characters" - Action: Shorten the text and try again - Show user which field caused the error 3. **Google Ads API Errors:** - Domain not verified - Budget too low - Account suspended - Action: Explain error clearly, provide troubleshooting steps 4. **Authentication Errors:** - Error: "No Google Ads account connected" - Action: Guide user to connect their Google Ads account 🔴 **STEP 6: MANDATORY — Add Extensions After Creation** After the campaign is successfully created, you MUST: 1. Crawl the user's website to gather relevant page links, features, and service categories 2. Add sitelinks: at least 4 links to key pages (add_sitelinks tool) 3. Add callout extensions: 4-6 business highlights (add_callout_extensions tool) 4. Add structured snippets: categorized features (add_structured_snippets tool) 5. Verify with list_campaign_extensions to confirm all extensions are attached Extensions are FREE and increase ad visibility by 15-25%. NEVER skip this step. **DO NOT:** - Retry automatically on failure - Call multiple times for same campaign - Skip collecting user's campaign details - Proceed without valid asset_bundle_id - Skip adding extensions after campaign creation **Campaign Creation Best Practices:** 🔴 **PRE-STEP: ALWAYS Discover Assets First** - Before ANY PMAX campaign, call discover_existing_assets - Show user what assets were found (images, logos with dimensions) - Ask: "Would you like to reuse these existing assets, upload new ones, or mix both?" - Based on answer: - Reuse → Use existing_image_ids in create_pmax_campaign - Upload new → Use validate_and_prepare_assets → asset_bundle_id - Mix both → Use both parameters (hybrid mode) - 🚫 NEVER skip this step 1. **Research First:** - Understand the business, products, audience - Review website messaging - Identify key selling points 2. **Strategic Ad Copy:** - Use action verbs - Include numbers/stats if available - Highlight benefits over features - Create urgency when appropriate - Match brand voice 3. **Quality Over Quantity:** - Better to have 5 great headlines than 15 mediocre ones - Each headline should be unique and valuable - Avoid repetition 4. **User Safety:** - Confirm budget with user before creating - Explain campaigns start PAUSED - Remind them this costs real money **Example Complete Flow:** User: "Create a PMax campaign for my luxury watch store" You: "I'll help you create a PMax campaign! First, let me check if you have any existing assets we can reuse." [Call discover_existing_assets(target_domain="luxurywatches.com")] [Returns: 8 images found] You: "Great news! I found 8 validated images from your previous campaigns: - 4 landscape images (1200x628) - 2 square images (1200x1200) - 2 logo images (1200x1200) Would you like to: A) Reuse these existing images (saves time, consistent branding) B) Upload new images C) Mix both (reuse some + add new ones)" [User chooses A - Reuse] You: "Perfect! Now I need a few details: 1. What daily budget would you like? (minimum $10, recommended $50+) 2. What's your landing page URL? 3. What locations should we target? (e.g., 'Bay Area', 'San Francisco', 'United States') I'll create compelling headlines and descriptions based on your luxury watch business." [User provides budget: $75, URL: https://luxurywatches.com, Location: Bay Area] You: "Great! Here's what I'll create: **Campaign Name:** Premium Watches Campaign 2025 **Budget:** $75/day **Landing Page:** https://luxurywatches.com **Locations:** Bay Area (targeted precisely) **Headlines I've generated:** - Premium Luxury Watches - Certified Authentic - Free Worldwide Shipping [...12 more] **Descriptions:** - Shop authentic Swiss timepieces with lifetime warranty and expert curation. - Discover premium watches from top brands. Free shipping. 30-day returns. [...2 more] **Using existing images:** 8 validated images (reuse mode) Ready to create this campaign? (It will start PAUSED so you can review first)" [User confirms] [Call create_pmax_campaign with existing_image_ids from discovery] **Returns:** - Campaign ID, name, status - Asset group summary - Next steps for activation **Execution Time:** 15-30 seconds (direct backend API call) **Authentication:** Required (MCP OAuth 2.1) **CRITICAL REMINDERS:** - Asset bundle expires after 1 hour - Campaign starts PAUSED for user safety - This costs real money - be transparent - Never retry on failure - report error to user - Provide excellent user experience throughout
get_pmax_asset_groups
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link List all asset groups on a Performance Max campaign. Shows per group: ID, name, status, **ad_strength** (Google's creative rating), **primary_status + reasons** (why a group is/isn't serving), final URLs and display paths. This is the read-back tool for the other asset-group tools. **Use when:** - "Why isn't my PMax campaign serving?" → check primary_status_reasons - "How strong are my asset groups?" → ad_strength per group - Getting asset_group_id for update/remove/add-image calls **Parameters:** - campaign_id: The PMax campaign ID (REQUIRED — get from list_campaigns) - customer_id: Optional (uses connected account if omitted) **Execution time:** 1-3 seconds
get_pmax_asset_performance
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Read Google's own per-asset performance_label for every image in a PMax campaign, plus asset-group-level rollup metrics. PMax does not expose per-image CTR / conversions on Google's side — Google instead publishes its own ML grade per asset: BEST / GOOD / LOW / LEARNING / PENDING. This tool surfaces that label directly, and adds a derived `recommended_action`: - LOW → REPLACE - LEARNING / PENDING → WAIT - GOOD / BEST → KEEP - UNKNOWN / UNSPECIFIED → REVIEW Per-group metrics (impressions, clicks, conversions, cost_micros, CTR, CVR) are rolled up for the requested date range. Labels themselves are not date-scoped on Google's API; they reflect Google's current grade. **Use when:** - Identifying which assets to swap during a monthly creative refresh - Sanity-checking that newly added assets have left LEARNING - Reporting on PMax creative health per asset group **Parameters:** - campaign_id: The PMax campaign ID - asset_group_id: optional — scope to one group - date_range / start_date+end_date: window for the group-level metrics - min_label_severity: optional filter (LOW / GOOD / BEST) **Execution time:** 2-5 seconds (two GAQL queries)
get_pmax_audience_signals
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Get current audience signals for a Performance Max campaign. Returns audience signal resource names and associated audience resource references. **Use when:** - User wants to see what audience signals are on their PMax campaign - Before adding new signals - To get resource_name for removal **Parameters:** - campaign_id: The PMax campaign ID **Execution time:** 1-2 seconds
get_pmax_search_themes
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Get current search themes for a Performance Max campaign. Returns each search theme's text and approval_status (APPROVED, LIMITED, DISAPPROVED, UNDER_REVIEW). **Use when:** - User wants to see what search themes are set on their PMax campaign - Before adding new themes (to check current count — max 50) - To verify theme approval status after adding **Parameters:** - campaign_id: The PMax campaign ID (get from list_campaigns) **Execution time:** 1-2 seconds
list_pmax_asset_group_assets
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link List the TEXT and VIDEO assets on a Performance Max campaign's asset groups. Complements list_pmax_asset_group_images (which covers images). Shows per group: headlines, long headlines, descriptions, business name, and YouTube videos — each with its field_type, status, performance_label, and the `asset_group_asset_resource_name` to pass to remove_pmax_asset_group_asset. **Parameters:** - campaign_id: The PMax campaign ID (REQUIRED) - asset_group_id: Optional — scope to one group - field_types: Optional list to filter (e.g. ["HEADLINE"]) - customer_id: Optional (uses connected account if omitted) **Execution time:** 1-3 seconds
list_pmax_asset_group_images
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link List image assets linked to Performance Max asset groups, grouped by asset_group_id. Returns image URL, dimensions, field_type, status, performance_label, and the `asset_group_asset_resource_name` you can pass straight back to `remove_pmax_asset_group_image`. **Use when:** - Auditing what creative is actually serving on a PMax campaign - Capturing resource names before a remove - Confirming `add_pmax_asset_group_image` succeeded **Parameters:** - campaign_id: The PMax campaign ID - asset_group_id: Optional — scope to one group **Execution time:** 1-3 seconds
remove_pmax_asset_group
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Remove (soft-delete) an asset group from a PMax campaign. Sets status=REMOVED — the group stops serving permanently and disappears from get_pmax_asset_groups. This cannot be undone via the API. The underlying assets stay in the Asset Library and remain reusable. Note: Google rejects removing a campaign's only serving asset group — pause it instead (update_pmax_asset_group status=PAUSED) if you want to stop delivery. **Parameters:** - campaign_id: The PMax campaign ID (REQUIRED) - asset_group_id: The group to remove (REQUIRED — never auto-picked) - customer_id: Optional (uses connected account if omitted) **Execution time:** 2-4 seconds
remove_pmax_asset_group_asset
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Unlink a text or video asset from a Performance Max asset group. The underlying asset stays in the Asset Library (reusable). Google rejects a removal that would drop a group below its required minimum for a field type (e.g. fewer than 3 headlines) — that constraint is surfaced as a clean error. Pass `asset_group_asset_resource_name` (preferred — from list_pmax_asset_group_assets) OR `asset_id` (with asset_group_id / field_type to disambiguate if the same asset is linked more than once). **Parameters:** - campaign_id: The PMax campaign ID (REQUIRED) - asset_group_asset_resource_name: The link to remove (preferred) - asset_id / field_type / asset_group_id: Alternative lookup by asset ID - customer_id: Optional (uses connected account if omitted) **Execution time:** 2-4 seconds
remove_pmax_asset_group_image
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Unlink an image from a PMax asset group. This UNLINKS the image — it does NOT delete the underlying Asset. The asset stays in the Asset Library so it can be re-linked elsewhere or re-added to the same group later. This matches Google's own UI behavior and is reversible. **Lookup patterns (pass ONE):** - A) `asset_group_asset_resource_name` — preferred, get it from `list_pmax_asset_group_images` - B) `asset_id` (+ optional `asset_group_id` if the same asset is linked into more than one group) **Parameters:** - campaign_id: The PMax campaign ID - asset_group_asset_resource_name OR asset_id - asset_group_id: optional disambiguator **Execution time:** 2-4 seconds
remove_pmax_audience_signal
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Remove a specific audience signal from a Performance Max campaign. Use get_pmax_audience_signals first to get the signal_resource_name. **Parameters:** - campaign_id: The PMax campaign ID - signal_resource_name: Resource name from get_pmax_audience_signals **Execution time:** 2-5 seconds
remove_pmax_search_themes
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Remove specific search themes from a Performance Max campaign. Matches themes by text (case-insensitive). Use get_pmax_search_themes first to see current themes. **Parameters:** - campaign_id: The PMax campaign ID - themes_to_remove: List of theme text strings to remove **Execution time:** 2-5 seconds
update_pmax_asset_group
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Update settings of an existing PMax asset group. Per-field isolation: only the fields you pass change. Supported fields: - **status**: ENABLED / PAUSED (pause a group without touching the campaign) - **name**: rename the group - **final_urls / final_mobile_urls**: replace the landing page URL list - **path1 / path2**: display URL paths (empty string clears) **Use when:** - "Pause the summer asset group" → status=PAUSED - "Point the sale group at the new landing page" → final_urls **Parameters:** - campaign_id: The PMax campaign ID (REQUIRED) - asset_group_id: Required if the campaign has 2+ groups (from get_pmax_asset_groups) - name / status / final_urls / final_mobile_urls / path1 / path2: at least one - customer_id: Optional (uses connected account if omitted) **Execution time:** 2-4 seconds
update_pmax_audience_signal
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Update the segment composition of an existing PMax audience IN PLACE (#325). USE THIS INSTEAD OF REMOVE + ADD when you want to change which audiences are in a signal — for example, to merge in a new Customer Match list while keeping existing in-market interests. Updating in place avoids the "audience with this name already exists" error that comes from removing a signal and re-adding under the same name. **Workflow:** 1. Call get_pmax_audience_signals → returns signals with their `audience` resource names AND current `composition` 2. Build a new audience_config dict with the FULL desired composition (this REPLACES, not merges — copy the current composition then add or remove segments as needed) 3. Call this tool with the audience_resource_name + new audience_config **Parameters:** - audience_resource_name: from get_pmax_audience_signals (the `audience` field on each signal — NOT the signal's own resource_name) - audience_config: same shape as add_pmax_audience_signal **Execution time:** 2-5 seconds
group
add_ad_group_audiences
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Add audience targeting to an ad group. ⚠️ Use `search_audiences` FIRST to find real audience IDs — NEVER fabricate IDs (wrong IDs target unrelated audiences and waste budget). **Accepts:** in_market_audiences, affinity_audiences, custom_audiences, user_lists. **Required:** ad_group_id + at least one audience list.
add_search_ad_group
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Add a new ad group to an EXISTING Search campaign. **When to use:** - User wants another themed ad group inside a Search campaign - User asks to "add an ad group to my Search campaign" **Each ad group can optionally be seeded with:** - keywords (plain text — run research_keywords first) - a Responsive Search Ad (headlines 3-15 @30ch + descriptions 2-4 @90ch + final_url) - an optional manual CPC bid (inherits campaign bidding otherwise) **Required:** campaign_id (Search campaign from list_campaigns), ad_group_name. **Execution time:** 5-15 seconds
get_ad_group_audiences
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Read audience targeting on an ad group. Returns the user lists, in-market / affinity, and custom audiences currently attached, with bid modifiers and whether each is a negative (exclusion). **Required:** ad_group_id (from get_campaign_structure).
get_ad_group_demographics
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Read demographic targeting on an ad group (Search, Display, etc.). Returns the age ranges, genders, and income ranges currently targeted/excluded, with any bid modifiers. Use before update_ad_group_demographics. **Required:** ad_group_id (from get_campaign_structure).
get_ad_group_device_bid_modifiers
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Read the device (MOBILE/TABLET/DESKTOP) bid modifiers on an ad group. Search ad groups carry implicit MOBILE/DESKTOP/TABLET rows that read back at 1.0× (no adjustment) until you set a real modifier via set_ad_group_device_bid_modifiers. So a device shown at "1.0× (no adjustment)" simply hasn't been bid up or down yet. **Required:** ad_group_id (from get_campaign_structure). Read-only, safe to call anytime. Pair with set_ad_group_device_bid_modifiers to adjust.
get_ad_group_settings
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Read every editable setting on ANY ad group (Search, Display, PMax, Demand Gen, YouTube). Returns id, name, status, type, cpc/cpm bids, target_cpa/target_roas, ad_rotation_mode, targeting_setting (audience OBSERVATION vs TARGETING), URL templates, and parent campaign. Use this before update_ad_group_settings so you know the current values. **Required:** ad_group_id (from get_campaign_structure).
remove_ad_group
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Remove (soft-delete) an ad group — sets status=REMOVED. ⚠️ **This is PERMANENT.** Google has no hard delete and REMOVED ad groups cannot be re-enabled. To temporarily stop an ad group, use pause_ad_group instead. Works on ad groups of any channel (Search, Display, PMax, Demand Gen, YouTube). **Required:** ad_group_id.
set_ad_group_device_bid_modifiers
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Set device bid modifiers on an AD GROUP — bid up/down per device, finer than the campaign level. Adjusts (or creates) MOBILE/TABLET/DESKTOP bid modifiers on ONE ad group. Update-or- create: existing device bids are updated, missing ones are created. Idempotent on re-set. **Each entry:** - device: MOBILE | TABLET | DESKTOP - bid_modifier: 1.2 = +20%, 0.8 = -20%, 1.0 = no change **Required:** ad_group_id + 1+ devices. Note: DemandGen ad groups use smart bidding and don't support device bid modifiers (guarded cleanly). CONNECTED_TV/OTHER are campaign-level only.
update_ad_group_demographics
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Set demographic TARGETING on an ad group (exclude-the-inverse). You list which age_ranges / genders / income_ranges to TARGET. Google achieves this by EXCLUDING every value you did NOT list, so be explicit about the full set you want. **Valid values:** - age_ranges: AGE_RANGE_18_24, _25_34, _35_44, _45_54, _55_64, _65_UP, AGE_RANGE_UNDETERMINED - genders: MALE, FEMALE, UNDETERMINED - income_ranges: INCOME_RANGE_0_50, _50_60, _60_70, _70_80, _80_90, _90_UP, INCOME_RANGE_UNDETERMINED **IMPORTANT:** Confirm with the user before narrowing demographics — excludes are live. **Required:** ad_group_id + at least one dimension.
update_ad_group_settings
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Update any combination of settings on ANY ad group (any channel). **Can update (all optional — only what you set changes):** - name, status (ENABLED/PAUSED) - cpc_bid_micros, cpm_bid_micros, target_cpa_micros, target_roas (fraction, e.g. 4.0=400%) - ad_rotation_mode (OPTIMIZE / ROTATE_FOREVER) - final_url_suffix, tracking_url_template - audience_targeting_mode (OBSERVATION vs TARGETING) **IMPORTANT:** Confirm with the user before changing bids or status. Call get_ad_group_settings first to see current values. **Required:** ad_group_id + at least one field to change.
analyze
analyze_meta_ad_performance
User wants detailed analysis of specific Meta ads, creative performance, or wants to identify winning/losing ad variations. This tool provides ad-level and creative-level insights for Meta campaigns. Returns: - Top performing ads by CTR and conversion rate - Underperforming ads that need attention - Creative fatigue indicators (high frequency, declining CTR) - Video completion metrics (25%, 50%, 75%, 100% watched) - Creative optimization recommendations When to use this tool: - "Which of my Meta ads are performing best?" - "Are any of my Facebook ads fatigued?" - "Show me my Instagram video ad performance" - "Which creatives should I pause?" - "Analyze my ad variations" Parameters: - lookback_days: 7, 14, 30 (default), 60, or 90 days - date_range: preset alternative to lookback_days / start_date / end_date. One of: 'last_7_days', 'last_14_days', 'last_30_days', 'last_60_days', 'last_90_days'. (Both 'last_30_days' and 'last_30d' / 'last_month' aliases accepted.) - start_date: Optional start date (YYYY-MM-DD). Overrides lookback_days when used with end_date. - end_date: Optional end date (YYYY-MM-DD). Overrides lookback_days when used with start_date. ⚠️ DATE CLARIFICATION: If the user's date request is vague or ambiguous (e.g., "March to June" without a year, "last quarter", "recently", "a few months ago"), ask the user to specify exact dates before calling this tool. Do not assume or guess dates. - campaign_id: Optional - filter to specific campaign - include_video_metrics: true (default) or false - ad_account_id: Required for multi-account users. Get from list_connected_accounts Execution time: 1-3 seconds (cached database query) Data source: ad_group_daily_metrics table (Meta ad sets stored as ad groups) Creative fatigue detection: - High frequency (>4.0) with declining CTR - CTR dropped >20% from first week - Same creative running >14 days without refresh
analyze_meta_audiences
User asks about Meta/Facebook/Instagram audience performance by demographics, age group or gender targeting optimization, audience saturation, or which demographic segments to target or exclude. This tool provides deep analysis of audience segment performance and detects audience saturation to optimize demographic targeting for Meta Ads. Returns: - Age group performance breakdown (18-24, 25-34, 35-44, 45-54, 55-64, 65+) - Gender performance breakdown (male, female, unknown) - Age + Gender combination analysis - Segments categorized as SCALE/MAINTAIN/REDUCE/EXCLUDE based on ROAS - Audience saturation score (0-100) with contributing factors - Best performing segments to scale - Underperforming segments to reduce/exclude - Targeting optimization recommendations - Quick actionable items When to use this tool: - "Which age groups perform best for my Meta ads?" - "Should I target men or women on Facebook?" - "Is my Meta audience saturated?" - "Which demographics should I exclude?" - "Analyze my Instagram audience performance" - "Best demographic targeting for my Facebook campaigns" - "Age and gender breakdown for my Meta ads" - "Are my lookalike audiences exhausted?" - "Which audience segments are wasting money?" Parameters: - lookback_days: 7, 14, 30 (default), 60, or 90 days - date_range: preset alternative to lookback_days / start_date / end_date. One of: 'last_7_days', 'last_14_days', 'last_30_days', 'last_60_days', 'last_90_days'. (Both 'last_30_days' and 'last_30d' / 'last_month' aliases accepted.) - start_date: Optional start date (YYYY-MM-DD). Overrides lookback_days when used with end_date. - end_date: Optional end date (YYYY-MM-DD). Overrides lookback_days when used with start_date. ⚠️ DATE CLARIFICATION: If the user's date request is vague or ambiguous (e.g., "March to June" without a year, "last quarter", "recently", "a few months ago"), ask the user to specify exact dates before calling this tool. Do not assume or guess dates. - breakdown_type: 'age', 'gender', 'age_gender', or 'all' (default) - include_saturation: Include saturation analysis (default: True) - target_roas: Optional override (default: from account goals or 2.0x) - ad_account_id: Required for multi-account users. Get from list_connected_accounts Execution time: 2-5 seconds (cached database query with analysis) Data source: meta_audience_daily_metrics table (demographic-level daily metrics) ROAS Thresholds for Segment Recommendations: - 🚀 SCALE (ROAS ≥ 1.5x target): Increase budget to this segment - ➖ MAINTAIN (ROAS 0.75x-1.5x target): Keep current allocation - ⚠️ REDUCE (ROAS 0.5x-0.75x target): Decrease budget - 🔴 EXCLUDE (ROAS < 0.5x target): Remove from targeting Saturation Score Factors (weighted): - Frequency Score (35%): How often users see ads (>3 indicates fatigue) - CTR Decline Score (30%): Week-over-week CTR changes - CPA Increase Score (25%): Rising cost per acquisition - Reach Saturation Score (10%): Audience reach exhaustion Saturation Levels: - ✅ HEALTHY (<40): Audience is fresh, continue scaling - 🟡 AT_RISK (40-69): Monitor frequency, prepare new audiences - 🔴 SATURATED (≥70): Expand targeting or refresh creatives Common Insights: - Age 25-44 typically has highest ROAS for e-commerce - Gender targeting varies significantly by product category - High frequency (>4) combined with declining CTR indicates saturation - Lookalike audiences can exhaust within 4-8 weeks at high spend
analyze_meta_catalog_performance
User wants to analyze how their Advantage+ Catalog / Dynamic Product Ads are performing AT THE PRODUCT or PRODUCT-SET level. Keywords: "which products are selling", "catalog performance", "best/worst products", "product ROAS", "product set performance", "which SKUs are wasting money". Breaks catalog performance down by PRODUCT and PRODUCT SET (the campaign-level perf tools can't do this). Returns: - Top products by catalog-attributed ROAS, and underperforming products (below target) - Products spending with ZERO conversions (the catalog waste signal) and zero-impression products - Per-product-set ROAS comparison + the funnel (views → carts → checkouts → purchases) - Units sold, and actionable recommendations (scale winners, exclude losers, shift budget between sets) Uses the same target-ROAS, severity and data-confidence conventions as the other performance tools. Reads cached nightly product metrics — if none exist yet, says so. When to use: "How are my catalog products doing?", "Which products should I scale or pause?", "What's my ROAS by product set?"
analyze_meta_wasted_spend
User asks about Meta/Facebook/Instagram ad spend efficiency, wasted money, underperforming campaigns, placement optimization, or creative fatigue. This tool identifies Meta Ads campaigns and placements that are wasting money by performing below target ROAS or below breakeven (ROAS < 1.0). It extends the base wasted spend detector with Meta-specific features: Returns: - Campaign-level wasted spend analysis (ROAS < 1.0 = actual losses) - Underperforming spend analysis (1.0 <= ROAS < target = opportunity cost) - Placement-level breakdown (which placements are wasting money: Feed, Stories, Reels, etc.) - Creative fatigue detection (high frequency + declining CTR) - Actionable recommendations for campaigns, placements, and creatives - Quick action items When to use this tool: - "Where am I wasting money on Meta/Facebook ads?" - "Which Meta placements should I exclude?" - "Are any of my Facebook creatives fatigued?" - "How can I reduce wasted ad spend on Instagram?" - "Which Meta campaigns are losing money?" - "What's my Meta ROAS by placement?" Parameters: - lookback_days: 7, 30 (default), 60, 90, or 120 days - date_range: preset alternative to lookback_days / start_date / end_date. One of: 'last_7_days', 'last_14_days', 'last_30_days', 'last_60_days', 'last_90_days'. (Both 'last_30_days' and 'last_30d' / 'last_month' aliases accepted.) - start_date: Optional start date (YYYY-MM-DD). Overrides lookback_days when used with end_date. - end_date: Optional end date (YYYY-MM-DD). Overrides lookback_days when used with start_date. ⚠️ DATE CLARIFICATION: If the user's date request is vague or ambiguous (e.g., "March to June" without a year, "last quarter", "recently", "a few months ago"), ask the user to specify exact dates before calling this tool. Do not assume or guess dates. - target_roas: Optional override (e.g., 3.0 for 3.0x ROAS) - include_placements: true (default) - Include placement-level analysis - include_fatigue: true (default) - Include creative fatigue analysis - ad_account_id: Required for multi-account users. Get from list_connected_accounts Execution time: 2-5 seconds (cached database query with analysis) Data source: campaign_daily_metrics + meta_placement_daily_metrics + meta_ad_creative_metrics tables Key definitions: - Wasted Spend (ROAS < 1.0): Actual money lost - for every $1 spent, getting back <$1 - Underperforming (1.0 <= ROAS < target): Profitable but below target - opportunity cost - Creative Fatigue: Ads with frequency >4x (cold traffic) or >7x (retargeting) showing declining CTR Meta-specific placement optimization: - Audience Network often has lowest ROAS - consider excluding - Instagram Stories/Reels typically perform differently than Feed - Facebook Marketplace can waste spend if not relevant **Quick Actions (IMPORTANT — read severity context first):** - ⏳ LEARNING campaigns → Do NOT pause. Monitor for 14+ days before judging. - ❓ INSUFFICIENT_DATA campaigns → Need more spend before analysis is meaningful. - 🚨 CRITICAL campaigns (established, 14+ days, ZERO conversions) → Consider pausing - 🚨 CRITICAL campaigns (established, 14+ days, HAS conversions) → Review performance, verify revenue in ad platform before reducing budget - 🔴 HIGH severity (established, 14+ days) → Consider reducing budget by 50-70% - 🟡 MEDIUM → Optimize targeting, ad copy, landing pages ⚠️ **NEVER say "pause" for a campaign that has conversions.** Say "review" or "reduce budget" instead. ⚠️ **NEVER recommend pausing a campaign in LEARNING phase.** ⚠️ **If ALL campaigns are LEARNING or INSUFFICIENT_DATA, tell the user their account is too new for waste analysis and recommend checking back in 2 weeks.** ⚠️ **Consider campaign objective: brand awareness campaigns will not have ROAS data. This is normal.** ⚠️ **When data confidence is MEDIUM or LOW, soften all recommendations and add verification prompts.**
analyze_search_terms
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Discover keyword opportunities and optimize match types by analyzing actual search terms. ⚠️ IMPORTANT: This tool retrieves READ-ONLY data. Safe to call multiple times. Google Ads only - NOT available for TikTok. 🎯 **What This Tool Does (Performance Agent - Phase 1 Feature 3):** - Identifies OPPORTUNITY keywords: Converting search terms NOT in your keyword list - Identifies NEGATIVE keywords: Expensive terms with zero conversions - Analyzes MATCH TYPE performance: Exact vs Phrase vs Broad efficiency - Provides specific recommendations with suggested bids and match types - Ranks opportunities by profit potential (not just ROAS) **Returns comprehensive keyword intelligence:** - Top 20 opportunity keywords with suggested bids and match types - Top 20 negative keyword candidates with wasted cost breakdown - Match type performance comparison (Exact/Phrase/Broad) - Broad→Exact conversion recommendations - Total opportunity value and wasted spend amounts - Actionable recommendations for immediate implementation 🔍 **What Search Term Mining Reveals:** **Opportunity Keywords (Money Left on Table):** - Search terms that ARE converting but you're NOT bidding on them directly - These are queries triggering your ads via Broad/Phrase match, but should be added as Exact keywords - Example: User searches "enterprise security software pricing" → converts → but you only have "security software" as keyword - **Action:** Add high-converting search terms as new keywords with suggested bids **Negative Keywords (Money Wasted):** - Search terms costing >$10 with ZERO conversions - Low-intent queries like "free", "download", "crack", "how to" - Example: "free security software download" → 120 clicks, $540 spent, 0 conversions - **Action:** Add as negative keywords to stop wasting budget **Match Type Optimization:** - Compares performance of Exact vs Phrase vs Broad match - Identifies Broad keywords that should be converted to Exact for better control - Example: Broad "security software" has 45% wasted spend, but top search terms have 20x ROAS - **Action:** Convert high-performing Broad keywords to Exact match **Parameters:** - lookback_days: 7, 30, 60, 90, or 120 days (default: 30) - start_date: Optional start date (YYYY-MM-DD). Overrides lookback_days when used with end_date. - end_date: Optional end date (YYYY-MM-DD). Overrides lookback_days when used with start_date. ⚠️ DATE CLARIFICATION: If the user's date request is vague or ambiguous (e.g., "March to June" without a year, "last quarter", "recently", "a few months ago"), ask the user to specify exact dates before calling this tool. Do not assume or guess dates. - analysis_type: 'opportunities', 'negatives', 'match_types', 'all', or **'raw_report'** (default: 'all') - Use **'raw_report'** when the user wants to SEE their actual search terms — the words customers type into Google - force_refresh: true to trigger immediate API collection (default: false, uses cached data) - customer_id: Optional (uses connected account if omitted) - **campaign_id**: Optional — filter search terms to a specific campaign (get from list_campaigns) - **page**: Page number for raw_report pagination (default: 1) - **page_size**: Results per page for raw_report (1-100, default: 50) - **sort_by**: Sort for raw_report: 'cost' (default), 'clicks', 'impressions', 'conversions' - **min_clicks**: Minimum clicks filter for raw_report (default: 0) **Execution time:** 1-3 seconds (cached database query) **Data source:** search_term_daily_metrics table (updated nightly, 120-day retention) **⚡ RAW REPORT PAGINATION CONTRACT:** - When using analysis_type='raw_report', results are paginated - Check `pagination.has_more` — if true, call again with next `page` - Continue until `has_more` is false, then present consolidated results - Use `campaign_id` to focus on a specific campaign's search terms **Use this tool when:** - User asks "what keywords should I add?" - User wants to find wasted spend at keyword level - User asks "what should I add as negative keywords?" - User wants to improve match type efficiency - User asks "which Broad keywords should be Exact?" - User wants to discover hidden keyword opportunities - **User asks "show me my search terms" or "what are people searching for?"** → use analysis_type='raw_report' - **User asks "show me search terms for campaign X"** → use analysis_type='raw_report' with campaign_id ⚠️ **Platform Limitation:** This tool ONLY works for Google Ads. TikTok Ads does not provide search term data due to privacy restrictions. 📊 **AFTER calling this tool, help the user understand:** **Opportunity Keywords:** - **What it means:** These are winning search terms you're missing - **Profit potential:** Shows expected additional profit if added - **Suggested action:** Add as new keywords with recommended bid and match type - **Priority:** Start with highest opportunity_value (profit potential) **Example:** Search term: "enterprise security software pricing" - 8 conversions, $240 cost, $4,800 value - Opportunity Value: $4,560 profit potential - Suggested Bid: $6.00 (based on current CPC and ROAS) - Suggested Match Type: EXACT (high intent, proven converter) - **Action:** Add this as an Exact match keyword with $6 bid **Negative Keywords:** - **What it means:** These queries waste money and never convert - **Cost:** Total wasted spend on non-converting terms - **Common patterns:** "free", "download", "crack", "review", "how to" - **Action:** Add as negative keywords (campaign or account level) **Example:** Search term: "free security software" - 120 clicks, $540 wasted, 0 conversions - Reason: Low purchase intent (free) - **Action:** Add "free" as negative keyword at campaign level **Match Type Performance:** - **Exact:** Tightest control, lowest waste, highest ROAS (recommended) - **Phrase:** Moderate flexibility, some waste, decent ROAS - **Broad:** Most volume, highest waste, lowest ROAS (use sparingly) **Example Analysis:** - Exact: 450 keywords, ROAS 4.8x, 2% wasted spend ✅ - Phrase: 280 keywords, ROAS 3.2x, 8% wasted spend ⚠️ - Broad: 120 keywords, ROAS 1.8x, 45% wasted spend 🔴 **Quick Actions:** 1. Add top 5 opportunity keywords as Exact match 2. Block top 10 negative keywords at campaign level 3. Convert high-performing Broad keywords to Exact 4. Review Phrase keywords with >10% wasted spend **Visualization Tip:** For opportunity keywords, suggest creating a scatter plot (x=ROAS, y=Spend, size=conversions) to visualize profit potential. **Implementation Steps:** 1. Review top opportunities and negatives 2. Start with 5-10 new keywords (don't overwhelm account) 3. Add negatives in batches (test impact over 7 days) 4. Convert Broad→Exact gradually (monitor volume drop) 5. Re-run analysis monthly to discover new opportunities **Best Practices:** - Focus on opportunity_value (profit) not just ROAS - Start with Exact match for all new keywords (tightest control) - Add negatives at campaign level first (easier to undo than account level) - Monitor match type distribution: Aim for 60%+ Exact, 30% Phrase, 10% Broad - Review search terms every 2 weeks during active optimization 💬 **Community**: For keyword optimization discussions, visit our Discord: https://discord.gg/dH3Qt4YS
analyze_wasted_spend
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Analyze wasted ad spend and identify campaigns losing money or underperforming. ⚠️ IMPORTANT: This tool retrieves READ-ONLY data. Safe to call multiple times. 🎯 **What This Tool Does (Performance Agent - Phase 1):** - Identifies campaigns LOSING money (ROAS < 1.0x) - Identifies campaigns UNDERPERFORMING (1.0x ≤ ROAS < target) - Separates true waste from opportunity cost - Provides severity-based classification (CRITICAL/HIGH/MEDIUM) - Generates actionable recommendations with expected impact - Shows top performing campaigns for budget reallocation **Returns detailed analysis:** - Total wasted spend (campaigns with ROAS < 1.0) - Total underperforming spend (profitable but below target) - Campaign-by-campaign breakdown with severity levels - Specific recommendations (PAUSE/REDUCE/OPTIMIZE) - Quick actions for immediate implementation - Budget reallocation suggestions **Target ROAS Resolution (3-tier priority):** 1. Account goals table (user-set or API-pulled) 2. 90-day historical average ROAS 3. Default to 2.0x if no data available **Severity Levels:** - 🚨 CRITICAL: ROAS < 0.5x (losing money severely) - 🔴 HIGH: ROAS < 1.0x (unprofitable/breakeven) - 🟡 MEDIUM: 1.0x ≤ ROAS < target (profitable but underperforming) **Parameters:** - lookback_days: 7, 30, 60, 90, or 120 days (default: 30) - start_date: Optional start date (YYYY-MM-DD). Overrides lookback_days when used with end_date. - end_date: Optional end date (YYYY-MM-DD). Overrides lookback_days when used with start_date. ⚠️ DATE CLARIFICATION: If the user's date request is vague or ambiguous (e.g., "March to June" without a year, "last quarter", "recently", "a few months ago"), ask the user to specify exact dates before calling this tool. Do not assume or guess dates. - target_roas: Optional override (e.g., 3.0 for 3.0x ROAS) - customer_id: Optional (uses connected account if omitted) **Execution time:** 1-3 seconds (cached database query) **Data source:** campaign_daily_metrics table (updated nightly) **Use this tool when:** - User asks "where is my money going?" - User wants to identify wasted spend - User wants to optimize campaign budgets - User asks which campaigns to pause/reduce - User wants to know which campaigns are losing money 📊 **AFTER calling this tool, help the user understand:** **Wasted vs. Underperforming:** - **Wasted Spend** = Actual losses (ROAS < 1.0, you're losing money) - **Underperforming Spend** = Opportunity cost (profitable but below target) **Example:** - Campaign A: Spent $1000, got $600 back (ROAS 0.6x) → $400 WASTED - Campaign B: Spent $1000, got $1500 back (ROAS 1.5x, target 3.0x) → $0 wasted, but $500 opportunity cost **Quick Actions (IMPORTANT — read severity context first):** - ⏳ LEARNING campaigns → Do NOT pause. Monitor for 14+ days before judging. - ❓ INSUFFICIENT_DATA campaigns → Need more spend before analysis is meaningful. - 🚨 CRITICAL campaigns (established, 14+ days, ZERO conversions) → Consider pausing - 🚨 CRITICAL campaigns (established, 14+ days, HAS conversions) → Review performance, verify revenue in ad platform before reducing budget - 🔴 HIGH severity (established, 14+ days) → Consider reducing budget by 50-70% - 🟡 MEDIUM → Optimize targeting, ad copy, landing pages - Top performers → Consider increasing budget ⚠️ **NEVER say "pause" for a campaign that has conversions.** Say "review" or "reduce budget" instead. ⚠️ **NEVER recommend pausing a campaign in LEARNING phase.** ⚠️ **If ALL campaigns are LEARNING or INSUFFICIENT_DATA, tell the user their account is too new for waste analysis and recommend checking back in 2 weeks.** ⚠️ **Consider campaign objective: brand awareness campaigns will not have ROAS data. This is normal.** ⚠️ **When data confidence is MEDIUM or LOW, soften all recommendations and add verification prompts.** **Visualization Tip:** For 10+ campaigns, suggest creating a treemap visualization to show wasted spend by campaign size. 💬 **Community**: For optimization discussions, visit our Discord: https://discord.gg/dH3Qt4YS
demandgen
add_demandgen_ad
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Add a new Demand Gen ad (image or video) to an EXISTING Demand Gen ad group. Use this to add MORE ads to an ad group you already have — e.g. test a second creative, or add a video ad alongside an image ad. It does NOT create an ad group or change targeting; get the ad_group_id from get_campaign_structure (it must be a DEMAND_GEN ad group). **Formats:** - **multi_asset** (default) — image ad: marketing_images (landscape 1.91:1), square_marketing_images (1:1), portrait_marketing_images (4:5), logo. Google mixes them. - **video_responsive** — video ad: youtube_video_ids (1-5) + logo. long_headlines recommended. **Creative bounds (Demand Gen):** headlines 1-5 (max 40 chars), descriptions 1-5 (max 90 chars), business_name max 25, long_headlines max 90 chars. **Assets:** provide NEW images via marketing_images/etc. as [{"url": "...", "name": "..."}], OR reuse existing asset resource names via existing_images, OR a logo by logo_asset_id (from discover_existing_assets). Videos are referenced by youtube_video_ids. **Parameters:** - ad_group_id (REQUIRED) — existing DEMAND_GEN ad group - ad_format, final_url (REQUIRED), business_name (REQUIRED), headlines (REQUIRED), descriptions (REQUIRED) - long_headlines, call_to_action, image/video/logo sources (optional per format) The ad is created ENABLED; delivery is still gated by the ad group + campaign status. **Execution time:** 10-20 seconds (assets are uploaded then the ad is created in one atomic mutate).
add_demandgen_ad_group
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Add a new ad group with targeting and ads to an EXISTING Demand Gen campaign. Use this after create_demandgen_campaign to add additional ad groups. Each ad group can have: - **Different location targeting** (e.g., US cities vs India cities vs UAE cities) - **Different audience targeting** (e.g., marketing pros vs tech founders vs agency owners) - **Same or different ad creative** (headlines, descriptions, images, videos) **Reuse Existing Audiences:** To attach an existing audience (from Google Ads UI or a previous campaign), pass: - audience_segments.existing_audience_id: numeric audience ID - audience_segments.existing_audience_resource_name: full resource name **Create New Audiences:** To create a new audience from interest segments: - audience_segments.in_market_audience_ids: [80517, 80520] - audience_segments.affinity_audience_ids: [92948] Use search_audiences to find segment IDs. **Parameters:** - campaign_id: Demand Gen campaign ID (from create_demandgen_campaign or list_campaigns) - ad_group_name: Descriptive name - Same creative fields as create_demandgen_campaign (headlines, descriptions, images, etc.) - target_locations: Location targeting specific to this ad group - audience_segments: Audience targeting specific to this ad group **Execution time:** 10-20 seconds
create_demandgen_campaign
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link 🔄 LONG-RUNNING TOOL: Creates a Demand Gen campaign across ALL Google channels — YouTube, Discover, Gmail, Display, and Maps. Emits MCP progress updates during creation (typically 10-20 seconds). ⚠️ CRITICAL WARNING ⚠️ - Call this tool ONLY ONCE per campaign - Creates REAL campaigns that cost REAL money - Do NOT retry automatically if errors occur - Report errors to user instead of retrying 🌐 **Demand Gen Campaign Channels (ALL enabled by default):** ✅ YouTube In-Feed (search results & related videos) ✅ YouTube In-Stream (before/during/after videos) ✅ YouTube Shorts (Shorts feed) ✅ Gmail (Promotions & Social tabs) ✅ Discover (Google Discover feed) ✅ Display (Google Display Network) ❌ Maps (opt-in, disabled by default) 📋 **YOUR CRITICAL ROLE: Campaign Strategist & Text Creator** **STEP 1: Collect Campaign Details from User** YOU MUST collect these from the user: 1. **Campaign Name** - Descriptive and unique 2. **Daily Budget** - In account's native currency (recommended $20+/day) 3. **Ad Format** - multi_asset (images) or video_responsive (videos) 4. **Final URL** - Landing page 5. **Business Name** - Max 25 characters **STEP 2: Discover Existing Assets** 🔴 MANDATORY: Call discover_existing_assets to find existing logos/images. - If logos found → use logo_asset_id or existing_images.logos_square - If NO logos → ask user for logo URL, run validate_and_prepare_assets **STEP 3: Generate Ad Copy** - Headlines (1-5): STRICT 40 character max each - Descriptions (1-5): STRICT 90 character max each - Long Headlines (optional, for video_responsive): 90 char max each **STEP 4: Prepare Images/Videos** For multi_asset: Need landscape (1.91:1) OR square (1:1) marketing images + logo For video_responsive: Need YouTube video IDs (validate first) + logo **STEP 5: Call create_demandgen_campaign with complete payload** **Bidding Options (your choice is honored — engine is advisory only):** - MAXIMIZE_CLICKS: Default, works without conversion tracking - MAXIMIZE_CONVERSIONS: Requires conversion tracking - TARGET_CPA: Requires target_cpa value - MAXIMIZE_CONVERSION_VALUE: Requires conversion tracking - TARGET_ROAS: Requires target_roas value **Channel Controls (optional):** Pass channels dict to disable specific channels: {"gmail": false, "display": false} → YouTube + Discover only **STEP 6: MANDATORY — Add Extensions After Creation** After success, add sitelinks, callouts, and structured snippets. **Execution Time:** 10-20 seconds **CRITICAL REMINDERS:** - Campaign starts PAUSED for user safety - This costs real money — be transparent - Never retry on failure — report error to user
get_demandgen_audiences
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Read the grouped audience targeting on a Demand Gen (or YouTube) ad group. Demand Gen ad groups use ONE grouped audience (a named audience built from segments), not individual audience criteria. This shows the audience name and its segments. Use this before replace_demandgen_audiences to see what's currently targeted. **Required:** ad_group_id (from get_campaign_structure). Only works on Demand Gen ad groups.
get_demandgen_channel_controls
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Read which delivery channels are enabled on a Demand Gen (or YouTube) ad group. Demand Gen ad groups deliver across 6 channels: youtube_in_stream, youtube_in_feed, youtube_shorts, discover, gmail, display. This shows the on/off state of each. Use this before update_demandgen_channel_controls so you know the current state. **Required:** ad_group_id (from get_campaign_structure). Only works on Demand Gen ad groups.
update_demandgen_channel_controls
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Turn Demand Gen (or YouTube) delivery channels on or off for an ad group. The 6 channels: youtube_in_stream, youtube_in_feed, youtube_shorts, discover, gmail, display. Pass only the channels you want to change — the rest keep their current value (this is a merge, not a replace). At least one channel must stay enabled. Example: set youtube_shorts=false to stop delivering on Shorts while leaving the rest on. **Required:** ad_group_id + at least one channel toggle. Only works on Demand Gen ad groups.
call
add_call_asset
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Add a phone call asset to a campaign. Call assets show a tap-to-call button on mobile and a visible phone number on desktop. They attach at campaign level via CampaignAssetService. **Parameters:** - campaign_id: The campaign ID (REQUIRED) - phone_number: digits or formatted ("929-478-4835", "+1 929 478 4835") - country_code: 2-letter ISO ("US", "GB", "IN", "AU") - call_conversion_action: Optional. Full resource name of a CallConversionAction (`customers/<cid>/conversionActions/<id>`) to count calls as conversions. Omit to skip call-conversion tracking. - customer_id: Optional (uses connected account if omitted) **Execution time:** 2-4 seconds **Example:** User: "Add 929-478-4835 (US) as a call asset on campaign 23847465076" Agent: add_call_asset(campaign_id="23847465076", phone_number="929-478-4835", country_code="US")
list_call_assets
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link List every phone (CALL) asset on a campaign, with status and resource names. Use this to inspect call assets before adding one (so you don't create a duplicate), or to find the asset/link to pause or remove. **Parameters:** - campaign_id: The campaign ID (REQUIRED). Get from list_campaigns. - customer_id: Optional Google Ads customer ID **Returns:** each call asset's phone_number, country_code, status (ENABLED/PAUSED), asset_resource_name, and campaign_asset_resource_name. **Execution time:** 1-2 seconds (read-only) **Example:** User: "What phone numbers are on this campaign?" Agent: list_call_assets(campaign_id="19850524478")
remove_call_assets
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Remove (unlink) phone (CALL) assets from a campaign. Unlinks the CampaignAsset from THIS campaign only — the underlying asset stays in the Asset Library and can be re-linked elsewhere. Use to clean up a duplicate phone number. **Parameters:** - campaign_id: The campaign ID (REQUIRED) - asset_ids: Optional list of asset IDs / resource_names to unlink (get from list_call_assets). OMIT to unlink ALL call assets on the campaign. - customer_id: Optional Google Ads customer ID **Execution time:** 2-4 seconds **Example:** User: "Remove the duplicate phone number from this campaign" Agent: 1. list_call_assets(campaign_id="19850524478") to get the asset IDs 2. remove_call_assets(campaign_id="19850524478", asset_ids=["411113414834"])
set_call_asset_status
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Pause or re-enable phone (CALL) asset links on a campaign — without deleting them. Pausing stops the number from showing while keeping it linked; enabling turns it back on. To fully unlink, use remove_call_assets. **Parameters:** - campaign_id: The campaign ID (REQUIRED) - status: 'PAUSED' or 'ENABLED' (REQUIRED) - asset_ids: Optional list of asset IDs / resource_names (get from list_call_assets). OMIT to change ALL call assets on the campaign. - customer_id: Optional Google Ads customer ID **Execution time:** 2-4 seconds **Example:** User: "Pause the old phone number before I add the new one" Agent: 1. list_call_assets to find the old asset ID 2. set_call_asset_status(campaign_id="19850524478", status="PAUSED", asset_ids=["..."])
conversion
create_conversion_action
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Create a WEBPAGE conversion action so the account can use TARGET_CPA / MAXIMIZE_CONVERSIONS / TARGET_ROAS bidding. **Why this matters:** Without conversion actions, Smart Bidding strategies (TARGET_CPA, MAXIMIZE_CONVERSIONS, TARGET_ROAS) can't function correctly. They need a "what counts as a conversion" definition to optimize toward. This tool creates that definition. **v1 scope:** WEBPAGE conversion actions only. After creating, the customer must: 1. Install the Google site tag (gtag.js) on their website if not already present 2. Add an event snippet on the conversion page (or fire it on a click/form submit) 3. Wait 24-48 hours for the first conversions to flow in 4. THEN apply TARGET_CPA bidding (it needs a few conversions to optimize) Phone-call / app / Firebase / Floodlight conversion types are deferred to a future tool. **Pick the right category:** - E-commerce purchase → PURCHASE (set value + currency) - Lead-gen form submit → SUBMIT_LEAD_FORM (set value if leads have known $ worth) - Newsletter signup / account creation → SIGNUP - Add-to-cart tracking → ADD_TO_CART - Begin-checkout (abandonment funnel) → BEGIN_CHECKOUT - Phone-call lead from ad → PHONE_CALL_LEAD - Outbound click on partner site → OUTBOUND_CLICK - Engagement metric (page time, scroll, video play) → ENGAGEMENT - "Get directions" tap on a map ad → GET_DIRECTIONS - Quote request → REQUEST_QUOTE - Appointment booked → BOOK_APPOINTMENT - Generic contact form → CONTACT - Use DEFAULT only if none fit. **Counting type:** - ONE_PER_CLICK (default): one conversion per ad click. Use for lead-gen, signups, downloads. - MANY_PER_CLICK: every purchase counts, even multiple from same click. Use for e-commerce. **Value settings:** - Recommended for lead-gen: set `value` to your average lead $ worth (e.g. 50.0 for $50/lead). This gives TARGET_CPA something to optimize. - Set `always_use_default_value=true` if every conversion has the same value (lead-gen). - Leave both unset for e-commerce — the tag sends actual transaction values. **Example:** User: "Set up TARGET_CPA bidding for my lead-gen campaign" Agent: 1. Calls create_conversion_action(name="Lead Form Submit", category="SUBMIT_LEAD_FORM", value=50.0, always_use_default_value=true) 2. Tells user: "Created the conversion goal. Now install the Google tag on your thank-you page, then I'll switch the campaign to TARGET_CPA." 3. After tag is installed and conversions are flowing, calls update_bid_strategy(strategy="TARGET_CPA", target_cpa=20.0).
get_conversion_action_performance
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Per-conversion-action performance breakdown. This tool retrieves READ-ONLY data via 2 live GAQL queries (cached 5 min in Redis). Safe to call multiple times. **Returns:** - `totals` — account or campaign aggregate: cost, conversions, conversion_value, CPA, ROAS, clicks, impressions - `breakdown` — per-conversion-action rows: conversions, conversion_value, all_conversions, all_conversions_value, avg_value_per_conversion, share_of_conversions, share_of_value - `note` — explains why per-action CPA/ROAS are NOT computed **Important — what this tool does NOT do:** Per-action CPA and ROAS are NOT shown. Google Ads rejects `cost_micros` when segmenting by `conversion_action` because cost is shared across all actions a click can produce. We do NOT prorate cost per action — that would fabricate data. Account/campaign-level CPA + ROAS appear in `totals`. Use `share_of_conversions` and `share_of_value` to see relative contribution per action. **Parameters:** - customer_id: Optional (uses connected account if omitted) - lookback_days: 7, 30, 60, 90, 120 (default 30). Ignored when both start_date and end_date set. - start_date / end_date: YYYY-MM-DD (override lookback_days when both provided) - campaign_id: Optional. Scopes the breakdown to a single campaign. **Execution time:** 2-5 seconds (2 GAQL queries, then cached 5 min) **Use this tool when:** - User asks "which conversion action drove the most conversions / value?" - User wants per-action breakdown for accounts with multiple conversion actions (e.g., lead vs purchase) - User wants to see relative contribution of each action to total conversions/value - After `list_conversion_actions` to map IDs to performance **Tip:** Use this AFTER `list_conversion_actions` so you know action names/IDs/categories. For a single campaign: pass `campaign_id` from `list_campaigns`.
list_conversion_actions
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link List conversion actions for the connected Google Ads account with full per-action metadata. This tool retrieves READ-ONLY data. Safe to call multiple times. **Returns for each conversion action:** - id, name, resource_name - category (PURCHASE, SUBMIT_LEAD_FORM, SIGNUP, ADD_TO_CART, BEGIN_CHECKOUT, BOOK_APPOINTMENT, etc.) - status (ENABLED, REMOVED, HIDDEN) - type (WEBPAGE, UPLOAD_CLICKS, GOOGLE_ANALYTICS_4, FIREBASE_*, etc.) - counting_type (ONE_PER_CLICK or MANY_PER_CLICK) - primary_for_goal (true if this action is primary for its category goal) - include_in_conversions_metric (true if it counts in Smart Bidding "Conversions") - click_through_lookback_window_days, view_through_lookback_window_days - value_settings: default_value, default_currency_code, always_use_default_value - attribution_model (GOOGLE_ADS_LAST_CLICK, DATA_DRIVEN, etc.) **Parameters:** - customer_id: Optional Google Ads customer ID (uses primary if omitted) - status_filter: 'ENABLED' (default — matches Google Ads UI active list), 'all' (include HIDDEN), or 'primary' (only primary_for_goal=true) - include_removed: false by default (matches Google Ads UI). Set true to include status=REMOVED for full audit. **Execution time:** 1-3 seconds (single GAQL query, cached 1 hour in Redis) **Use this tool when:** - User asks for conversion setup, conversion action list, or conversion tracking audit beyond a health-score summary - User wants per-action category, counting mode, or value settings to reason about ROAS / TARGET_ROAS bidding - User wants to see secondary or non-primary actions that audit_conversion_tracking truncates - Before any per-conversion-action analysis (downstream tools may need the action IDs) **Tip:** For accounts with many actions (100+), `status_filter='primary'` returns just the goal-primary actions used by Smart Bidding — usually the most relevant subset.
update_conversion_action
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Update an EXISTING conversion action (change its name, category, status, value, counting, lookback windows, primary flag, whether it counts in Conversions, or attribution model). Only the fields you pass change — everything else stays as-is. It never removes a conversion action (to pause it, set status=PAUSED, which is reversible). **Parameters:** - conversion_action_id: The conversion action to update (REQUIRED). Get it from list_conversion_actions or audit_conversion_tracking. - Any of: name, category, status (ENABLED/PAUSED), value (+ currency_code, always_use_default_value), counting_type, click_through_lookback_window_days, view_through_lookback_window_days, include_in_conversions_metric, primary_for_goal, attribution_model. - customer_id: Optional. **Common uses:** - "Set the payment-calculator conversion to secondary" → primary_for_goal=false - "Stop counting Get Directions in Conversions" → include_in_conversions_metric=false - "Assign $250 to the Lead Submit conversion" → value=250 - "Pause the old duplicate conversion" → status=PAUSED **Execution time:** 2-4 seconds. Confirm changes with the user first — this changes a live conversion setup.
google
google_analytics
Read Google Analytics 4 reports and metadata for the user's connected GA4 properties. **Use action="list_tools" first** to discover available actions and their parameters. Then use action="execute" with the specific tool_name and arguments. **When to use:** - Website / app traffic, sessions, users, page views, bounce rate, engagement - Conversions, conversion events, key events, goal completions - Audience demographics, geography, device breakdown - Traffic sources (organic, paid, referral, social, direct) - Comparing ad spend (from `google_ads` / `meta_ads`) to actual site outcomes - "How is my website performing?", "show GA4 conversions", "what's my bounce rate" If the user hasn't connected Google Analytics, this tool returns a friendly message asking them to open Settings → Connections to authorize the connection. **Example — list actions:** action: "list_tools" **Example — run a report:** action: "execute" tool_name: "google_analytics-run-report" arguments: {"propertyId": "493035312", "dateRanges": [{"startDate": "7daysAgo", "endDate": "today"}], "metrics": [{"name": "sessions"}, {"name": "totalUsers"}]}
google_search_console
Read organic-search performance for the user's verified sites, and submit URLs for re-indexing. **Use action="list_tools" first** to discover available actions and their parameters. Then use action="execute" with the specific tool_name and arguments. **When to use:** - Organic search performance — clicks, impressions, CTR, average position - Which search queries bring traffic, and which pages rank for them - Breakdowns by query, page, country, device, or date - Comparing PAID search (`google_ads`) against ORGANIC search - "What keywords am I ranking for?", "why did organic traffic drop?", "which pages lost impressions?" - Asking Google to re-crawl a page after publishing or updating it If the user hasn't connected Search Console, this tool returns a friendly message asking them to open Settings → Connections to authorize the connection. **⚠️ Side effects & confirmation:** `google_search_console-submit-url-for-indexing` is a WRITE — it notifies Google that a URL was updated or deleted. Confirm the exact URL with the user before submitting. The performance action is read-only. **Example — list actions:** action: "list_tools" **Example — top queries last 28 days:** action: "execute" tool_name: "google_search_console-retrieve-site-performance-data" arguments: {"siteUrl": "https://example.com/", "startDate": "2026-07-16", "endDate": "2026-08-12", "dimensions": ["query"], "rowLimit": 25}
google_tag_manager
Read and manage tags and variables in the user's Google Tag Manager containers. **Use action="list_tools" first** to discover available actions and their parameters. Then use action="execute" with the specific tool_name and arguments. **When to use:** - Which tags (conversion pixels, analytics, remarketing) are on their site - Whether a specific pixel/tag exists and is configured correctly - Diagnosing why a conversion pixel isn't firing — read the tag config - Creating or updating a tag or a GTM variable - "Is my Meta pixel installed?", "list my GTM tags", "why isn't my conversion tracking firing" If the user hasn't connected Google Tag Manager, this tool returns a friendly message asking them to open Settings → Connections to authorize the connection. **⚠️ Side effects & confirmation:** create-tag, update-tag and update-variable WRITE to a live container that fires the customer's tracking on their real website — a wrong edit can silently break conversion tracking site-wide. Confirm the exact change before any write; prefer the read actions (get-tag, get-tags) for diagnostics. **Example — list actions:** action: "list_tools" **Example — list tags in a container:** action: "execute" tool_name: "google_tag_manager-get-tags" arguments: {"accountId": "6000000000", "containerId": "12345678", "workspaceId": "3"}
list_google_languages
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link List Google Ads language constants. Returns the catalog of valid language resource names for `target_languages` in campaign creation tools. **WHEN TO USE:** Call this BEFORE campaign creation whenever the user requests a language that isn't obviously ISO-2 (e.g., user says "Brazilian Portuguese", "Swiss German", "Simplified Chinese"). Returns the correct `languageConstants/<id>` + the ISO code Google expects. Campaign creation tools accept ISO codes (e.g., 'en', 'pt-BR'), numeric IDs (1000), or full resource names (`languageConstants/1000`) — but the catalog here is authoritative. **INPUT:** optional `search` substring (searches both name and code), optional `only_targetable` (default true — excludes non-targetable legacy codes). **Execution time:** instant after first call. Redis-cached 24 hours.
pause
pause_ad
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Pause an ad to stop it from showing. This is REVERSIBLE using resume_ad. **Parameters:** - ad_id: The ad ID to pause (REQUIRED) - ad_group_id: The ad group ID (REQUIRED) - customer_id: Optional **Execution time:** 1-2 seconds **When to use:** - User says "pause this ad", "stop this ad" - User wants to A/B test by pausing one ad - Ad is underperforming and needs a break - Making changes before re-enabling **Example:** User: "Pause my underperforming ad" Agent: 1. Uses get_campaign_structure to find ad_id and ad_group_id 2. Uses pause_ad to stop the ad
pause_ad_group
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Pause an ad group so none of its ads serve. Works on ad groups of any channel — Search, Display, PMax, Demand Gen, YouTube. This is REVERSIBLE using resume_ad_group. **Parameters:** - ad_group_id: The ad group ID to pause (REQUIRED) - customer_id: Optional **Execution time:** 1-2 seconds **When to use:** - User wants to pause an entire ad group while keeping its sibling ad groups running - New build SOPs that require ad groups to start PAUSED until launch (PMax/Search SOPs) - Temporarily silencing a themed ad group without removing it **Note:** This is the ad-group-level counterpart to `pause_ad` (ad-level) and `pause_campaign` (campaign-level). Unlike `update_display_ad_group`, this works for Search ad groups too.
pause_campaign
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Quickly pause a running campaign. Pausing a campaign stops all ads from showing immediately. This is REVERSIBLE using resume_campaign. **Parameters:** - campaign_id: The campaign ID (REQUIRED - get from list_campaigns) - customer_id: Optional (uses connected account if omitted) **Execution time:** 1-2 seconds **Returns:** - Campaign name - Before status (e.g., ENABLED) - After status (PAUSED) - Confirmation message **When to use:** - User says "pause the campaign", "stop the ads", "turn it off" - User wants to temporarily stop spending - User needs to make changes before ads continue **Example:** User: "Pause my summer sale campaign" Agent: Uses pause_campaign with the campaign_id
pause_meta_campaign
User wants to pause a running Meta campaign. IMPORTANT: Pausing a campaign stops all ad delivery immediately. No more budget will be spent until resumed. Returns: - Confirmation that campaign is paused - Campaign details - Ads Manager URL When to use this tool: - "Pause my Meta campaign" - "Stop my Facebook ads" - "Pause campaign 123456" - "Turn off my Instagram campaign" Parameters: - campaign_id: The Meta Campaign ID to pause (required) Execution time: 2-5 seconds Effect: Campaign status changes to PAUSED immediately
product
add_product_group
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Subdivide a Shopping ad group's products by a dimension — set a bid for a partition or exclude it. Splits products by `dimension_type`=`value` (e.g. product_brand=Nike, product_type=Shoes with level=LEVEL1, product_item_id=SKU123, product_condition=NEW). Creates a biddable partition (bid_micros) OR an excluded one (exclude=true) — plus the required "everything else" sibling automatically. FIRST call on a serve-all ad group subdivides the root. To split an EXISTING partition further, pass parent_criterion_id (the UNIT to subdivide, from get_product_groups). **Required:** ad_group_id, dimension_type, value. Optional: level (for type/category), index (for custom_attribute), bid_micros OR exclude, parent_criterion_id.
get_product_groups
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Read a Shopping ad group's product-partition (listing-group) tree. Shows how the ad group's products are subdivided for bidding. Returns each node: criterion_id, parent_id, node_type (SUBDIVISION branch / UNIT leaf), the dimension it represents, its bid, and whether it's excluded. An empty tree means the ad group serves ALL products at the ad-group bid. **Required:** ad_group_id (a Shopping ad group).
remove_product_group
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Remove a product-group node from a Shopping ad group's tree (and its subtree). Get the criterion_id from get_product_groups. Removing a subdivision removes everything under it. **Required:** ad_group_id, criterion_id.
update_product_group
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Change the max CPC bid on a biddable product-group (UNIT) node. Get the criterion_id from get_product_groups. Only biddable UNIT leaves have a bid (SUBDIVISION branches and excluded nodes do not). **Required:** ad_group_id, criterion_id, bid_micros.
resume
resume_ad
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Resume a paused ad to start showing it again. Only works on PAUSED ads (not REMOVED). **Parameters:** - ad_id: The ad ID to resume (REQUIRED) - ad_group_id: The ad group ID (REQUIRED) - customer_id: Optional **Execution time:** 1-2 seconds **When to use:** - User says "resume", "turn it back on", "enable" - User finished making changes - User wants to reactivate a paused A/B test variant **Example:** User: "Turn my paused ad back on" Agent: 1. Uses get_campaign_structure to find the paused ad 2. Uses resume_ad to enable it
resume_ad_group
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Resume a paused ad group (any channel). Reverses a previous `pause_ad_group`. Only works on PAUSED ad groups (not REMOVED). **Parameters:** - ad_group_id: The ad group ID to resume (REQUIRED) - customer_id: Optional **Execution time:** 1-2 seconds **When to use:** - User finished pre-launch review of a PAUSED ad group and wants it live - User wants to reactivate a paused A/B-test ad group - Lifting a temporary pause on a themed ad group
resume_campaign
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Resume a paused campaign. Resuming a campaign makes ads start showing again. Only works on PAUSED campaigns (not REMOVED). **Parameters:** - campaign_id: The campaign ID (REQUIRED - get from list_campaigns) - customer_id: Optional (uses connected account if omitted) **Execution time:** 1-2 seconds **Returns:** - Campaign name - Before status (e.g., PAUSED) - After status (ENABLED) - Confirmation message **When to use:** - User says "resume", "turn it back on", "start it again" - User wants to re-enable a paused campaign - User finished making changes and wants ads to run **Example:** User: "Turn my campaign back on" Agent: Uses resume_campaign with the campaign_id
resume_meta_campaign
User wants to resume a paused Meta campaign. IMPORTANT: Resuming a campaign restarts ad delivery. Budget will start being spent again. Returns: - Confirmation that campaign is active - Campaign details - Ads Manager URL When to use this tool: - "Resume my Meta campaign" - "Turn on my Facebook ads" - "Reactivate campaign 123456" - "Start my paused Instagram campaign" Parameters: - campaign_id: The Meta Campaign ID to resume (required) Execution time: 2-5 seconds Effect: Campaign status changes to ACTIVE immediately
shopping
add_shopping_ad_group
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Add a new ad group to an existing Standard Shopping campaign. Creates a SHOPPING_PRODUCT_ADS ad group plus its product ad(s). Use this to structure a Shopping campaign into multiple ad groups (e.g. one per product category) after it's created — each ad group can then get its own product-partition tree via add_product_group and its own CPC bid. To edit/pause/remove an ad group afterward, use the channel-neutral tools update_ad_group_settings / pause_ad_group / resume_ad_group / remove_ad_group (they work on Shopping ad groups). **Required:** campaign_id (a Shopping campaign). Optional: name, cpc_bid_micros, num_product_ads.
add_shopping_product_ad
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Add product ad(s) to an existing Shopping ad group. A Shopping product ad is a marker that lets the ad group serve products from the linked Merchant Center feed (it has no creative — the products come from the feed). Most ad groups need only one. Use this if an ad group has no product ad (so it can't serve) or you want extras. To LIST an ad group's ads use get_campaign_structure; to REMOVE one use remove_ad. **Required:** ad_group_id (a Shopping ad group). Optional: count (default 1).
create_shopping_campaign
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Create a full Standard Shopping campaign advertising the products in a linked Merchant Center feed. ⚠️ Creates a REAL campaign (starts PAUSED — resume_campaign when ready). Call ONCE; do NOT auto-retry. PREREQUISITE: a Merchant Center account must be linked. Check get_merchant_center_links; if none, link one with link_merchant_center first. Pass that MC id as `merchant_id`. WHAT THIS BUILDS: budget + SHOPPING campaign (bound to the MC feed) + one or MORE ad groups, each with one or more product ads. Supports the full bidding + settings surface. The campaign serves ALL products in the feed until you subdivide with `add_product_group` (the listing-group tree). MULTIPLE AD GROUPS: pass `ad_groups: [{name, cpc_bid_micros, num_product_ads}, ...]` to build several at once (e.g. one ad group per product category). Omit it to create a single ad group from ad_group_name/cpc_bid_micros. **Required:** campaign_name, budget_daily, merchant_id. **Bidding:** bidding_strategy (MANUAL_CPC default | TARGET_SPEND=MaxClicks | TARGET_ROAS | MAXIMIZE_CONVERSION_VALUE | MAXIMIZE_CONVERSIONS | TARGET_CPA) + target_roas / target_cpa_micros / cpc_bid_ceiling_micros / cpc_bid_floor_micros / enhanced_cpc as applicable. **Settings:** campaign_priority (0-2), enable_local, disable_product_feed, network_settings, feed_label (omit unless the MC account uses feed labels — a wrong value serves zero products), start_date/end_date (YYYYMMDD).
get_shopping_settings
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Read a Shopping campaign's Merchant Center settings. Returns the shopping_setting that binds the campaign to Merchant Center: merchant_id, feed_label, campaign_priority (0-2), enable_local, disable_product_feed. Use get_campaign_structure for the ad groups / ads / budget / bidding / network; this tool is specifically for the Merchant-Center binding. **Required:** campaign_id (a Shopping campaign — from list_campaigns).
validate
validate_and_prepare_assets
🔄 LONG-RUNNING TOOL — **GOOGLE ADS ONLY**. ⚠️ **WRONG TOOL FOR OTHER PLATFORMS.** Each platform has its own asset validator because the image specs (aspect ratios, sizes, allowed formats) differ: • Google Ads → use `validate_and_prepare_assets` (this tool) • Meta Ads → use `validate_and_prepare_meta_assets` • LinkedIn Ads → use `validate_and_prepare_linkedin_assets` • TikTok Ads → use `validate_and_prepare_tiktok_assets` If the user is building for Meta/LinkedIn/TikTok, STOP and call the matching platform-specific tool instead. Calling this Google tool with non-Google images will fail validation because the field shapes (`marketing_images_landscape`, `square_marketing_images`, `logo_images`) are Google-Ads-specific. This tool validates multiple images from URLs for Google Performance Max / Display campaigns. Emits MCP progress updates while downloading and validating 5-10 images (typically 5-15 seconds). Progress stages: download → validate → commit. ⚠️ CRITICAL: This tool accepts IMAGE URLS (from postimages.org), NOT base64 or file paths! 📋 **YOUR CRITICAL ROLE: URL Validator & Categorizer** **STEP 1: Call help_user_upload First** Before anything else: - Call help_user_upload() to show upload instructions - User will upload to postimages.org and paste Direct links - User provides links like: https://i.postimg.cc/ABC123/image.jpg **STEP 2: Categorize URLs by Examining Images** When user pastes URLs, YOU MUST: 1. **Request to view each image** (you can see images from URLs) 2. **Calculate aspect ratio** for each: width / height 3. **Categorize based on ratio**: - Landscape (1.8-2.0): ~1.91:1 like 1200×628px - Square (0.95-1.05): ~1:1 like 1200×1200px - Portrait (0.75-0.85): ~0.8:1 like 960×1200px - Logo: Small images or very wide (4:1) 4. **Verify minimum requirements**: - At least 1 landscape - At least 1 square (non-logo) - At least 1 logo 5. If missing types, ask user to upload more 2. **Tell them what images they need:** - **REQUIRED:** - At least 1 landscape image (1.91:1 ratio, like 1200×628px or 600×314px) - At least 1 square image (1:1 ratio, like 1200×1200px or 300×300px) - At least 1 square logo (1:1 ratio, min 128×128px, recommended 1200×1200px) - **OPTIONAL:** - Portrait images (4:5 ratio, like 960×1200px or 400×600px) - Landscape logos (4:1 ratio, like 1200×300px or 512×128px) 3. **Provide OS-specific help if user asks how to check/resize images:** - **Mac users:** - "Right-click image → Get Info → shows dimensions" - "Use Preview app → Tools → Adjust Size to resize" - "Recommended free tool: GIMP (gimp.org) for precise aspect ratio control" - **Windows users:** - "Right-click image → Properties → Details tab → shows dimensions" - "Use Paint → Resize → maintain aspect ratio checkbox" - "Recommended free tool: GIMP (gimp.org) or Paint.NET" - **Online tools (any OS):** - "Canva.com (free, easy templates for exact sizes)" - "Photopea.com (free Photoshop alternative)" - "ResizePixel.com (quick resize tool)" 4. **CRITICAL: Read, Examine, and Categorize Images BEFORE Calling This Tool:** **Step 4a: READ FILE CONTENTS (REQUIRED!)** - When user uploads images, ChatGPT stores them as files with paths like `/mnt/data/image.png` - **YOU MUST READ EACH FILE** to get the actual image data - **DO NOT** send file paths or FILE:file_xxx references to this tool - **DO NOT** send data URIs with FILE: references like `data:image/png;base64,FILE:file_xxx` - **YOU MUST** read the file contents using your file reading capabilities - Convert file contents to base64 string - Send actual base64 encoded data (the binary image bytes encoded as base64) **Step 4b: EXAMINE AND CATEGORIZE** - **USE EXTENDED THINKING** to analyze each image - When you read the image file, you can see its dimensions - Calculate aspect ratio: width / height - Categorize based on aspect ratio: * **Landscape** (1.80-2.00 ratio): ~1.91:1 images like 1200×628px * **Square** (0.95-1.05 ratio): ~1:1 images like 1200×1200px * **Portrait** (0.75-0.85 ratio): ~0.8:1 (4:5) images like 960×1200px * **Logo Square** (0.95-1.05 ratio + small size <500px): Small square logos * **Logo Landscape** (3.80-4.20 ratio): ~4:1 images like 1200×300px **Step 4c: VERIFY MINIMUM REQUIREMENTS** - Count images in each category - **REQUIRED MINIMUM**: * At least 1 landscape image * At least 1 square image (non-logo) * At least 1 logo (square or landscape) - If missing ANY required type: * Tell user: "You need at least 1 landscape, 1 square, and 1 logo image" * Ask user to upload missing types * DO NOT call this tool yet **STEP 2: Call This Tool with ACTUAL Base64 Data** ⚠️ **CRITICAL - Data Format**: ```python # ❌ WRONG - DO NOT SEND: "data:image/png;base64,FILE:file_xxx" # File reference - will fail! "/mnt/data/image.png" # File path - will fail! # ✅ CORRECT - SEND THIS: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA..." # Actual base64 encoded image bytes # OR just the base64 string without prefix: "iVBORw0KGgoAAAANSUhEUgAA..." # Also works ``` **How to get actual base64**: 1. Read the uploaded file from its path 2. Get the file contents (binary data) 3. Encode to base64 string 4. Pass to this tool **Example**: - User uploads `image.png` - ChatGPT stores as `/mnt/data/image123.png` - You read the file → get binary PNG data - You encode to base64 → get "iVBORw0K..." - You send to tool: `marketing_images_landscape: ["iVBORw0K..."]` **IMPORTANT**: - The tool needs ACTUAL image data to validate dimensions and aspect ratios - File references cannot be validated - You must convert files to base64 before calling this tool **Image Requirements (Google Ads PMax specs):** | Type | Aspect Ratio | Min Size | Recommended | Max File Size | |------|--------------|----------|-------------|---------------| | Landscape | 1.91:1 | 600×314px | 1200×628px | 5MB | | Square | 1:1 | 300×300px | 1200×1200px | 5MB | | Portrait | 4:5 (0.8:1) | 400×600px | 960×1200px | 5MB | | Logo Square | 1:1 | 128×128px | 1200×1200px | 5MB | | Logo Landscape | 4:1 | 512×128px | 1200×300px | 5MB | - **Tolerance:** ±2% aspect ratio deviation allowed - **Formats:** JPEG, PNG, WEBP only **STEP 3: Pre-Flight Checks (BEFORE Calling Tool)** **Check #1: Count Images** - Count how many images you categorized in each type - **REQUIRED MINIMUM**: * 1+ landscape images * 1+ square images (non-logo) * 1+ logo images - If missing ANY required type: * "I see you uploaded [N] images, but I need at least 1 landscape, 1 square, and 1 logo." * "Please upload [missing type] image(s)." * DO NOT call this tool yet * Wait for user to upload more images **Check #2: Verify Categorization** - Use extended thinking to double-check your categorization - Example thinking: * "Image 1: 1200×628 = 1.91 ratio → landscape ✓" * "Image 2: 1200×1200 = 1.0 ratio, large size → square marketing image ✓" * "Image 3: 200×200 = 1.0 ratio, small size → logo ✓" - If uncertain about categorization, explain to user and ask for clarification **STEP 4: Handle Validation Results** **If validation FAILS:** - Show the user the EXACT error message from this tool - Explain what the error means in simple terms - Provide step-by-step instructions to fix: - How to check current dimensions - What the correct dimensions should be - How to resize the image - How to re-upload **If validation SUCCEEDS:** - Celebrate! ✅ - Show the asset_bundle_id to the user - Tell them the bundle is valid for 1 hour - Move to collecting campaign text details (name, headlines, etc.) - DO NOT call create_pmax_campaign until you have ALL text details **Returns:** - SUCCESS: asset_bundle_id (UUID) + summary of validated images - FAILURE: Specific error for the first invalid image + instructions to fix **Common Validation Errors & How to Help:** 1. **Wrong aspect ratio** - Error: "Expected 1.91:1, got 2.0:1" - Help: "Your image is slightly too wide. Crop it to 1200×628px exactly." 2. **Image too small** - Error: "Minimum size is 600×314px, got 500×250px" - Help: "Use a higher resolution image or upscale this one." 3. **File too large** - Error: "File too large. Maximum 5 MB, got 6.2 MB" - Help: "Compress the image using an online tool or save as JPEG with lower quality." 4. **Wrong format** - Error: "Unsupported format 'BMP'" - Help: "Convert to JPEG or PNG format." **Example User Flow:** User: "I want to create a PMax campaign" You: "Great! Let's start by uploading your images. You'll need: - At least 1 landscape image (1200×628px recommended) - At least 1 square image (1200×1200px recommended) - At least 1 square logo (1200×1200px recommended) Click the paperclip icon (📎) to attach your images." [User uploads images] You: "Perfect! I can see your images. Let me validate them..." [Call validate_and_prepare_assets] **Execution Time:** 1-3 seconds (fast validation) **Authentication:** NOT required for this tool (validation only) **REMEMBER:** - Be extremely patient and helpful with image validation - Provide clear, actionable instructions for fixing errors - Never proceed to create_pmax_campaign without a valid asset_bundle_id - The bundle expires in 1 hour - if expired, re-validate images
validate_and_prepare_meta_assets
**META ADS ONLY.** Validates and uploads images for Meta (Facebook/Instagram) campaigns. ⚠️ **WRONG TOOL FOR OTHER PLATFORMS.** Each ad platform has its own validator because image specs differ: • Meta Ads (this tool) → 1080×1080 carousel, 1200×628 feed, etc. • Google Ads → use `validate_and_prepare_assets` • LinkedIn Ads → use `validate_and_prepare_linkedin_assets` • TikTok Ads → use `validate_and_prepare_tiktok_assets` This tool validates image URLs against Meta's specifications and uploads them to get image hashes needed for campaign creation. It stores validated assets in a temporary bundle (60-minute TTL). Returns: - Validation results (pass/fail per image) - Image hashes for successfully uploaded images - Asset bundle ID for use in campaign creation - Placement compatibility information When to use this tool: - "Upload this image for my Meta campaign" - "Validate my product images for Facebook ads" - "Prepare images for Instagram ads" - User provides image URLs and wants to create a campaign Parameters: - image_urls: List of public URLs to validate and upload (1-10 images) - placement: Target placement - 'feed' (default), 'stories_reels', or 'carousel' - ad_account_id: Required for multi-account users. Get from list_connected_accounts Execution time: 5-15 seconds (depends on image count and size) Data source: Meta Ad Image Upload API Image Requirements: | Placement | Aspect Ratio | Min Dimensions | Max Size | |-----------|-------------|----------------|----------| | Feed | 1:1 or 4:5 | 600x600 | 30MB | | Stories/Reels | 9:16 | 500x888 | 30MB | | Carousel | 1:1 | 1080x1080 | 30MB | Workflow: 1. Use `validate_and_prepare_meta_assets` with image URLs 2. If successful, receive an `asset_bundle_id` 3. Use that bundle_id with `create_meta_image_campaign`
validate_catalog_readiness
User wants to create Advantage+ Catalog / Dynamic Product Ads, or asks "is my catalog ready for ads?". Run this PRE-FLIGHT before setting up a catalog campaign. Aggregates the real signals that decide whether dynamic product ads will actually deliver: - Catalog exists and has products - Product set (if given) is non-empty - Sampled products have images (catalog ads render the product image — no image = no render) - Feed health (last-upload errors), best-effort - If a pixel_id is given: classifies RETARGETING readiness (needs ViewContent/AddToCart) vs PROSPECTING-only Returns an overall verdict (ready / ready_with_warnings / not_ready), explicit blockers, warnings, and a recommended audience strategy. Always prefer this before catalog campaign creation so we never launch a dead retargeting campaign. When to use: - "Create a catalog ad", "set up dynamic product ads", "advantage+ catalog" - "Is my product catalog ready to advertise?"
validate_video
Validate video for ad campaigns (unified tool for all platforms). ⚠️ IMPORTANT: This is a READ-ONLY validation tool. Safe to call multiple times. 🎯 **What This Tool Does:** - Validates videos for Google Ads PMAX or TikTok campaigns - For PMAX: Validates YouTube video (privacy, duration, embeddable) - For TikTok: Validates public video URL is accessible - Returns metadata (title, duration, privacy, thumbnail) **DOES NOT upload videos** - user must already have video uploaded: - PMAX: Video must be on YouTube (public or unlisted) - TikTok: Video must be on public hosting (Google Drive, Vimeo, etc.) **Parameters:** - video_url_or_id (required): YouTube URL/ID (PMAX) or public video URL (TikTok) - platform (required): 'pmax' or 'tiktok' **For PMAX:** Accepts YouTube formats: - Full URL: https://youtube.com/watch?v=dQw4w9WgXcQ - Short URL: https://youtu.be/dQw4w9WgXcQ - Shorts: https://youtube.com/shorts/dQw4w9WgXcQ - Direct ID: dQw4w9WgXcQ (11 characters) Validates: - Video exists and is accessible - Privacy is Public or Unlisted (NOT Private) - Embeddable is enabled - Duration ≥10 seconds (PMAX requirement) Returns: - Video title - Duration - Privacy status - Thumbnail URL - Video ID **For TikTok:** Accepts public video file URLs: - Google Drive: https://drive.google.com/file/d/ABC123/view - Vimeo: https://vimeo.com/video/123456 - Dropbox: https://dropbox.com/s/abc/video.mp4 - Any publicly accessible video URL Validates: - URL is accessible (HTTP 200) - Content-Type is video/* (when available) Returns: - URL validation status - Content-Type - File size (if available) **Execution Time:** 1-3 seconds (YouTube Data API call or HTTP request) **When to Use:** - BEFORE creating a campaign with videos - To verify video meets platform requirements - To get video metadata (title, duration) **Example Usage:** ``` User: "I want to use this YouTube video in my PMAX campaign: dQw4w9WgXcQ" YOU: [Call validate_video with video_url_or_id="dQw4w9WgXcQ", platform="pmax"] Response: Video validated, title="Product Demo", duration=45s, ready for use ``` ``` User: "Can I use this video for TikTok ads: https://drive.google.com/file/d/ABC/view" YOU: [Call validate_video with video_url_or_id="https://drive...", platform="tiktok"] Response: URL validated, accessible, ready for campaign ``` **Error Handling:** - Private videos: Clear error asking user to change privacy to Public/Unlisted - Short videos (<10s for PMAX): Error with duration requirement - Invalid URLs: Error with accessibility details - Not embeddable: Error asking user to enable embedding
app
add_app_ad_asset
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Add an image or video asset to an existing App (Universal App / UAC) ad. App ads are largely automated, but you can supply extra image/video creative that Google mixes into the ads. This tool appends one asset to the app ad (existing assets are kept). **Parameters:** - ad_id (REQUIRED), ad_group_id (REQUIRED) — the App ad. Get from get_campaign_structure / get_ad_creative. - asset_type (REQUIRED): 'image' or 'video'. - image (asset_type=image): image_url (public http(s) URL or data:image/...;base64,... to UPLOAD) OR image_asset (an existing customers/<cid>/assets/<id> resource name). - video (asset_type=video): youtube_video_id (a YouTube video id). - customer_id: Optional. Works on all App sub-types (install / engagement / pre-registration). **Execution time:** 2-6 seconds (upload + mutate).
create_app_campaign
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Create a Google App campaign (Universal App Campaign / UAC) to drive app installs, in-app engagement, or Play pre-registrations. ⚠️ Creates a REAL campaign (starts PAUSED — resume_campaign when ready). Call ONCE; do NOT auto-retry. PREREQUISITE: a real, published app listing. Pass its store id as `app_id` (Play package name for GOOGLE_APP_STORE, e.g. com.company.app; numeric App Store id for APPLE_APP_STORE, e.g. 1234567890) and the matching `app_store`. Google validates the app_id against the store — a made-up id is rejected. WHAT THIS BUILDS: budget + MULTI_CHANNEL/App campaign (with the app + bidding goal) + one auto-managed ad group + one app ad. App campaigns are largely automated — Google assembles ads from your store listing plus the assets you provide. TYPES (`app_campaign_type`): install (default) | engagement (re-engagement — needs a deep-link + audience) | pre_registration (Google Play only). Install is the common case. **Required:** campaign_name, budget_daily, app_id, app_store. **Bidding:** bidding_strategy (leave UNSET to auto-pick the strategy that matches the goal | TARGET_CPA | MAXIMIZE_CONVERSIONS | TARGET_ROAS) + target_cpa_micros / target_roas + optional bidding_goal_type. **Creative (`ad`):** headlines (≤30), descriptions (≤90), image_assets / video_assets (resource names of EXISTING assets). start_date/end_date (YYYYMMDD).
remove_app_ad_asset
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Remove an image or video asset from an App (UAC) ad. **Parameters:** - ad_id (REQUIRED), ad_group_id (REQUIRED). - asset_type (REQUIRED): 'image' or 'video'. - asset_resource_name (customers/<cid>/assets/<id>) OR asset_id (numeric) — which asset to drop. Get the app ad's current assets from get_ad_creative. - customer_id: Optional. **Execution time:** 2-4 seconds.
asset
add_asset_group_listing_filter
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Subdivide a retail Performance Max asset group's products — include or exclude a partition. Splits products by dimension_type=value (e.g. product_brand=Nike, product_type=Shoes). exclude=true makes the partition UNIT_EXCLUDED (those products won't serve from this asset group); otherwise it's UNIT_INCLUDED. Retail PMax has NO per-node bids (bidding is fully automated). The "everything else" sibling is created automatically. FIRST call on an unpartitioned asset group subdivides the root. To split an EXISTING partition further, pass parent_filter_id (from get_asset_group_listing_filters). **Required:** asset_group_id, dimension_type, value. Optional: level (type/category), index (custom_attribute), exclude, parent_filter_id.
get_asset_group_listing_filters
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Read a retail Performance Max asset group's product listing-filter tree. Retail PMax (a PMax campaign linked to a Merchant Center account) can partition which products each asset group promotes. Returns each filter node: filter_id, parent_id, node_type (SUBDIVISION / UNIT_INCLUDED / UNIT_EXCLUDED), the dimension it represents, and whether it's excluded. An empty tree means the asset group promotes ALL feed products. **Required:** asset_group_id (a retail-PMax asset group, from get_pmax_asset_groups).
remove_asset_group_listing_filter
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Remove a listing-filter node (and its whole subtree) from a retail-PMax asset group. Get the filter_id from get_asset_group_listing_filters. Removing a subdivision removes everything under it. Remove the root to return the asset group to promoting ALL feed products. **Required:** asset_group_id, filter_id.
optimize
optimize_budget_allocation
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Optimize budget allocation across campaigns using linear programming to maximize conversions. ⚠️ IMPORTANT: This tool retrieves READ-ONLY optimization recommendations. Safe to call multiple times. Does NOT automatically change budgets. 🎯 **What This Tool Does (Performance Agent - Phase 1):** - Uses linear programming to optimize budget distribution - Maximizes total conversions while respecting constraints - Provides current vs optimized allocation comparison - Categorizes campaigns into actions: PAUSE/SCALE/REDUCE/MAINTAIN - Shows expected conversion lift from optimization - Generates specific recommendations with budget amounts **Returns detailed optimization plan:** - Current allocation (what you have now) - Optimized allocation (what you should have) - Expected conversion lift (absolute and percentage) - Campaign-by-campaign actions with reasoning - Budget change amounts and percentages - Specific implementation recommendations **Optimization Algorithm:** Uses scipy linear programming with constraints: 1. Sum of budgets = total_budget (you don't overspend) 2. Only campaigns with ROAS >= target get significant budget 3. Min budget per campaign >= min_daily_budget (or $0 to pause) 4. Max change per campaign <= ±max_change_percentage (avoid drastic shifts) **Target ROAS Resolution (3-tier priority):** 1. User override (if target_roas parameter provided) 2. Account goals table (user-set or API-pulled) 3. 90-day historical average ROAS 4. Default to 1.0x (breakeven) if no data **Configuration Parameters:** - **total_budget**: Total monthly budget to allocate (REQUIRED) - **lookback_days**: 7, 30, 60, 90, or 120 days (default: 30) - **start_date**: Optional start date (YYYY-MM-DD). Overrides lookback_days when used with end_date. - **end_date**: Optional end date (YYYY-MM-DD). Overrides lookback_days when used with start_date. - **target_roas**: Optional override (e.g., 3.0 for 3.0x) - **max_change_percentage**: 0.0-1.0 (default: 0.5 = ±50%) * 0.3 = Conservative (±30% change, minimal disruption) * 0.5 = Balanced (±50% change, standard optimization) * 0.7 = Aggressive (±70% change, fast scaling) - **min_daily_budget**: Minimum $ per campaign (default: $5.00, or $0.00 to allow pausing) - **customer_id**: Optional (uses connected account if omitted) **Execution time:** 1-5 seconds (depends on campaign count) **Data source:** campaign_daily_metrics table (updated nightly) **Use this tool when:** - User wants to optimize budget allocation - User asks "how should I allocate my budget?" - User wants to maximize conversions with current spend - User wants data-driven budget recommendations - After running wasted spend analysis (natural next step) 📊 **AFTER calling this tool, help the user understand:** **Campaign Actions:** - **PAUSE**: Campaigns below target ROAS, losing money (ROAS < target) - **SCALE**: High performers, increase budget by X% (top conversion rates) - **REDUCE**: Underperformers, decrease budget by X% (low efficiency) - **MAINTAIN**: Steady performers, keep current budget (±5% change) **Expected Impact:** - Current conversions: What you get now - Optimized conversions: What you could get - Conversion lift: Additional conversions (+X%) **Example Interpretation:** "Implementing this optimization will increase your conversions by 45 (+18.8%) without spending more money. You should scale 'Brand - Exact' campaign by $2,250/month and pause 'Display - Broad' to free up $3,000/month." **Implementation Steps:** 1. Review recommended changes carefully 2. Start with campaigns marked CRITICAL (pause/scale first) 3. Apply changes gradually if user is risk-averse 4. Monitor performance for 7-14 days after changes 5. Re-run optimization monthly for continuous improvement **Important Notes:** - This is a RECOMMENDATION tool, not automated budget application - User must review and apply changes manually in Google Ads - Avoid large changes (>50%) for campaigns in learning phase (<7 days) - Consider seasonality when interpreting results - Re-optimize every 30 days as performance changes **Visualization Tip:** For 5+ campaigns, suggest creating a grouped bar chart showing current vs optimized budgets side-by-side. **Best Practices:** - Start conservative (max_change_percentage=0.3) for first optimization - Increase aggressiveness (0.5-0.7) as you gain confidence - Use longer lookback_days (60-90) during seasonal changes - Set realistic target_roas (start with 1.0x breakeven, increase gradually) 💬 **Community**: For optimization discussions, visit our Discord: https://discord.gg/dH3Qt4YS
optimize_meta_budget
User asks about Meta/Facebook/Instagram budget optimization, reallocating ad spend, maximizing conversions with their budget, or wants data-driven budget recommendations. This tool uses linear programming (scipy.optimize) to find the optimal budget allocation across Meta Ads campaigns or ad sets to maximize conversions while respecting constraints. Returns: - Optimal budget allocation for each campaign/ad set - Expected conversion lift from reallocation - Campaigns to scale up (high ROAS performers) - Campaigns to reduce (below target ROAS) - Campaigns to consider pausing (ROAS < 1.0) - Actionable recommendations - CBO (Campaign Budget Optimization) notes When to use this tool: - "How should I allocate my Meta budget?" - "Optimize my Facebook ad spend for conversions" - "Which Instagram campaigns should I increase budget?" - "Reallocate my $5000 Meta budget" - "Maximize conversions with my current spend" - "What's the optimal budget split across campaigns?" Parameters: - total_budget: **REQUIRED.** Total budget to allocate across campaigns/ad sets in the account's own currency as a decimal — NOT cents, NOT USD (e.g., 5000.00). Must be > 0 — this is the pool that gets redistributed. Without it the tool has nothing to optimize and returns a validation error. - lookback_days: 7, 14, 30 (default), 60, or 90 days for analysis - date_range: preset alternative to lookback_days / start_date / end_date. One of: 'last_7_days', 'last_14_days', 'last_30_days', 'last_60_days', 'last_90_days'. (Both 'last_30_days' and 'last_30d' / 'last_month' aliases accepted.) - start_date: Optional start date (YYYY-MM-DD). Overrides lookback_days when used with end_date. - end_date: Optional end date (YYYY-MM-DD). Overrides lookback_days when used with start_date. ⚠️ DATE CLARIFICATION: If the user's date request is vague or ambiguous (e.g., "March to June" without a year, "last quarter", "recently", "a few months ago"), ask the user to specify exact dates before calling this tool. Do not assume or guess dates. - target_roas: Optional override (default: from account goals or 2.0x) - max_change_percentage: Max budget change per item (default: 0.5 = 50%) - min_daily_budget: Minimum budget per item (default: 5.00) - optimization_level: 'campaign' (default) or 'ad_set' - ad_account_id: Required for multi-account users. Get from list_connected_accounts Execution time: 2-5 seconds (cached database query + optimization) Data source: campaign_daily_metrics + ad_group_daily_metrics tables Key concepts: - Linear Programming: Mathematical optimization to maximize objective (conversions) subject to constraints - Efficiency Score: Conversions per dollar spent - used to prioritize allocation - Max Change Constraint: Prevents dramatic shifts (e.g., ±50% max from current) - Target ROAS: 3-tier resolution: account_goals - 90-day historical - default 2.0x Meta-specific considerations: - CBO campaigns: Budget set at campaign level, Meta distributes to ad sets - ABO campaigns: Budget set at ad set level, more granular control - Learning Phase: New campaigns need 50+ conversions before optimization
optimize_meta_placements
User asks about Meta/Facebook/Instagram placement performance, which placements work best, Feed vs Stories vs Reels, should they use Audience Network, or wants placement optimization recommendations. This tool analyzes placement-level performance (Feed, Stories, Reels, Audience Network, Messenger, etc.) and provides optimization recommendations including budget reallocation suggestions. Returns: - Placement ROAS ranking (sorted by performance) - Placements categorized as SCALE/MAINTAIN/REDUCE/EXCLUDE - Budget reallocation recommendations between placements - Expected ROAS improvement from optimization - Optimal placement mix for campaign objective - Savings from excluding underperforming placements - Actionable recommendations and quick actions When to use this tool: - "Which Meta placements should I use?" - "Should I exclude Audience Network?" - "Instagram Stories vs Reels - which is better?" - "Feed vs Stories performance comparison" - "Where should I allocate my Meta ad budget?" - "Which placements are wasting money?" - "What's the optimal placement mix for conversions?" - "Facebook Marketplace performance?" Parameters: - lookback_days: 7, 14, 30 (default), 60, or 90 days - date_range: preset alternative to lookback_days / start_date / end_date. One of: 'last_7_days', 'last_14_days', 'last_30_days', 'last_60_days', 'last_90_days'. (Both 'last_30_days' and 'last_30d' / 'last_month' aliases accepted.) - start_date: Optional start date (YYYY-MM-DD). Overrides lookback_days when used with end_date. - end_date: Optional end date (YYYY-MM-DD). Overrides lookback_days when used with start_date. ⚠️ DATE CLARIFICATION: If the user's date request is vague or ambiguous (e.g., "March to June" without a year, "last quarter", "recently", "a few months ago"), ask the user to specify exact dates before calling this tool. Do not assume or guess dates. - objective: 'conversions' (default), 'traffic', or 'awareness' - for optimal mix recommendations - target_roas: Optional override (default: from account goals or 2.0x) - ad_account_id: Required for multi-account users. Get from list_connected_accounts Execution time: 2-5 seconds (cached database query with analysis) Data source: meta_placement_daily_metrics table (placement-level daily metrics) ROAS Thresholds for Recommendations: - ✅ SCALE (ROAS ≥3.0x): Increase budget by 20-30% - ➖ MAINTAIN (ROAS 1.5-3.0x): Keep current budget - ⚠️ REDUCE (ROAS 1.0-1.5x): Reduce budget by 30-50% - 🔴 EXCLUDE (ROAS <1.0x): Remove from campaigns Meta Placements Analyzed: - Facebook: Feed, Stories, Reels, Marketplace, Search Results - Instagram: Feed, Stories, Reels, Explore - Messenger: Inbox, Stories - Audience Network: All placements Common Insights: - Audience Network often has lowest ROAS for conversion campaigns - consider excluding - Instagram Feed and Reels typically have highest conversion rates - Stories are great for awareness but may have lower conversion rates - Facebook Marketplace can be effective for e-commerce
business
add_business_name_asset
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Add a BUSINESS_NAME asset to a Search campaign. The business name shows in Search ads next to the URL. It is a brand identifier, not promotional copy. Max 25 characters. **Parameters:** - campaign_id: The campaign ID (REQUIRED — get from list_campaigns) - business_name: The display name (max 25 chars) - customer_id: Optional (uses connected account if omitted) **Behavior:** Creates a new TextAsset in the Asset Library and links it to the campaign with field_type=BUSINESS_NAME. Existing business name assets on the campaign are not removed — call this once per campaign or unlink the previous asset first if you want a clean swap. **Execution time:** 2-4 seconds **Example:** User: "Set the business name on campaign 23847465076 to 'Refresh Wellington'" Agent: add_business_name_asset(campaign_id="23847465076", business_name="Refresh Wellington")
get_business_profile
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Get the user's business profile for contextual recommendations. ⚠️ IMPORTANT: This tool retrieves READ-ONLY data. Safe to call multiple times. 🎯 **What This Tool Does (Performance Agent - Phase 1 Feature 5):** - Retrieves the user's saved business profile - Returns business vertical, size, goals, target audience - Provides context for more relevant recommendations - Shows profile source (user-set, inferred, or none) **Returns business context:** - Business vertical (retail, services, technology, etc.) - Business size (small, medium, large) - Primary goal (leads, sales, awareness, traffic) - Target audience description - Geographic focus (local, regional, national, international) - Seasonality patterns - Profile confidence level **Use this tool when:** - You need business context for recommendations - Before providing industry-specific advice - User asks "what type of business am I?" - You want to personalize optimization suggestions **If no profile exists:** - Use `infer_business_profile` to automatically detect from campaign data - Or ask user to provide business details via `save_business_profile` **Execution time:** 1-2 seconds (database lookup)
detect
detect_meta_catalog_waste
User wants to find and recover WASTED catalog spend at the PRODUCT level. Keywords: "which products waste money", "recover spend", "stop wasting budget", "SKUs that don't convert", "products below break-even". Detects recoverable spend: SKUs spending with ZERO conversions + SKUs converting BELOW break-even (1.0x ROAS). Returns the account recoverable-spend total and a prioritized, severity-ranked SKU action list. Carries the same guards as the campaign-level wasted-spend tool: never "pause" a SKU that still converts (says reduce/tighten instead), respects minimum spend, and softens copy when conversion tracking looks incomplete. Reads cached nightly product metrics (never calls Meta live). When to use: "Which products are wasting my budget?", "How much catalog spend can I recover?"
detect_meta_creative_fatigue
User asks about creative fatigue, ad refresh timing, frequency management, declining CTR, when to replace ads, or audience exhaustion on Meta/Facebook/Instagram. This tool analyzes all Meta Ads creatives for fatigue indicators using frequency-CTR correlation analysis and provides a fatigue score (0-100) for each ad. Returns: - Fatigue score (0-100) for each ad based on weighted factors - Severely fatigued ads (score ≥80) - immediate action required - At-risk ads (score 50-79) - plan refresh within 7-14 days - Healthy ads count - Daily spend being wasted on fatigued creatives - Projected monthly waste - Refresh schedule recommendations - Contributing factors for each fatigued ad When to use this tool: - "Are any of my Meta/Facebook/Instagram ads fatigued?" - "When should I refresh my creatives?" - "Why is my CTR declining?" - "Which ads have high frequency?" - "How much am I wasting on fatigued ads?" - "What's my ad refresh schedule?" - "Are my retargeting ads showing too often?" Parameters: - lookback_days: 7, 14, 30 (default), 60, or 90 days - date_range: preset alternative to lookback_days / start_date / end_date. One of: 'last_7_days', 'last_14_days', 'last_30_days', 'last_60_days', 'last_90_days'. (Both 'last_30_days' and 'last_30d' / 'last_month' aliases accepted.) - start_date: Optional start date (YYYY-MM-DD). Overrides lookback_days when used with end_date. - end_date: Optional end date (YYYY-MM-DD). Overrides lookback_days when used with start_date. ⚠️ DATE CLARIFICATION: If the user's date request is vague or ambiguous (e.g., "March to June" without a year, "last quarter", "recently", "a few months ago"), ask the user to specify exact dates before calling this tool. Do not assume or guess dates. - frequency_threshold_cold: 2.0-8.0 (default: 4.0) - threshold for cold traffic audiences - frequency_threshold_retargeting: 4.0-10.0 (default: 7.0) - threshold for retargeting audiences - ctr_decline_threshold: 0.10-0.50 (default: 0.20 = 20%) - CTR decline to flag as fatigued - ad_account_id: Required for multi-account users. Get from list_connected_accounts Execution time: 2-5 seconds (cached database query with analysis) Data source: meta_ad_creative_metrics table (ad-level daily metrics with frequency, CTR, video completion) Fatigue Score Calculation: The fatigue score (0-100) is calculated using weighted factors: - Frequency (40%): impressions/reach ratio vs threshold - CTR Decline (35%): % drop in CTR vs previous period - Days Running (25%): creative age vs optimal refresh timing Severity Levels: - 🔴 Score ≥80: Severely fatigued - PAUSE immediately and replace - 🟡 Score 50-79: At risk - prepare replacement within 7-14 days - ✅ Score <50: Healthy - continue monitoring Best practices: - Cold traffic: Refresh creatives when frequency reaches 3-4x - Retargeting: Can tolerate higher frequency (up to 6-7x) - Create 3-5 variations per ad set for automatic rotation - Monitor weekly for frequency and CTR trends
diagnose
diagnose_funnel
DIAGNOSE why a user's ads aren't producing sales/leads — the ordered root-cause check that tells them WHICH part of their funnel is broken and what to do about it. **Call this when the user asks:** - "why aren't my ads selling / working / converting?", "I'm not getting any sales", "my ads aren't performing", "what's wrong with my account?", "what would you do to increase sales?", "I'm losing money on ads" - any open-ended "something is wrong and I don't know what" question **How it differs from the performance tools:** those DESCRIBE the numbers for one platform. This walks the whole chain in ORDER — is conversion tracking real → should there even be revenue → is there traffic → is it converting → (we can't see the landing page) → where is the money going — and STOPS at the first broken step, reporting the rest as 'not assessed' rather than 'fine'. That ordering is the point: a broken pixel makes every number below it meaningless, and advice about bids or budgets would be guesswork until it's fixed. **Inputs (all optional):** `platform` and `account_id` to narrow to one account; `lookback_days` (14-90, default 60). With no arguments it checks every connected account and leads with the worst one — call it bare. ⛔ It ABSTAINS honestly: if the account has too little data, or the numbers can't be verified, it says so and says what would unlock an answer, rather than guessing. It never invents benchmarks or promises outcomes. If the funnel is healthy and the user wants budget advice, follow up with generate_media_plan. Renders an interactive widget; the text carries the same diagnosis.
diagnose_meta_catalog_funnel
User wants to know WHERE in the catalog shopping funnel they're losing shoppers. Keywords: "funnel", "drop-off", "people add to cart but don't buy", "abandoned carts", "why aren't products converting", "checkout drop". Reports the catalog funnel (product view → add to cart → checkout → purchase) per product and account-wide, from cached nightly metrics. For each product and the account it computes the stage-to-stage drop-off RATES and states, as a MEASURED FACT, the stage with the largest drop (e.g. "82% of carts didn't reach checkout"). It does NOT label a drop "severe" or assert a diagnosed cause — it offers COMMON REASONS to check at that stage (creative/feed at view→cart; price/shipping at cart→checkout; payment/checkout friction or pixel firing at checkout→purchase) as guidance, not a verdict. Reads cached nightly product metrics (never calls Meta live). When to use: "Where are shoppers dropping off in my catalog funnel?", "Why am I getting carts but fewer sales?"
discover
discover_existing_assets
🔍 Discover existing assets in the Google Ads account (images, sitelinks, callouts, structured snippets). **Phase 0: Asset Discovery** - Read-only tool, safe to call anytime. 🔴 **MANDATORY WORKFLOW - ALWAYS DO THIS FIRST:** BEFORE creating ANY Performance Max campaign, you MUST: 1. Call this tool: discover_existing_assets(target_domain="<user's domain>") 2. Show the user what was found (images, sitelinks) 3. Ask: "Would you like to reuse these assets or upload new ones?" 4. Based on answer: - Reuse → Use existing_image_ids in create_pmax_campaign - Upload new → Use validate_and_prepare_assets → asset_bundle_id - Mix both → Use both parameters (hybrid mode) 🚫 **NEVER create PMAX without discovering assets first** (unless user explicitly says "skip discovery, upload new") **What This Tool Does:** - Queries Google Ads Asset Library for existing validated assets - Returns campaign-validated assets FIRST, then the rest of the asset library - Includes downloadable image URLs (full-size, from Google's CDN) 📄 **PAGINATED — YOU MUST FETCH ALL PAGES:** Results come in pages of 50 per asset type. The response footer states whether more pages exist. If it says more assets are available, CALL THIS TOOL AGAIN with page=2 (then 3, ...) until it reports that ALL assets have been returned. Accumulate results across pages — never present page 1 as the complete inventory. **2-Tier Smart Discovery:** **Tier 1: Campaign-Validated Assets (High Confidence)** ✅ - Assets currently attached to ENABLED, PAUSED, or REMOVED campaigns - These have been validated by Google and won't fail - Includes domain filtering for sitelinks - Best option for reuse **Tier 2: No Validated Assets (Ask User)** ⚠️ - Account has no suitable assets in campaigns - Recommends uploading fresh assets or website research - Safer than using orphaned assets from library **Parameters:** - target_domain: Optional domain to filter sitelinks (e.g., "rooterhero.com") - **CRITICAL for multi-domain accounts!** Google rejects wrong-domain sitelinks - **Extract the base domain** from campaign URL (just the domain part) - Examples: "https://www.rooterhero.com/services" → "rooterhero.com", "sahaayak.life" → "sahaayak.life" - Only sitelinks matching this domain will be returned - Prevents Google API errors for domain mismatches **Returns:** - images: List of validated images (landscape, square, portrait, logos) - sitelinks: List of validated sitelinks (filtered by domain if provided) - callouts: List of validated callouts - structured_snippets: List of validated structured snippets - recommendation: Smart guidance on whether to reuse or upload new **Example ChatGPT Flow:** User: "Create a campaign for rooterhero.com" (or "https://www.rooterhero.com/services") Step 1: Extract base domain → "rooterhero.com" Step 2: Call discover_existing_assets(target_domain="rooterhero.com") If Tier 1 (validated assets found): ChatGPT: "I found 8 sitelinks and 11 images from your previous Rooter Hero campaigns. These were validated by Google. Would you like to reuse them, or upload fresh assets?" User: "Reuse them" → Use those assets in Phase 1 User: "Upload new" → Follow current upload flow If Tier 2 (no validated assets): ChatGPT: "No validated assets found for rooterhero.com in your campaigns. Options: 1. Upload fresh images/sitelinks 2. Let me research rooterhero.com and suggest sitelinks 3. Create campaign without extensions" **When to Call:** - BEFORE creating Search campaigns (to discover sitelinks, callouts, snippets) - BEFORE creating PMAX campaigns (to discover images) - When user asks "What assets do I have?" - When user wants to reuse existing assets **When NOT to Call:** - User explicitly says "I'll upload new images" - User wants to create minimal campaign without extensions **Execution Time:** 1-3 seconds (read-only query) **Authentication:** Required (MCP OAuth 2.1) **Note:** This is Phase 0 - discovery only. Phase 1 will enable reusing discovered assets in campaigns.
discover_meta_assets
User wants to browse existing images and videos in their Meta Ad Library for reuse in new campaigns. This tool retrieves existing images and videos that have been uploaded to Meta's Ad Library, allowing users to reuse them in new campaigns without uploading again. Returns: - List of existing images with their hashes (dimensions, created timestamps) - List of existing videos with their IDs (title, duration, created timestamps) - Instructions for using assets in campaigns When to use this tool: - "Show me my existing Meta ad images" - "What videos do I already have in Meta?" - "I want to reuse an existing image/video for my campaign" - "List my Facebook ad library assets" - Before uploading new assets - check if they already exist Parameters: - ad_account_id: Required for multi-account users. Get from list_connected_accounts - asset_type: 'all' (default), 'image', or 'video' - filters which asset types are returned - limit: Max assets to return (default 50, max 100) Execution time: 2-5 seconds Data source: Meta Ad Library API (live) Workflow: 1. Use `discover_meta_assets` to find existing images and/or videos 2. Copy the `image_hash` (images) or `video_id` (videos) of the asset you want to reuse 3. Use that value with `create_meta_image_campaign` (`existing_image_hash`) or `create_meta_video_campaign` (`existing_video_id`)
explain
explain_meta_anomaly
User asks why Meta/Facebook/Instagram performance dropped or changed, what happened to their ROAS/CTR/CPM, or wants to understand why a metric changed during a specific period. This tool analyzes why a specific metric changed during a specified period by comparing it to historical baselines and identifying contributing factors. It detects Meta-specific causes including creative fatigue, audience saturation, placement mix shifts, and auction competition. Returns: - Current metric value vs historical averages (30/60/90-day) - Deviation percentages from baselines - Contributing factors ranked by estimated impact - Factor explanations with details - Similar historical periods with comparable changes - Assessment of anomaly severity (CRITICAL/WARNING/MINOR/NORMAL) - Specific recommendations based on detected factors - Quick actionable items When to use this tool: - "Why did my Meta ROAS drop?" - "What happened to my Facebook CTR this week?" - "Why is my Instagram CPM so high?" - "Explain my Meta performance change" - "My conversions dropped last week - why?" - "Why did my frequency spike?" - "What caused my ROAS to decline 40%?" - "Diagnose my Meta performance problem" Parameters: - metric: Required - 'roas', 'ctr', 'cpc', 'cpm', 'conversions', 'conversion_rate', 'frequency', or 'reach' - period_start: Required - Start date (YYYY-MM-DD format) - period_end: Required - End date (YYYY-MM-DD format, must be ≤30 days from start) - ad_account_id: Required for multi-account users. Get from list_connected_accounts Execution time: 3-8 seconds (statistical analysis across multiple periods) Data source: campaign_daily_metrics + meta_placement_daily_metrics + meta_ad_creative_metrics tables Contributing Factors Detected: - CPM Change: Auction competition fluctuations (holidays, competitor activity) - CTR Change: Creative performance (fatigue, messaging, targeting) - Conversion Rate Change: Landing page or offer issues - Frequency Change: Audience saturation (Meta-specific) - Creative Fatigue: High frequency + declining CTR (Meta-specific) - Placement Mix Change: Shift in placement distribution (Meta-specific) - Campaign Changes: Paused/new campaigns affecting overall performance Severity Levels: - 🔴 CRITICAL (≥40% deviation): Immediate action required - 🟡 WARNING (25-40% deviation): Review recommended - 🟢 MINOR (15-25% deviation): Monitor situation - ✅ NORMAL (<15% deviation): Within normal variation Similar Historical Periods: Finds past periods with comparable deviations to provide context (e.g., "similar drop occurred during Black Friday 2024") Best for: - Diagnosing sudden performance drops - Understanding seasonal patterns - Identifying actionable causes vs. external factors - Prioritizing optimization efforts
explain_performance_anomaly
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Explain why a performance metric changed using statistical analysis and historical context. ⚠️ IMPORTANT: This tool retrieves READ-ONLY data. Safe to call multiple times. Uses statistical analysis only (no ML models). 🎯 **What This Tool Does (Performance Agent - Phase 1 Feature 4):** - Explains why metrics changed (ROAS, CTR, CPC, conversions, conversion rate) - Compares current period to historical averages (30/60/90-day) - Identifies contributing factors with severity levels - Detects campaign changes (paused, new, budget changes) - Finds similar historical periods (seasonality detection) - Provides actionable recommendations to address issues **Returns comprehensive anomaly explanation:** - Current metric value vs historical averages - Deviation percentages (how much it changed) - Contributing factors: - CPC changes (>15% = auction competition shifts) - Conversion rate changes (>10% = landing page/seasonality issues) - Campaign changes (paused high-performers, new campaigns, budget changes) - Day-of-week patterns (weekend vs weekday effects) - Similar historical periods for context - Assessment (normal variation vs requires action) - Specific recommendations to fix the issue 🔍 **How Anomaly Detection Works:** **Historical Comparison:** - Compares current period to 30/60/90-day averages - ±15% deviation considered "normal variation" - >15% deviation flagged as requiring attention **Contributing Factor Detection:** 1. **CPC Changes** (>15% threshold) - Increased CPC = auction competition increased - Decreased CPC = auction competition decreased or bid adjustments 2. **Conversion Rate Changes** (>10% threshold) - Decreased = landing page issues, seasonality, audience quality - Increased = landing page improved, better targeting 3. **Campaign Changes:** - Paused high-performers (ROAS > 3.0x) = lost revenue driver - New campaigns (>$1K spend) = learning phase affecting overall performance - Budget changes (>20%) = delivery and auction participation affected 4. **Day-of-Week Patterns:** - Weekend-heavy periods often show different performance - Normal for B2C (higher weekend conversion) - Normal for B2B (lower weekend conversion) 5. **Seasonality Detection:** - Finds similar historical periods (±10% metric value) - Helps identify if drop is seasonal vs real issue **Parameters:** - metric: 'roas', 'ctr', 'cpc', 'conversions', 'conversion_rate' (REQUIRED) - period_start: Start date in YYYY-MM-DD format (REQUIRED) - period_end: End date in YYYY-MM-DD format (REQUIRED, max 30 days period) - customer_id: Optional (uses connected account if omitted) **Execution time:** 2-4 seconds (statistical analysis + database queries) **Data source:** campaign_daily_metrics table (updated nightly, 120-day retention) **Analysis method:** Statistical comparison (no ML models) **Trigger:** Reactive (user asks "why?"), not proactive alerts **Use this tool when:** - User asks "why did my ROAS drop?" - User asks "why did my CTR increase?" - User notices unexpected metric changes - User wants to understand performance fluctuations - After seeing performance changes in dashboards 📊 **AFTER calling this tool, help the user understand:** **Normal vs Abnormal Variation:** - **Normal**: ±15% deviation, typical day-of-week/seasonal patterns - **Abnormal**: >15% deviation with specific contributing factors **Severity Levels:** - 🔴 **HIGH**: >25% change with clear cause (CPC spike, campaign paused) - 🟡 **MEDIUM**: 15-25% change or multiple minor factors - 🟢 **LOW**: <15% change, likely normal variation **Example Interpretation:** "Your ROAS dropped 33% from 4.2x to 2.8x. This was caused by two high-severity factors: 1. CPC increased 25% (auction competition spike during holiday season) 2. Your top campaign 'Brand - Exact' was paused, losing $240/day in high-ROAS revenue This is NOT normal variation - these are actionable issues. Recommendations: - Reduce bids by 10-15% to counter CPC inflation - Re-enable 'Brand - Exact' campaign if budget allows - Review landing page conversion rate (also dropped 12%)" **Similar Period Context:** If tool finds similar historical periods, explain seasonality: "Your ROAS was similarly low (2.7x) on December 18, 2024, which was also during the holiday shopping season. This suggests some of the drop is seasonal, but the campaign pause is amplifying the effect." **Quick Actions:** Based on contributing factors, prioritize: 1. **Campaign paused** → Re-enable high performers immediately 2. **CPC spike** → Adjust bids, improve Quality Score 3. **Conversion rate drop** → Review landing page, check for bugs 4. **Budget changes** → Monitor delivery as it stabilizes 5. **Weekend effect** → Normal variation, no action needed **Visualization Tip:** Suggest creating a line chart showing the metric over time with 30-day average band and annotations for detected factors (e.g., "Campaign paused here", "CPC spike started here"). **Important Notes:** - This is REACTIVE explanation, not proactive monitoring - Max 120-day historical lookback (database retention limit) - Uses simple statistics (mean, variance), no ML predictions - Focus on actionable factors user can control - Consider seasonality when interpreting results **Best Practices:** - Run this tool when you notice >15% metric changes - Compare multiple time periods to confirm trends - Cross-reference with other tools (wasted spend, budget optimizer) - Use for post-mortem analysis of performance changes - Help user distinguish normal variation from real issues 💬 **Community**: For anomaly analysis discussions, visit our Discord: https://discord.gg/dH3Qt4YS
keywords
add_keywords
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Add keywords to an existing ad group. ⚠️ **CRITICAL: Run `research_keywords` BEFORE using this tool!** **MANDATORY WORKFLOW:** 1. Call `get_campaign_structure` to get ad_group_id and see existing keywords 2. Call `research_keywords` with business context to get quality keyword suggestions 3. Show keyword suggestions to user with CPC, search volume, intent level 4. Get user approval on which keywords to add 5. ONLY THEN call this tool with approved keywords **Why research first?** - Ensures keywords have real search volume - Shows CPC costs so user understands budget impact - Provides HIGH/MEDIUM/LOW intent classification - Prevents adding low-quality or irrelevant keywords **Requires:** - ad_group_id: Get from get_campaign_structure (REQUIRED) - keywords: List of keywords to add (from research_keywords results) **Each keyword needs:** - text: The keyword phrase (e.g., "buy running shoes online") - match_type: EXACT, PHRASE, or BROAD (default: BROAD) - cpc_bid_micros: Optional bid override (1 USD = 1,000,000 micros) **Match Type Guide:** - BROAD: Ads show for related searches (widest reach) - Google's 2025 recommendation - PHRASE: Ads show when query contains keyword phrase - EXACT: Ads show only for exact query or close variants **IMPORTANT:** - Keyword text and match_type CANNOT be changed after creation - To "change" a keyword, remove the old one and add a new one - Get ad_group_id from get_campaign_structure first **Execution time:** 2-4 seconds **Example Workflow:** User: "Add more keywords to my plumbing campaign" Agent Steps: 1. Call get_campaign_structure → get ad_group_id, see existing keywords 2. Call research_keywords with business_description="plumbing services" 3. Show user: "I found these keyword suggestions from Keyword Planner: - emergency plumber near me (HIGH intent, $45 CPC, 12K searches/mo) - 24 hour plumber (HIGH intent, $38 CPC, 8K searches/mo) Which would you like to add?" 4. User selects keywords 5. Call add_keywords with selected keywords
remove_keywords
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Remove keywords from an ad group. **Parameters:** - ad_group_id: The ad group containing the keywords (REQUIRED) - keyword_ids: List of keyword IDs to remove (REQUIRED) - customer_id: Optional **Get keyword_ids from:** Use get_campaign_structure to see all keywords with their IDs. **WARNING: This is PERMANENT and IRREVERSIBLE.** Keywords removed cannot be recovered. Always confirm with the user first. **Execution time:** 2-4 seconds **Example:** User: "Remove the underperforming keywords" Agent: 1. Uses get_campaign_structure to show keywords 2. Confirms with user which ones to remove 3. Uses remove_keywords with the keyword_ids
negative
add_negative_keywords
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Add negative keywords to a campaign. Negative keywords prevent your ads from showing for certain searches. They help save budget by avoiding irrelevant clicks. **Parameters:** - campaign_id: The campaign ID (REQUIRED - get from list_campaigns) - keywords: List of negative keywords to add - customer_id: Optional **Each keyword needs:** - text: The keyword phrase (e.g., "free", "cheap", "diy") - match_type: EXACT, PHRASE, or BROAD (default: BROAD) **Campaign-level vs Ad Group-level:** This adds negative keywords at CAMPAIGN level, affecting ALL ad groups. **Common negative keywords:** - "free", "cheap", "discount" (for premium brands) - "jobs", "salary", "careers" (for product companies) - "diy", "how to", "tutorial" (for service providers) **Execution time:** 2-4 seconds **Example:** User: "Block searches containing 'free' and 'cheap'" Agent: Uses add_negative_keywords with campaign_id and keywords list
remove_negative_keywords
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Remove negative keywords from a campaign. ⚠️ **WARNING: This is PERMANENT and IRREVERSIBLE.** Once removed, the negative keywords cannot be recovered. **Parameters:** - campaign_id: The campaign ID (REQUIRED) - keyword_ids: List of negative keyword IDs to remove (REQUIRED) - customer_id: Optional **Get keyword IDs from:** Use `get_campaign_structure` to see all campaign negative keywords with their IDs. Look for the "Campaign Negative Keywords" section. **When to use:** - Remove accidentally added negative keywords - Clean up obsolete negative keywords - Fix over-blocking that's limiting traffic **Execution time:** 2-4 seconds **Example:** User: "Remove the negative keyword 'discount' I added by mistake" Agent: 1. Uses get_campaign_structure to find the keyword ID 2. Uses remove_negative_keywords with campaign_id and keyword_ids
placement
add_placement_exclusions
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Exclude placements — add negative placement criteria so your ads STOP serving on specific websites, YouTube channels/videos, or apps. This is the write side that closes the optimization loop after `get_placement_performance` finds wasted or off-target placements. **What it does:** adds NEGATIVE placement criteria at the campaign level (applies to all ad groups) OR a single ad-group level. It is non-destructive — it does NOT pause or delete any campaign, ad group, ad, or existing targeting; it only prevents future serving on the placements you list. (To undo, the negative criterion can be removed later.) **Scope — provide exactly ONE:** - `campaign_id` — exclude across the whole campaign (all ad groups) - `ad_group_id` — exclude only within that ad group **Placements** — a list of `{type, value}`: - `WEBSITE` → value = domain/url (e.g. `msn.com`) - `YOUTUBE_CHANNEL` → value = channel id - `YOUTUBE_VIDEO` → value = video id - `MOBILE_APPLICATION` → value = app id Typically you take the `target_url` / `display_name` of placements that `get_placement_performance` shows with spend but zero conversions, and pass them here. **Returns:** which placements were `added` (with their criterion resource names) and which were `skipped` (invalid type/empty value), plus counts. Invalid rows are reported, never silently dropped. **Parameters:** - customer_id: Optional (uses connected account if omitted) - campaign_id OR ad_group_id: exactly one (required) - placements: list of {type, value} (required) **Use this tool when:** - User wants to exclude wasteful placements found via `get_placement_performance` - User says "block ads on <site>", "exclude this channel/app", "stop showing on these placements" **Tip:** Pair with `get_placement_performance` (`zero_conversions_only=true` + `min_cost`) to find the waste, then exclude it here in the same workflow.
get_placement_performance
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Per-PLACEMENT performance WITH conversions — where your ads actually ran (websites, YouTube channels/videos, apps) and what each placement cost and produced. This tool retrieves READ-ONLY data via 1 live GAQL query (cached 5 min in Redis). Safe to call multiple times. **Why this tool:** `get_display_placements` shows only the placements you manually targeted (config, no metrics). `get_campaign_performance` stops at ad-group granularity. This is the ONLY tool that shows WHERE Display / Demand Gen / Video / Smart ads actually delivered — including automatic placements Google chose — with cost AND conversions per placement. It's the data behind the Google Ads UI "Where ads showed" / Content → Placements report. **Returns one row per placement** (or per domain/channel when group_view=true): - Identity: `placement_type` (WEBSITE / YOUTUBE_CHANNEL / YOUTUBE_VIDEO / MOBILE_APPLICATION / …), `display_name`, `target_url` (the site / channel / app), `campaign_name`, `ad_group_name` (detail view) - Metrics for the date range: `impressions`, `clicks`, `ctr`, `cost`, `conversions`, `conversion_value`, `all_conversions`, `cpc`, `cpa`, `roas` - `totals` block + `pagination` (page / total_pages / has_more) **These reports are huge** (a Demand Gen account can have 150,000+ placements). Filter SERVER-SIDE so you don't pull everything: - `min_cost` — only placements that spent at least this much (account currency) - `min_impressions` — only placements above an impression floor - `zero_conversions_only` — only placements with ZERO conversions (spent money, no conversions). Pair with `min_cost` to find wasted spend to exclude. - `placement_type` — restrict to WEBSITE / YOUTUBE_CHANNEL / etc. - `order_by` — cost | conversions | impressions | clicks - `group_view=true` — roll up per domain/channel for fewer rows **Pagination:** results are paged. Check `pagination.has_more` in the response — if true, call again with `page` incremented (page=2, page=3, …) to get the next set of placements. Continue until has_more is false. **Coverage:** Display, Demand Gen, Video, Smart campaigns (any campaign that runs on the Display/YouTube network). Search campaigns have no placement rows. **These numbers are the account's own measured data — this tool renders NO verdicts, invents no "good/bad" thresholds, and applies no baseline.** It shows the placements and their metrics so you (and the user) can decide. `zero_conversions_only` is a factual filter, not a judgement. **Parameters:** - customer_id: Optional (uses connected account if omitted) - lookback_days: 7, 30, 60, 90, 120 (default 30). Ignored when both start_date and end_date set. - start_date / end_date: YYYY-MM-DD (override lookback_days when both provided) - campaign_id: Optional — scope to one campaign - placement_type / group_view / min_cost / min_impressions / zero_conversions_only / order_by: filters above - page / page_size: pagination (page_size default 50, max 200) **Execution time:** 1-4 seconds (1 GAQL query, then cached 5 min) **Use this tool when:** - User asks "where did my ads show?", "which websites / YouTube channels / apps converted?", "where is Display/Demand Gen wasting money?" - User wants to find placements with spend but no conversions to exclude them - User wants per-placement cost / conversions / CPA to optimize Display or Demand Gen **Tip:** Find waste with `zero_conversions_only=true` + `min_cost`, then exclude it with `add_placement_exclusions`.
select
select_google_campaign_type
**USE THIS TOOL FIRST WHEN:** User wants to create a Google Ads campaign but hasn't specified the campaign type. **IMPORTANT:** Call BEFORE any keyword research, asset discovery, or campaign creation when the user says things like: - "Create a Google Ads campaign" - "I want to run Google Ads" - "Set up a Google advertising campaign" - "Help me create ads on Google" - "Create a campaign" - "Run ads" This tool guides the user to select their campaign TYPE, then returns a step-by-step workflow with which tools to call next. **Campaign Types Available:** 1. **search** — Text ads in Google Search results (best for high-intent keywords, lead gen, local services) 2. **pmax** — Performance Max across all Google channels (best for ecommerce, brand awareness, multi-channel reach) 3. **youtube** — Video ads on YouTube (best for video content, brand storytelling, product demos) 4. **demandgen** — Demand Gen across YouTube + Gmail + Discover + Display (best for cross-channel mid-funnel) 5. **display** — Responsive Display Ads on the Google Display Network (GDN) — banner placements on millions of websites, apps, and YouTube display slots. Smart Display (`smart_display=true`) is a Google-managed variant within this type. **Returns:** step-by-step workflow, requirements, and a natural follow-up question for the chosen type. **Do NOT use this tool if:** - User specifically asks for "search campaign" or "text ads" → go directly to research_keywords then create_search_campaign - User specifically asks for "PMax" or "Performance Max" → go directly to discover_existing_assets then create_pmax_campaign - User specifically asks for "YouTube campaign" or "video campaign" → go directly to validate_video then create_youtube_campaign - User specifically asks for "Demand Gen" → go directly to create_demandgen_campaign - User specifically asks for "Display campaign", "banner ads", or "GDN" → go directly to create_display_campaign - User is asking about performance/analytics → use get_campaign_performance - User is asking about existing campaigns → use list_campaigns **Parameters:** - campaign_type: 'search' | 'pmax' | 'youtube' | 'demandgen' | 'display' **Execution time:** Instant (no API call)
select_meta_campaign_type
User wants to create a Meta (Facebook/Instagram) ad campaign but hasn't specified the campaign type (image, video, carousel, or app). IMPORTANT: This tool should be called BEFORE any asset discovery or campaign creation when the user says things like: - "Create a Meta campaign" - "Create a Facebook ad" - "I want to run Instagram ads" - "Set up a Meta advertising campaign" - "Help me create ads on Facebook" - "Promote my mobile app on Meta / drive app installs" This tool asks the user what TYPE of campaign they want to create, then provides guidance on the next steps. Campaign Types Available: 1. image - Single image ad (most common, good for static visuals) 2. video - Video ad including Reels (good for engagement, storytelling) 3. carousel - 2-10 swipeable cards (good for showcasing multiple products) 4. app - Mobile App Promotion (OUTCOME_APP_PROMOTION). Optimizes for app installs or in-app events. Requires Facebook App ID + App/Play Store URL. Picks creative format (image/video/carousel/DCO) inside the workflow. Do NOT use this tool if: - User specifically asks for "image campaign" - use create_meta_image_campaign - User specifically asks for "video campaign" or "Reels" - use create_meta_video_campaign - User specifically asks for "carousel campaign" - use create_meta_carousel_campaign - User is asking about performance/analytics - use performance analysis tools For app campaigns: ALWAYS use this tool first (with campaign_type='app') even when the user is specific about app — the workflow gathers required app_id + app_store_url and explains the FB App ID vs bundle/package ID distinction (a common customer trip-up). Parameters: - campaign_type: 'image', 'video', 'carousel', or 'app'
sitelinks
add_sitelinks
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Add sitelink extensions to a campaign. Sitelinks are clickable links to specific pages on your website. Recommended 4-6 sitelinks per campaign. **CONSTRAINTS:** - link_text max 25 characters - description1 max 35 characters (optional) - description2 max 35 characters (required if description1 is set) **EXAMPLE SITELINKS:** { "link_text": "How It Works", "final_url": "https://example.com/how-it-works", "description1": "See the platform in action", "description2": "Step-by-step walkthrough" } { "link_text": "Pricing", "final_url": "https://example.com/pricing", "description1": "Affordable plans for all", "description2": "Start free today" } **Parameters:** - campaign_id: The campaign ID (REQUIRED). Get from list_campaigns. - sitelinks: List of sitelink objects with link_text, final_url, and optional descriptions. - customer_id: Optional Google Ads customer ID **Execution time:** 2-5 seconds **When to use:** - User wants to add sitelinks to their campaign - User asks about adding more links to ads - User asks about extensions, ad enhancements, or assets generally — sitelinks are the highest-impact extension; offer them FIRST (before callouts / structured snippets) whenever a user asks to improve or extend an ad/campaign - After creating a campaign, proactively suggest adding sitelinks **Example:** User: "Add sitelinks to my campaign" / "How do I add extensions?" / "Make my ads better" Agent: 1. Uses list_campaigns to get campaign_id 2. Uses add_sitelinks with relevant page links (Services, Pricing, About, Contact)
remove_sitelinks
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Remove sitelink extensions from a campaign. Unlinks sitelinks from THIS campaign. The underlying Asset stays in your account and can be re-linked elsewhere. **Why this matters:** - Old policy-violating sitelinks keep serving until removed - Stale URLs / outdated promotional copy must be removed before adding new ones - A campaign can only show 8 sitelinks max — must remove older ones to make room **Parameters:** - campaign_id: Campaign whose sitelinks to remove (REQUIRED) - asset_ids: Optional list of asset IDs (or full resource_names) to remove specifically. Get IDs from `list_campaign_extensions`. If omitted, ALL sitelinks on this campaign are removed. - customer_id: Optional (uses connected account if omitted) **Workflow:** 1. Call `list_campaign_extensions(campaign_id)` to see what's currently linked 2. Identify which sitelinks to remove by their asset_id or text 3. Call this tool with those asset_ids (or omit to clear ALL) 4. Use `add_sitelinks` to add fresh ones if needed **Example:** User: "Remove the old sitelinks from my Krav Maga campaign — they have outdated promo copy" Agent: 1. list_campaign_extensions → shows 4 sitelinks with their asset_ids 2. Confirms: "I'll remove sitelinks 'Free Trial' and 'Summer Sale 2024'. Proceed?" 3. Calls remove_sitelinks(campaign_id, asset_ids=['12345', '67890'])
structured
add_structured_snippets
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Add structured snippet extensions to a campaign. Structured snippets highlight specific aspects of your products/services. **VALID HEADERS:** - AMENITIES, BRANDS, COURSES, DEGREE_PROGRAMS, DESTINATIONS - FEATURED_HOTELS, INSURANCE_COVERAGE, MODELS, NEIGHBORHOODS - SERVICE_CATALOG, SHOWS, STYLES, TYPES **RULES:** - Header must be from predefined list - 3-10 values required per snippet - Each value max 25 characters **EXAMPLES:** For SaaS/Platform: Header: "Types" Values: ["Google Ads", "Meta Ads", "LinkedIn Ads", "TikTok Ads"] For Services: Header: "Services" (maps to SERVICE_CATALOG) Values: ["Campaign Launch", "Analytics", "Optimization", "Reporting"] For Brands: Header: "Brands" Values: ["Nike", "Adidas", "Puma", "New Balance"] **Parameters:** - campaign_id: The campaign ID (REQUIRED). Get from list_campaigns. - snippets: List of {header, values} objects (REQUIRED). - customer_id: Optional Google Ads customer ID **Execution time:** 2-5 seconds **When to use:** - User wants to add structured snippets - User asks to highlight product types, services, or brands - After creating a campaign, suggest adding snippets **Example:** User: "Add structured snippets showing our ad platform types" Agent: 1. Uses list_campaigns to get campaign_id 2. Uses add_structured_snippets with header "Types" and relevant values
remove_structured_snippets
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Remove structured snippet extensions from a campaign. Unlinks structured snippets from THIS campaign. The underlying Asset stays in your account and can be re-linked elsewhere. **Why this matters:** - Stale snippet headers/values (e.g. last season's "Styles" or discontinued "Brands") look bad to users - Must remove old snippets before fresh ones take their place - The sibling of `add_structured_snippets` — completes the add/remove pair (like remove_sitelinks / remove_callouts) **Parameters:** - campaign_id: Campaign whose structured snippets to remove (REQUIRED) - asset_ids: Optional list of asset IDs (or full resource_names) to remove specifically. Get IDs from `list_campaign_extensions`. If omitted, ALL structured snippets on this campaign are removed. - customer_id: Optional (uses connected account if omitted) **Workflow:** 1. Call `list_campaign_extensions(campaign_id)` to see what's currently linked 2. Identify which snippets to remove by their asset_id 3. Call this tool with those asset_ids (or omit to clear ALL) 4. Use `add_structured_snippets` to add fresh ones if needed **Example:** User: "Remove the old structured snippets from my campaign" Agent: 1. list_campaign_extensions → shows current structured snippets with asset_ids 2. Confirms: "I'll remove all structured snippets. Proceed?" 3. Calls remove_structured_snippets(campaign_id)
amazon
amazon_ads
Access all Amazon Ads campaign management tools (Sponsored Products + Sponsored Brands). **Required first step:** call this tool with `action: "list_tools"` (optionally add the FULL `intent` — the user's COMPLETE request verbatim, not a summary — it helps us improve tool discovery). Then call again with `action: "execute"`, a specific `tool_name` from that list, and `arguments`. Calling `action: "execute"` without `tool_name` is INVALID and will return an error — do not retry the same broken call. **Available capabilities:** - **Accounts**: List advertiser profiles (per-marketplace accounts) - **Campaign Management**: List, create, update, pause/resume, delete Sponsored Products and Sponsored Brands campaigns; ad groups; product ads; keywords - **Targeting**: Keywords (EXACT/PHRASE/BROAD), negative keywords, product/category targeting (target competitor ASINs or categories) - **Optimization**: Amazon's own keyword recommendations, bid recommendations, budget recommendations, budget usage (campaigns capping out) - **Analytics**: Campaign performance (impressions, clicks, spend, sales, ACOS, ROAS) and search-term reports (what shoppers actually typed) **When to use this tool:** - "Create an Amazon ad campaign for my product B0..." - "How are my Amazon campaigns performing?" - "What search terms are wasting spend on Amazon?" - "Raise the bid on my Amazon keywords" - "Pause my Amazon campaigns" **⚠️ Side effects & confirmation:** Write operations change a live Amazon Ads account. New campaigns are created **PAUSED** and must be explicitly confirmed by the user before launch. Bid, budget, and status changes (pause/resume) take effect immediately and can disrupt ad delivery. Deleting a campaign is irreversible. **Typical flows:** - New campaign: `create_amazon_sp_campaign` with the product's ASIN — AUTO targeting is the best start; it goes live PAUSED for review, then `resume_amazon_campaigns`. - Optimization loop: `get_amazon_search_terms` → add converting terms via `add_amazon_keywords` (EXACT) → block wasteful terms via `add_amazon_negative_keywords`. **Example — list tools:** action: "list_tools" **Example — create campaign:** action: "execute" tool_name: "create_amazon_sp_campaign" arguments: {"name": "Summer Sale - Widget", "daily_budget": 10, "asins": ["B0EXAMPLE1"]} **Example — performance:** action: "execute" tool_name: "get_amazon_campaign_performance" arguments: {"start_date": "2026-06-01", "end_date": "2026-06-10"}
audiences
search_audiences
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Search for available audience segments (in-market, affinity, custom). Use this tool to discover audience segment IDs for: - **PMax campaigns:** Use IDs with `add_pmax_audience_signal` (audience signals/hints) - **Demand Gen / YouTube campaigns:** Pass IDs via `audience_segments` parameter in `create_demandgen_campaign` or `create_youtube_campaign` (direct targeting) **Audience types:** - **In-market:** Users actively researching products/services (e.g., "Business Software") - **Affinity:** Users with long-term interests (e.g., "Technology Enthusiasts") - **Custom:** Your account's existing remarketing/customer match lists **Parameters:** - query: Search term (e.g., "advertising services", "SaaS tools") **Execution time:** 2-5 seconds
audit
audit_conversion_tracking
Review your conversion tracking setup across ad platforms. Checks Meta Pixel (event volume, CAPI status, dedup, diagnostics), LinkedIn (conversion rules, CAPI, Insight Tag), and Google Ads (conversion actions, enhanced conversions, attribution). Returns a health score (0-100), grade (A-F), detailed findings, and suggestions with self-validation steps for each platform. Note: Some checks rely on API data availability and may not capture all configurations. Where findings are inconclusive, the tool provides guidance on how to verify directly in the platform's dashboard. Parameters: - platform (optional): 'google_ads', 'meta_ads', or 'linkedin_ads'. If omitted, reviews all connected platforms. - account_id (optional): scope the audit to ONE account (Google Ads customer ID, Meta ad account ID, or LinkedIn account ID). If omitted, EVERY active account on the platform is audited — for a user with many active accounts that is many live API calls. To audit a single account, pass account_id; do NOT switch or deactivate active accounts to narrow the audit (that changes account state for the whole login). - customer_id (optional): alias for account_id. - lookback_days (optional): 7, 14, 30, 60, or 90 days (default: 30) Execution time: ~5-15 seconds (includes live API calls to ad platforms).
benchmark
get_benchmark_context
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Get industry benchmark context for AI-powered recommendations. ⚠️ IMPORTANT: This tool retrieves READ-ONLY data. Safe to call multiple times. 🎯 **What This Tool Does (Performance Agent - Phase 1 Feature 5):** - Generates contextual benchmark data for the user's business - Combines business profile with industry benchmarks - Provides recommended ROAS targets based on vertical - Returns formatted context for AI prompts **Returns benchmark context:** - Business vertical and size context - Industry-specific ROAS benchmarks (typical, good, excellent) - CTR benchmarks by industry - CPC expectations for the vertical - Seasonality considerations - Custom recommendations based on profile **Industry Benchmarks Included:** | Vertical | Typical ROAS | Good ROAS | Excellent ROAS | |----------|--------------|-----------|----------------| | Retail | 4.0x | 6.0x | 8.0x | | Services | 3.0x | 5.0x | 7.0x | | Technology | 3.5x | 5.5x | 8.0x | | Healthcare | 2.5x | 4.0x | 6.0x | | Finance | 5.0x | 8.0x | 12.0x | | Education | 2.0x | 3.5x | 5.0x | **Parameters:** - **include_recommendations**: Include performance recommendations (default: true) - **customer_id**: Optional (uses connected account if omitted) **Use this tool when:** - Before providing performance analysis - When comparing user's metrics to industry standards - User asks "how am I doing compared to others?" - You need context for optimization recommendations **Integration with Other Tools:** Call this BEFORE or AFTER these tools for enhanced recommendations: - `analyze_wasted_spend` - Contextualize waste against industry norms - `optimize_budget_allocation` - Use industry-appropriate ROAS targets - `get_campaign_performance` - Compare metrics to benchmarks - `explain_performance_anomaly` - Understand if changes are industry-wide **Execution time:** 1-2 seconds (profile lookup + benchmark calculation)
bid
update_bid_strategy
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Change campaign bidding strategy. **Available Strategies:** - MAXIMIZE_CLICKS: Get as many clicks as possible within budget - MAXIMIZE_CONVERSIONS: Get as many conversions as possible - TARGET_CPA: Set a target cost per acquisition (requires target_cpa) - TARGET_ROAS: Set a target return on ad spend (requires target_roas) - TARGET_IMPRESSION_SHARE: Bid to appear for a target share of auctions at a chosen page position (requires impression_share_location + impression_share_target_percent) **Parameters:** - campaign_id: The campaign ID (REQUIRED) - strategy: one of the strategies above (REQUIRED) - target_cpa: Required if strategy is TARGET_CPA. In dollars, e.g., 25.00 for $25 CPA - target_roas: Required if strategy is TARGET_ROAS. Multiplier, e.g., 4.0 for 400% ROAS - impression_share_location: Required if strategy is TARGET_IMPRESSION_SHARE. ABSOLUTE_TOP_OF_PAGE, TOP_OF_PAGE, or ANYWHERE_ON_PAGE - impression_share_target_percent: Required if strategy is TARGET_IMPRESSION_SHARE. 1-100, e.g., 80 for 80% - cpc_bid_ceiling: Used with TARGET_IMPRESSION_SHARE. Max CPC in the ACCOUNT'S currency (not cents, not USD; for 4.00 send 4). Optional but STRONGLY recommended - customer_id: Optional (uses connected account if omitted) **IMPORTANT:** - TARGET_CPA requires conversion tracking to be set up - TARGET_ROAS requires conversion value tracking - TARGET_IMPRESSION_SHARE is for visibility goals (Search/Display); set cpc_bid_ceiling so bids don't run away chasing the target - This changes the bidding on a LIVE campaign immediately — review the values (especially the CPC ceiling and target %) before moving on - Changing strategy may take 1-2 weeks to stabilize performance - Confirm with user before changing **Execution time:** 2-4 seconds **Examples:** User: "I want to target $30 CPA" Agent: Uses update_bid_strategy with strategy=TARGET_CPA, target_cpa=30.00 User: "Target absolute top of page, 80% impression share, max CPC $4" Agent: Uses update_bid_strategy with strategy=TARGET_IMPRESSION_SHARE, impression_share_location=ABSOLUTE_TOP_OF_PAGE, impression_share_target_percent=80, cpc_bid_ceiling=4.00
browse
browse_meta_targeting
User wants to browse all targeting options in a specific category without a search query. This tool retrieves all options in a Meta targeting category for exploration and discovery. Returns: - List of all targeting options in the category - IDs, names, and audience sizes - Useful for discovering targeting options when user doesn't have a specific query When to use this tool: - "Show me all available behaviors for Meta targeting" - "What interest categories are available?" - "Browse demographic targeting options" - "List all life events I can target" - "What income targeting options exist?" Categories Available: - interests: All interest targeting categories - behaviors: All behavior targeting options - demographics: All demographic targeting options - life_events: All life event targeting options - industries: Industry targeting options - income: Income bracket targeting options - family_statuses: Family status targeting options Parameters: - category: Category to browse (required) - limit: Maximum results (1-500, default: 100) - locale: Locale for results (default: en_US) - ad_account_id: Required for multi-account users. Get from list_connected_accounts Execution time: 1-3 seconds Data source: Meta Marketing API Targeting Search
bulk
bulk_update_keyword_status
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Pause or enable MANY keywords in one ad group in a SINGLE call. Use this instead of calling update_keyword once per keyword — pausing N keywords here is ONE tool call (and one quota debit) instead of N. Fully reversible: it sets status, it never removes keywords (unlike remove_keywords). **Parameters:** - ad_group_id: The ad group containing the keywords (REQUIRED). One call per ad group. - keyword_ids: List of keyword IDs to update, all in that ad group (REQUIRED). Max 300/call. - status: PAUSED or ENABLED (REQUIRED) - customer_id: Optional **Get keyword_ids from:** get_campaign_structure (shows every keyword + its ID). **To pause keywords across several ad groups:** make one call per ad group. **Execution time:** 2-6 seconds **Example:** User: "Pause all the non-core keywords in that ad group" Agent: 1. get_campaign_structure to list the keywords + IDs 2. Confirms which ones to pause 3. bulk_update_keyword_status(ad_group_id, keyword_ids=[...], status="PAUSED")
callout
add_callout_extensions
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Add callout extensions to a campaign. Callouts are short, non-clickable highlights that appear below your ad. They communicate quick trust signals and differentiators. **IMPORTANT RULES (from google-ads-creative-guidelines.md):** - Max 25 characters each - 4-8 callouts recommended - Should NOT be CTAs (no "click", "buy", "order", "call") - Should NOT end with periods **GOOD EXAMPLES:** - "Free Shipping" - "24/7 Support" - "No Code Required" - "30 Second Setup" - "Award Winning" **BAD EXAMPLES (will be rejected):** - "Click Now" (CTA word) - "Buy Today" (CTA word) - "Free Shipping." (ends with period) **Parameters:** - campaign_id: The campaign ID (REQUIRED). Get from list_campaigns. - callouts: List of callout text strings (REQUIRED). Each max 25 chars. - customer_id: Optional Google Ads customer ID **Execution time:** 2-5 seconds **When to use:** - User wants to add callouts/highlights to their campaign - User asks about extensions or ad enhancements - After creating a campaign, suggest adding callouts **Example:** User: "Add some callouts to my campaign" Agent: 1. Uses list_campaigns to get campaign_id 2. Uses add_callout_extensions with relevant callouts
callouts
remove_callouts
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Remove callout extensions from a campaign. Unlinks callouts from THIS campaign. The underlying Asset stays in your account and can be re-linked elsewhere. **Why this matters:** - Old callouts containing words like "Doctor Reviewed" / "Medical" / "Clinical" can flag a campaign for policy issues - Stale promotional callouts (e.g. "Summer Sale 2024") look bad to users - Must remove old callouts before fresh ones take their place **Parameters:** - campaign_id: Campaign whose callouts to remove (REQUIRED) - asset_ids: Optional list of asset IDs (or full resource_names) to remove specifically. Get IDs from `list_campaign_extensions`. If omitted, ALL callouts on this campaign are removed. - customer_id: Optional (uses connected account if omitted) **Workflow:** 1. Call `list_campaign_extensions(campaign_id)` to see what's currently linked 2. Identify which callouts to remove by their asset_id or text 3. Call this tool with those asset_ids (or omit to clear ALL) 4. Use `add_callout_extensions` to add fresh ones if needed **Example:** User: "Remove all my callouts and add new ones" Agent: 1. Confirms: "I'll remove all 4 current callouts and let you add new ones. Proceed?" 2. Calls remove_callouts(campaign_id) — clears all 3. Then add_callout_extensions with new list
campaigns
list_campaigns
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link List all Google Ads campaigns for the connected account. ⚠️ CRITICAL: Call this tool BEFORE creating new campaigns to ask the user: "Would you like to create a new campaign or update an existing one?" This tool retrieves READ-ONLY data. Safe to call multiple times. **Returns:** - List of all campaigns with IDs, names, status, type, budget - 30-day performance metrics for each campaign (impressions, clicks, cost, conversions) - Total campaign count **Parameters:** - status_filter: ENABLED, PAUSED, or ALL (optional, default: ALL) - campaign_type: SEARCH, PERFORMANCE_MAX (or PMAX), DISPLAY, SHOPPING, VIDEO, DEMAND_GEN, APP, or ALL (optional, default: ALL) - customer_id: Optional (uses connected account if omitted) **Execution time:** 2-5 seconds (direct Google Ads API call) **Campaign Management Guidelines:** BEFORE Starting Any Campaign Work: 1. ALWAYS use `list_campaigns` first 2. Ask user: "Would you like to create a new campaign or update an existing one?" 3. If updating, use `get_campaign_structure` to see full details User Intent Mapping: | User Says | Agent Action | |-----------|--------------| | "Create a campaign for X" | List existing first, then ask create vs update | | "Change the budget" | Get structure, then use update tools | | "Add more keywords" | Get structure, then add keywords | | "Update my ads" | Get structure, then update ad content | | "Pause the campaign" | Use pause_campaign tool | **Use this tool to:** - View all existing campaigns before creating new ones - Find campaign IDs for update operations - Get a quick overview of account structure - Identify active vs paused campaigns
chatgpt
chatgpt_ads
Access all ChatGPT Ads (OpenAI Ads) tools — ads shown inside ChatGPT responses. **Required first step:** call this tool with `action: "list_tools"` (optionally add the FULL `intent` — the user's COMPLETE request verbatim, not a summary — it helps us improve tool discovery). Then call again with `action: "execute"`, a specific `tool_name` from that list, and `arguments`. Calling `action: "execute"` without `tool_name` is INVALID and will return an error — do not retry the same broken call. **Multi-account:** a user can connect several ChatGPT Ads accounts (one Advertiser API key each). When more than one is connected, pass `account_id` inside `arguments` to pick which account a tool acts on — get the exact ids from `list_chatgpt_accounts`. With a single connected account you can omit it. If you omit it while several are connected, the tool replies with the list of accounts and their `account_id`s — re-run with the one the user means. **Available capabilities:** - **Account**: the connected ChatGPT Ads account(s); `list_chatgpt_accounts` shows each with its `account_id` - **Create**: `launch_chatgpt_ad` — one-shot campaign → ad group → image upload → chat_card ad (created PAUSED; needs headline, body, public image URL, destination URL, daily budget, and a target location) - **Manage**: pause/activate/archive/update campaigns, ad groups, and ads - **Analyze**: campaign performance (impressions, clicks, spend, CTR, CPC) - **Geo**: resolve a location name to OpenAI location IDs for targeting **⚠️ Side effects & confirmation:** Write operations change a live ChatGPT (OpenAI) Ads account. Ads are created **PAUSED** — nothing serves or spends until activated, so launch must be explicitly confirmed by the user. Status changes (pause/activate) take effect immediately. Archiving a campaign/ad group/ad is irreversible. **Important:** ChatGPT Ads connects via a pasted OpenAI Advertiser API key (not OAuth). OpenAI does not currently approve ads for third-party AI services, so ad review may be rejected — the tools surface review status honestly. **Example — list tools:** action: "list_tools" **Example — create an ad:** action: "execute" tool_name: "launch_chatgpt_ad" arguments: {"name": "Summer Sale", "headline": "50% Off Today", "body": "Shop our summer collection now", "image_url": "https://example.com/ad.png", "target_url": "https://example.com/shop", "daily_budget": 10, "location_query": "United States"} **Example — performance:** action: "execute" tool_name: "get_chatgpt_performance" arguments: {"lookback_days": 30}
compare
compare_meta_catalog_product_sets
User wants to compare their catalog PRODUCT SETS against each other and decide where to put budget. Keywords: "which product set is best", "compare product sets", "where should budget go", "best sellers vs the rest", "product set ROAS". Ranks product sets by catalog-attributed ROAS, sizes a suggested budget shift from the weakest set toward the strongest, and flags OVERLAP — the same product spending across multiple sets (self-competition that fragments budget and inflates costs). Reads cached nightly product metrics (never calls Meta live). When to use: "Which product set performs best?", "Should I move budget between my product sets?"
competitor
competitor_ads_research
Research what a COMPETITOR is actually advertising right now — their live ad creatives, headlines, offers, calls to action, formats, and how long each ad has been running — pulled from public ad-transparency sources and read with vision analysis, then placed SIDE BY SIDE with the user's own connected ad account. **Call this when the user asks:** - "what ads is <competitor> running", "show me my competitor's ads" - "what are competitors doing", "competitor ad research/analysis/intelligence" - "what messaging/offers/creatives do they use", "what's working for them" - "how do my ads compare to <competitor>", "am I bidding on their brand" - anything about competitor creative, competitor copy, or competitive ad strategy **Inputs:** `competitor_domains` (REQUIRED — a list of competitor WEBSITE DOMAINS like ['semrush.com','ahrefs.com']). ⛔ It must be a DOMAIN, not a brand name: a bare brand returns zero results. If the user names a company without giving a website, ASK for the domain — do NOT guess it and do NOT auto-discover competitors. `region` (optional ISO country like 'US','IN','GB' — defaults to the user's own account market; note TikTok and LinkedIn ads are worldwide and cannot be filtered by market). `sources` (optional list — which ad platforms to pull: `['google']` (default, Google Search/Display/YouTube ads), add `'meta'` for their Facebook/Instagram ads, `'tiktok'` for their TikTok ads, and/or `'linkedin'` for their LinkedIn ads — e.g. `['google','meta','tiktok','linkedin']`. Add 'meta' when the user asks about Facebook/Instagram/Meta ads, 'tiktok' when they ask about TikTok ads, and 'linkedin' when they ask about LinkedIn/B2B ads or want a fuller picture). `max_creatives` (optional cap). **What it returns:** an interactive gallery of their real creatives with run-durations, plus the user's own ads and any competitor brand terms they already pay for. ⛔ It does NOT return competitor spend, ROAS, conversions, CPC or impressions — no source publishes those, so the tool never estimates them. Do not ask it for, or infer, how a competitor's ads PERFORM; a long run-duration is a duration, not proof it works. ⚠️ Plus, Pro & Max (not Free). Renders an interactive widget; the text fallback carries the same findings.
connections
get_connections_status
View connected ad accounts and OAuth connections. Shows all connected ad platforms (Google Ads, TikTok Ads, Meta Ads, LinkedIn Ads) with: - Connection status and account details - Primary account indicator - Option to switch primary account - Quick links to connect new platforms Use this tool when user asks about: - "how many accounts do I have" / "how many ad accounts" - "what accounts are connected" / "connected accounts" - "which account am I using" / "current account" - "show my connections" / "list my accounts" - "connection status" / "account status" - "what platforms do I have connected" - Account count, account list, or connection overview Do not use for: - Discovering campaigns, ads, or keywords (use discover_existing_assets) - Performance data or metrics (use performance tools) - Creating or managing campaigns This is specifically for OAuth connections and account management.
content
update_ad_content
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Combined update for ad content (RSA, RDA, or DemandGen video-responsive / multi-asset) in a single API call with combined field mask. Backend auto-detects ad type and applies the right proto branch. **Parameters:** - ad_id (REQUIRED), ad_group_id (REQUIRED) - headlines: Optional — RSA 3-15 (max 30 chars) / RDA 1-5 (max 30 chars) / DemandGen 1-5 (max 40 chars) - descriptions: Optional — RSA 2-4 / RDA 1-5 / DemandGen 1-5, each max 90 chars - long_headline: Optional — RDA only (single string, max 90 chars). Rejected for RSA and DemandGen (DemandGen uses long_headlineS, plural — not editable via this tool). - final_urls: Optional — landing page URLs (all types) - final_mobile_urls: Optional — mobile-specific landing URLs (all types). Send [] to clear. - tracking_url_template: Optional — per-ad tracking template, e.g. "{lpurl}?utm_source=google" (all types). Send "" to clear. - customer_id: Optional At least one of headlines, descriptions, long_headline, final_urls, final_mobile_urls, or tracking_url_template is required. **Execution time:** 2-4 seconds. **Example (RDA ad):** Update headlines + long_headline + descriptions in one call.
create
create_ad
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Create a new Responsive Search Ad (RSA) in an existing ad group. Useful for A/B testing different ad copy or adding variation to an ad group. **Parameters:** - ad_group_id: The ad group to add the ad to (REQUIRED) - headlines: 3-15 headlines (REQUIRED, max 30 chars each) - descriptions: 2-4 descriptions (REQUIRED, max 90 chars each) - final_urls: Landing page URLs (REQUIRED, at least one) - path1: Optional display path 1 (max 15 chars) - path2: Optional display path 2 (max 15 chars) - customer_id: Optional **Execution time:** 3-5 seconds **New ad goes through Google's review process.** **Example:** User: "Create a new ad to test different messaging" Agent: 1. Gets ad_group_id from get_campaign_structure 2. Prepares headlines and descriptions 3. Creates new ad with create_ad
creative
get_ad_creative
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Read/export the creative composition of existing ads — videos, images (downloadable URLs), and all text. This tool retrieves READ-ONLY data via 2 live GAQL queries (cached 15 min in Redis). Safe to call multiple times. **Why this tool:** `get_campaign_structure` shows ads but not what they're made of. This tool returns the full creative payload of any existing ad so you can audit, archive, or rebuild winners into other formats. **Returns per ad:** - Identity: `ad_id`, `ad_name`, `ad_type`, `status`, `ad_strength`, ad group + campaign context - **Videos:** YouTube `video_id` + `watch_url` + `thumbnail_url` + title per video asset - **Images:** direct downloadable `url` (Google CDN) + `width`/`height` + `mime_type` + `role` (marketing / square_marketing / portrait_marketing / logo / square_logo) - **Text:** `headlines[]`, `long_headlines[]`, `descriptions[]`, `business_name`, `call_to_actions[]` - **Carousel ads:** per-card headline + CTA + card images (resolved to URLs) - `final_urls`, `display_url`; RSA `path1`/`path2`; RDA colors **Supported ad types (v1):** DEMAND_GEN_VIDEO_RESPONSIVE_AD, DEMAND_GEN_MULTI_ASSET_AD, DEMAND_GEN_CAROUSEL_AD, RESPONSIVE_SEARCH_AD, RESPONSIVE_DISPLAY_AD. PMax creative lives in asset groups (no per-ad rows) — not covered; use list_pmax_asset_group_images. **Known API limits (not bugs):** video files are NOT downloadable via the Google Ads API (YouTube watch URL is the canonical reference); per-video orientation (landscape/square/portrait) is not exposed by the API. **Parameters:** - customer_id: Optional (uses connected account if omitted) - ad_id: single ad — OR ad_group_id — OR campaign_id (bulk). At least one required. - status_filter: 'all' (default — includes paused, useful for archiving) | 'enabled' - limit: max ads (default 50, max 100) **Execution time:** 2-5 seconds (2 GAQL queries, then cached 15 min) **Use this tool when:** - User asks "what's in this ad?", "download/export my creatives", "which video/image does this ad use?" - After get_ad_performance identified a winner/loser and the user wants to see or reuse its creative - User wants to rebuild a winning ad in another format or audit live creatives **Tip:** Pair with `get_ad_performance` — performance tells you WHICH ad wins, this tells you WHAT it's made of.
descriptions
update_ad_descriptions
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Update descriptions for a Responsive Search Ad (RSA), Responsive Display Ad (RDA), OR a DemandGen ad (video-responsive / multi-asset). Backend auto-detects ad type; per-type count bounds: - RSA: 2-4 descriptions - RDA: 1-5 descriptions - DemandGen (video-responsive / multi-asset): 1-5 descriptions Each description is max 90 characters (all types). **Parameters:** - ad_id (REQUIRED), ad_group_id (REQUIRED), descriptions (REQUIRED) - customer_id (optional) **Description Rules:** - Should expand on headlines and include specific details + CTAs - Formula: [Value Prop]. [Specific Detail]. [CTA]. **Execution time:** 2-4 seconds. **WARNING:** Updated ads go through Google's review process.
duplicate
duplicate_meta_campaign
User wants to duplicate/copy an existing Meta campaign with all its ad sets, ads, and settings. IMPORTANT: This creates a NEW real campaign in Meta Ads. The duplicate starts in PAUSED status by default for review. This tool copies the entire campaign structure including: - Campaign settings (objective, budget strategy) - All ad sets (targeting, budgets, schedules, promoted_object) - All ads (creatives, text, CTAs, app_link_spec deep links) App Campaigns (OUTCOME_APP_PROMOTION) — preserved on duplicate: - ad-set promoted_object (application_id + object_store_url + custom_event_type) - creative app_link_spec (deep_link_url_ios / deep_link_url_android) - creative asset_feed_spec.link_urls.ios_url / android_url (DCO ads) After duplicating an app campaign, run get_meta_campaign_details on the new campaign ID to verify the 'App Campaign:' section shows the same app_id, store URL, and event type as the original. Returns: - Original and new campaign IDs - New campaign status - Ads Manager URL for the new campaign - Next steps for review and activation When to use this tool: - "Duplicate my campaign" - "Copy campaign [ID]" - "Create a copy of this campaign" - "I want to A/B test with a copy of my campaign" - "Clone my campaign with different targeting" Parameters: - campaign_id: The Meta Campaign ID to duplicate (required) - new_name: Name for the new campaign (optional, defaults to original + " - Copy") - status: Status for new campaign — 'PAUSED' (default, recommended) or 'ACTIVE' Execution time: 10-30 seconds (depends on campaign size) Creates: New real campaign in Meta Ads Common use cases: 1. A/B Testing: Duplicate, then modify targeting or creative on the copy 2. Seasonal variants: Copy a proven campaign, update copy and dates 3. New market expansion: Duplicate, change location targeting 4. Budget testing: Copy, change budget levels Workflow: 1. Use `list_meta_campaigns` to find the campaign ID 2. Use `duplicate_meta_campaign` to create the copy 3. Use `update_meta_campaign` or `update_meta_ad_set` to modify the copy 4. Use `resume_meta_campaign` when ready to launch
headlines
update_ad_headlines
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Update headlines for a Responsive Search Ad (RSA), Responsive Display Ad (RDA), OR a DemandGen ad (video-responsive / multi-asset). The backend auto-detects the ad type and enforces per-type count + character bounds: - RSA (Search): 3-15 headlines, max 30 chars each - RDA (Display): 1-5 headlines, max 30 chars each - DemandGen (video-responsive / multi-asset): 1-5 headlines, max 40 chars each **MANDATORY WORKFLOW:** 1. Call `get_campaign_structure` or `get_ad_creative` to find ad_id and ad_group_id 2. Review current headlines 3. Prepare new headlines: - RSA — 3-15 headlines. Follow the category system (Category A: What It Is, Category B: Benefits, Category C: Pain/Proof/CTA). Headlines must work in ANY combination. - RDA — 1-5 short headlines (max 30 chars each). You'll also likely want to update the `long_headline` via `update_ad_content` (RDA only, max 90 chars). - DemandGen — 1-5 headlines (max 40 chars each). This replaces the ad's short headlines; it does NOT touch long_headlines/descriptions. 4. Validate (char limit per type above, no "!" marks, no unverified superlatives like "Best", "#1") 5. Get user approval 6. Call this tool with ad_id, ad_group_id, headlines **Parameters:** - ad_id (REQUIRED), ad_group_id (REQUIRED), headlines (REQUIRED) - customer_id (optional) **Execution time:** 2-4 seconds. **WARNING:** Updated ads go through Google's review process (24-48 hours).
help
help_user_upload
Show user instructions for uploading images to postimages.org for Performance Max campaigns. ⚠️ CALL THIS FIRST when user wants to create a PMax campaign! **YOUR ROLE**: Image Upload Guide **WHEN TO USE**: - User says "create PMax campaign" or similar - Before asking for image uploads - Anytime user needs help uploading images **WHAT THIS DOES**: - Returns clear, step-by-step instructions - Tells user to upload to postimages.org - Explains how to get Direct links (not share pages) - Shows example URL format **DO NOT**: - Ask user to upload via ChatGPT's paperclip (won't work with size limits!) - Request base64 data (too large!) - Skip this step (user needs clear guidance) **AFTER THIS**: - User uploads to postimages.org - User pastes Direct links in chat - You call validate_and_prepare_assets with those URLs **Execution Time**: <1 second (just returns text) **Authentication**: Not required
infer
infer_business_profile
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Automatically infer business profile from campaign data using AI analysis. ⚠️ IMPORTANT: This tool ANALYZES data but may SAVE a profile if confidence is high. 🎯 **What This Tool Does (Performance Agent - Phase 1 Feature 5):** - Analyzes campaign names, keywords, and ad copy - Uses Claude AI to classify business type - Infers business vertical, size, goals, and audience - Returns confidence level (high, medium, low) - Auto-saves if confidence is HIGH, asks confirmation for LOW **Inference Process:** 1. Collects campaign names and keywords from Google Ads 2. Analyzes patterns (B2B vs B2C, product vs service) 3. Uses AI to classify business vertical 4. Estimates business size from ad spend 5. Identifies primary goals from campaign types **Confidence Levels:** - **HIGH** (≥0.8): Auto-saves profile, high certainty - **MEDIUM** (0.5-0.8): Saves profile, reasonable certainty - **LOW** (<0.5): Returns suggestion, asks user to confirm **Parameters:** - **force_save**: Set to true to save even low-confidence profiles - **customer_id**: Optional (uses connected account if omitted) **Returns:** - Inferred business profile (vertical, size, goal, audience) - Confidence level and reasoning - Whether profile was saved or needs confirmation - Suggested confirmation prompt for low-confidence results **Use this tool when:** - User doesn't have a business profile set - User asks "analyze my business" - You need business context but none exists - After user connects a new Google Ads account **Example Flow:** 1. Call `get_business_profile` - returns no profile 2. Call `infer_business_profile` - analyzes campaigns 3. If HIGH confidence: Profile saved automatically 4. If LOW confidence: Ask user to confirm with suggested prompt **Execution time:** 3-8 seconds (AI analysis + optional save)
keyword
update_keyword
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Update keyword bid or status. **Parameters:** - keyword_id: The keyword to update (REQUIRED - get from get_campaign_structure) - ad_group_id: The ad group containing the keyword (REQUIRED) - cpc_bid_micros: New bid in micros (1 USD = 1,000,000). Example: 2500000 = $2.50 - status: ENABLED or PAUSED - customer_id: Optional **Can update:** - Bid amount (cpc_bid_micros) - Status (ENABLED/PAUSED) **CANNOT update (immutable):** - Keyword text - Match type **Execution time:** 2-3 seconds **Example:** User: "Increase the bid on 'running shoes' to $3" Agent: 1. Uses get_campaign_structure to find the keyword_id 2. Uses update_keyword with cpc_bid_micros=3000000
klaviyo
klaviyo
Read and act on the user's Klaviyo (email + SMS marketing) account. **Use action="list_tools" first** to discover available actions and their parameters. Then use action="execute" with the specific tool_name and arguments. **When to use:** - Klaviyo lists, segments, profiles, subscribers - Email campaign performance (opens, clicks, conversions, revenue) - Flows (welcome series, abandoned cart, post-purchase) - Adding profiles or events, triggering flows - "Show my Klaviyo campaign stats", "add a contact to list X", "what flows do I have" If the user hasn't connected Klaviyo, this tool returns a friendly message asking them to open Settings → Connections to authorize the connection. **⚠️ Side effects & confirmation:** Write operations change a live Klaviyo account — adding profiles or events writes contact PII, and triggering a flow can send real email/SMS to subscribers. These take effect immediately; confirm before writing. **Example — list actions:** action: "list_tools" **Example — add a profile:** action: "execute" tool_name: "klaviyo-add-profile-to-list" arguments: {"listId": "abc123", "email": "[email protected]"}
label
create_label
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Create an account label — a reusable tag for organizing campaigns (e.g. 'Q3 Promo', 'Brand'). After creating, use add_campaign_label to attach it to a campaign. Check list_labels first to avoid duplicates. **Required:** name. Optional: description, background_color (hex like '#FF5733').
labels
list_labels
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link List the account's labels (for organizing and reporting on campaigns). Returns each label's id, name, and description. Use the id with add_campaign_label to tag a campaign, or with create_label to make a new one first.
link
link_merchant_center
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Link a Merchant Center account to this Google Ads account. This is the prerequisite for Shopping campaigns — the product feed lives in Merchant Center, and the link lets Google Ads serve those products. If the same Google login administers both accounts the link is created directly; otherwise Google creates a pending invitation that must be accepted on the Merchant Center side. **Required:** merchant_center_id (the numeric ID shown in Merchant Center).
linkedin
linkedin_ads
Access all LinkedIn Ads campaign management tools. **Use action="list_tools" first** to see available operations and their parameters. When you do, pass the FULL `intent` — the user's COMPLETE request verbatim, not a summary — it helps us improve tool discovery. Then use action="execute" with the specific tool_name and arguments. **Available capabilities:** - **Campaign Performance**: Analyze metrics, engagement, audience insights, wasted spend, anomaly detection - **Campaign Creation**: Image, video, carousel, text ad campaigns with asset discovery - **Campaign Management**: Update settings, pause/resume, clone, batch update, budget/schedule/targeting changes - **Creative Management**: Add/update/pause/resume/delete creatives (image, text, video, carousel) - **Multi-Campaign Composition**: Add campaigns to existing groups (different audiences), add creatives to campaigns (A/B testing) - **Targeting**: Search targeting options, research business for targeting, 19 targeting facets - **Conversions**: List, associate, manage conversion tracking - **Campaign Groups**: List and update campaign groups - **AI Features**: Generate ad creatives, explain objectives, research business targeting **When to use this tool:** - "How are my LinkedIn campaigns performing?" - "Create a new LinkedIn sponsored content campaign" - "Show me my LinkedIn ad engagement metrics" - "What targeting options are available on LinkedIn?" - "Pause my underperforming LinkedIn campaigns" **⚠️ Side effects & confirmation:** Write operations change a live LinkedIn Ads account. New campaigns are created **PAUSED** and must be explicitly confirmed by the user before launch. Budget, targeting, and status changes (pause/resume) take effect immediately and can disrupt ad delivery. **Deleting a creative is irreversible.** **Raw data mode (performance tools only):** If the user asks for "raw data", "raw metrics", "just the numbers", "no recommendations", or "no commentary" — pass `raw_data: true` inside `arguments` when calling any performance tool (`get_linkedin_campaign_performance`, `get_linkedin_engagement_metrics`, `get_linkedin_audience_insights`, `analyze_linkedin_wasted_spend`, `optimize_linkedin_budget`, `explain_linkedin_anomaly`, `analyze_linkedin_creative_performance`). You receive a JSON code block of metrics only: spend, clicks, impressions, conversions, CPA, CPC, CTR, CVR, engagement rate, lead form completion rate by campaign/creative/date. Severity labels, suggested bids, suggested budgets, industry benchmarks, and optimization recommendations are stripped. Default is `false` (full formatted analysis). **Example — list tools:** action: "list_tools" **Example — get performance:** action: "execute" tool_name: "get_linkedin_campaign_performance" arguments: {"lookback_days": 30} **Example — raw performance (user asked for raw data):** action: "execute" tool_name: "get_linkedin_campaign_performance" arguments: {"lookback_days": 30, "raw_data": true}
location
update_location_targeting
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Change a campaign's location-targeting MODE without recreating the campaign. This is the "Presence vs Presence-or-Interest" toggle. It controls *who* sees ads inside the campaign's existing location list — it does NOT change the location list itself (use targeting tools for that). **Modes:** - PRESENCE (recommended for performance): People physically in or regularly in the targeted locations - PRESENCE_OR_INTEREST (Google's default): People in OR interested in the locations (broader; can waste budget on out-of-area users) - SEARCH_INTEREST: People searching for the location (Search campaigns only) **When to use:** - Customer says "my ads are showing to people not in my target area" → switch to PRESENCE - Local-only business (medical, restaurants, services) → PRESENCE - Brand-awareness or interest-based reach → keep PRESENCE_OR_INTEREST **Channel-type rules (auto-enforced):** - Display: rejects negative=PRESENCE_OR_INTEREST. Tool auto-defaults negative to PRESENCE if omitted. - Display: rejects positive=SEARCH_INTEREST. - Search/PMax: all combinations supported. **Parameters:** - campaign_id: Campaign to update (REQUIRED) - positive_geo_target_type: PRESENCE, PRESENCE_OR_INTEREST, or SEARCH_INTEREST (REQUIRED) - negative_geo_target_type: PRESENCE or PRESENCE_OR_INTEREST (OPTIONAL — leave existing untouched if omitted, except Display where we force PRESENCE) **Example:** User: "My Display campaign is showing to people not in my city, fix it." Agent: 1. Confirms: "I'll switch the location targeting to 'People physically in your locations' (PRESENCE). Proceed?" 2. Calls update_location_targeting(campaign_id, positive_geo_target_type='PRESENCE')
merchant
get_merchant_center_links
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link List the Merchant Center accounts linked to this Google Ads account. A Merchant Center link is required before you can create a Shopping campaign. Returns each link's merchant_center_id and product_link_id. An empty list means no Merchant Center account is linked yet — use link_merchant_center to add one.
monitoring
monitoring_and_reporting
Access monitoring, scheduled reporting, and research tools. **Use action="list_tools" first** to see available operations and their parameters. When you do, pass the FULL `intent` — the user's COMPLETE request verbatim, not a summary — it helps us improve tool discovery. Then use action="execute" with the specific tool_name and arguments. **Available capabilities:** - **Scheduled Briefs**: Set up daily/weekly performance reports delivered by email - **Campaign Monitors**: Create 24/7 alerts for metric thresholds (ROAS, CPA, spend, CTR) - **Research Jobs**: Launch async AI-powered research (competitor analysis, keyword research, market landscape) - **Report Generation**: Generate on-demand performance reports across all ad platforms - **Task Management**: List, manage, and review scheduled tasks, monitors, and pending actions **⚠️ Side effects & confirmation:** Some operations create, modify, or delete persistent monitors and scheduled tasks, and applying signal actions changes a live ad account. Deleting a monitor or scheduled task is irreversible, and applied actions (e.g. pause/budget changes) take effect immediately — confirm before applying. **When to use this tool:** - "Set up a daily performance brief" - "Alert me when ROAS drops below 2x" - "Research my competitors' ad strategies" - "Show me my scheduled tasks" - "Generate a report for last week" **Example — list tools:** action: "list_tools" **Example — create a monitor:** action: "execute" tool_name: "create_monitor" arguments: {"platform": "google_ads", "metric": "roas", "operator": "less_than", "threshold": 2.0}
performance
get_ad_performance
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Per-AD performance breakdown — one row per ad, with individual metrics. This tool retrieves READ-ONLY data via 1 live GAQL query (cached 5 min in Redis). Safe to call multiple times. **Why this tool:** `get_campaign_performance` stops at ad-group granularity. When an ad group contains several live ads, this is the only tool that shows which creative is winning so you can pause losers and scale winners. **Returns one row per ad:** - Identity: `ad_id`, `ad_name`, `ad_group_id`, `ad_group_name`, `campaign_id`, `campaign_name` - State: `ad_type` (e.g. DEMAND_GEN_VIDEO_RESPONSIVE_AD, DEMAND_GEN_MULTI_ASSET_AD, RESPONSIVE_SEARCH_AD), `status`, `ad_strength`, `is_live` (ad + ad group + campaign all ENABLED) - Metrics for the date range: `impressions`, `clicks`, `ctr`, `cost`, `conversions`, `conversion_value`, `cpc`, `cpa`, `roas`, `video_views`, `video_view_rate` (video ads) - `totals` block + explicit truncation info (`total_ads_matched` vs `returned`) **Coverage:** Search, Display, Demand Gen, YouTube campaigns. NOT PMax — PMax has no per-ad rows (asset-group model); use `get_pmax_asset_performance` instead. **Row filter:** REMOVED ads excluded. Paused ads are included only if they actually served in the window (so per-ad numbers still roll up to ad-group totals without zero-row noise). **Parameters:** - customer_id: Optional (uses connected account if omitted) - lookback_days: 7, 30, 60, 90, 120 (default 30). Ignored when both start_date and end_date set. - start_date / end_date: YYYY-MM-DD (override lookback_days when both provided) - campaign_id: Optional — scope to one campaign - ad_group_id: Optional — scope to one ad group - limit: Max ads returned, cost-desc (default 100, max 500) **Execution time:** 1-3 seconds (1 GAQL query, then cached 5 min) **Use this tool when:** - User asks "which ad/creative is performing best?" or "which video is winning?" - User wants to pause losing creatives or scale winning ones (follow with pause_ad) - User needs per-ad CTR / CPA / ROAS / video view rate inside an ad group - After get_campaign_performance shows an ad group worth drilling into **Tip:** Pair with `get_ad_creative` to see WHAT each winning/losing ad is made of (videos, images, headlines).
policy
get_ad_policy_violations
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Read policy review/approval state for ads. Surfaces the exact reason an ad was disapproved or limited. **When to use:** - User says "my ad got disapproved, why?" - User says "my campaign isn't serving — is there a policy issue?" - Routine pre-launch check for newly created ads **Returns per ad:** - approval_status: APPROVED, APPROVED_LIMITED, DISAPPROVED, AREA_OF_INTEREST_ONLY, UNSPECIFIED - review_status: REVIEW_IN_PROGRESS, REVIEWED, UNDER_APPEAL, ELIGIBLE_MAY_SERVE - topic_entries: list of specific policy topics violated, each with: - topic: human-readable policy name (e.g. "Healthcare and medicines") - type: PROHIBITED, LIMITED, FULLY_LIMITED, DESCRIPTIVE, BROADENING, AREA_OF_INTEREST_ONLY - evidences: text snippets, URLs, language codes that triggered the flag - constraints: countries / certifications affected **Filters (provide at least one of ad_id / ad_group_id / campaign_id):** - ad_id: most precise; use when investigating one specific ad - ad_group_id: every ad in this ad group - campaign_id: every ad in this campaign - status_filter (default DISAPPROVED_OR_LIMITED): DISAPPROVED, LIMITED, DISAPPROVED_OR_LIMITED, or ALL **Limitations:** - Returns up to 500 ads per call - REMOVED ads are excluded - Asset-level violations (image disapprovals) are reported on the parent ad - New ads in REVIEW_IN_PROGRESS won't show topic_entries yet — wait for review **Example:** User: "Why isn't my ad serving in the lead-gen campaign?" Agent: 1. Calls list_campaigns to find campaign_id 2. Calls get_ad_policy_violations(campaign_id=X, status_filter='DISAPPROVED_OR_LIMITED') 3. If results: shows topic, type, and evidence for each — explains what to fix 4. If empty: "All ads are approved. The non-serving issue is elsewhere (budget, bidding, targeting)."
reach
get_reach_frequency
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Reach & frequency — how many UNIQUE users your campaigns reached, and the average number of times each person saw your ads. This tool retrieves READ-ONLY data via 1 live GAQL query (cached 5 min in Redis). Safe to call multiple times. **Why this tool:** `get_campaign_performance` reports impressions but not unique reach. This is the only tool that returns `unique_users` (de-duplicated people reached) and `average_impression_frequency_per_user` (the "Avg. impr. freq. / user" column in the Google Ads UI) — the direct signal for creative-fatigue and rotation decisions on YouTube / Demand Gen / Video campaigns, instead of proxying frequency from CPM/CTR trends. **Returns one row per campaign** (sorted by impressions): - `campaign_id`, `campaign_name`, `campaign_type`, `status` - `impressions`, `unique_users`, `avg_impression_frequency_per_user` **Google constraints (surfaced honestly, not bugs):** - Reach metrics are **campaign-level only** — Google REJECTS them at the ad-group level, so this tool cannot break reach down by ad group. - Reach is populated for reach-eligible campaign types (Demand Gen, Video/YouTube, Performance Max, Display). Search campaigns typically report 0 unique users. - Google reports unique reach only for a **trailing ~92-day window**; a longer window silently returns zeros, so the lookback is clamped to 92 days (the tool tells you when it clamped). - `unique_users` is de-duplicated over the window and is **NOT summed across campaigns** (the same person can be reached by more than one campaign). **These are the account's own measured numbers — the tool renders NO verdict and invents no "healthy frequency" threshold.** Whether a given frequency is too high depends on the campaign and goal; the tool reports the number and leaves the call to you. **Parameters:** - customer_id: Optional (uses connected account if omitted) - lookback_days: 7, 30, 60, 90 (clamped to ≤92). Ignored when both start_date and end_date set. - start_date / end_date: YYYY-MM-DD (override lookback_days when both provided; clamped to last 92 days) - campaign_id: Optional — scope to one campaign **Execution time:** 1-3 seconds (1 GAQL query, then cached 5 min) **Use this tool when:** - User asks "what's my reach / frequency?", "how many unique users did I reach?", "how often is each person seeing my ad?" - User is deciding whether to rotate/refresh creative on a YouTube or Demand Gen campaign (frequency is the fatigue signal) - User wants unique reach instead of raw impressions
remove
remove_ad
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Remove (soft-delete) an ad — sets status=REMOVED. ⚠️ **This is PERMANENT.** REMOVED ads cannot be re-enabled. To temporarily stop an ad, use pause_ad instead. Works on ads of any channel. **Required:** ad_group_id + ad_id.
replace
replace_demandgen_audiences
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Replace the grouped audience on a Demand Gen (or YouTube) ad group. Demand Gen uses a single grouped audience per ad group — you cannot add one more segment to a live ad group, so this REPLACES the whole audience (removes the old one and builds a new grouped audience from the segment IDs you pass). ⚠️ Use `search_audiences` FIRST to find real audience IDs — NEVER fabricate IDs (wrong IDs target unrelated audiences and waste budget). **Accepts:** in_market_audience_ids, affinity_audience_ids, custom_audience_ids, user_list_ids. **Required:** ad_group_id + at least one audience ID. Only works on Demand Gen ad groups.
research
research_keywords
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Research high-intent keywords using Google Keyword Planner API. ⚠️ IMPORTANT: This is a READ-ONLY tool. Safe to call multiple times. 🎯 **What This Tool Does:** - Researches keywords via Google Keyword Planner API - Returns keywords with real CPC data, search volume, and competition metrics - Groups keywords by commercial intent (HIGH/MEDIUM/LOW based on dynamic CPC thresholds) - Selects top 15-20 keywords optimized for conversions - Provides budget recommendations based on actual keyword costs **When to Use:** - BEFORE creating a Google Search campaign - When you need data-driven keyword insights - To understand keyword costs and search volume - To get budget recommendations **Parameters:** - business_description (required): What the business sells/offers - website_url (optional): Business website for better keyword suggestions - target_location (optional): Geographic target (default: "United States") - language (optional): 'de' / 'German' / '1001' — defaults to the language the account's campaigns target (auto-detected), falling back to English. For non-English seeds, location AND language should match (e.g. German seeds → target_location "Germany" + language auto/de). - seed_keywords (optional): 5-10 seed keywords (will auto-extract if not provided) - customer_id (optional): Google Ads account ID **Returns:** - Keyword table with dynamic CPC thresholds (adapts to any industry) - HIGH/MEDIUM/LOW intent grouping - Budget recommendations (Conservative/Moderate/Aggressive) - Top 15-20 recommended keywords for campaign **Execution time:** 3-8 seconds (calls live Google Ads API) 📊 **Example Usage:** 1. User: "I want to create a campaign for my plumbing business" 2. YOU call: research_keywords with business_description="Emergency plumbing services" 3. Tool returns: Keyword table with 100+ keywords, 20 recommended, budget suggestions 4. YOU show user: The keyword table and ask if they want modifications 5. User approves or requests changes 6. YOU call: create_search_campaign with approved keywords 💡 **Dynamic Thresholds:** This tool automatically adapts CPC thresholds to any industry: - Plumbing: HIGH ≥$6, MEDIUM $3-6, LOW <$3 - Legal: HIGH ≥$95, MEDIUM $45-95, LOW <$45 - E-commerce: HIGH ≥$2, MEDIUM $0.50-2, LOW <$0.50 All keywords returned will use **BROAD match** (Google's 2025 recommendation with Smart Bidding). --- 📊 **CRITICAL: AFTER calling this tool, YOU MUST explain these insights to the user:** **1. Keyword Discovery Summary:** - "I found [X] keywords from Google Keyword Planner for your [business type] business" - "I analyzed real search data and CPC costs from Google Ads" - "Here are the top 20 keywords I recommend based on commercial intent" **2. Seed Keywords Used:** - "I used these seed keywords: [list the seeds from the response]" - "Google expanded these into [X] keyword suggestions" **3. CPC Cost Analysis (CRITICAL - Discuss this with user!):** - "The median CPC for your industry is $[X]" - "Keywords range from $[LOW] to $[HIGH] per click" - "HIGH intent keywords (top 25% most expensive) cost $[threshold]+ per click" - "These are keywords where advertisers pay more = higher commercial value" **4. Budget Recommendations (CRITICAL - Explain all 3 tiers!):** - "Based on the keyword costs, here are my budget recommendations:" - "💰 Conservative ($[X]/day): Safe starting budget based on median CPC, expect ~[Y] clicks/day" - "💰 Moderate ($[X]/day): Balanced budget based on average CPC, expect ~[Y] clicks/day" - "💰 Aggressive ($[X]/day): Maximum budget to compete for all keywords, expect ~[Y] clicks/day" - "I recommend starting with $[conservative]-[moderate]/day" **5. Keyword Selection Explanation:** - "I selected these 20 keywords by prioritizing:" - " • HIGH intent keywords (expensive = high commercial value)" - " • High search volume (more potential customers)" - " • Mix of broad and specific terms" - "All keywords will use BROAD match - Google's 2025 recommendation for maximum reach with Smart Bidding" **6. Ask for User Feedback:** - "Would you like to modify this keyword selection?" - "Options: Add specific keywords, remove keywords, use only HIGH intent, or proceed with recommendations" **DO NOT just show the raw table without explanation!** **Users need YOU to interpret the data and provide strategic guidance!**
resolve
resolve_google_locations
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Resolve free-text location queries (country, state/province, city, district, postal code) into Google's exact `geoTargetConstants/<id>` resource names. **WHEN TO USE:** Call this tool BEFORE `create_display_campaign`, `create_search_campaign`, `create_pmax_campaign`, or `create_demandgen_campaign` whenever the user requests targeting by location. This gets you the precise geoTargetConstants/<id> values the Google Ads API accepts — eliminating ambiguity (e.g., "London" could be London UK, Londonderry, or London Ontario). **INPUT:** JSON array of free-text queries, optional locale + country_code filter. **OUTPUT:** For each query, up to N candidate geoTargetConstants with canonical_name, target_type (Country/State/City/District/etc.), country_code, reach estimate. The AI client picks the right ID and passes it to the campaign-creation tool. **WORKFLOW EXAMPLE:** 1. User says "target London and California" 2. Call `resolve_google_locations` with `queries: ["London","California"]` 3. Disambiguate with the user if multiple candidates exist (e.g., London UK vs London Ontario) 4. Pass chosen resource names (e.g., `["geoTargetConstants/1006886","geoTargetConstants/21137"]`) as `target_locations` to the campaign-creation tool. Display campaign creation accepts BOTH formats (free-text OR resource names / bare IDs) but the API is most reliable with pre-resolved IDs. **Execution time:** 1-3 seconds. Redis-cached 5 minutes.
save
save_business_profile
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Save or update the user's business profile with provided details. ⚠️ IMPORTANT: This tool WRITES data. Use when user confirms their business profile. 🎯 **What This Tool Does (Performance Agent - Phase 1 Feature 5):** - Saves user's business profile to database - Updates existing profile if one exists - Sets profile source as 'user_confirmed' or 'user_mcp' - Enables personalized recommendations going forward **Required Parameters:** - **business_vertical**: retail, services, technology, healthcare, finance, education, travel, food_beverage, automotive, real_estate - **business_size**: small (<$50K/month), medium ($50K-$500K/month), large (>$500K/month) - **primary_goal**: leads, sales, awareness, traffic, engagement, app_installs **Optional Parameters:** - **target_audience**: Free-text description (e.g., "B2B enterprise clients") - **geographic_focus**: local, regional, national, international - **seasonality**: none, holiday_heavy, summer_peak, winter_peak, q4_heavy, back_to_school - **customer_id**: Optional (uses connected account if omitted) **Use this tool when:** - User provides their business details - User confirms an inferred profile - User wants to update their business profile - After asking user clarifying questions about their business **Example Usage:** User: "I run a small local plumbing business targeting homeowners" → Call save_business_profile with: - business_vertical: "services" - business_size: "small" - primary_goal: "leads" - target_audience: "homeowners" - geographic_focus: "local" **Execution time:** 1-2 seconds (database write)
start
start_here
Show the user where to start and what to try next with Adspirer — a visual 'first wins' guide personalized to their connected platforms, real account data, and what they've already done. **Call this when:** - A user has just connected Adspirer (first session, few or no tool calls yet) - The user asks "what can you do?", "where do I start?", "what should I try?", or anything about Adspirer's capabilities - The user seems unsure what to do next Free — never counts against the user's quota. Renders an interactive getting-started card; the text fallback lists the same steps.
suggest
suggest_ad_content
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Generate AI-suggested headlines and descriptions based on campaign keywords. Analyzes campaign keywords and generates optimized ad content following creative guidelines: - 15 headlines across 3 categories (What It Is, Benefits, Pain/Proof/CTA) - 4 descriptions with value props and CTAs - All validated for character limits **Parameters:** - campaign_id: The campaign to analyze (REQUIRED) - business_description: Optional context about the business - key_benefits: Optional list of benefits (e.g., ["fast setup", "no dashboard"]) - proof_points: Optional proof points (e.g., [{"number": "2000+", "metric": "campaigns"}]) - pain_points: Optional pain points (e.g., ["manual ads", "complex UI"]) - customer_id: Optional **Returns:** - suggested_headlines: 15 headlines ready to use - suggested_descriptions: 4 descriptions ready to use - headline_categories: Headlines organized by category - keyword_themes: Top themes from campaign keywords **Use this when:** - User wants fresh ad copy ideas - User asks "what should my headlines be?" - Starting a new A/B test - Refreshing stale ad content **Execution time:** 3-5 seconds **Example:** User: "Suggest some better headlines for my campaign" Agent: 1. Uses suggest_ad_content to generate ideas 2. Shows suggestions organized by category 3. User picks favorites 4. Uses update_ad_headlines to apply selected headlines
switch
switch_primary_account
Activate ad accounts for a platform. Two modes: 1. `account_id` (singular) — ADDS this account to the active set. Other already-active accounts stay active. Safe to call multiple times to activate accounts one by one. 2. `account_ids` (plural, list) — REPLACES the full active set with this exact list. Any account NOT in the list becomes inactive. Use this only when the user explicitly wants to set a specific group of accounts as the complete active set (e.g., "only use accounts A, B, C"). Use this tool when: - User wants to activate a different ad account (use account_id — singular) - User wants to activate multiple specific accounts (use account_ids — plural) - User says "also use my other account" (use account_id — additive) - User says "only use accounts X, Y" (use account_ids — replace) Get account IDs from get_connections_status. IMPORTANT: Returns updated connections list after activation.
tiktok
tiktok_ads
Access all TikTok Ads campaign management tools. **Required first step:** call this tool with `action: "list_tools"` (optionally add the FULL `intent` — the user's COMPLETE request verbatim, not a summary — it helps us improve tool discovery). Then call again with `action: "execute"`, a specific `tool_name` from that list, and `arguments`. Calling `action: "execute"` without `tool_name` is INVALID and will return an error — do not retry the same broken call (issue #297 Bug G). **Available capabilities:** - **Campaign Performance**: Analyze metrics, wasted spend, budget optimization, creative fatigue, audience and geo insights, anomaly detection - **Asset Discovery**: List the advertiser's existing ad videos (with the `video_id` needed to reuse one in a new ad) via `list_tiktok_ad_videos` - **Conversion Setup**: List TikTok Pixels and the exact optimization events each supports via `list_tiktok_pixels` — call this before creating any conversion (`WEB_CONVERSIONS`) campaign to get the NUMERIC pixel_id and a valid optimization_event - **Asset Validation**: Validate and prepare images/videos for TikTok ad specs - **Campaign Creation**: Create video-based TikTok ad campaigns, plus ad groups and ads - **Campaign Management**: List campaigns/ad groups/ads, update settings and budgets, pause/resume, and delete campaigns/ad groups/ads - **Targeting**: Search TikTok targeting options **⚠️ Side effects & confirmation:** Write operations change a live TikTok Ads account. New campaigns are created **PAUSED** and must be explicitly confirmed by the user before launch. Budget and status changes (pause/resume) take effect immediately and can disrupt ad delivery. Deleting a campaign, ad group, or ad is irreversible. **When to use this tool:** - "Create a new TikTok ad campaign" - "Show me my existing TikTok assets" - "Create a TikTok video campaign" - "Validate my images for TikTok ads" - "How are my TikTok campaigns performing?" **Raw data mode (performance tools only):** If the user asks for "raw data", "raw metrics", "just the numbers", "no recommendations", or "no commentary" — pass `raw_data: true` inside `arguments` when calling any performance tool (`get_tiktok_campaign_performance`, `get_tiktok_ad_performance`, `analyze_tiktok_wasted_spend`, `optimize_tiktok_budget`, `detect_tiktok_creative_fatigue`, `explain_tiktok_anomaly`, `get_tiktok_audience_insights`, `analyze_tiktok_geo_performance`). You receive a JSON code block of metrics only: spend, clicks, impressions, conversions, CPA, CPC, CTR, CVR, ROAS, hook rate, video completion rate, engagement rate by campaign/ad/date. Severity labels, suggested bids, suggested budgets, industry benchmarks, and optimization recommendations are stripped. Default is `false` (full formatted analysis). **Example — list tools:** action: "list_tools" **Example — create campaign:** action: "execute" tool_name: "create_tiktok_video_campaign" arguments: {"campaign_name": "Summer Sale", "objective": "CONVERSIONS", "video_url": "https://example.com/ad.mp4"} **Example — raw performance (user asked for raw data):** action: "execute" tool_name: "get_tiktok_campaign_performance" arguments: {"lookback_days": 30, "raw_data": true}
tool
get_tool_schema
Get the exact, authoritative signature (name, parameters, types, required fields, allowed values) for one or more tools by name. Call this after `search_tools` and BEFORE calling a tool, so you send correct arguments and never guess. ALWAYS pass `intent` — the user's COMPLETE request verbatim (word-for-word, not a summary or paraphrase) — every time you call this. It is how we learn which tool is the right answer for a request, so it directly improves tool discovery; do not omit it. The schema returned is the live tool definition — always current. This is a TOP-LEVEL tool like `search_tools`: call it DIRECTLY by name, e.g. get_tool_schema({"tool_names": ["pause_meta_campaign"], "intent": "pause my summer sale campaign on Facebook"}). Do NOT route it through a platform tool and do NOT wrap it in action="execute" — it is not platform-specific.
tools
search_tools
Find the right Adspirer tool(s) for a task by describing what you want to do in natural language. Returns the best-matching tool names with a one-line summary — then call `get_tool_schema` with a name to get its exact parameters before calling it. Use this instead of guessing tool names. Optionally filter by `platform` (google-ads, meta-ads, tiktok-ads, linkedin-ads, amazon-ads, chatgpt-ads).
unlink
unlink_merchant_center
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Remove a Merchant Center link from this Google Ads account. Detaches the Merchant Center account; Shopping campaigns relying on it will stop serving. The Merchant Center account itself is not deleted. Get the merchant_center_id from get_merchant_center_links. **Required:** merchant_center_id.
usage
get_usage_status
Get your current usage status with interactive quota widget. This tool shows your tool call usage for the current billing period and provides upgrade options if needed. For annual subscribers it shows the pooled yearly allowance ("X / 1,800 used this year"), the annual reset date, and confirms there is no monthly cap. **Returns:** - Current usage (calls used / limit) — monthly limit or annual pool - Subscription tier (Free, Plus, Pro, Enterprise) and billing period (monthly / annual) - When the quota or annual pool resets - Upgrade options with pricing **Use this tool when:** - User asks "how many calls do I have left?" - User asks about their subscription or quota - User wants to check their usage - User asks about upgrading their plan **Interactive widget:** On hosts that support interactive tool widgets, this tool renders a usage card with: - Visual progress bar showing usage - Upgrade buttons that open Stripe checkout - Plan comparison with pricing **Note:** This tool is READ-ONLY and safe to call anytime.
youtube
create_youtube_campaign
🚨 **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link 🔄 LONG-RUNNING TOOL: Creates a YouTube Video campaign using Google Ads Demand Gen format with YouTube-only placements. Emits MCP progress updates during authentication and campaign creation (typically 10-20 seconds). Progress stages: validate → commit. ⚠️ CRITICAL WARNING ⚠️ - Call this tool ONLY ONCE per campaign - Creates REAL campaigns that cost REAL money - Do NOT retry automatically if errors occur - Report errors to user instead of retrying ⚠️ CRITICAL PREREQUISITE: - MUST validate the YouTube video first using validate_video tool - Video must be public or unlisted on YouTube (NOT private) 🎬 **YouTube Campaign Placements:** ✅ YouTube In-Feed (appears in search results & related videos) ✅ YouTube In-Stream (plays before/during/after videos) ✅ YouTube Shorts (appears in Shorts feed) ❌ Gmail (disabled for YouTube campaigns) ❌ Discover (disabled for YouTube campaigns) ❌ Display (disabled for YouTube campaigns) 📋 **YOUR CRITICAL ROLE: Campaign Strategist & Text Creator** **STEP 1: Validate Video First** Before calling this tool: 1. Get user's YouTube video URL or ID 2. Call validate_video tool with platform="pmax" to verify it 3. Confirm video is accessible (public or unlisted) 🔴 **STEP 1.5: MANDATORY — Discover Existing Assets** BEFORE proceeding, you MUST call discover_existing_assets to check for existing image/logo assets: 1. Call: discover_existing_assets(asset_types=["image", "logo"], target_domain="<user's domain>") 2. Present findings to the user: - Show all available logos and images with dimensions - Show count of assets found per type 3. Ask the user: "I found [N] existing assets in your account. Would you like to: A) Reuse an existing logo (saves time, consistent branding) B) Upload a new logo image C) Upload a new logo from URL" 4. Based on answer: - Reuse → Use logo_asset_id from discovered assets - Upload new → Use validate_and_prepare_assets with logos_square → asset_bundle_id 5. 🚫 NEVER skip this step — even if the user didn't mention assets **STEP 2: Collect Campaign Details from User** YOU MUST collect these from the user (ask if not provided): **REQUIRED Fields:** 1. **Campaign Name** - Descriptive and unique 2. **Daily Budget** - Minimum $15/day (recommended $50+) 3. **YouTube Video ID** - 11-character video ID (validated in Step 1) 4. **Final URL** - Landing page (must match verified domain) 5. **Business Name** - Max 25 characters **STEP 3: Generate High-Quality Ad Copy** **🚨 BEFORE GENERATING TEXT - READ CHARACTER LIMITS 🚨** **Headlines (1-5 required):** - **STRICT LIMIT: 40 characters maximum per headline** - Count characters BEFORE calling this tool! - Examples: - "Shop Premium Watches Today" (26 chars) ✅ - "Free Worldwide Shipping Now" (27 chars) ✅ **Descriptions (1-5 required):** - **STRICT LIMIT: 90 characters maximum per description** - Count characters BEFORE calling this tool! - Examples: - "Shop authentic luxury timepieces with expert curation and free worldwide shipping." (82 chars) ✅ **Long Headlines (optional, 1-5):** - **STRICT LIMIT: 90 characters maximum per long headline** - Falls back to regular headlines if not provided **⚠️ WILL BE REJECTED IF YOU EXCEED LIMITS - NO RETRIES!** **LOGO (REQUIRED - one of two options):** - **Option A** (existing logo): logo_asset_id from discover_existing_assets — use this if the account already has logo images - **Option B** (new upload): asset_bundle_id from validate_and_prepare_assets — use this if the account has NO existing logos (e.g., Search-only accounts) **Workflow:** 1. First try discover_existing_assets to find existing logos 2. If logos found → use logo_asset_id 3. If NO logos found → ask user for a logo image URL, run validate_and_prepare_assets with logos_square, then use the returned asset_bundle_id **OPTIONAL Fields (use defaults if not provided):** - call_to_action: Default "LEARN_MORE". Options: SHOP_NOW, SIGN_UP, SUBSCRIBE, DOWNLOAD, BOOK_NOW, CONTACT_US, GET_QUOTE, APPLY_NOW, WATCH_NOW, ORDER_NOW, BUY_NOW, SEE_MORE, START_NOW, VISIT_SITE, REGISTER - target_locations: Defaults to ["United States"] - target_languages: Defaults to ["en"] - additional_video_ids: Up to 4 more videos (5 total max) - bidding_strategy: MAXIMIZE_CLICKS (default), MAXIMIZE_CONVERSIONS (needs conversion tracking), TARGET_CPA - target_cpa: Required only for TARGET_CPA bidding **STEP 4: Call create_youtube_campaign** After you have ALL details: - Validate character counts yourself BEFORE calling - Call create_youtube_campaign with complete payload - Wait for response (may take 10-20 seconds) **STEP 5: Handle Response** **If SUCCESS:** - Show campaign ID, name, budget, status - Explain YouTube-only placements (In-Feed, In-Stream, Shorts) - Explain campaign starts PAUSED for safety - Provide next steps (review, activate, monitor) **If FAILURE:** - Show error message clearly - Do NOT retry automatically - Guide user to fix the issue **Example Conversation Flow:** User: "I want to run YouTube ads for my product" You: "I'd be happy to help create a YouTube video campaign! First, can you share your YouTube video URL so I can validate it?" [User provides: https://youtu.be/eIZtladpm6c] [Call validate_video with video_url_or_id="eIZtladpm6c", platform="pmax"] You: "Your video is validated and ready! Now I need a few details: 1. Campaign name? 2. Daily budget? (minimum $15, recommended $50+) 3. Landing page URL? 4. Business name? I'll create compelling headlines and descriptions for your YouTube ads." [User provides details] [Call create_youtube_campaign with all details] **Video Specifications:** - Must be on YouTube (public or unlisted, NOT private) - Minimum 10 seconds duration recommended - Maximum 5 videos per campaign (1 primary + 4 additional) - Validated via validate_video tool before campaign creation **Bidding Options:** - MAXIMIZE_CLICKS: Best for most campaigns (default, works without conversion tracking) - MAXIMIZE_CONVERSIONS: Best when conversion tracking is set up on the account - TARGET_CPA: Best when you know your target cost per acquisition (requires conversion tracking) **Campaign Creation Best Practices:** 1. Always validate video first with validate_video tool 2. 🔴 MANDATORY: Run discover_existing_assets to find logos/images — present results to user, ask if they want to reuse or upload new 3. If reuse → use logo_asset_id; if upload new → validate_and_prepare_assets → asset_bundle_id 4. Confirm budget with user ($15/day minimum) 5. Create compelling, benefit-focused ad copy 6. Campaign starts PAUSED - explain this to user 7. This costs real money - be transparent 8. 🔴 AFTER campaign creation: Add extensions (sitelinks, callouts, structured snippets) — see STEP 6 below **STEP 6: MANDATORY — Add Extensions After Creation** After the campaign is successfully created, you MUST: 1. Crawl the user's website to gather relevant page links, features, and service categories 2. Add sitelinks: at least 4 links to key pages (add_sitelinks tool) 3. Add callout extensions: 4-6 business highlights (add_callout_extensions tool) 4. Add structured snippets: categorized features (add_structured_snippets tool) 5. Verify with list_campaign_extensions to confirm all extensions are attached Extensions are FREE and increase ad visibility by 15-25%. NEVER skip this step. **Execution Time:** 10-20 seconds (direct backend API call) **Authentication:** Required (MCP OAuth 2.1) **CRITICAL REMINDERS:** - Campaign starts PAUSED for user safety - This costs real money - be transparent with user - Never retry on failure - report error to user - Always validate video BEFORE creating campaign

Endpoints

URLTransportStateLatencyChecked
https://mcp.adspirer.com/mcp streamable-http needs key 382 ms 11 min ago

Alternatives to Ads

same job, measured the same way
Synter Ads
by jshorwitz

Manage ad campaigns across Google, Meta, LinkedIn, Reddit, TikTok, and more via AI.

73 installs/wk 209 tools answering
Synter Ads
by synter-media-ai

Manage ad campaigns across Google, Meta, LinkedIn, Reddit, TikTok, and more via AI.

209 tools answering
Ads MCP
by adkit

Create, launch & analyze ad campaigns, spy on competitors - Google, Meta, TikTok, LinkedIn & more.

answering
Adako: ad ops for AI assistants
by adako

Google, Meta, ChatGPT, TikTok and LinkedIn Ads for AI assistants. Every change needs your approval.

answering
PaidSync.ai
by paidsync

Run ads on Google, Meta, LinkedIn, TikTok and more from AI. 460+ tools across 14 platforms.

answering
Ainative Gtm MCP
by ainative-studio

Full Google Ads, Analytics & Tag Manager lifecycle MCP for AI agents — 57 tools.

105 installs/wk local only
Adside
by adside

AI agents that manage paid ads on Meta, LinkedIn, and Google Ads from any MCP client.

answering
LoomaScale Ads
by loomascale

Run Google Ads and Meta Ads from ChatGPT or Claude: audit wasted spend, create and manage campaigns.

answering

Ads — questions

Answers built from our own checks of this server.

What can Ads do?
It exposes 234 tools, read directly from the server on our last check. Among them: add_ad_group_audiences, add_app_ad_asset, add_asset_group_listing_filter, add_business_name_asset, add_call_asset, add_callout_extensions and 228 more. The full list with descriptions is on this page — we take it from the server itself via tools/list, not from a README. How MCP servers expose tools in the first place →
What is Ads mostly used for?
Its tools cluster around meta, display and pmax. That is what this server is built to work with — the grouping comes from the actual tool names, not from a category we assigned.
Is Ads working right now?
We send a real MCP handshake every 15 minutes. Over the last 24 hours 91 of 91 checks got a reply (100.0%), average response time 340 ms. The bar chart above shows every period we have measured.
How do I connect Ads?
Copy the ready config from this page — we generate it for Claude Code, Claude Desktop, Codex, Cursor and VS Code, each with the file path that client actually reads. It is a remote server, so there is nothing to install — the client connects to the address. You will need your own key: it refuses anonymous clients.
Does Ads need an API key?
Yes. Every time we knock, Ads answers with an authorization challenge instead of its tool list — that is how we know it is running and gated rather than broken. Bring your own credentials and it will talk.
How fast is Ads?
It answers our handshake in 340 ms on average, which is faster than 45% of all working MCP servers we measure. The comparison comes from our own checks across the whole registry, every 15 minutes.
Is Ads open source?
Yes — it is published under the MIT licence, written in Jupyter Notebook, 93 stars on GitHub and 7 open issues. The source link is on this page, so you can read exactly what it does with your data before you connect it.