Skip to main content
Glama
kLOsk

Google Ads - AdLoop

by kLOsk

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault

No arguments

Capabilities

Features and capabilities supported by this server

CapabilityDetails
tools
{
  "listChanged": true
}
logging
{}
prompts
{
  "listChanged": false
}
resources
{
  "subscribe": false,
  "listChanged": false
}
extensions
{
  "io.modelcontextprotocol/ui": {}
}
experimental
{}

Tools

Functions exposed to the LLM to take actions

NameDescription
health_checkA

Test AdLoop connectivity — checks OAuth token, GA4 API, and Google Ads API.

Run this first if other tools are failing. Returns status for each service and actionable guidance if something is broken.

get_account_summaries

List all GA4 accounts and properties accessible by the authenticated user.

Use this as the first step to discover which GA4 properties are available. Returns account names, property names, and property IDs.

run_ga4_reportA

Run a custom GA4 report with specified dimensions, metrics, and date range.

Common dimensions: date, pagePath, sessionSource, sessionMedium, country, deviceCategory, eventName Common metrics: sessions, totalUsers, newUsers, screenPageViews, conversions, eventCount, bounceRate

Date formats: "today", "yesterday", "7daysAgo", "28daysAgo", "90daysAgo", or "YYYY-MM-DD". If property_id is empty, uses the default from config.

run_realtime_report

Run a GA4 realtime report showing current active users and events.

Useful for checking if tracking is firing correctly after code changes. Common dimensions: unifiedScreenName, eventName, country, deviceCategory Common metrics: activeUsers, eventCount

get_tracking_events

List all GA4 events and their volume for the given date range.

Returns every distinct event name with its total event count. Use this to understand what tracking is configured and active.

list_gsc_sitesA

List all Google Search Console properties the authenticated user can access.

Use this first to discover which site URLs are available before running search analytics reports. Returns the site URL and permission level for each property.

run_gsc_reportA

Run a Google Search Console search analytics report.

Returns clicks, impressions, CTR, and average position broken down by the requested dimensions. Useful for diagnosing organic traffic drops, finding keyword opportunities, and cross-referencing with GA4 and Ads data.

site_url: the GSC property URL (e.g. "https://example.com/" or "sc-domain:example.com"). Defaults to gsc.site_url in config.yaml. dimensions: one or more of ["query", "page", "country", "device", "date"]. Defaults to ["query"]. date_range_start / date_range_end: ISO dates (YYYY-MM-DD) or relative values like "7daysAgo", "30daysAgo", "today". search_type: "web" (default), "image", "video", "news", "discover", or "googleNews". dimension_filter_groups: optional GSC DimensionFilterGroup list to filter by query, page, country, or device. Example: [{"filters": [{"dimension": "query", "operator": "contains", "expression": "analytics"}]}] limit: maximum rows to return (default 100, max 25000).

analyze_page_speed

Run PageSpeed Insights for a landing page — Lighthouse + real-user data.

Returns the performance score (0-100), lab Core Web Vitals (LCP, CLS, TBT, FCP), CrUX field data from real Chrome users where available (p75 LCP/INP/CLS + FAST/AVERAGE/SLOW ratings), and the top improvement opportunities with estimated savings.

Use on ad final_urls: slow landing pages depress Quality Score and waste paid clicks. strategy: "mobile" (default — most paid traffic) or "desktop". Takes 10-30s; that is normal for a Lighthouse run.

list_merchant_accountsA

List Google Merchant Center accounts the connected user can access.

Call first to discover merchant IDs for get_merchant_feed_health. Distinguishes standalone accounts from aggregator (MCA) accounts.

get_merchant_feed_healthA

Merchant Center feed health — disapproved products + account issues.

Disapproved feed items silently starve Shopping and Performance Max campaigns; this surfaces approved/pending/disapproved counts per reporting context (Shopping ads, free listings, ...), the top product issues by affected products (with documentation links), and account-level issues — CRITICAL ones stop offers serving entirely.

account_id: numeric Merchant Center ID from list_merchant_accounts. Product-status data lags reality by ~30 minutes.

list_accountsA

List accessible Google Ads accounts.

Returns account names, IDs, and status. The default cap of 200 covers the vast majority of agency MCCs in one call. If the user explicitly asked to see ALL of their accounts and the response comes back with 'truncated: true', call this tool again with a much higher limit (e.g. list_accounts(limit=1000)) — do not stop at the truncated list. For workflows that target a specific account you don't need to enumerate at all: pass customer_id directly to get_campaign_performance, run_gaql, etc.

