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_summariesA

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_reportA

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_eventsA

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_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_performanceA

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.

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.

get_keyword_performanceB

Get keyword metrics including quality scores and competitive data.

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

get_search_termsA

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.

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_campaignsA

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_recommendationsA

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_performanceA

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 Google Ads API v23. 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_performanceA

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.

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.

run_gaqlA

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_campaignA

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.

propose_negative_keyword_listA

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_listA

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_campaignsA

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.

update_ad_groupC

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

draft_calloutsC

Draft campaign callout assets — returns a PREVIEW.

draft_structured_snippetsB

Draft campaign structured snippet assets — returns a PREVIEW.

draft_image_assetsC

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_applyA

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.

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

validate_trackingA

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_codeA

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_budgetA

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

Uses Google Ads Keyword Planner to estimate campaign performance without creating anything. Essential for budget planning before launching campaigns.

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_keywordsA

Discover new keyword ideas using Google Ads Keyword Planner.

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

  • Start with keywords: pass seed_keywords (e.g. ["running shoes"])

  • Start with a website: pass url (e.g. "https://example.com/products")

  • 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