Help us improve
Share bugs, ideas, or general feedback.
From hyper-marketing
Builds new Google Ads Search, Display, and Performance Max campaigns end-to-end via Hyper MCP. Handles setup, research, conversion tracking check, and blueprint-based creation.
npx claudepluginhub hyperfx-ai/marketing-skills --plugin hyper-marketingHow this skill is triggered — by the user, by Claude, or both
Slash command
/hyper-marketing:google-adsThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Strategic guide for building new Google Ads campaigns. Research first, consult intelligently, validate everything, and use the blueprint flow for controlled creation.
Manages ad campaigns across Google Ads, Meta Ads, LinkedIn Ads, and TikTok Ads via Adspirer MCP server. Analyzes performance, researches keywords, creates campaigns, optimizes budgets.
Audits Google Ads accounts across Search, PMax, Display, YouTube, and Demand Gen campaigns using 80 checks covering conversion tracking, wasted spend, account structure, and Smart Bidding. Evaluates ad spend efficiency and campaign health.
Operates and optimizes Google Ads accounts: campaigns, keywords, bids, budgets, negatives, search terms, location targeting, experiments, asset management, portfolio bidding, offline conversions.
Share bugs, ideas, or general feedback.
Strategic guide for building new Google Ads campaigns. Research first, consult intelligently, validate everything, and use the blueprint flow for controlled creation.
If google_ads_list_accounts is not in the tool list, stop and tell the user to enable Hyper MCP and connect Google Ads.
google-ads-operator skill.ad-creative-generation.meta-ads / tiktok-ads separately.| Tool | Purpose |
|---|---|
google_ads_list_accounts | Discover accessible accounts (and MCC sub-accounts). |
google_ads_execute_gaql | Run a GAQL query (conversion actions, search term reports, etc.). |
google_ads_search_locations | Resolve human-readable location names to IDs. |
google_ads_list_assets, google_ads_upload_image_asset | Manage image assets for Display / PMax. |
google_ads_preview_blueprint, google_ads_create_from_blueprint | Validate + create Search/Display campaigns. |
google_ads_preview_pmax_blueprint, google_ads_create_from_pmax_blueprint | Validate + create Performance Max campaigns. |
Call google_ads_list_accounts() to list accessible accounts.
CRITICAL: Verify account access before any operations.
Before asking questions, run the purpose-built diagnostic (simpler than a hand-rolled GAQL query):
google_ads_diagnose_conversion_tracking(customer_id="<from list_accounts>")
This returns all conversion actions, their status, and any tracking signal issues in one call. If the user's MCP doesn't expose google_ads_diagnose_conversion_tracking, fall back to GAQL:
google_ads_execute_gaql(
customer_id="<from list_accounts>",
query="""
SELECT conversion_action.id, conversion_action.name,
conversion_action.status, conversion_action.type
FROM conversion_action
WHERE conversion_action.status = 'ENABLED'
"""
)
google_ads_execute_gaqlvsgoogle_ads_run_gaql:execute_gaqlworks on manager accounts (MCC) and sub-accounts.run_gaqlis only available on non-manager accounts. Useexecute_gaqlconsistently — it works everywhere.
Act as a partner, not order-taker:
google_ads_search_locations(customer_id="...", location_names="New York"). Note: location_names is a single string, not an array — pass a city, state, country, or postal code and the tool returns matching geo target IDs.Campaign Strategy for [Business Name]
Sources: [URL], GAQL
Conversion Setup: [GAQL findings]
Primary Goal: [objective + why]
Bidding: [strategy + why]
Budget: $[X]/day (expectations)
Locations: [targets + rationale]
Keyword Themes: [themes + match types + 2-3 examples]
Messaging: [angles pulled from site]
Trade-offs/Risks: [bullets]
Approve to proceed?
Wait for explicit approval. No emojis. No assumptions.
CRITICAL: Always use the blueprint system for campaign creation. It validates locally, fills smart defaults, resolves locations, and rolls back on failure.
Preview: google_ads_preview_blueprint(blueprint={...})
Create: google_ads_create_from_blueprint(blueprint={...})
{
"customer_id": "1234567890",
"name": "Campaign Name",
"budget_amount_micros": 50000000,
"advertising_channel_type": "SEARCH",
"bidding_strategy": "MAXIMIZE_CLICKS",
"status": "PAUSED",
"location_names": ["New York", "Los Angeles"], // array in blueprints; note: google_ads_search_locations takes a single string for manual lookup
"conversion_action_ids": ["1234567890"],
"ad_schedules": [
{"day_of_week": "MONDAY", "start_hour": 9, "end_hour": 17}
],
"sitelinks": [
{"link_text": "Free Trial", "final_urls": ["https://example.com/trial"]}
],
"callouts": [{"callout_text": "Free Shipping"}],
"ad_groups": [
{
"name": "Ad Group 1",
"keywords": [
{"text": "marketing software", "match_type": "PHRASE"},
{"text": "competitor brand", "match_type": "EXACT", "negative": true}
],
"ads": [
{
"headlines": ["Headline 1", "Headline 2", "Headline 3"],
"descriptions": ["Description 1", "Description 2"],
"final_urls": ["https://example.com"]
}
],
"audiences": [{"audience_id": "1234567890"}]
}
]
}
For Display campaigns, set "advertising_channel_type": "DISPLAY" and use display_ads instead of ads:
"display_ads": [{
"headlines": ["Headline 1", "Headline 2", "Headline 3"],
"long_headline": "Longer headline up to 90 characters",
"descriptions": ["Description 1", "Description 2"],
"business_name": "Business Name",
"final_urls": ["https://example.com"],
"marketing_image_asset_ids": ["1234567890"],
"square_marketing_image_asset_ids": ["1234567891"],
"logo_asset_ids": ["1234567892"]
}]
CRITICAL (Display): All three image asset types are REQUIRED:
marketing_image_asset_ids— landscape 1.91:1 (e.g. 1200×628).square_marketing_image_asset_ids— square 1:1 (e.g. 1200×1200).logo_asset_ids— square 1:1 or landscape 4:1.
Preview: google_ads_preview_pmax_blueprint(blueprint={...})
Create: google_ads_create_from_pmax_blueprint(blueprint={...})
{
"customer_id": "1234567890",
"name": "PMax Campaign",
"budget_amount_micros": 50000000,
"bidding_strategy": "MAXIMIZE_CONVERSIONS",
"status": "PAUSED",
"location_names": ["United States"],
"conversion_action_ids": ["1234567890"],
"asset_groups": [
{
"name": "Asset Group 1",
"headlines": ["Headline 1", "Headline 2", "Headline 3"],
"long_headlines": ["Longer headline up to 90 characters"],
"descriptions": ["Description 1", "Description 2"],
"business_name": "Business Name",
"final_urls": ["https://example.com"],
"marketing_image_asset_ids": ["1234567890"],
"square_marketing_image_asset_ids": ["1234567891"],
"logo_asset_ids": ["1234567892"]
}
]
}
CRITICAL (PMax): All three image asset types are REQUIRED with correct aspect ratios. The preview tool validates ratios before creation.
| Feature | Details |
|---|---|
| Smart defaults | Budget name, start date, network settings, ad group type auto-filled. |
| Location resolution | Pass location_names (human-readable) instead of IDs. |
| Client-side validation | Char limits, match types, image ratios checked before any API call. |
| Batch operations | Keywords, extensions, ad schedules batched for efficiency. |
| Cleanup on failure | Entire campaign removed if any step fails after campaign creation. |
| Ad extensions | Sitelinks, callouts, structured snippets — created and linked automatically. |
| Ad scheduling | Day-parting at campaign level via ad_schedules. |
| Audiences | Target or exclude audiences per ad group. |
| Conversion actions | Link specific conversion actions via conversion_action_ids. |
| Strategy | Fields | Notes |
|---|---|---|
MANUAL_CPC | — | Manual cost-per-click. |
MAXIMIZE_CLICKS | — | Default, good starting point. |
MAXIMIZE_CONVERSIONS | target_cpa_micros (optional) | Requires conversion tracking. |
MAXIMIZE_CONVERSION_VALUE | target_roas (optional) | Requires conversion values. |
TARGET_CPA | target_cpa_micros (required) | Sets a target cost per acquisition. |
TARGET_ROAS | target_roas (required) | Sets a target return on ad spend. |
For PMax:
TARGET_CPAandTARGET_ROASare translated to constraints withinMAXIMIZE_CONVERSIONS/MAXIMIZE_CONVERSION_VALUE.
location_names in blueprint (auto-resolved) or google_ads_search_locations for manual lookup.google_ads_list_assets to find them).Initial Setup → Research (site + GAQL + market) → Analyze (goals, audience, keywords) → Consult (options + trade-offs) → Recommend (structure + bids) → Confirm (summary approved) → Build Blueprint → Preview → User Approval → Create (PAUSED) → Activate (post-approval).
Critical: Not all Google Ads resources can be joined in a single query.
Use segments.keyword.info.* for keyword text and match type — never ad_group_criterion.*:
SELECT
search_term_view.search_term,
customer.descriptive_name,
segments.keyword.info.text,
segments.keyword.info.match_type,
campaign.name,
ad_group.name,
metrics.clicks,
metrics.impressions,
metrics.conversions,
metrics.cost_micros
FROM search_term_view
WHERE segments.date DURING LAST_7_DAYS
ORDER BY metrics.impressions DESC
ad_group_criterion is incompatible with search_term_view as the FROM resource. Selecting ad_group_criterion.* fields will always fail with PROHIBITED_RESOURCE_TYPE_IN_SELECT_CLAUSE.
For keyword performance (Quality Score, bid estimates):
SELECT
ad_group_criterion.keyword.text,
ad_group_criterion.keyword.match_type,
metrics.clicks,
metrics.impressions,
metrics.historical_quality_score
FROM keyword_view
WHERE segments.date DURING LAST_30_DAYS
When a user provides a manager account (MCC) with multiple sub-accounts:
Never query more than 5 sub-accounts in a single run. Each google_ads_execute_gaql call goes through a proxy with a timeout. Querying 10+ accounts sequentially in one loop reliably causes 504 timeouts.
Process in batches of 5 and aggregate results before proceeding:
Batch 1: accounts[0:5] → collect results
Batch 2: accounts[5:10] → collect results
Batch 3: accounts[10:15] → collect results
...merge all batches...
Announce progress to the user: "Processing accounts 1-5 of 23...".
If a google_ads_execute_gaql call times out (504 / "Google Ads API timed out after retries"):
LIMIT, or split the account list further.For MCC search term reports across many sub-accounts:
1. Get all accounts: google_ads_list_accounts()
Filter to sub-accounts: [a for a in result.accounts if not a["manager"]]
2. For each batch of 5 accounts:
- Run search_term_view GAQL (using segments.keyword.info.*, NOT ad_group_criterion).
- Collect results tagged with customer.descriptive_name.
3. Merge all batches into a single dataset.
4. Write to Google Sheets or CSV file for the user.
Minimum required columns for a search term report:
Never:
ad_group_criterion with search_term_view in GAQL.google_ads_query_insights is exposed)If the MCP exposes google_ads_query_insights, use it for large multi-account performance queries — it reads from a local cache refreshed hourly and avoids API timeouts entirely.
Call google_ads_query_insights — its built-in description includes the exact table name, schema, and example queries. Read the tool description first, then pass a SQL query targeting that table. Typical pattern:
google_ads_query_insights(
query="SELECT date, campaign_name, SUM(cost_micros) as spend, SUM(clicks) as clicks
FROM <table>
WHERE customer_id = '1234567890'
AND date >= CURRENT_DATE - INTERVAL '7 days'
GROUP BY date, campaign_name ORDER BY date DESC"
)
Replace <table> with the table name shown in the google_ads_query_insights tool description. Cache is refreshed hourly — no manual sync needed.
If the tool returns a "no data cached" error, check the
suggestionfield in the response — it will contain the correct workspace-specific table name. Retry the query using that suggested table name instead.
Key columns available (verify in tool description):
date, customer_id, campaign_id, campaign_name, campaign_statusimpressions, clicks, cost_micros (÷ 1,000,000 for dollars)conversions, conversions_value, conversion_ratectr, average_cpc, average_cpmSupports standard SQL aggregations and window functions. For cross-account queries, omit the customer_id filter and GROUP BY it instead.