get_campaign_performance

Get campaign-level performance metrics for a date range.

Returns: campaign name, status, type, impressions, clicks, cost, conversions, CPA, ROAS, CTR for each campaign. Date format: "YYYY-MM-DD". Empty = last 30 days.

Set compact=true for audits/overviews on large accounts: returns account totals, status/type breakdowns, the top-10 spenders, and zero-conversion offenders instead of every row (~90% smaller).

get_ad_performanceB

Get ad-level performance data including headlines, descriptions, and metrics.

Returns: ad type, headlines, descriptions, final URL, impressions, clicks, CTR, conversions, cost for each ad.

Set compact=true for audits/overviews: returns totals, the top-10 ads with headline/description COUNTS instead of full asset lists, plus incomplete-RSA and single-ad ad-group findings (~90% smaller).

get_keyword_performance

Get keyword metrics including quality scores and competitive data.

Returns: keyword text, match type, quality score, impressions, clicks, CTR, CPC, conversions for each keyword.

Set compact=true for audits/overviews: returns totals, match-type distribution, the top-10 spenders, low-quality-score keywords, and zero-conversion spenders instead of every row (~90% smaller).

get_search_terms

Get search terms report — what users actually typed before clicking your ads.

Critical for finding negative keyword opportunities and understanding user intent. Returns: search term, campaign, ad group, impressions, clicks, conversions.

Set compact=true for audits/overviews: returns totals, the top-10 terms by clicks, ready-made negative-keyword waste candidates (5+ clicks, zero conversions), and top converters (~90% smaller).

get_negative_keywordsA

List existing negative keywords for a campaign or all campaigns.

Use this before adding negative keywords to check for duplicates. If campaign_id is empty, returns negatives across all campaigns.

get_negative_keyword_listsA

List all shared negative keyword lists (SharedSets) in the account.

Returns each list's ID, name, status, and keyword count. Always call this before propose_negative_keyword_list to avoid creating duplicates — a suitable list may already exist and just need attaching to a campaign.

get_negative_keyword_list_keywordsA

List the keywords inside a shared negative keyword list.

shared_set_id: numeric ID from get_negative_keyword_lists (shared_set.id).

get_negative_keyword_list_campaigns

List which campaigns a shared negative keyword list is attached to.

shared_set_id: numeric ID from get_negative_keyword_lists. Omit to see all list-to-campaign attachments across the account.

get_recommendations

Retrieve Google's auto-generated recommendations with estimated impact.

Returns each recommendation's type, associated campaign/ad group, current (base) and projected (potential) metrics, and the estimated improvement.

recommendation_types: optional filter — e.g. ["KEYWORD", "TARGET_CPA_OPT_IN", "MAXIMIZE_CONVERSIONS_OPT_IN", "RESPONSIVE_SEARCH_AD"]. Empty = all types. campaign_id: optional — scope to a single campaign.

Includes insights that flag budget-increase recommendations (often self-serving) and highlight high-impact suggestions worth investigating.

get_pmax_performance

Get Performance Max campaign and asset group performance.

Returns two result sets:

  • campaigns: PMax campaign metrics broken down by ad_network_type (SEARCH, CONTENT, YOUTUBE_SEARCH, YOUTUBE_WATCH, MIXED). Note: MIXED is a catch-all that Google uses for most PMax traffic — full channel splits are not available via the API.

  • asset_groups: per-asset-group metrics including ad_strength (EXCELLENT, GOOD, AVERAGE, POOR).

Includes insights flagging weak ad strength, zero-conversion asset groups, and network type distribution. Date format: "YYYY-MM-DD". Empty = last 30 days.

get_asset_performanceA

Get per-asset details for Performance Max campaigns.

Returns each asset's field_type (HEADLINE, DESCRIPTION, MARKETING_IMAGE, YOUTUBE_VIDEO, etc.), primary_status (ELIGIBLE, NOT_ELIGIBLE, PAUSED, PENDING), and content (text or image URL).

Note: per-asset performance labels (BEST/GOOD/LOW) are not available for PMax assets in the Google Ads API. Use get_detailed_asset_performance to see which asset combinations Google selects most — the closest proxy for individual asset quality.

