{"id":95450,"plugin_id":"plugin_asdk_app_6ac147f11c0081919882be44a32f3948","kind":"skill","collection_source":"plugin_package","comparison_source":null,"observed_at":"2026-11-13T18:11:43.911Z","digest":"a90710357cf01a202821cff4d1b36de09fca45ca88026385b0e880573097dad2","against":null,"payload":{"description":"Read a Google Ads account connected through AdCopilot and say what happened, what it cost, what is wasting money and what to change, then propose the change and apply it only when the customer says yes. Use when the user asks how their Google Ads are doing, or for a status, check, update, report, weekly summary or audit of the account; asks about spend, clicks, impressions, results, cost per result or budget; asks which keywords or search terms are wasting money, which negative keywords to add, what is working, or what to pause or fix; or asks what to do next about their ads. Reads the account instead of answering performance questions from memory.","included_files":[],"name":"adcopilot-review","skill_md_contents":"---\nname: adcopilot-review\ndescription: Read a Google Ads account connected through AdCopilot and say what happened, what it cost, what is wasting money and what to change, then propose the change and apply it only when the customer says yes. Use when the user asks how their Google Ads are doing, or for a status, check, update, report, weekly summary or audit of the account; asks about spend, clicks, impressions, results, cost per result or budget; asks which keywords or search terms are wasting money, which negative keywords to add, what is working, or what to pause or fix; or asks what to do next about their ads. Reads the account instead of answering performance questions from memory.\n---\n\n# AdCopilot review\n\nThe customer asked how their Google Ads are doing. Answer the whole question in\none pass, through the AdCopilot connector at `https://mcp.adcopilot.cloud/mcp`.\nA thin answer is the failure here. Reading the account is the easy part; a\ncustomer who has to ask four follow-up questions to learn what one answer could\nhave told them has been short-changed.\n\n## Start\n\nCall `get_org_context` first, before any other tool, and pass no `source`, on\nthis call or any later one. Then follow the answer's `next_step`, `playbook` and\n`cross_reads`: they carry the reads this answer starts with and its rules.\nEverything below runs inside them. `next_step` describes the account, not this\nrequest: do what the customer asked, pass on what it says about today's\noperations, and offer what it suggests afterwards unless this request already\ncovered it.\n\nAccount ids come from that answer. If more than one Google Ads account is\nswitched on and the customer did not say which, ask which. Never read an\naccount the answer does not list.\n\nIf Google Ads is not connected, no account is switched on, or the account\ncannot be read, say exactly that, in the server's words, and stop. The\n`adcopilot-connect` skill walks the customer through connecting. A report built\non guesses is worse than no report.\n\nThese rules hold throughout, whether or not the answer repeats them: reads run\nfreely; every change is proposed first and applied only after the customer's\nexplicit yes in this conversation; campaigns, ad groups, ads and keywords are\npaused, never removed (never set a status of REMOVED); a campaign AdCopilot\nbuilt is created paused, and the customer switches it on in Google Ads\nthemselves, never you. Dates go in as YYYY-MM-DD.\n\nOn an account with campaigns to read, which is when the answer's situation is\n`ADS_DORMANT`, `ADS_ACTIVE_UNTRACKED` or `ADS_ACTIVE_TRACKED`, the answer also\ncarries `question_map`: for each kind of question, the read that answers it\n(wasted spend, search terms and negatives, keywords, ads, budget, results\nchanged, tracking, what to do). Use it to choose the first read for a question\nthat is narrower than the whole account. It is absent when there is nothing to\nread, so when it is missing the list below stands in for it.\n\n## Make the reads the answer needs\n\n`cross_reads.ads_reads_max` is how many Google Ads reads the server says this\nanswer starts with: make them all, then every read `cross_reads` names. It is\nwhere the answer starts, not where it stops, except on a day the server itself\ncalls short, when `cross_reads.reads_left_today` is present: then the playbook's\nsection for few operations left today, or the hint that says how many look-ups\nare kept for the change, says where this answer stops, and you follow it. The\naccount's own numbers are what make the answer true, and a number you did not\nread is a number you must not state. Never trim the read list to be economical:\nif a read would have changed what you say, make it.\n\nIf the server refuses a read at the daily limit, say which reads ran and which\ndid not, answer only from the ones that ran, and do not retry in a loop. Then\ngive the server's own line about the limit, word for word, every time: it says\nthe count and when it resets, and a link when the server adds one. Calls\nrefused together carry it once (\"Not run: same daily limit as the call refused\njust before it.\"), so say it once. A call that worked can carry the same line,\nas `limit_notice` or as a `usage_notice` that says the limit is reached; pass\nthat on the same way. A read refused because it counts more than what is left\ntoday names the lighter reads that still fit: make those, then give its line.\n\nWhat you cannot read, say you cannot read. Never estimate a figure, and never\ncarry one over from an earlier turn as if it were fresh.\n\n## Follow `related_reads`\n\nWhen a lens or `search` result ends with `related_reads`, run the ones that bear\non the question, at most three, then answer from all you hold. Each names its\ntool, its arguments and a `why` built from the numbers of the result you just\nread; skip one that does not bear on what the customer asked. Never repeat a\nread you hold. Offer, do not chase, the `related_reads` those reads bring back.\nThey are reads only: a change is still only proposed, and waits for the\ncustomer's yes. A related read past those three is offered as the next read in\none statement, never a second question and never as a limit you hit (\"The next\nread would show how each campaign bids; say the word and I will run it.\").\nNever offer a read for what a result you hold already shows. A read you skipped\nbecause it does not bear on the question is neither offered nor mentioned, and\nthe figure in its `why` stays out of the answer.\n\n## A tool that is missing\n\nA tool that is missing from your list, refuses a parameter it should take, or\ncarries a revision different from the `tools_revision` the server reports is\nstale, not a permission the customer lacks. Call `get_org_context` with `tools`\nset to the names you need and go by what it returns; that works even when the\nschema you hold shows no `tools` parameter. If the tool is still missing, run\nthe reads you do have and report what they found for the dates their answers\ncover, say plainly that the tool list this session holds is out of date and\nwhich read you could not run, and say you will run it once the list is\nrefreshed. Point the customer to `https://adcopilot.cloud/docs/troubleshooting`\nfor how to refresh the connection. That is a step for them, not a change to the\naccount, so it is not put as a proposal and carries no cost lines. A missing\ntool halves an answer; it does not cancel it. Name no revision value to the\ncustomer.\n\n## The sequence\n\n**Open with `full_audit`, with `depth=\"deep\"` and `days` set to the window you\nare reporting.** Pass `depth=\"deep\"` explicitly. A call that names no depth also\nruns deep today, but if that run can't finish it falls back to a quick audit\n(the result says so); an explicit `deep` never does. A quick audit scores three\nof the seventy-three checks over the month to date, which is not an audit and\nnot what the customer asked for. Deep attempts all seventy-three over your\nwindow and says which it could not evaluate. Give coverage as the count the\nresult gives, \"N of 73 checks gave a result\", never as a percentage next to the\ncount, and give reasons for the rest only in the result's own words. An\nunevaluated check is not a pass, and a reason you supply yourself is a guess.\n\nOne lens is ONE read and covers what many hand-written queries would. It orders\nits findings by severity, NOT by money, so re-sort by cost before you choose the\nthree you report. For the cost ranking itself, `analyze_waste` is the read;\n`analyze_search_terms` names the searches that cost money and converted\nnothing, costliest first, and groups them into negative-keyword themes.\nTogether they usually answer step 3 below, so read it yourself only for what\nthey did not cover.\n\nA question narrower than the whole account starts with the lens that answers it\nrather than with `full_audit`: `analyze_waste` for money spent on nothing,\n`analyze_search_terms` for negatives, `keyword_opportunities` for keywords worth\nadding or fixing, `quality_score_breakdown` for ad rank and Quality Score,\n`rsa_asset_report` for the ad copy, `bidding_audit` for how campaigns bid,\n`day_of_week` for which days and hours earn, `budget_pacing` for budgets,\n`change_history` for what changed and who changed it, and\n`conversion_setup_audit` for what is counted. Do not write a `search` for what\none of these already returns: the lens reads the account the way Google counts\nit, and a hand-written query reads one slice of it.\n\nThen, in this order, each one the lenses you ran did not already answer:\n\n1. **The period against the one before it.** Campaign metrics by day for the\n   fourteen days ending on the account's yesterday (`search` over `campaign`,\n   with `segments.date`), folded into two weeks so every headline number has a\n   comparison. No lens returns a time series, so this read is yours to make.\n   End your own `search` reads on the `date_range.end` that `full_audit` and\n   the other lenses carry, and say the dates once. AdCopilot ends those\n   windows on the account's yesterday, the last full day in the account's own\n   time zone (UTC's, when it could not read the zone), so the audit and your\n   reads cover the same days. `budget_pacing` and `change_history` are the\n   exceptions: they run through the account's today, so give their dates on\n   their own and never end a `search` read on them. When a finding names a\n   shorter window, say its dates. If your own reads show a result after that\n   window, say so in the same sentence. A window a finding gives only as a\n   length ends on the result's `date_range.end` unless it says otherwise.\n2. **Where the money went inside that.** Which campaigns and which keywords\n   carried the spend, and which carried the results (`keyword_view`), unless\n   `full_audit` already ranked it.\n3. **What was paid for that should not have been.** The search terms with cost\n   and no conversions, worst first, which is often the largest finding.\n   `analyze_search_terms` is one read for six query shapes and all six\n   negative-keyword themes: use it, never `search_term_view` written by hand.\n   Before you give a count of searches, look for their names in every result\n   you hold: `analyze_search_terms`' \"Costliest search terms with no\n   conversion\" (the costliest first, with their clicks and cost, and how many\n   there are) and the wasted-spend check's evidence in `full_audit` or\n   `analyze_waste` (G16, each search with its clicks and cost). When one lists\n   them, name the top ones with their cost in this answer. When that list says\n   no conversion was recorded anywhere in the account, they cost the most and\n   are not proven waste: say so, and propose blocking one that fits no theme\n   only once tracking is checked. When what you hold only counts them (G16\n   lists none on an account that counted no result in its window), say how many\n   there are and what they cost, and that the reads count them without naming\n   them. Offer a read for searches no result you hold names only when a\n   `related_reads` entry's `why` says that read shows them; one that only names\n   the area, such as wasted spend, is not that promise.\n4. **Whether delivery is being held back.** `budget_pacing` is one read for the\n   month-to-date projection against each daily budget. A campaign at its cap\n   every day is turning away traffic the customer is willing to pay for, and\n   they cannot see it from the dashboard.\n5. **Whether results are being counted at all.** `conversion_setup_audit` is one\n   read for what is counted and what is aimed at. An account counting nothing\n   makes every other number meaningless, so say that first if it is true.\n6. **Whether anything is switched off by Google, and what changed.** Disapproved\n   ads are a `search` on `ad_group_ad` (no lens returns them). When spend,\n   results or cost per result moved against the period before, `change_history`\n   says what was changed in the account, when, by which Google login and through\n   which channel; when nothing moved, leave it. It keeps thirty days and omits\n   Google Ads Editor changes and some rows, so a quiet log does not prove\n   nothing changed; say that when the numbers moved and the log shows no cause.\n\nRead the account, never the profile's memory of it. A saved note is context for\nyour wording, never a substitute for a read. The decisions `get_org_context`\ncarries say what was approved on a date, not what is set now: a budget, a split\nor a setting you did not read this turn is not yours to state, and a thirty-day\nshare of impressions lost to budget describes the budgets of those thirty days,\nnot today's. Say the window, or read the latest day.\n\n## The answer\n\n**One headline line.** Spent, clicks, results, cost per result, each against the\nperiod before, in the account's own currency.\n\nThe lenses return amounts already formatted for the account (`*_display`); use\nthose words as they come. A raw `search` does not: it returns\n`metrics.cost_micros`, which is millionths. So take the period comparison from\n`full_audit`'s own figures where it covers the window, and where you must read\nit raw, divide by 1,000,000 once, say the currency, and never print a micros\nnumber as money.\n\n**Then at most three findings, biggest money first.** Each one carries the\ncounts behind it: what it cost, over what period, how many clicks or searches.\nA finding without a number is an opinion.\n\nA finding that says \"if X\" is not a step until you have checked X. Either make\nthe read it names and say what you found, or carry the condition into your own\nsentence. Never turn it into an instruction.\n\nOn a new account, keep what is only newness out of the findings. A new account\nscores badly for reasons that are only its age: keywords with no impressions\nyet, a Quality Score showing 0 because Google has not rated the keyword yet, a\nbidding strategy still learning. Say in one line which items those are, and do\nnot count them as problems.\n\n**Then one recommendation**, with the money spelled out both ways (what it costs\nto act and what it costs to do nothing) as a proposal they say yes or no to.\nNever apply it first.\n\nFor two to three weeks after anything went live, such as a campaign switched on\nor a change to how it bids or what it counts, recommend no bidding change:\nGoogle's bidding is still learning, and a change starts it over. The one\nexception is a campaign getting no traffic, where Maximize Clicks with a\nper-click cap is the fix.\n\nSay what each finding means in plain words the first time it appears. \"Search\nterms\" are the things people actually typed; \"negative keywords\" are the words\nyou tell Google never to match. Teach on the step being taken, and say what the\nstep unlocked, or will unlock once they have done it.\n\n## When the ask is a full audit, a weekly summary or negatives\n\nThe customer's own words pick the shape. These are the same reads as above,\nshaped for the ask. Nothing in them changes the account.\n\n### A full audit, a deep review or a health check\n\nThe answer is a written report that has to stand alone, and it runs longer than\nthe three-finding answer above. Run `full_audit` as described, then\n`budget_pacing`, then whatever of the sequence the audit did not cover. If the\naudit ends with `related_reads` because a section failed, follow them as above.\n`account_health_score` returns the score alone and is not a substitute for the\naudit.\n\nCover, in this order:\n\n1. **Whether results are counted at all.** If nothing is counted, say so first;\n   every other number is unanchored without it.\n2. **The period against the one before.** Spend, clicks, impressions, results\n   and cost per result, in the account's currency. Say the window in the\n   report's first line, and use the same number of days for the audit and the\n   comparison, dated as in step 1 of the sequence above, so the two cover the\n   same days.\n3. **Where the money went.** Campaigns, then ad groups, then keywords: which\n   carried the spend and which carried the results. Name the ones doing neither.\n4. **What was paid for and should not have been.** Search terms with cost and no\n   conversions, worst first, grouped: a competitor's brand, the wrong product,\n   the wrong language, plainly off-topic. Name the top ones with their cost, and\n   keep to step 3 of the sequence above on where their names are found, on \"not\n   proven waste\" and on a result that only counts them.\n5. **Whether delivery is held back.** Budgets at their cap every day, and\n   anything Google has disapproved or switched off.\n6. **Structure worth saying out loud.** One keyword or one campaign taking\n   nearly all the spend while the rest get none is a finding, not a detail.\n7. **What changed, and who changed it.** The last thirty days, by which Google\n   login and through which channel, so a budget or a bid that moved is\n   attributed and not listed as unknown. A quiet log does not prove nothing\n   changed; say so when the numbers moved and the log shows no cause.\n\nWrite the report in this shape. Open with the account (by the name Google Ads\nshows, not its number), the period, and one line on whether it is healthy. Then\nthe findings, biggest money first: what it is, what it cost over what period,\nthe counts behind it, and what you would do. No finding without a number. Then\nthe proposals, ordered by money saved, each with what it costs to act and what\nit costs to do nothing. Mark any proposal that cannot be undone through\nAdCopilot. A negative keyword is not one: each of the three ways to add one has\na removal behind it, under the same yes. The one-way action is attaching a\nshared negative-keyword list, because there is no matching detach tool; a list\nis detached in Google Ads under Tools, Shared library, Exclusion lists. If\nnothing in the report is one-way, say so. Then one line the reader needs:\nnothing above has been applied, and any of these changes happens only after the\ncustomer says yes in this conversation. A proposal with its cost and an undo\nbeside it reads as a change already made unless that line stands next to it.\nClose with what you could not check and why, so nobody mistakes a gap for a\nclean bill of health. Write plainly: no tool names, no field names, no account\nnumbers in the prose.\n\n### A weekly summary\n\nThe week runs Monday to Sunday in the account's time zone, which\n`get_org_context` gives, and the summary sets last week against the week before.\nFour reads, in this order:\n\n1. **The two weeks.** `search` on `campaign` with `start_date` and `end_date`\n   spanning both weeks, `segments.date` and the cost, clicks and conversions\n   metrics: each week's spend, conversions and cost per conversion, per campaign\n   and in total.\n2. **What changed.** `change_history` with `days` reaching back to last Monday\n   (at most thirty; keep only last week's changes): who changed what, when and\n   through which channel. It omits Google Ads Editor changes and some rows, so a\n   quiet log does not prove nothing changed; say that when the numbers moved and\n   the log shows no cause.\n3. **What Google switched off.** `search` on `ad_group_ad` with\n   `ad_group_ad.policy_summary.approval_status`, and on `campaign` with\n   `campaign.status` for the campaigns that are no longer on: any ad disapproved\n   or limited, with Google's stated reason, and any campaign stopped. The change\n   log does not hold a disapproval, so read 2 cannot stand in for this one.\n4. **This month.** `budget_pacing`: whether the month is on track.\n\nSay the two weeks' dates once, in the first line. A result that covers other\ndates, such as this month's pacing, is given with its own. When a finding names\na shorter window, say its dates. If your own reads show a result after that\nwindow, say so in the same sentence.\n\nThen the summary, in this order, in plain words someone could forward without\nediting:\n\n- **The week.** Spend, conversions and cost per conversion, each against the\n  week before, money in the account's currency, rounded.\n- **The three biggest changes.** The largest moves in the numbers (a campaign\n  whose spend or conversions moved most), the changes someone made and who made\n  them, and anything Google switched off itself. Say which is which.\n- **Three things to do this week.** Each one concrete, each tied to a number\n  above, the most valuable first.\n\nNo account numbers and no field names. A week with no spend says so in one line,\nand says what that means. Change nothing: all three are proposals, and the one\nquestion, if any, is which to start with.\n\n### Negatives\n\nWhen the ask is about searches that cost money and brought nothing, or about\nnegative keywords, read `analyze_search_terms` with `days: 7` for the last week\n(or the window the customer named). It groups the searches that took clicks and\nconverted nothing into themes (people looking for jobs, for something free, for\ninformation, for a competitor, searches in another language, and the words this\nworkspace already said it never wants to show for) and names a ready call for\neach theme. It also lists the costliest of them, any theme or none, with no\nready call (\"Costliest search terms with no conversion\"): name the top ones, and\nleave one that fits no theme to the customer, as it can be what they sell. When\nit says nothing was recorded anywhere in the account, say they cost the most and\nare not proven waste. Seven days can hold too few searches to show a pattern;\nif the tool finds nothing, say so and offer the last 30 days instead.\n\nReport each theme in plain words: the searches, what they cost in the account's\ncurrency, and the never-show-for words that would block them, each with its\nmatch type said out loud (Phrase or Exact; the tool never proposes Broad, and\nneither do you). Google's name for them is negative keywords (under Keywords,\nthen Negative search keywords, at the time of writing). Say where each would go:\nthe campaign that paid for the searches, or the account's own list for words the\nbusiness never wants anywhere, which every search campaign then inherits. A\ncompetitor's name is the customer's call, not yours. The one question is which\nthemes to block, and nothing is added until they answer.\n\nOn a yes, `add_negative_keywords` puts them on a campaign and\n`add_account_negatives` on the account's list. Then read them back with `search`\non `campaign_criterion` (the campaign's negative keywords) or on\n`shared_criterion` (the account's list, by the shared set the add call\nreturned), and say what is now blocked, in the words Google shows.\n\n## When they say yes\n\nA yes counts when it is given here, to the change as you stated it, on today's\nnumbers. A fix agreed in an earlier conversation is read again and proposed\nagain before anything is applied; nothing carries over.\n\nApply it. Then read back only what its own result does not show (a status,\nnegatives once Google has normalised them, locations by the name Google shows)\nand call nothing live until a read says so. Say exactly what changed and how to\nundo it, and record it with `save_org_context` as a decision: what was approved,\nin the customer's own framing, and which campaign it touched. A fix they did not\nsay yes to is recorded, if at all, as proposed and not applied; never as\napproved. Record nothing about the business that the customer has not said\nthemselves.\n\nThen propose the next finding's fix the same way: the change, its money both\nways, a yes or a no. One at a time, biggest money first. When nothing left is\nworth its money, say so and stop proposing.\n\nNegatives go on with `add_negative_keywords` at PHRASE match using the search as\ntyped, unless a broader word is plainly safe. Read them back before claiming\nthey are live. A negative can be taken back out through AdCopilot (there is a\nremoval behind each of the three ways to add one, under the same yes), so it is\nreversible, and you may say so.\n\nCampaigns and keywords are paused, never removed. A campaign you built is never\nswitched on by you. Pause a campaign, or switch one on, only with\n`set_campaign_status`, never with a status in `update_campaign`, which is for a\ncampaign's settings.\n\n## What breaks\n\nAnswering from the summary `get_org_context` returns alone: it carries a\nthirty-day total and nothing about which search terms wasted money, so the\nanswer sounds informed and helps with nothing. Reporting a number without its\ncomparison: \"₹8,700 last week\" means nothing until it sits next to the week\nbefore. Proposing negatives without reading the terms they block: a phrase\nnegative is a blunt instrument and a careless one blocks searches the customer\nwants.\n\nCalling anything a limit that no call returned. Say daily limit, quota or\n\"today's look-ups\" only when the server refused a call because the day's\nallowance was used up, or its own answer says the day is short. A read you did\nnot make is an offer for the next turn, never a limit you hit, and it needs no\nreason.\n\n## What is next\n\nBefore any yes, offer, in this order: the first fix as a change you will make\nnow; and the never-show-for words you found. After a yes, the next offer is the\nnext fix, as above. If the answer shows tracking is broken, the\n`adcopilot-measure` skill is where that gets fixed; if the customer wants new\ncampaigns, `adcopilot-launch` is. Offer the one that fits, after the fix in\nfront of them.\n\nAdCopilot can also email a daily check-in and a Monday summary. If\n`get_org_context`'s `next_step` asks you to offer them, make that offer once in\nthe conversation, at the close and before any question the reply ends on, in\nthe server's words and with only the address the server names. The offer is its\nown paragraph, with a blank line before and after it, never on the end of a\nfinding's sentences and never inside a bullet. Do not make it when the server\nreports one is already on (`routine.daily.status` is `in_app` and\n`routine.runner` is not `paused`), or when the reply ends on something the\ncustomer must fix first. A no ends it for this conversation. Say nothing of\nyour own about scheduling beyond what the server's answer says.\n"},"changes":[],"summary":"First saved snapshot. No earlier version is available for comparison.","summary_kind":"deterministic","summary_metadata":{}}