---
name: gentic-google-ads
description: "Give your AI agent control of your Google Ads account. Create Search campaigns, research keywords, analyze performance, and manage budgets — all through the Model Context Protocol."
license: MIT
metadata:
  author: gentic
  version: "1.0.0"
---

# Gentic Google Ads

Connect any AI agent to manage Google Search campaigns — keyword research, campaign creation, bid management, and performance analysis — all through the Model Context Protocol. OAuth connects in one click, and every mutating tool defaults to PAUSED for safe review.

## When to apply

- User wants to create, manage, or optimize Google Search campaigns.
- User wants to research keywords with search volume, competition, and bid estimates.
- User wants to analyze Google Ads performance (spend, clicks, conversions, CTR, CPA, ROAS).
- User wants to create responsive search ads with headlines and descriptions.
- User wants to see which search terms are triggering their ads.
- User wants to run arbitrary GAQL queries against their Google Ads data.
- User wants to adjust campaign budgets, ad group CPC bids, or toggle campaign status (pause/enable).
- User wants to pause, enable, or remove individual ad groups or ads.
- User wants to add negative keywords to stop ads from showing on irrelevant queries.
- User wants to switch which Google Ads account (or MCC login account) the agent operates against.

## Tools

| Tool | Description | Cost |
|------|-------------|------|
| `add_keywords` | Bulk-add keywords to an ad group. Each keyword has a text and a match type (BROAD, PHRASE, or EXACT). 1–200 keywords per call. | 25¢ / call |
| `add_negative_keywords` | Bulk-add negative keywords at either the campaign or ad-group level. Set level="campaign" with campaignResourceName to exclude across the whole campaign (most common), or level="adGroup" with adGroupResourceName for narrower exclusion. Each keyword has a text and a match type (BROAD, PHRASE, or EXACT). 1–200 keywords per call. | 25¢ / call |
| `analyze_campaign` | AI-narrated campaign analysis: pulls performance for the requested period and the prior equivalent period, then returns a ranked narrative comparing the two with winners, losers, and concrete recommendations. | 50¢ / call |
| `create_ad_group` | Create a SEARCH_STANDARD ad group inside a campaign with a default CPC bid. Defaults to PAUSED. | 25¢ / call |
| `create_campaign_budget` | Create a Google Ads campaign budget. amountMicros is the daily budget in micros (1 USD = 1,000,000). ⚠️ Double-check the digit count before submitting — values ≥ 100,000,000 ($100/day) are typo-prone (an extra zero turns $10/day into $100/day). Confirm the intended dollar amount with the user when amountMicros exceeds 100,000,000. | 25¢ / call |
| `create_responsive_search_ad` | Create a responsive search ad inside an ad group. Requires 3–15 headlines (≤30 chars each) and 2–4 descriptions (≤90 chars each). Defaults to PAUSED. ⚠️ path1/path2 render in the ad's DISPLAYED URL (e.g. example.com/path1/path2) — they're cosmetic breadcrumbs that should describe the landing page's content ("hydration", "sale") and do NOT need to match a real route on finalUrls. Don't fabricate paths that imply a section that doesn't exist; omit them entirely to show only the bare domain. | 25¢ / call |
| `create_search_campaign` | Create a SEARCH-channel Google Ads campaign referencing a budget. Defaults to PAUSED — to create an ENABLED campaign that spends immediately, you MUST pass status="ENABLED" AND confirmEnableSpend=true. Bidding is either manual CPC or target CPA. Defaults `containsEuPoliticalAdvertising` to DOES_NOT_CONTAIN_EU_POLITICAL_ADVERTISING (required by EU TTPA regulation on every new campaign); pass CONTAINS_EU_POLITICAL_ADVERTISING only if the campaign actually runs EU political ads. STRONGLY recommended to pass `geoTargetLocations` (e.g. ["US"]) and `language` (e.g. "en") — if omitted, the campaign serves globally in all languages, which usually wastes budget. These are written as separate CampaignCriterion records after the campaign is created. | 25¢ / call |
| `generate_keyword_ideas` | Discover new keyword ideas relevant to a business using Google's Keyword Planner data (KeywordPlanIdeaService). Provide seed keywords, a landing-page URL, or both. Returns per-keyword average monthly searches, competition level, and top-of-page bid range. | 25¢ / call |
| `get_ad_group_performance` | Structured ad-group performance metrics for a date range. Optionally filter to a single campaign. | 15¢ / call |
| `get_ad_history` | Read the org's ad mutation log. Returns one row per past ad-platform mutation (campaigns/ad sets/ads/keywords created, or status/bid/budget changed, or images/videos uploaded) across Google Ads and Meta. Use this to learn what's already been built for the brand before proposing new ads. Filters by platform, entity_type, account_id, tool_name, and timestamp range. Newest first; default limit 50, max 500. | Free |
| `get_ad_performance_trends` | Read the org's accumulated ad performance snapshots across Google Ads and Meta. Each row is a (campaign\|ad_group\|adset\|ad\|keyword\|search_term) × date_range fact: impressions, clicks, spend (micros), conversions, ctr, cpc, cpm, plus platform-specific extras. Use this to see how ads have performed over time and surface patterns the live API view alone can't (week-over-week deltas, multi-platform comparisons). Spend/cpc/cpm are in MICROS — divide by 1,000,000 for dollars. Filters by platform, account, entity, and date range. Default limit 200, max 2000. | Free |
| `get_campaign_performance` | Structured campaign performance: impressions, clicks, cost, conversions, CTR, CPA, ROAS for a date range, grouped by campaign and sorted by spend. | 15¢ / call |
| `get_keyword_performance` | Structured keyword-level performance including quality score, for a date range. | 15¢ / call |
| `get_search_terms_report` | Search-terms report — the actual user queries that triggered ads. Useful for identifying negative-keyword candidates. Filter by campaign, ad group, and/or minimum impressions. | 15¢ / call |
| `google_ads_connection_status` | Check whether this organization has connected a Google Ads account. Returns the connection status plus stored customer IDs. Does not call Google. | Free |
| `list_accessible_customers` | List all Google Ads customer accounts the connected credentials can access, enriched with account name, currency, time zone, manager flag, and status (ENABLED / CANCELED / SUSPENDED / CLOSED). Only ENABLED non-manager accounts can serve campaigns — agents should filter to status=='ENABLED' && manager==false when picking a target customer, and use select_google_ads_account to set it. | Free |
| `run_gaql_query` | Execute an arbitrary Google Ads Query Language (GAQL) query via GoogleAdsService.search. Paginated; capped at GOOGLE_ADS_MAX_ROWS_PER_QUERY (default 1000) per call. | 15¢ / call |
| `select_google_ads_account` | Update which Google Ads account this org operates against. Set `selectedCustomerId` to change the default customer used by other tools when no customerId is passed. Set `loginCustomerId` to the manager (MCC) ID that contains that customer — required when the account is accessed via an MCC. Pass `loginCustomerId: null` to clear it (use only for direct-access non-managed accounts). Run `list_accessible_customers` first to see valid IDs and identify which one is a manager. After saving, runs a smoke GAQL query against the new combination and returns `verified: true` on success or `verified: false` plus `verificationError` when the credentials don't actually work — check this before making real API calls. | Free |
| `update_ad_group_bid` | Update an ad group's default CPC bid (cpcBidMicros). ⚠️ cpcBidMicros is in micros (1 USD = 1,000,000; e.g. $3.50 = 3500000) — double-check the digit count before submitting. Confirm the intended dollar amount with the user when cpcBidMicros exceeds 20,000,000 ($20/click). | 25¢ / call |
| `update_ad_group_status` | Change an ad group's status to ENABLED, PAUSED, or REMOVED. status="ENABLED" requires confirmEnableSpend=true (explicit opt-in to start serving ads). status="REMOVED" requires confirmRemove=true (irreversible — Google Ads cannot restore a removed ad group; prefer PAUSED if you only want to stop serving). | 25¢ / call |
| `update_ad_status` | Change an ad's status to ENABLED, PAUSED, or REMOVED. Operates on the AdGroupAd resource (resource name format: customers/{cid}/adGroupAds/{adGroupId}~{adId}), which is what `create_responsive_search_ad` returns. status="ENABLED" requires confirmEnableSpend=true. status="REMOVED" requires confirmRemove=true (irreversible — Google Ads cannot restore a removed ad; prefer PAUSED if you only want to stop serving). | 25¢ / call |
| `update_campaign_budget` | Update the daily amount (in micros) of a campaign budget. ⚠️ amountMicros is in micros (1 USD = 1,000,000) — double-check the digit count before submitting. Confirm the intended dollar amount with the user when amountMicros exceeds 100,000,000 ($100/day). | 25¢ / call |
| `update_campaign_status` | Change a campaign's status to ENABLED, PAUSED, or REMOVED. status="ENABLED" requires confirmEnableSpend=true (explicit opt-in to start spending). status="REMOVED" requires confirmRemove=true (irreversible — Google Ads cannot restore a removed campaign; prefer PAUSED if you only want to stop spending). | 25¢ / call |