campaign_id: optional filter to a single PMax campaign. Includes by_status and by_field_type summaries.

get_detailed_asset_performanceA

Get top-performing asset combinations for Performance Max campaigns.

Shows which headline + description + image combinations Google selects most often. Each combination lists the assets used and their field types. This data helps identify which creative elements work well together.

campaign_id: optional filter to a single PMax campaign.

get_audience_performance

Get audience segment performance metrics.

Returns performance by audience type — remarketing lists (USER_LIST), in-market segments (USER_INTEREST), affinity, demographics (AGE_RANGE, GENDER), etc. Shows display_name, impressions, clicks, cost, conversions, CTR, and CPC for each audience.

Works for campaigns with explicit audience targeting (Search, Display). PMax audience targeting is automatic and may not appear in this report. campaign_id: optional filter to a single campaign. Date format: "YYYY-MM-DD". Empty = last 30 days.

get_demographic_targetingA

List demographic targeting criteria (age, gender, parental status, income).

Provide exactly one of ad_group_id or campaign_id. Returns each criterion's value, whether it's negative (excluded) or positive (narrowing), status, and a remove_id (composite resource ID) that can be passed directly to remove_entity with entity_type='ad_group_criterion' or 'campaign_criterion'.

By default, Google Ads serves ads to ALL demographic segments — a criterion only appears here once you've actively excluded or narrowed.

analyze_campaign_conversionsA

Campaign clicks → GA4 conversions mapping — the real cost-per-conversion.

Combines Google Ads campaign metrics with GA4 session/conversion data to reveal click-to-session ratios (GDPR indicator), compare Ads-reported vs GA4-reported conversions, and compute cost-per-GA4-conversion.

Also returns non-paid channel conversion rates for comparison context. Date format: "YYYY-MM-DD". Empty = last 30 days.

landing_page_analysisB

Analyze which landing pages convert and which don't.

Combines ad final URLs with GA4 page-level data to show paid traffic sessions, conversion rates, bounce rates, and engagement per landing page. Identifies pages that get ad clicks but zero conversions and orphaned URLs. Date format: "YYYY-MM-DD". Empty = last 30 days.

attribution_checkA

Compare Ads-reported conversions vs GA4 — find tracking discrepancies.

Checks whether conversions reported by Google Ads match what GA4 records, diagnoses GDPR consent gaps, attribution model differences, and missing conversion event configuration.

conversion_events: optional list of GA4 event names to specifically check (e.g. ["sign_up", "purchase"]). If omitted, compares aggregate totals only. Date format: "YYYY-MM-DD". Empty = last 30 days.

audit_event_coverage

Three-way audit: codebase events ↔ GTM tags ↔ GA4 actual fires.

First, search the user's codebase for gtag('event', ...) and dataLayer.push({event: ...}) calls and extract every distinct event name. Pass that list as expected_events. The tool fetches the LIVE GTM container, joins it against GA4 event counts for the date range, and returns a per-event matrix with one of these statuses: ok — tag active and event firing ok_auto_collected — GA4 Enhanced Measurement event, no tag needed no_tag_no_fire — codebase event, no GTM tag, never fires tag_paused — GTM tag exists but is paused tag_active_but_not_firing — tag is active but no GA4 hits gtm_only_firing — GA4 event from a tag, not in codebase gtm_paused_but_firing — only paused tag(s), not in codebase, yet GA4 still fires (event comes from elsewhere) gtm_only_not_firing — tag exists, not in codebase, no fires ga4_only — fires in GA4, no tag, no codebase ref ga4_fires_no_tag — codebase event firing without a GTM tag auto_event_only — Enhanced Measurement event with no codebase ref

Also surfaces dynamic-event tags ({{Event}} variables) and Custom HTML tags that the audit cannot interpret automatically.

GTM IDs come from Tag Manager UI → Admin → Container Settings. Date format: "YYYY-MM-DD". Empty = last 30 days.

list_gtm_accounts

List all GTM accounts the AdLoop service account / OAuth user can read.

Use this for first-time discovery before calling audit_event_coverage — you need the account_id from here. If this returns an empty list, the service account hasn't been added to any GTM container with at least Read permission.

list_gtm_containersA

List all containers under a GTM account.

Returns container_id (the numeric ID needed by audit_event_coverage), public_id (the GTM-XXXXXXX string shown in the UI), name, and usage context (web / iOS / Android / amp / server).

list_gtm_tagsA

