Agent skills reference
Skill workflow reference
Detailed specification for each of the five propose-only skills the SpendSignoff operator runs. What each skill reads, when it fires, what a draft looks like, and what the 24h envelope means per skill.
All five skills are propose-only
propose_change. The resulting Draft sits in the approval queue until you run the two-step Approve and push live → Confirm control. There is no mcp.approve scope — the AI client cannot confirm its own drafts.Skill 1 — Budget reallocation
Finds spend stranded on under-performing campaigns and ad sets, then drafts a shift toward the ones converting. It moves nothing on its own. The draft shows the exact dollar amounts moving, the before and after daily budgets, and the projected ROAS impact.
Trigger condition
Fires when one or more campaigns have a cost-per-conversion more than 25% above the account target CPA over the trailing 7 days, while at least one other campaign in the same account is converting at or below target. Both conditions must be true; the skill will not draft a shift if there is nowhere better to move the budget.
What it reads
Calls get_account_snapshot for pacing, then get_performance with a 7-day window to pull cost, conversions, CPA, and ROAS per campaign and ad set. Read-only — mcp.read scope only at this stage.
Draft shape
Calls propose_change with type budget_reallocation. The payload contains: source campaign ID + current daily budget, destination campaign ID + current daily budget, proposed delta in account currency, and a rationale string quoting the CPA gap. The approval queue shows a two-column before → after diff.
24h envelope
The draft amount is sized so the net daily spend change fits inside the account's envelope ceiling. If the optimal shift would exceed the ceiling, the skill drafts the largest amount that fits and notes the cap in the rationale. A second shift cannot be drafted until 24 hours after the first approved change.
Skill 2 — Bid tuning
Compares current bids against measured cost-per-conversion and drafts per-entity bid changes where the gap is costing money. Each change is a targeted diff — not a blanket sweep — so you approve exactly which keywords or audiences move and by how much.
Trigger condition
Fires when a keyword or audience bid is more than 30% above the implied max CPC derived from target CPA and measured CVR, or more than 30% below it and the entity is converting. At least three conversions in the trailing 14 days are required before the skill will touch a bid — below that volume it has no signal.
What it reads
Calls query_entities for keyword and audience bids, then get_performance with a 14-day window. Derives implied max CPC as target_cpa × cvr per entity.
Draft shape
One propose_change call per entity, type bid_adjustment. Payload: entity ID, entity type (keyword / audience), current bid, proposed bid, implied max CPC, and conversion count that justified the signal. The queue groups these into a single reviewable set if multiple entities fire in the same cycle.
24h envelope
Bid changes do not directly move spend, so they are not counted against the spend delta ceiling. However, the skill is still rate-limited: it produces at most one batch of bid drafts per 24-hour window per account, regardless of how many entities qualify.
Skill 3 — Pacing fix
Catches campaigns spending too fast or too slow against their daily budget window and drafts a correction sized to bring end-of-day spend back on track. You see the projected end-of-day spend before you confirm.
Trigger condition
Fires when a campaign's spend-to-time ratio at the current hour implies it will over-deliver by more than 15% or under-deliver by more than 20% by midnight in the account timezone. Evaluated once per loop cycle; the skill skips campaigns with shared budgets — those require a manual review.
What it reads
Calls get_account_snapshot for today's spend-so-far, then reads the campaign daily budget and the account timezone from query_entities. Computes spend rate as spend_so_far / (current_hour / 24).
Draft shape
Type budget_pacing_fix. Payload: campaign ID, current daily budget, proposed daily budget (the corrected value), projected end-of-day spend at current rate, projected end-of-day spend at proposed rate, and the account-local hour the draft was generated. The queue shows both projections side by side.
24h envelope
The corrected budget is capped so the implied remaining spend for today does not exceed the envelope ceiling. If correcting the pacing would require exceeding the ceiling, the skill drafts the largest correction that fits and adds a warning to the rationale. A correction drafted in the morning may become stale by afternoon — the queue shows the generation timestamp so you can re-evaluate before approving.
Skill 4 — Anomaly triage & alerts
Watches for the breaks: a spend spike, a CTR collapse, a disapproved ad, a budget about to exhaust. When it trips, it raises an alert and — where there is a safe corrective move — drafts that move alongside the alert. The alert is informational; the fix is always a draft you approve. The skill never pauses or edits the account on its own.
Trigger conditions
Any of the following trips the skill: spend in the last hour is more than 3× the hourly average for the trailing 7 days; CTR drops more than 40% day-over-day for a campaign with at least 500 impressions; one or more ads enter a disapproved or limited status; daily budget is more than 90% exhausted before 18:00 account-local time.
What it reads
Calls get_account_snapshot for current status flags, then get_performance with a 1-day and 7-day window to compute the anomaly ratios. Ad status is read via query_entities with a status filter.
Draft shape
Always emits a notification event first. If a corrective draft is possible (e.g., pausing a runaway ad set), calls propose_change with type anomaly_response. Payload: anomaly type, affected entity ID, observed metric value, threshold that was crossed, and the proposed corrective field change. The queue renders the alert banner above the diff so you have context before acting.
24h envelope
Anomaly-response drafts count against the envelope like any other spend-affecting change. If the envelope is exhausted, the skill still raises the alert but notes it cannot produce a corrective draft until the window resets. You can approve the situation manually — only autonomous drafts are gated.
Skill 5 — Creative rotation
Reads creative-level performance and drafts a rotation: pausing fatigued creatives whose CTR has decayed and shifting delivery toward variants still earning clicks. It proposes which creatives go quiet and which get more room — as a reviewable diff. Nothing is paused or promoted until you approve.
Trigger condition
Fires when a creative has served at least 5,000 impressions in the trailing 14 days and its CTR has declined more than 30% compared to its own 7-day-prior baseline. A replacement creative must exist in the same ad set with a higher or flat CTR trend — the skill will not draft a pause if there is nothing to rotate toward.
What it reads
Calls get_performance at the creative level with a 14-day window, then computes week-over-week CTR delta per creative within each ad set. Reads creative status via query_entities to confirm the replacement is active and not disapproved.
Draft shape
Type creative_rotation. Payload: fatigued creative ID + current status + CTR trend, replacement creative ID + CTR trend, ad set ID, and the impression and CTR values that justified the signal. The queue shows the creative names (or IDs if names are unavailable), the CTR delta, and the proposed status change side by side.
24h envelope
Creative pauses do not directly change spend, so they are not counted against the spend delta ceiling. Like bid changes, the skill produces at most one creative-rotation batch per 24-hour window per account. If multiple ad sets qualify, the skill prioritizes the one with the largest absolute CTR decline and defers the rest to the next cycle.
Shared invariants across all five skills
- Every skill runs with
mcp.readandmcp.draftscopes only. There is nomcp.approvescope. - A skill that finds nothing worth changing emits nothing. No filler drafts reach the queue.
- Every draft a skill writes is logged in the KMS-signed append-only audit log — including drafts you reject.
- Skills do not chain. Approving a budget draft does not trigger a bid draft in the same cycle.
- The 24h envelope applies at approval time, not draft time. A draft that looks valid when generated may be blocked at approval if a prior approval in the same window already consumed the ceiling.
Next
Autonomy loop
How the loop schedules these skills, what it reads each cycle, and how drafts reach your queue.