/diagnose-underperformer
Diagnose why a specific Google Ads or Meta Ads campaign / ad set / ad is underperforming and prescribe the next concrete action. Use when the user says something like "why is X not converting?", "this campaign is wasting money", or "why are impressions so low?". Read-only — no
$ npx -y skills add markifact/markifact-mcp --agent claude-codeShips with markifact. Installing the plugin gets this command.
How it fires
How this command gets triggered: by you, by Claude, or both.
- Fires itselfClaude auto-loads it when your prompt matches the work.
- You can call itInvoke it directly when you want it.
- Slash command
/diagnose-underperformer
Context preview
What this command does when you run it.
Diagnose why a specific Google Ads or Meta Ads campaign / ad set / ad is underperforming and prescribe the next concrete action. Use when the user says something like "why is X not converting?", "this campaign is wasting money", or "why are impressions so low?". Read-only — no
Command definition
diagnose-underperformer.mddescription: Diagnose why a specific Google Ads or Meta Ads campaign / ad set / ad is underperforming and prescribe the next concrete action. Use when the user says something like "why is X not converting?", "this campaign is wasting money", or "why are impressions so low?". Read-only — no changes are made.
argument-hint: [target, e.g. "campaign Spring Sale" or "Meta ad set 123"]
Goal
Pull the right report, walk a structured decision tree, and hand the user a ranked list of likely causes with the **specific next op to call** to fix it. No writes — diagnosis only.
Inputs to confirm (batch)
1. Account name (substring) — required. 2. Target — campaign / ad set / ad name or ID — required. 3. Date range — default last 14 days; if the entity is < 14 days old, use its lifetime. 4. Comparison window (optional) — previous 14 days, for trend. 5. Primary KPI — conversions / ROAS / CPA / CPL — required if the entity has a conversion goal.
Workflow
1. **Discover** ops. For Google Ads: `gads_select_accounts`, `gads_list_report_fields`, `gads_get_report`, `gads_get_account_history`. For Meta: `meta_ads_select_accounts`, `meta_ads_list_report_fields`, `meta_ads_get_report`, `meta_ads_get_account_history`, `meta_ads_get_adset_settings`, `meta_ads_get_campaign_settings`. 2. **Inspect** with `get_operation_inputs`. **Always call `*_list_report_fields` before `*_get_report`** — never guess metric/dimension names. 3. **Resolve account** with substring match. 4. **Pull the report** at the right granularity (campaign / ad set / ad). Required metrics:
- Spend, impressions, clicks, CTR, CPC, conversions, conv rate, CPA / ROAS, frequency (Meta), search impression share + lost-to-budget + lost-to-rank (Google Search).
5. **Pull settings/history** to check for recent edits that could have triggered the dip:
- Google: `gads_get_account_history` filtered to this campaign — look for budget changes, bid strategy switches, status flips, asset changes.
- Meta: `meta_ads_get_campaign_settings` / `meta_ads_get_adset_settings` for current state, `meta_ads_get_account_history` for recent changes.
6. **Walk the decision tree below** and rank the matching diagnoses by likelihood + impact. 7. **Present**: top 3 diagnoses, evidence from data, and the exact next op to call (or the matching slash command). Do not run any write op.
Decision tree
Branch A — Low impressions / low spend (entity not delivering)
| Signal | Diagnosis | Next action | |---|---|---| | Google: search impression share lost to budget > 20% | Budget-capped | Raise daily budget or use `/markifact:negative-keyword-sweep` to free spend | | Google: search impression share lost to rank > 30% | Bid / Quality Score too low | Raise CPC bid (manual) or improve ad relevance (Quality Score components) | | Google: campaign status `LIMITED` (account history) | Eligibility / policy / payment / learning | Inspect `gads_get_account_history` for the cause; route based on subtype | | Meta: ad set status `IN_REVIEW` or `REJECTED` | Policy | Check creative against Meta policies; replace creative | | Meta: estimated audience size < 500K and CBO is on | Audience too narrow + CBO starved it | Widen audience or move to ABO with fixed budget | | Meta: > 4 ad sets in same campaign with CBO | Auction overlap, CBO concentrating spend on one | Consolidate ad sets or split into separate campaigns | | Both: budget set but daily spend << budget | Bid too low for the auction OR audience tiny OR creative not eligible | Inspect bid + audience size + creative status |
Branch B — Spending normally, low CTR
| Signal | Diagnosis | Next action | |---|---|---| | Meta: frequency > 3.5 + CTR dropping WoW | Creative fatigue | `/markifact:rotate-creative` | | Google: RSA ad strength `Poor` / `Average` | Weak asset variety | Add more headline variety, re-create RSA | | CTR way below industry baseline (Search < 3%, Meta feed < 0.8%) and frequency low | Wrong audience or weak hook | Tighten targeting; try a new creative angle | | Branded search CTR < 5% | Competitor bidding on brand or weak ad copy | Check `gads_ads_transparency` for competitors; strengthen brand copy / pin brand headline |
Branch C — Good CTR, low conversion rate
| Signal | Diagnosis | Next action | |---|---|---| | Bounce rate high in GA4 / time on page short | Landing page mismatch | Send fresh LP variant; consider `/markifact:edit-meta-creative` to swap URL | | Conversion event firing but CVR < 0.5% | LP friction / wrong offer / wrong audience intent | Audit funnel; consider gating with a softer CTA | | Conversion not firing at all in last 7 days | Pixel / tag broken | Meta: `meta_ads_check_capi_health` and `meta_ads_get_pixel_stats`; Google: check conversion action import from GA4 | | Mobile CVR << desktop CVR | Mobile LP problem | Fix mobile LP; consider device bid adjustment |
Branch D — Good CVR, low overall conversions
| Signal | Diagnosis | Next action | |---|---|---| | Spend capped (see Branch A signals) | Budget-bound winner | Raise budget incrementally (≤ 20%/day on Smart Bidding) | | Audience small + saturated (Meta freq > 4) | Audience exhausted | Build lookalike from converters; expand interests | | Strong perf only on weekends | Schedule misalignment | Adjust ad schedule / bid by hour |
Branch E — Sudden performance drop
| Signal | Diagnosis | Next action | |---|---|---| | Account history shows a bid strategy switch in the last 14 days | Bid strategy reset learning | Either revert or wait 14 days; warn about future switches | | Budget cut > 30% recently | Underfunded learning | Restore budget or accept slower learning | | Creative replaced recently with major change | Soft learning reset | Wait 7 days before judging | | Seasonal / industry-wide | Compare to category trend | Note and move on; not a config issue |
Platform-specific rules the model MUST respect
- **`list_report_fields` first.** Field names differ per platform; never guess.
- **Account-name su
Read more
description: Diagnose why a specific Google Ads or Meta Ads campaign / ad set / ad is underperforming and prescribe the next concrete action. Use when the user says something like "why is X not converting?", "this campaign is wasting money", or "why are impressions so low?". Read-only — no changes are made. argument-hint: [target, e.g. "campaign Spring Sale" or "Meta ad set 123"]
Goal
Pull the right report, walk a structured decision tree, and hand the user a ranked list of likely causes with the **specific next op to call** to fix it. No writes — diagnosis only.
Inputs to confirm (batch)
1. Account name (substring) — required. 2. Target — campaign / ad set / ad name or ID — required. 3. Date range — default last 14 days; if the entity is < 14 days old, use its lifetime. 4. Comparison window (optional) — previous 14 days, for trend. 5. Primary KPI — conversions / ROAS / CPA / CPL — required if the entity has a conversion goal.
Workflow
1. **Discover** ops. For Google Ads: `gads_select_accounts`, `gads_list_report_fields`, `gads_get_report`, `gads_get_account_history`. For Meta: `meta_ads_select_accounts`, `meta_ads_list_report_fields`, `meta_ads_get_report`, `meta_ads_get_account_history`, `meta_ads_get_adset_settings`, `meta_ads_get_campaign_settings`. 2. **Inspect** with `get_operation_inputs`. **Always call `*_list_report_fields` before `*_get_report`** — never guess metric/dimension names. 3. **Resolve account** with substring match. 4. **Pull the report** at the right granularity (campaign / ad set / ad). Required metrics:
- Spend, impressions, clicks, CTR, CPC, conversions, conv rate, CPA / ROAS, frequency (Meta), search impression share + lost-to-budget + lost-to-rank (Google Search).
5. **Pull settings/history** to check for recent edits that could have triggered the dip:
- Google: `gads_get_account_history` filtered to this campaign — look for budget changes, bid strategy switches, status flips, asset changes.
- Meta: `meta_ads_get_campaign_settings` / `meta_ads_get_adset_settings` for current state, `meta_ads_get_account_history` for recent changes.
6. **Walk the decision tree below** and rank the matching diagnoses by likelihood + impact. 7. **Present**: top 3 diagnoses, evidence from data, and the exact next op to call (or the matching slash command). Do not run any write op.
Decision tree
Branch A — Low impressions / low spend (entity not delivering)
| Signal | Diagnosis | Next action | |---|---|---| | Google: search impression share lost to budget > 20% | Budget-capped | Raise daily budget or use `/markifact:negative-keyword-sweep` to free spend | | Google: search impression share lost to rank > 30% | Bid / Quality Score too low | Raise CPC bid (manual) or improve ad relevance (Quality Score components) | | Google: campaign status `LIMITED` (account history) | Eligibility / policy / payment / learning | Inspect `gads_get_account_history` for the cause; route based on subtype | | Meta: ad set status `IN_REVIEW` or `REJECTED` | Policy | Check creative against Meta policies; replace creative | | Meta: estimated audience size < 500K and CBO is on | Audience too narrow + CBO starved it | Widen audience or move to ABO with fixed budget | | Meta: > 4 ad sets in same campaign with CBO | Auction overlap, CBO concentrating spend on one | Consolidate ad sets or split into separate campaigns | | Both: budget set but daily spend << budget | Bid too low for the auction OR audience tiny OR creative not eligible | Inspect bid + audience size + creative status |
Branch B — Spending normally, low CTR
| Signal | Diagnosis | Next action | |---|---|---| | Meta: frequency > 3.5 + CTR dropping WoW | Creative fatigue | `/markifact:rotate-creative` | | Google: RSA ad strength `Poor` / `Average` | Weak asset variety | Add more headline variety, re-create RSA | | CTR way below industry baseline (Search < 3%, Meta feed < 0.8%) and frequency low | Wrong audience or weak hook | Tighten targeting; try a new creative angle | | Branded search CTR < 5% | Competitor bidding on brand or weak ad copy | Check `gads_ads_transparency` for competitors; strengthen brand copy / pin brand headline |
Branch C — Good CTR, low conversion rate
| Signal | Diagnosis | Next action | |---|---|---| | Bounce rate high in GA4 / time on page short | Landing page mismatch | Send fresh LP variant; consider `/markifact:edit-meta-creative` to swap URL | | Conversion event firing but CVR < 0.5% | LP friction / wrong offer / wrong audience intent | Audit funnel; consider gating with a softer CTA | | Conversion not firing at all in last 7 days | Pixel / tag broken | Meta: `meta_ads_check_capi_health` and `meta_ads_get_pixel_stats`; Google: check conversion action import from GA4 | | Mobile CVR << desktop CVR | Mobile LP problem | Fix mobile LP; consider device bid adjustment |
Branch D — Good CVR, low overall conversions
| Signal | Diagnosis | Next action | |---|---|---| | Spend capped (see Branch A signals) | Budget-bound winner | Raise budget incrementally (≤ 20%/day on Smart Bidding) | | Audience small + saturated (Meta freq > 4) | Audience exhausted | Build lookalike from converters; expand interests | | Strong perf only on weekends | Schedule misalignment | Adjust ad schedule / bid by hour |
Branch E — Sudden performance drop
| Signal | Diagnosis | Next action | |---|---|---| | Account history shows a bid strategy switch in the last 14 days | Bid strategy reset learning | Either revert or wait 14 days; warn about future switches | | Budget cut > 30% recently | Underfunded learning | Restore budget or accept slower learning | | Creative replaced recently with major change | Soft learning reset | Wait 7 days before judging | | Seasonal / industry-wide | Compare to category trend | Note and move on; not a config issue |
Platform-specific rules the model MUST respect
- **`list_report_fields` first.** Field names differ per platform; never guess.
- **Account-name su
Showing the first part of this file.
Manage Google Ads, Meta Ads, TikTok Ads, LinkedIn Ads, Microsoft Ads, Reddit Ads, Pinterest Ads, Snapchat Ads, Amazon Ads, DV360, GA4, BigQuery, Google Search Console, Google Business Profile, Google Merchant Center, Facebook, Instagram, LinkedIn, Shopify,
Other commands on markifact.
- /edit-meta-creative
Edit a Meta ad's creative content — landing page URL, primary text, headline, description, CTA, link description — across one ad or many. Use when the user says "change the URL on my ads", "update the copy", "swap the CTA", or anything that changes what an existing Meta ad
Open command - /launch-google-search
Launch a complete Google Ads Search campaign — campaign, ad group, responsive search ads, keywords, sitelinks, callouts, and negatives — built paused and ready to review. Use when the user wants to spin up a new Search campaign on Google Ads.
Open command - /launch-meta-campaign
Launch a complete Meta Ads campaign — campaign, ad set, and ad(s) — built paused and ready to review. Use when the user wants a new Facebook/Instagram campaign.
Open command - /launch-pmax
Launch a Google Ads Performance Max campaign with a complete asset group, audience signals, and (for ecom) listing groups. Built paused for review. Use when the user wants a new PMax campaign.
Open command - /negative-keyword-sweep
Find wasted spend in Google Ads search terms and add negatives at the right scope (account list, campaign, or ad group). Use when the user says "find junk keywords", "stop wasting on bad searches", or wants a search-terms cleanup.
Open command - /rotate-creative
Pause fatigued ads and ship fresh creative variants in their place. Works on both Meta and Google Ads. Use when CTR is dropping, frequency is climbing, or the user says "creative is tired" / "let's refresh ads". Always starts new variants paused.
Open command