List every tag in the LIVE GTM container.

Each tag includes type, status, parsed parameters, the GA4 event name (for GA4 event tags), and resolved firing/blocking trigger names. Use after audit_event_coverage to inspect specific tags.

get_gtm_tagA

Get the full RAW configuration for a single GTM tag.

Includes every parameter, firing/blocking triggers (with their filter conditions resolved to text), priority, pause status, sampling, and monitoring metadata. Use to inspect a tag flagged by audit_event_coverage.

list_gtm_triggersA

List every trigger in the LIVE GTM container.

Each trigger has its filter conditions parsed to readable text (e.g. "{{Page Path}} matches RegExp ^/service-promotions/"). Use to diagnose why a tag fires or doesn't fire on specific pages.

get_gtm_triggerA

Get the full RAW configuration for a single GTM trigger.

Includes filters, auto-event filters, custom-event filters, validation settings, and a list of every tag that uses this trigger. Use to diagnose why a tag with a specific trigger ID does or doesn't fire.

list_gtm_variablesA

List GTM variables — both custom and enabled built-in.

Custom variables come from the live container. Built-in variables (Page URL, Click Element, Form ID, etc.) come from the workspace's enabled-built-ins list. Variables matter because triggers reference them — if a trigger uses {{Form ID}} but Form ID isn't enabled, the trigger never matches.

list_gtm_workspaces

List workspaces (drafts) under a GTM container.

Workspace IDs are needed for get_gtm_workspace_diff. Most containers have a single Default Workspace; multiple workspaces appear when the team uses parallel drafts.

get_gtm_workspace_diff

Show drafted-but-not-published changes in a GTM workspace.

Returns the list of entities (tags, triggers, variables) added, modified, or deleted relative to the live published version, plus any merge conflicts. Common cause of "I edited a tag but nothing happened" — the workspace was never published. is_clean=true means no pending changes and no conflicts.

list_gtm_versionsA

List published GTM version history (newest first).

Version headers include version_id, name, and entity counts. Use to correlate a metric drop with a recent publish: fetch versions, find one with timestamps near the drop date, then call get_gtm_version for full content + author info.

get_gtm_version

Get full metadata + entity counts for a single GTM container version.

Returns name, description, fingerprint, and lists of tag/trigger/ variable names at that point in time. Use after list_gtm_versions when correlating a metric drop with a specific publish.

run_gaql

Execute an arbitrary GAQL (Google Ads Query Language) query.

Use this for advanced queries not covered by the other tools. See the GAQL reference in the AdLoop cursor rules for syntax help.

format: "table" (default, readable), "json" (structured), "csv" (exportable)

draft_campaign

Draft a full campaign structure — returns a PREVIEW, does NOT create anything.

Creates: CampaignBudget + Campaign (PAUSED) + AdGroup + optional Keywords

  • geo targeting + language targeting. Ads are NOT included — use draft_responsive_search_ad after the campaign exists.

bidding_strategy: MAXIMIZE_CONVERSIONS | TARGET_CPA | TARGET_ROAS | MAXIMIZE_CONVERSION_VALUE | TARGET_SPEND | MANUAL_CPC target_cpa: required if bidding_strategy is TARGET_CPA (in account currency) target_roas: required if bidding_strategy is TARGET_ROAS keywords: list of {"text": "keyword", "match_type": "EXACT|PHRASE|BROAD"} search_partners_enabled: include ads on Search partners display_network_enabled: enable Search campaign display expansion display_expansion_enabled: alias for display_network_enabled max_cpc: manual CPC bid for the initial ad group when bidding_strategy is MANUAL_CPC, or the Maximize Clicks CPC cap when bidding_strategy is TARGET_SPEND geo_target_ids: REQUIRED list of geo target constant IDs Common: "2276" Germany, "2040" Austria, "2756" Switzerland, "2840" USA, "2826" UK, "2250" France. Full list: Google Ads API geo target constants. language_ids: REQUIRED list of language constant IDs Common: "1001" German, "1000" English, "1002" French, "1004" Spanish, "1014" Portuguese. Full list: Google Ads API language constants.

Call confirm_and_apply with the returned plan_id to execute.

draft_ad_groupA

Draft a new ad group within an existing campaign — returns a PREVIEW, does NOT create.

Creates an ad group (ENABLED, type SEARCH_STANDARD) in the specified campaign. Optionally includes keywords in the same atomic operation.