## Workflow

### 1. Check connection with `google_ads_connection_status`

Free call — returns whether the org has connected a Google Ads account, plus the selected customer ID. If not connected, direct the user to the Gentic dashboard Integrations section to authorize via OAuth. Use `list_accessible_customers` (also free) to see all accounts the credentials can access, keep only the ones where status is ENABLED and manager is false (manager accounts can't serve campaigns), then switch with `select_google_ads_account` — pass `loginCustomerId` to the MCC if the account is accessed via a manager. `select_google_ads_account` runs a smoke GAQL query and returns `verified: true/false` so you catch a bad combination before making real calls.

### 2. Research keywords with `generate_keyword_ideas` (25¢/call)

Provide seed `keywords`, a `pageUrl`, or both. Returns per-keyword average monthly searches, competition level (LOW/MEDIUM/HIGH), and top-of-page bid range in micros. Filter by `language` (default "en"), `geoTargetLocations` (default ["US"]), and `network`. Paginate with `pageSize` and `pageToken` for large result sets.

### 3. Create the campaign structure (25¢ per mutating call)

Build bottom-up: `create_campaign_budget` (daily amount in micros — 1 USD = 1,000,000) → `create_search_campaign` (references the budget, choose MANUAL_CPC or TARGET_CPA) → `create_ad_group` (set default CPC bid) → `add_keywords` (1-200 keywords with BROAD/PHRASE/EXACT match types) → `create_responsive_search_ad` (3-15 headlines ≤30 chars, 2-4 descriptions ≤90 chars). **Everything defaults to PAUSED.** To create ENABLED campaigns that spend immediately, pass `status="ENABLED"` AND `confirmEnableSpend=true`.

### 4. Pull structured performance with `get_campaign_performance` (15¢/call)

Returns impressions, clicks, cost, conversions, CTR, CPA, and ROAS grouped by campaign. Use `dateRange` with a preset (`LAST_7_DAYS`, `LAST_30_DAYS`, etc.) or custom `startDate`/`endDate`. Drill down with `get_ad_group_performance` and `get_keyword_performance` (both 15¢). Filter by `campaignId` or `adGroupId` to narrow results.

### 5. Get AI-narrated analysis with `analyze_campaign` (50¢/call)

Pulls performance for the requested period and the prior equivalent period, then returns a ranked narrative comparing the two with winners, losers, and concrete recommendations. Use this when the user wants strategic insights rather than raw numbers. Filter to specific campaigns with `campaignIds`.

### 6. Investigate search terms with `get_search_terms_report` (15¢/call)

Shows the actual user queries that triggered ads — critical for finding negative keyword candidates and wasted spend. Filter by `campaignId`, `adGroupId`, and `minImpressions`. Present results as a ranked table by impressions or cost, highlighting irrelevant queries the user should add as negatives.

### 7. Exclude irrelevant queries with `add_negative_keywords` (25¢/call)

Once you've identified wasted spend in the search terms report, use `add_negative_keywords` to stop ads from serving on those queries. Pass `level: "campaign"` with `campaignResourceName` to exclude across the whole campaign (most common), or `level: "adGroup"` with `adGroupResourceName` for narrower exclusion. 1–200 keywords per call, each with a `matchType` of BROAD, PHRASE, or EXACT.

### 8. Run arbitrary queries with `run_gaql_query` (15¢/call)

Execute any Google Ads Query Language query when the built-in tools don't cover a specific metric or dimension. Capped at 1,000 rows per call — paginate with `pageSize` and `pageToken`. Use this for edge cases like segmenting by device, hour of day, or custom attribute combinations.

### 9. Adjust budgets, bids, and status after launch (25¢ per mutating call)

Once campaigns are live, use `update_campaign_budget` to change the daily amount (in micros) on an existing budget resource, `update_ad_group_bid` to change an ad group's default CPC (also in micros — sanity-check the digit count), and `update_campaign_status` / `update_ad_group_status` / `update_ad_status` to pause, enable, or remove a campaign, ad group, or individual ad. Status accepts `ENABLED`, `PAUSED`, or `REMOVED`. Note that `update_ad_status` takes the `AdGroupAd` resource name, not a raw ad ID; transitioning anything to `ENABLED` is gated by `confirmEnableSpend: true`, and transitioning to `REMOVED` is gated by `confirmRemove: true` — see Notes for all three.

### 10. Present results clearly

For performance: lead with the headline metric (spend, CTR, top performer), show a ranked table, and call out outliers or period-over-period changes. For campaign creation: echo back the resource names, budget (in dollars, not micros), bidding strategy, and the fact that everything is **PAUSED — needs manual activation**. For keyword research: rank by search volume, highlight low-competition/high-volume opportunities.

## Notes

- **OAuth required.** Users must connect their Google Ads account via the Gentic dashboard before the agent can access any tools (except `google_ads_connection_status`, `list_accessible_customers`, and `select_google_ads_account` — all free).
- `customerId` is optional on most tools — if omitted, it uses the `selected_customer_id` stored on the connection. Change the default with `select_google_ads_account`, or pass `customerId` explicitly on a single call to operate on a different account.
- **MCC accounts:** if the target customer is accessed via a manager account, set `loginCustomerId` on `select_google_ads_account` to that manager's 10-digit ID. Pass `loginCustomerId: null` only for direct-access, non-managed accounts. `select_google_ads_account` verifies the combination with a smoke GAQL query and returns `verified: false` + `verificationError` if the credentials don't actually work — check this before making real calls.
- **Budgets and bids are in micros** — 1 USD = 1,000,000 micros. `amountMicros: "5000000"` = $5/day.
- All campaigns, ad groups, and ads are created in **PAUSED** status by default. Enabling spend — at creation OR via `update_campaign_status` / `update_ad_group_status` / `update_ad_status` — requires `status: "ENABLED"` AND `confirmEnableSpend: true`.
- Removing a campaign, ad group, or ad via `update_*_status` with `status: "REMOVED"` requires `confirmRemove: true` and is **irreversible** — Google Ads cannot restore a removed entity. Prefer `PAUSED` if you only want to stop serving.
- `update_ad_status` operates on the `AdGroupAd` resource. Use the `adGroupAdResourceName` returned by `create_responsive_search_ad` (format `customers/{cid}/adGroupAds/{adGroupId}~{adId}`), not the raw ad ID.
- `update_ad_group_bid` takes `cpcBidMicros` in micros (1 USD = 1,000,000). Double-check the digit count before submitting and confirm the dollar amount with the user when it exceeds 20,000,000 ($20/click).
- Responsive search ads require **3-15 headlines** (≤30 chars each) and **2-4 descriptions** (≤90 chars each). Use `pinnedField` to lock a headline or description to a specific position.
- `path1` / `path2` on responsive search ads are cosmetic breadcrumbs on the displayed URL — they don't need to match a real route on `finalUrls`. Omit them entirely to show only the bare domain.
- `create_search_campaign` defaults `containsEuPoliticalAdvertising` to `DOES_NOT_CONTAIN_EU_POLITICAL_ADVERTISING` — required by EU TTPA on every new campaign. Pass `CONTAINS_EU_POLITICAL_ADVERTISING` only when the campaign actually runs EU political ads.
- Strongly recommended to pass `geoTargetLocations` (e.g. `["US"]`) and `language` (e.g. `"en"`) on `create_search_campaign` — if omitted, the campaign serves globally in all languages, which usually wastes budget.
- `generate_keyword_ideas` needs at least one of `keywords` or `pageUrl`. Provide both for the best results.
- `run_gaql_query` is capped at 1,000 rows per call. Use `pageSize` and `pageToken` for pagination.
- Performance tools cost 15¢/call, mutating tools cost 25¢/call, and `analyze_campaign` costs 50¢/call. Connection, account listing, and account selection are free.
- All tools are organization-scoped — users only see their own Google Ads accounts.

## Tool details

- `add_keywords` — Bulk-add keywords to an ad group. Each keyword has a text and a match type (BROAD, PHRASE, or EXACT). 1–200 keywords per call.
  - `customerId` (string) — Google Ads customer ID (10-digit numeric, or a full resource name like customers/1234567890). If omitted, uses the selected_customer_id stored on the connection.
  - `adGroupResourceName` (string, required)
  - `keywords` (array of object, required)
- `add_negative_keywords` — Bulk-add negative keywords at either the campaign or ad-group level. Set level="campaign" with campaignResourceName to exclude across the whole campaign (most common), or level="adGroup" with adGroupResourceName for narrower exclusion. Each keyword has a text and a match type (BROAD, PHRASE, or EXACT). 1–200 keywords per call.
  - `customerId` (string) — Google Ads customer ID (10-digit numeric, or a full resource name like customers/1234567890). If omitted, uses the selected_customer_id stored on the connection.
  - `level` (string, enum: `campaign` | `adGroup`, required)
  - `campaignResourceName` (string) — Required when level="campaign".
  - `adGroupResourceName` (string) — Required when level="adGroup".
  - `keywords` (array of object, required)
- `analyze_campaign` — AI-narrated campaign analysis: pulls performance for the requested period and the prior equivalent period, then returns a ranked narrative comparing the two with winners, losers, and concrete recommendations.
  - `customerId` (string) — Google Ads customer ID (10-digit numeric, or a full resource name like customers/1234567890). If omitted, uses the selected_customer_id stored on the connection.
  - `dateRange` (required)
  - `campaignIds` (array of string)
- `create_ad_group` — Create a SEARCH_STANDARD ad group inside a campaign with a default CPC bid. Defaults to PAUSED.
  - `customerId` (string) — Google Ads customer ID (10-digit numeric, or a full resource name like customers/1234567890). If omitted, uses the selected_customer_id stored on the connection.
  - `campaignResourceName` (string, required)
  - `name` (string, required)
  - `cpcBidMicros` (string, required)
  - `status` (string, enum: `PAUSED` | `ENABLED`)
- `create_campaign_budget` — Create a Google Ads campaign budget. amountMicros is the daily budget in micros (1 USD = 1,000,000). ⚠️ Double-check the digit count before submitting — values ≥ 100,000,000 ($100/day) are typo-prone (an extra zero turns $10/day into $100/day). Confirm the intended dollar amount with the user when amountMicros exceeds 100,000,000.
  - `customerId` (string) — Google Ads customer ID (10-digit numeric, or a full resource name like customers/1234567890). If omitted, uses the selected_customer_id stored on the connection.
  - `name` (string, required)
  - `amountMicros` (string, required)
  - `deliveryMethod` (string, enum: `STANDARD` | `ACCELERATED`)
- `create_responsive_search_ad` — Create a responsive search ad inside an ad group. Requires 3–15 headlines (≤30 chars each) and 2–4 descriptions (≤90 chars each). Defaults to PAUSED. ⚠️ path1/path2 render in the ad's DISPLAYED URL (e.g. example.com/path1/path2) — they're cosmetic breadcrumbs that should describe the landing page's content ("hydration", "sale") and do NOT need to match a real route on finalUrls. Don't fabricate paths that imply a section that doesn't exist; omit them entirely to show only the bare domain.
  - `customerId` (string) — Google Ads customer ID (10-digit numeric, or a full resource name like customers/1234567890). If omitted, uses the selected_customer_id stored on the connection.
  - `adGroupResourceName` (string, required)
  - `finalUrls` (array of string, required)
  - `headlines` (array of object, required)
  - `descriptions` (array of object, required)
  - `path1` (string) — Cosmetic display-URL segment (≤15 chars). Renders as example.com/{path1} in the ad — does NOT need to exist as a real route on finalUrls. Use to describe content (e.g. "hydration"), not to imply non-existent sections. Omit to show only the bare domain.
  - `path2` (string) — Cosmetic display-URL second segment (≤15 chars). Renders as example.com/{path1}/{path2}. Same rules as path1: cosmetic only, not a real route.
  - `status` (string, enum: `PAUSED` | `ENABLED`)
- `create_search_campaign` — Create a SEARCH-channel Google Ads campaign referencing a budget. Defaults to PAUSED — to create an ENABLED campaign that spends immediately, you MUST pass status="ENABLED" AND confirmEnableSpend=true. Bidding is either manual CPC or target CPA. Defaults `containsEuPoliticalAdvertising` to DOES_NOT_CONTAIN_EU_POLITICAL_ADVERTISING (required by EU TTPA regulation on every new campaign); pass CONTAINS_EU_POLITICAL_ADVERTISING only if the campaign actually runs EU political ads. STRONGLY recommended to pass `geoTargetLocations` (e.g. ["US"]) and `language` (e.g. "en") — if omitted, the campaign serves globally in all languages, which usually wastes budget. These are written as separate CampaignCriterion records after the campaign is created.
  - `customerId` (string)
  - `name` (string, required)
  - `budgetResourceName` (string, required)
  - `biddingStrategy` (required)
  - `networkSettings` (object)
  - `startDate` (string)
  - `endDate` (string)
  - `status` (string, enum: `PAUSED` | `ENABLED`)
  - `confirmEnableSpend` (boolean)
  - `containsEuPoliticalAdvertising` (string, enum: `DOES_NOT_CONTAIN_EU_POLITICAL_ADVERTISING` | `CONTAINS_EU_POLITICAL_ADVERTISING`)
  - `geoTargetLocations` (array of string)
  - `language` (string)
- `generate_keyword_ideas` — Discover new keyword ideas relevant to a business using Google's Keyword Planner data (KeywordPlanIdeaService). Provide seed keywords, a landing-page URL, or both. Returns per-keyword average monthly searches, competition level, and top-of-page bid range.
  - `customerId` (string) — Google Ads customer ID (10-digit numeric, or a full resource name like customers/1234567890). If omitted, uses the selected_customer_id stored on the connection.
  - `keywords` (array of string)
  - `pageUrl` (string)
  - `language` (string) — ISO language code (e.g. "en") or raw languageConstants/{id}. Default "en".
  - `geoTargetLocations` (array of string) — 2-letter country codes (e.g. ["US","CA"]) or raw geoTargetConstants/{id}. Default ["US"].
  - `network` (string, enum: `GOOGLE_SEARCH` | `GOOGLE_SEARCH_AND_PARTNERS`)
  - `includeAdultKeywords` (boolean)
  - `pageSize` (integer)
  - `pageToken` (string)
- `get_ad_group_performance` — Structured ad-group performance metrics for a date range. Optionally filter to a single campaign.
  - `customerId` (string) — Google Ads customer ID (10-digit numeric, or a full resource name like customers/1234567890). If omitted, uses the selected_customer_id stored on the connection.
  - `dateRange` (required)
  - `campaignId` (string)
- `get_ad_history` — Read the org's ad mutation log. Returns one row per past ad-platform mutation (campaigns/ad sets/ads/keywords created, or status/bid/budget changed, or images/videos uploaded) across Google Ads and Meta. Use this to learn what's already been built for the brand before proposing new ads. Filters by platform, entity_type, account_id, tool_name, and timestamp range. Newest first; default limit 50, max 500.
  - `platform` (string, enum: `google_ads` | `meta`)
  - `entity_type` (string, enum: `campaign` | `ad_group` | `adset` | `ad` | `keyword` | `negative_keyword` | `budget` | `image` | `video`)
  - `account_id` (string)
  - `tool_name` (string)
  - `since` (string)
  - `until` (string)
  - `limit` (integer)
- `get_ad_performance_trends` — Read the org's accumulated ad performance snapshots across Google Ads and Meta. Each row is a (campaign|ad_group|adset|ad|keyword|search_term) × date_range fact: impressions, clicks, spend (micros), conversions, ctr, cpc, cpm, plus platform-specific extras. Use this to see how ads have performed over time and surface patterns the live API view alone can't (week-over-week deltas, multi-platform comparisons). Spend/cpc/cpm are in MICROS — divide by 1,000,000 for dollars. Filters by platform, account, entity, and date range. Default limit 200, max 2000.
  - `platform` (string, enum: `google_ads` | `meta`)
  - `account_id` (string)
  - `entity_type` (string, enum: `campaign` | `ad_group` | `adset` | `ad` | `keyword` | `search_term`)
  - `entity_id` (string)
  - `since` (string)
  - `until` (string)
  - `limit` (integer)
- `get_campaign_performance` — Structured campaign performance: impressions, clicks, cost, conversions, CTR, CPA, ROAS for a date range, grouped by campaign and sorted by spend.
  - `customerId` (string) — Google Ads customer ID (10-digit numeric, or a full resource name like customers/1234567890). If omitted, uses the selected_customer_id stored on the connection.
  - `dateRange` (required)
  - `campaignIds` (array of string)
- `get_keyword_performance` — Structured keyword-level performance including quality score, for a date range.
  - `customerId` (string) — Google Ads customer ID (10-digit numeric, or a full resource name like customers/1234567890). If omitted, uses the selected_customer_id stored on the connection.
  - `dateRange` (required)
  - `campaignId` (string)
  - `adGroupId` (string)
- `get_search_terms_report` — Search-terms report — the actual user queries that triggered ads. Useful for identifying negative-keyword candidates. Filter by campaign, ad group, and/or minimum impressions.
  - `customerId` (string) — Google Ads customer ID (10-digit numeric, or a full resource name like customers/1234567890). If omitted, uses the selected_customer_id stored on the connection.
  - `dateRange` (required)
  - `campaignId` (string)
  - `adGroupId` (string)
  - `minImpressions` (integer)
- `google_ads_connection_status` — Check whether this organization has connected a Google Ads account. Returns the connection status plus stored customer IDs. Does not call Google.
- `list_accessible_customers` — List all Google Ads customer accounts the connected credentials can access, enriched with account name, currency, time zone, manager flag, and status (ENABLED / CANCELED / SUSPENDED / CLOSED). Only ENABLED non-manager accounts can serve campaigns — agents should filter to status=='ENABLED' && manager==false when picking a target customer, and use select_google_ads_account to set it.
- `run_gaql_query` — Execute an arbitrary Google Ads Query Language (GAQL) query via GoogleAdsService.search. Paginated; capped at GOOGLE_ADS_MAX_ROWS_PER_QUERY (default 1000) per call.
  - `customerId` (string) — Google Ads customer ID (10-digit numeric, or a full resource name like customers/1234567890). If omitted, uses the selected_customer_id stored on the connection.
  - `query` (string, required) — Raw GAQL query string
  - `pageSize` (integer)
  - `pageToken` (string)
- `select_google_ads_account` — Update which Google Ads account this org operates against. Set `selectedCustomerId` to change the default customer used by other tools when no customerId is passed. Set `loginCustomerId` to the manager (MCC) ID that contains that customer — required when the account is accessed via an MCC. Pass `loginCustomerId: null` to clear it (use only for direct-access non-managed accounts). Run `list_accessible_customers` first to see valid IDs and identify which one is a manager. After saving, runs a smoke GAQL query against the new combination and returns `verified: true` on success or `verified: false` plus `verificationError` when the credentials don't actually work — check this before making real API calls.
  - `selectedCustomerId` (string) — 10-digit customer ID (or customers/{id} resource name) to set as the default customer for subsequent tool calls.
  - `loginCustomerId` — 10-digit manager (MCC) ID to send as the login-customer-id header. Pass null to clear. Required when the selected customer is accessed via an MCC.
- `update_ad_group_bid` — Update an ad group's default CPC bid (cpcBidMicros). ⚠️ cpcBidMicros is in micros (1 USD = 1,000,000; e.g. $3.50 = 3500000) — double-check the digit count before submitting. Confirm the intended dollar amount with the user when cpcBidMicros exceeds 20,000,000 ($20/click).
  - `customerId` (string) — Google Ads customer ID (10-digit numeric, or a full resource name like customers/1234567890). If omitted, uses the selected_customer_id stored on the connection.
  - `adGroupResourceName` (string, required)
  - `cpcBidMicros` (string, required)
- `update_ad_group_status` — Change an ad group's status to ENABLED, PAUSED, or REMOVED. status="ENABLED" requires confirmEnableSpend=true (explicit opt-in to start serving ads). status="REMOVED" requires confirmRemove=true (irreversible — Google Ads cannot restore a removed ad group; prefer PAUSED if you only want to stop serving).
  - `customerId` (string)
  - `adGroupResourceName` (string, required)
  - `status` (string, enum: `ENABLED` | `PAUSED` | `REMOVED`, required)
  - `confirmEnableSpend` (boolean)
  - `confirmRemove` (boolean)
- `update_ad_status` — Change an ad's status to ENABLED, PAUSED, or REMOVED. Operates on the AdGroupAd resource (resource name format: customers/{cid}/adGroupAds/{adGroupId}~{adId}), which is what `create_responsive_search_ad` returns. status="ENABLED" requires confirmEnableSpend=true. status="REMOVED" requires confirmRemove=true (irreversible — Google Ads cannot restore a removed ad; prefer PAUSED if you only want to stop serving).
  - `customerId` (string)
  - `adGroupAdResourceName` (string, required)
  - `status` (string, enum: `ENABLED` | `PAUSED` | `REMOVED`, required)
  - `confirmEnableSpend` (boolean)
  - `confirmRemove` (boolean)
- `update_campaign_budget` — Update the daily amount (in micros) of a campaign budget. ⚠️ amountMicros is in micros (1 USD = 1,000,000) — double-check the digit count before submitting. Confirm the intended dollar amount with the user when amountMicros exceeds 100,000,000 ($100/day).
  - `customerId` (string) — Google Ads customer ID (10-digit numeric, or a full resource name like customers/1234567890). If omitted, uses the selected_customer_id stored on the connection.
  - `budgetResourceName` (string, required)
  - `amountMicros` (string, required)
- `update_campaign_status` — Change a campaign's status to ENABLED, PAUSED, or REMOVED. status="ENABLED" requires confirmEnableSpend=true (explicit opt-in to start spending). status="REMOVED" requires confirmRemove=true (irreversible — Google Ads cannot restore a removed campaign; prefer PAUSED if you only want to stop spending).
  - `customerId` (string)
  - `campaignResourceName` (string, required)
  - `status` (string, enum: `ENABLED` | `PAUSED` | `REMOVED`, required)
  - `confirmEnableSpend` (boolean)
  - `confirmRemove` (boolean)

---

_This SKILL.md is generated from the live Gentic MCP manifest. Tool names, descriptions, and pricing are always current. Connect Gentic Google Ads at https://gentic.co/google-ads._
