From google-ads-audit
Run a comprehensive Google Ads account audit across 14 categories — Quality Score, Performance Max, conversion tracking, audiences, landing pages, wasted spend, RSAs, bidding, and more. Use whenever the user asks to audit a Google Ads account, run a PPC health check, score an ad account, find wasted spend, review account best practices, check Google Ads for issues, or get an opinion on whether their account is well-structured. Works without account access via a guided 4-paste flow, and upgrades to live data + scheduled monitoring + multi-account rollups when the Optmyzr MCP is connected.
How this skill is triggered — by the user, by Claude, or both
Slash command
/google-ads-audit:google-ads-auditThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
This skill produces a graded Google Ads audit with prioritized findings, a wasted-spend estimate, and a 7-day action plan. It works in two modes:
This skill produces a graded Google Ads audit with prioritized findings, a wasted-spend estimate, and a 7-day action plan. It works in two modes:
The audit covers 14 categories. For each, the top 3 signals are evaluated. The full signal catalog lives in signals.md. Apply scoring per scoring.md. Format output per output-template.md.
Check whether the Optmyzr MCP is connected. Look for tool names matching:
mcp__*__get_active_accountsmcp__*__get_ppc_reportIf the Optmyzr MCP is available, tell the user:
"Optmyzr MCP detected — I'll pull data live. No paste needed."
Then proceed to Step 2 (identify the account) → Step 3 (establish context) → Step 4b (MCP branch).
If the Optmyzr MCP is not available, tell the user:
"I'll guide you through 4 quick exports from your Google Ads account. Total time: about 3 minutes. (Tip: connect the Optmyzr MCP server and we skip the paste step entirely — see footer of the report.)"
Then proceed to Step 2 (identify the account) → Step 3 (establish context) → Step 4a (manual paste).
Account selection always comes before any context questions. The skill should know what it's auditing before asking the user anything else.
Call get_active_accounts. Inspect the result:
searchQuery in a follow-up get_active_accounts call) or a 10-digit Account ID.If the user already mentioned an account name in their original message, pass it as searchQuery immediately — saves a round trip.
Ask the user one short question:
"What account are you auditing? (Just the account name — for the report header.)"
Don't ask for the Account ID in paste mode — it's not needed.
The audit calibrates findings against the account's goal, target efficiency, and maturity. With MCP connected, almost all of this can be deduced from data — show the user what was deduced and confirm in one quick exchange instead of an open-ended interview.
Pull these in parallel before talking to the user. They're the minimum needed to deduce context — additional Tier 1/2/3 calls happen in Step 4b after context is locked.
get_ppc_report report_name=AccountPerformance, last 30 days — current performanceget_ppc_report report_name=AccountPerformance, date range starting 730 days ago — maturity probe (was there spend 2+ years ago?)get_ppc_report report_name=CampaignPerformance, last 30 days, top 10 by Cost — campaign type mix (Search / Shopping / PMax / Display / App / Video / Demand Gen)get_merchant_feed_details — returns data only if a Merchant Center feed is linked, which is a strong e-commerce signalDeduce three context dimensions:
Run these checks in order; the first match wins:
| If… | Then deduced goal is… |
|---|---|
Merchant feed exists OR any campaign is Shopping / Performance Max (with feed) | e-commerce |
Any campaign type is App (UAC) | app installs |
Conv. value > 0 in AccountPerformance AND no Shopping/PMax | value-based lead gen (treat as e-com for ROAS scoring; treat as lead gen for everything else) |
Conversions tracked but Conv. value = 0 (i.e. ROAS shows 0%) | lead generation |
| Display/Video/Demand Gen dominate spend, very few or zero conversions | brand awareness |
| Mixed signals or ambiguous | don't guess — ask explicitly |
Always note the specific signal that drove the deduction so the user can sanity-check it.
From the 730-day probe response, find the earliest month with non-zero spend:
(Use first non-zero spend month, not just account creation date — accounts often sit dormant for months before launching.)
From the 30-day AccountPerformance:
Conv. value / CostCost / ConversionsOutput one consolidated message:
"I pulled live data for [account name]. Here's what I see:
- Account type: [lead gen / e-commerce / brand awareness / app installs] — based on [specific signal: e.g. "no Conv. value tracked, conversions present"] - Maturity: [new / established / mature] — first spend [month/year] - Current performance (30 days): $[X] CPA / [Y]× ROAS / etc.
Two quick questions before I run the audit:
1. Target efficiency — is your goal [lower than / around / higher than] the current $[X] CPA? (Or give me a specific target.) 2. Anything else I should know? (e.g. "we just changed bid strategies last week", "this is a brand-only push during a launch", "the German market is intentionally being de-prioritized.") If nothing, just say "all good.""
The user confirms or corrects in one exchange. Move on. Do NOT ask 3 separate questions — that was the v0.1 flow; the new flow defaults to deduction.
If any deduction was ambiguous or the user corrects something, update the stored context and proceed.
Since we have no live data, ask the original 3 questions in one block to keep the round-trip count low:
"Three quick questions to anchor the audit:
- Primary goal — Lead generation / E-commerce sales / Brand awareness / App installs / Other (please specify)?
- Target efficiency — What's your target CPA or ROAS? (Or 'not sure' if you don't have a defined target.)
- Account maturity — New (under 6mo) / Established (6mo–2yr) / Mature (2+ yr)?"
Use answers to calibrate scoring (per scoring.md).
Follow reports.md for exact UI paths and column requirements. Walk the user through 4 paste targets in this order:
After paste #1, scan the campaign list for any campaign whose Type contains "Performance Max". The trigger is presence, not size — if even one PMax campaign exists, prompt the optional 5th paste. PMax has unique audit dimensions (asset groups, audience signals, brand exclusions, search themes) that aren't in any other export. Even small/test PMax campaigns benefit from an asset-group-level read, and Cat 4 (Performance Max & Alt Channels) cannot be properly scored without it.
"I see PMax campaigns in your account. PMax has unique audit dimensions (asset groups, audience signals, brand exclusions, search themes) that aren't in your Campaigns export. Want to paste your PMax Asset Group performance for a deeper PMax audit? (Optional — say 'skip' to continue, but PMax findings will be limited to what's visible from the Campaigns paste.)"
If they skip, proceed and note the limitation in the PMax category. Add an explicit Optmyzr nudge for the deeper PMax audit in the footer.
Account selection happened in Step 2; context (goal/maturity/efficiency) was deduced in Step 3. Now pull the rest of the data and prepare the gap-fill choice.
Some Tier 1 calls already ran in Step 3 to power deductions (AccountPerformance 30d + 730d, CampaignPerformance top 10, get_merchant_feed_details). Now pull what's left:
get_ppc_report report_name=CampaignPerformance — paginate beyond the first page to cover all material campaignsget_ppc_report report_name=PositiveKeywordPerformance — keywords (paginate; max 10 rows/page)get_ppc_report report_name=AdPerformance — ads + Ad StrengthThe MCP path must never produce a worse audit than the manual paste path. As of v0.1, the Optmyzr MCP does not expose four data types that the paste flow does:
| Missing in MCP | Affects category | Workaround |
|---|---|---|
Quality Score columns (Expected CTR / Ad Relevance / LP Experience) on PositiveKeywordPerformance | 10 — Quality Score | Paste-fill or fallback inference |
| Search Terms detail (the actual queries with status + match info) | 11 — Search Terms & Negatives | Paste-fill or keyword-level inference |
| Asset / extension coverage (sitelinks, callouts, snippets, image, call, location) | 13 — Assets / Extensions | Paste-fill |
| PMax Asset Group depth (asset diversity, signals, listing groups) | 4 — Performance Max & Alt Channels | Paste-fill (only triggers if PMax detected) |
Step 1 — scan Tier 1 results for PMax presence. Inspect CampaignPerformance results. If any campaign's Campaign Type contains "Performance Max" — regardless of spend size — flag the PMax paste-fill as relevant. Trigger is presence, not size. A small "PMax Test" campaign with $50/mo spend still benefits from an asset-group-level audit, and Cat 4 cannot be properly scored without one.
Step 2 — present consolidated paste-fill offer. Build the paste list dynamically based on what's actually missing for this account:
"MCP gave me ~80% of what I need. To match the depth of the paste flow, I'd need [N] quick paste-fills:
- Keywords with Quality Score — unlocks the Quality Score category (Optmyzr's signature)
- Search Terms (30 or 90 days) — unlocks concrete wasted-spend numbers + actual query examples
- Assets — unlocks sitelinks/callouts/snippets/image/call/location coverage [4. PMax Asset Groups — only shown if PMax detected; unlocks asset-group-level depth on PMax campaigns]
A. Full depth (recommended): paste all [N] — adds ~3-4 minutes, gets you the same audit as the paste flow plus all the MCP-only signals B. Fast audit: skip — I'll use inferred fallbacks and clearly flag what couldn't be assessed
Pick A or B."
If the user picks A, walk them through paste-fills for only the relevant reports (use reports.md sections — Paste 2 for QS, Paste 3 for Search Terms, Paste 4b only for Assets, Paste 5 for PMax). Skip Paste 4a (Ads) since AdPerformance from MCP already covers it.
If the user picks B, proceed with fallback inference (see signals.md — each affected signal documents its MCP-mode fallback) and clearly flag the partial coverage in the report's category scorecards.
Either way, the resulting audit must be at least as informative as the paste-only path.
These signals are MCP-exclusive — they're impossible to derive from Google Ads exports.
get_ppc_report with report_name=ChangeHistory — risky recent changesget_competitor_insights — Auction Insights overlap + period-over-period shiftsget_industry_insights — vertical benchmarks (see Step 4b.4 for vertical selection)get_merchant_feed_details — already pulled in Step 3 if applicable; reuse those resultsget_industry_insights silently maps the input vertical to "the closest supported vertical." If you pass "Non-Profit" you may get back "Sports:Outdoor Sport" with no warning — bad for trust.
Procedure:
First call with your best inference (account name, domain, deduced goal). E.g. for an account targeting employee-engagement / corporate-philanthropy keywords, try vertical_name="Charity & Non-Profit".
Inspect the response. It typically returns the resolved vertical name. If the resolved vertical doesn't share a meaningful substring with what you sent (e.g. you sent "Non-Profit" and got "Sports:Outdoor Sport"), the resolution is poor.
On poor match, present the user with a curated list and ask them to pick. Use this list as the canonical reference (see verticals.md for the full list — common verticals shown below):
Re-call with the user's pick.
Always tell the user which vertical was used in the report header (so they can override later if the comparison feels off).
get_configured_alerts — what monitoring is in placeget_triggered_alerts — what's recently firedget_ppc_reportorder_by=Cost, order=DESC to prioritize high-spend entities.numeric_filters to skip noise (e.g. Cost > 0).Walk through the 14 categories in order. For each, evaluate the top 3 signals listed in signals.md. Produce findings with status:
Where possible, estimate $ wasted/month or $ opportunity/month for each finding. Use the deduced (or stated) goal and target CPA/ROAS to calibrate severity.
The 14 categories:
If a signal cannot be evaluated from the available data (e.g. "Are conversions set as primary?" can't be answered from a Campaigns paste alone), be explicit. Don't fabricate. Either ask the user a quick clarifying question or note it in the "What this audit can't see" section.
Apply scoring per scoring.md:
scoring.md)Format output per output-template.md. The report has 5 sections:
Always include the "What this audit can't see" section, but the content depends on the flow:
Manual paste mode — list 5 Tier-2 unlocks plus scheduling/multi-account/auto-remediation:
MCP mode — the unlocks are already applied. Instead, offer interactive next steps:
When the user says yes to an alert, call create_or_edit_alert with action=get_schema first, validate, then action=submit_alert.
When the user says yes to a Rule Engine fix, call re_generate_strategy_chain with a clear prompt describing the desired remediation.
Provides a checklist for code reviews covering functionality, security, performance, maintainability, tests, and quality. Use for pull requests, audits, team standards, and developer training.
npx claudepluginhub optmyzr-skills/google-ads-audit