campaign_id: The campaign to add the ad group to (get from get_campaign_performance). ad_group_name: Name for the new ad group. keywords: Optional list of {"text": "keyword", "match_type": "EXACT|PHRASE|BROAD"}. cpc_bid_micros: Optional ad group CPC bid in micros (only for MANUAL_CPC campaigns).

Call confirm_and_apply with the returned plan_id to execute.

update_campaignA

Draft an update to an existing campaign — returns a PREVIEW, does NOT apply.

Only include the parameters you want to change. Omit the rest.

campaign_id: the numeric ID of the campaign to update (required) bidding_strategy: MAXIMIZE_CONVERSIONS | TARGET_CPA | TARGET_ROAS | MAXIMIZE_CONVERSION_VALUE | TARGET_SPEND | MANUAL_CPC target_cpa: required if bidding_strategy is TARGET_CPA (in account currency) target_roas: required if bidding_strategy is TARGET_ROAS daily_budget: new daily budget in account currency geo_target_ids: REPLACES all geo targets. Common IDs: "2276" Germany, "2040" Austria, "2756" Switzerland, "2840" USA, "2826" UK language_ids: REPLACES all language targets. Common IDs: "1001" German, "1000" English, "1002" French, "1004" Spanish search_partners_enabled: include ads on Search partners display_network_enabled: enable Search campaign display expansion display_expansion_enabled: alias for display_network_enabled max_cpc: Maximize Clicks CPC cap when bidding_strategy is TARGET_SPEND, or when the existing campaign already uses TARGET_SPEND

Call confirm_and_apply with the returned plan_id to execute.

draft_responsive_search_adA

Draft a Responsive Search Ad — returns a PREVIEW, does NOT create the ad.

Provide 3-15 headlines (max 30 chars each) and 2-4 descriptions (max 90 chars each). The preview shows exactly what will be created. Call confirm_and_apply to execute.

Each headline/description entry may be either:

  • a plain string (unpinned), or

  • a dict {"text": "...", "pinned_field": "HEADLINE_1"} (pinned).

Valid pin values: headlines: HEADLINE_1, HEADLINE_2, HEADLINE_3 descriptions: DESCRIPTION_1, DESCRIPTION_2

Google caps: at most 2 headlines per pin slot, at most 1 description per pin slot. Mixed plain-string and dict entries are allowed within a single call (e.g. brand pinned to HEADLINE_1, the rest unpinned).

draft_keywordsA

Draft keyword additions — returns a PREVIEW, does NOT add keywords.

keywords: list of {"text": "keyword phrase", "match_type": "EXACT|PHRASE|BROAD"} Call confirm_and_apply with the returned plan_id to execute.

add_negative_keywordsA

Draft negative keyword additions — returns a PREVIEW.

Negative keywords prevent your ads from showing for irrelevant searches. match_type: "EXACT", "PHRASE", or "BROAD" Call confirm_and_apply with the returned plan_id to execute.

add_negative_locations

Draft negative geo location additions — returns a PREVIEW.

Use this to exclude cities/regions from a campaign while keeping broader positive targets such as State of Sao Paulo. geo_target_ids are numeric Google geo target constant IDs. Call confirm_and_apply with the returned plan_id to execute.

propose_negative_keyword_list

Draft a shared negative keyword list and attach it to a campaign — returns a PREVIEW.

Creates a reusable negative keyword list that can later be applied to multiple campaigns, unlike add_negative_keywords which adds directly to one campaign. match_type: "EXACT", "PHRASE", or "BROAD" Call confirm_and_apply with the returned plan_id to execute.

add_to_negative_keyword_list

Append keywords to an EXISTING shared negative keyword list — returns a PREVIEW.

Use this when a suitable list already exists and only needs more keywords (instead of propose_negative_keyword_list, which creates a new list). Always call get_negative_keyword_lists first to find the right shared_set_id and get_negative_keyword_list_keywords to avoid duplicating existing terms.

shared_set_id: numeric ID from get_negative_keyword_lists (shared_set.id). keywords: list of keyword strings to append (duplicates in the input list are collapsed). match_type: "EXACT", "PHRASE", or "BROAD"

Call confirm_and_apply with the returned plan_id to execute.

attach_shared_set_to_campaigns

Attach an existing shared set to one or more campaigns — returns a PREVIEW.

Creates CampaignSharedSet linkages so the campaigns inherit the shared set's criteria (e.g. negative keywords). Most commonly used to attach a shared negative keyword list to newly-built campaigns.

Use get_negative_keyword_lists to find the shared_set_id, and get_negative_keyword_list_campaigns to inspect existing attachments.

shared_set_id: numeric ID from get_negative_keyword_lists. campaign_ids: list of numeric campaign IDs to attach the set to.

Call confirm_and_apply with the returned plan_id to execute.

detach_shared_set_from_campaignsA

Detach a shared set from one or more campaigns — returns a PREVIEW.

Removes CampaignSharedSet linkages so the campaigns no longer inherit the shared set's criteria. The shared set itself is unchanged; only the per-campaign attachment is removed.

Use get_negative_keyword_list_campaigns to inspect existing attachments before detaching.

shared_set_id: numeric ID from get_negative_keyword_lists. campaign_ids: list of numeric campaign IDs to detach the set from.

Call confirm_and_apply with the returned plan_id to execute.

draft_demographic_targetingA

Draft demographic targeting (age/gender/parental status/income) — returns a PREVIEW.

By default, Google Ads serves to all demographic segments. This tool adds criteria that EXCLUDE a segment (negative=True, default) or NARROW targeting to it (negative=False — uncommon).

Provide exactly one of ad_group_id or campaign_id. At least one of the four demographic lists must contain a value.

Accepted values:

  • age_ranges: '18-24', '25-34', '35-44', '45-54', '55-64', '65+'. Google's buckets are FIXED — 'Exclude 23-35' has no exact mapping; ask the user which buckets to use.

  • genders: 'female', 'male', 'undetermined'

  • parental_statuses: 'parent', 'not_a_parent', 'undetermined'

  • income_ranges: PERCENTILES (not currency). 'top-10', '11-20', '21-30', '31-40', '41-50', 'lower-50', 'undetermined'. Available in select countries only (US, AU, JP, etc.).

Call confirm_and_apply with the returned plan_id to execute.

update_ad_groupC

Draft an ad group update for name and/or manual CPC bid.

draft_callouts

Draft campaign callout assets — returns a PREVIEW.

draft_structured_snippetsB

Draft campaign structured snippet assets — returns a PREVIEW.

draft_image_assets

Draft campaign image assets from local PNG, JPEG, or GIF files.

pause_entityA

Draft pausing a campaign, ad group, ad, or keyword — returns a PREVIEW.

entity_type: "campaign", "ad_group", "ad", or "keyword" entity_id format by type:

  • campaign: campaign ID (e.g. "12345678")

  • ad_group: ad group ID (e.g. "12345678")

  • ad: "adGroupIdadId" (e.g. "12345678987654")

  • keyword: "adGroupIdcriterionId" (e.g. "12345678987654")

Call confirm_and_apply with the returned plan_id to execute.

enable_entityA

Draft enabling a paused campaign, ad group, ad, or keyword — returns a PREVIEW.

entity_type: "campaign", "ad_group", "ad", or "keyword" entity_id format by type:

  • campaign: campaign ID (e.g. "12345678")

  • ad_group: ad group ID (e.g. "12345678")

  • ad: "adGroupIdadId" (e.g. "12345678987654")

  • keyword: "adGroupIdcriterionId" (e.g. "12345678987654")

Call confirm_and_apply with the returned plan_id to execute.

remove_entityA

Draft REMOVING an entity — returns a PREVIEW. This is IRREVERSIBLE.

entity_type: "campaign", "ad_group", "ad", "keyword", "negative_keyword", "shared_criterion", "campaign_asset", "asset", or "customer_asset" entity_id: The resource ID. For keywords: "adGroupIdcriterionId" For negative_keywords: "campaignIdcriterionId" (use the resource_id field from get_negative_keywords) For shared_criterion: "sharedSetIdcriterionId" (use the resource_id field from get_negative_keyword_list_keywords) For campaign_asset: "campaignIdassetIdfieldType" For asset: simple asset ID For customer_asset: "assetIdfieldType"

WARNING: Removed entities cannot be re-enabled. Use pause_entity instead if you just want to temporarily disable something.

Call confirm_and_apply with the returned plan_id to execute.

draft_sitelinksA

Draft sitelink extensions for a campaign — returns a PREVIEW.

Sitelinks appear as additional links below your ad, increasing click area and directing users to specific pages.

campaign_id: the campaign to attach sitelinks to sitelinks: list of dicts, each with: - link_text (str, required, max 25 chars) — the clickable text shown - final_url (str, required) — destination URL for this sitelink - description1 (str, optional, max 35 chars) — first description line - description2 (str, optional, max 35 chars) — second description line

Google recommends at least 4 sitelinks per campaign. Fewer than 2 may not show.

Call confirm_and_apply with the returned plan_id to execute.

confirm_and_apply

Execute a previously previewed change.

IMPORTANT: Defaults to dry_run=True. You MUST explicitly pass dry_run=false to make real changes to the Google Ads account.

Config override: if 'safety.require_dry_run: true' is set in the user's config file (default ~/.adloop/config.yaml), dry_run=false is IGNORED and this tool will keep returning DRY_RUN_SUCCESS. When that happens the response includes 'dry_run_forced_by', 'config_path', and 'remediation' fields — surface those to the user verbatim and STOP retrying. Calling this tool again with dry_run=false will not change anything until the user edits the config file, sets 'require_dry_run: false', and restarts the AdLoop MCP server.

Two-phase apply: if 'safety.two_phase_apply: true' is set (always on for AdLoop Cloud tenants), dry_run=false is REFUSED with status DRY_RUN_REQUIRED until this plan_id has completed one dry_run=true pass. Run the dry run, show it to the user, then apply for real.

The plan_id comes from a prior draft_* or pause/enable tool call.

draft_key_event

Draft marking a GA4 event as a key event (conversion) — returns a PREVIEW.

The fix for "the event fires but isn't tracked as a conversion": attribution_check / validate_tracking diagnose it, this closes the loop. counting_method: ONCE_PER_EVENT (purchases) or ONCE_PER_SESSION (sign-ups). Call confirm_and_apply with the returned plan_id to execute. Applies to future data only.

validate_tracking

Compare tracking events found in the codebase against actual GA4 data.

First, search the user's codebase for gtag('event', ...) or dataLayer.push calls and extract event names. Then pass those names here to check which ones actually fire in GA4.

Returns: matched events, events missing from GA4, unexpected GA4 events, and auto-collected events (page_view, session_start, etc.).

generate_tracking_code

Generate a GA4 event tracking JavaScript snippet.

Produces ready-to-paste gtag code for the specified event. Includes recommended parameters for well-known GA4 events (sign_up, purchase, etc.). Optionally checks GA4 to warn if the event already fires.

trigger: "form_submit", "button_click", or "page_load" — wraps the gtag call in an appropriate event listener. Empty = bare gtag call.

estimate_budget

Forecast clicks, cost, and conversions for a set of keywords.

Uses Google Ads Keyword Planner to estimate campaign performance without creating anything. Essential for budget planning before launching campaigns. Per-keyword max_cpc values are collapsed to a campaign-level manual CPC cap (the highest one) — the Ads API forecast takes no per-keyword bids.

keywords: list of {"text": "keyword", "match_type": "EXACT|PHRASE|BROAD", "max_cpc": 1.50} max_cpc is optional (defaults to 1.00 in account currency) geo_target_id: geo target constant (2276=Germany, 2840=USA, 2826=UK, 2250=France) language_id: language constant (1000=English, 1001=German, 1002=French, 1003=Spanish) daily_budget: if provided, insights will show what % of traffic the budget captures forecast_days: forecast horizon in days (default 30)

discover_keywords

Discover new keyword ideas using Google Ads Keyword Planner.

Mirrors the "Discover new keywords" UI in Keyword Planner:

Set include_monthly_volumes=true for per-month search history (last 24 months, top-20 ideas) plus a seasonality insight — use when the user asks about demand trends, seasonality, or "when should I ramp budget".

  • Both together: keywords + url for more targeted ideas

Returns keyword ideas sorted by avg monthly search volume, with competition level (LOW/MEDIUM/HIGH) and top-of-page bid range.

geo_target_id: geo target constant (2276=Germany, 2840=USA, 2826=UK) language_id: language constant (1000=English, 1001=German, 1002=French) page_size: max keyword ideas to return (default 50, max 1000)

Prompts

Interactive templates invoked by user choice

NameDescription

No prompts

Resources

Contextual data attached and managed by the client

NameDescription

No resources

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/kLOsk/adloop'

If you have feedback or need assistance with the MCP directory API, please join our Discord server