Meta ads automation agent: build a 24/7 ad ops loop
How to deploy a Claude Code cron agent that pauses fatigued ads, drafts competitor hooks, and briefs you every Monday.

Sections
A meta ads automation agent isn't a magic dashboard. It's a piece of software you've signed a contract with — and the contract terms determine whether you sleep well or wake up to a burned budget. Most operators build the automation first and write the contract never. That's why their agents drift, overspend, and produce alerts nobody reads. This post walks through building the contract first, then the cron loops that execute it, using Meta Ads MCP and adlibrary as the signal layer.
TL;DR: A 24/7 meta ads automation agent built on Claude Code and Meta Ads MCP runs three cron loops — fatigue auto-pause, competitor-hook draft, and Monday brief — all triggered by adlibrary signals, not Meta dashboards. Define your delegation contract (decide / draft / escalate) before writing a single line of cron config, or the agent will be unobservable and ungovernable within a week.
The delegation contract: what your agent is actually for
Hiring a human junior buyer means signing an implicit employment contract: here's what you can approve, here's what you draft for review, here's what you escalate immediately. A 24/7 meta ads agent needs the same contract in writing — because software doesn't have judgment, only scope.
The contract has three buckets:
Decide — actions the agent executes without human review. Pause an ad set that hits a frequency threshold. Cap daily spend when CPA) drifts 30% above target. These are mechanical, reversible, and bounded.
Draft — actions the agent proposes but does not take. A new creative angle built from a competitor hook found on adlibrary. A bid adjustment crossing a dollar threshold you've defined. The agent writes the proposal and routes it to Slack; you approve or reject.
Escalate — conditions where the agent stops acting and pages you. Budget exhaustion approaching. An ad account flag. A creative entering review for the third time.
Automation without escalation policy is just an unobservable junior buyer — one who keeps spending, keeps pausing, and keeps drifting until the month-end report reveals the damage. Define the three buckets first. The cron is the execution layer.
Step 0: every loop starts on an adlibrary signal
This is the design decision most operators get wrong. They point their meta ads automation agent at Meta's own ads_insights_anomaly_signal endpoint and assume that's where intelligence lives. It isn't. Meta surfaces account-level anomalies after the fact. adlibrary surfaces what the entire market is doing right now.
Every loop starts with a query to adlibrary's API. The fatigue loop starts with a timeline pull from ad-timeline-analysis to see which creative formats competitors have already rotated away from. The competitor-hook loop starts with a query to adlibrary's unified ad search for new in-market ads from your ICP category, enriched by ai-ad-enrichment to extract hook structure. The Monday brief loop starts by pulling the last seven days of competitor creative activity from adlibrary's /api/ads/*/timeline endpoint.
Only after the adlibrary signal is fetched does the agent call Meta Ads MCP at mcp.facebook.com/ads. The adlibrary layer tells the agent what's worth acting on. The MCP layer is where it acts.
This is the same pattern described in agentic marketing workflows with Claude Code-marketing-workflows-with-claude-code): external signal → reasoning → action. Never action-first.
Architecture in five boxes
The full 24/7 ad ops agent has five components. Each has a single job.
Cron scheduler — triggers the agent on a schedule. A standard cron daemon on Linux or macOS launchd. Here is the actual config this architecture uses:
# /etc/cron.d/adlibrary-meta-ops
# Every 4 hours: fatigue scan + paused-draft proposals
0 */4 * * * murat /usr/local/bin/claude-code run /Users/murat/agents/fatigue-loop.md
# Every Monday 08:00: weekly brief
0 8 * * 1 murat /usr/local/bin/claude-code run /Users/murat/agents/monday-brief.md
Signal puller — queries adlibrary's /api/search and /api/ads/*/timeline endpoints to get current market state. This is a Claude Code tool call, not a custom script.
Claude reasoning loop — Claude Code running against a markdown prompt file that encodes the delegation contract. It reads the adlibrary signal, reads the Meta account state via ads_update_entity, and decides: execute, draft, or escalate.
MCP action layer — Meta Ads MCP is the only write path to your account. The agent calls it only when the delegation contract says "decide." Every call is logged.
Escalation channel — a Slack webhook. When the contract says "draft" or "escalate," the agent posts a structured message with the proposed action, the reasoning, and the approval/reject interface.
For the MCP layer setup, see the Meta Ads MCP setup guide.
Loop 1: fatigue auto-pause (the low-risk first step)
Fatigue auto-pause is the safest autonomous action in your delegation contract because it's mechanical, reversible, and easy to audit. Start here.
Trigger: Every four hours, the cron fires fatigue-loop.md. The meta ads automation agent queries adlibrary's ad-timeline-analysis for your top competitor categories. It looks for creative formats running heavily 14 days ago that have since dropped — a leading indicator those hooks have exhausted their audiences. It then pulls your active ad sets via the Meta Marketing API insights endpoint and computes frequency against the thresholds you've defined in the prompt. Use the frequency cap calculator to set your starting values.
Decision rule (inside the prompt):
IF ad_set.frequency >= contract.frequency_hard_cap
AND ad_set.spend_last_7d >= contract.min_spend_to_act
AND adlibrary_signal.format_in_category_dropoff == true
THEN: pause ad_set via ads_update_entity [DECIDE — no approval required]
ELSE IF ad_set.frequency >= contract.frequency_soft_cap
THEN: draft Slack proposal [DRAFT — requires approval]
Log line (mandatory for every action):
[FATIGUE-PAUSE] 2026-05-05T08:00:01Z | ad_set_id=23847291 | action=PAUSED | frequency=4.2 | adlibrary_signal=video_format_dropoff_7d | spend_protected=$0 | reversible=true
Every agent action must write a log line in this format — not for debugging, but for the weekly audit that tells you whether the contract is calibrated correctly.
Run the learning phase calculator before setting your min_spend_to_act threshold. Pausing an ad set mid-learning costs more than the frequency damage.
Loop 2: new competitor hook → paused draft
This is medium-risk because creative quality is harder to encode in a threshold than frequency. The agent drafts; it never publishes autonomously here.
Trigger: The same 4-hour cron checks for new competitor ads on adlibrary. The agent calls /api/search for your ICP category, filtered to ads first seen in the last 48 hours, and passes results through ai-ad-enrichment to extract hook structure: the opening claim, the emotional mechanism, and the proof format.
The prompt structure for hook extraction:
System: You are an ad analyst. Extract the hook structure from each ad below.
For each ad return:
- hook_type: [claim | question | story | social_proof | contrast]
- opening_claim: (exact words, ≤15 words)
- emotional_mechanism: (what desire or fear it activates)
- proof_format: [stat | testimonial | demo | before_after | none]
Then: given our ICP profile below, propose ONE new ad hook that we haven't tested,
based on the whitespace in the competitor set. Output as a paused draft ad body.
Do not output more than one draft.
The output is a single ad body, routed to Slack as a draft with a "Create as paused ad" button backed by a Meta Ads MCP call. It does not go live until a human approves it.
For the manual version of this workflow, see competitor ad to Meta campaign with MCP — the agent runs it on schedule.
For ads saved to the swipe file that feed this loop's baseline, saved-ads is the right curation layer. The agent searches fresh; the swipe file is the historical anchor.
Loop 3: Monday brief generator (zero-risk, high-return)
This loop has no write access to Meta. It's pure signal aggregation and synthesis — and it's the first loop you should build. The Monday brief earns trust in the agent's signal quality before you give it any write access.
Trigger: Every Monday at 08:00, the cron fires monday-brief.md.
What the agent pulls:
- adlibrary: last 7 days of new in-market ads in your ICP category
- adlibrary: timeline data for the top 5 competitors to surface creative rotation patterns
- Meta Ads MCP: last 7 days of your own account performance (spend, CPA, ROAS, top ad sets)
- Meta Ads MCP: any Advantage+ campaign shifts in audience targeting
What the brief contains (in order):
- Market pulse: new hooks that entered the category this week
- Competitor rotation: which brands rotated creative and toward what format
- Your account: what worked, what fatigued, what's approaching learning phase exit
- Proposed agenda: 3 bullets the operator should decide on this week
Once the brief is consistently accurate — meaning you act on the agenda it proposes — you're ready to expand the 24/7 meta ads agent's scope.
The adlibrary API workflows post covers the specific API calls that feed this brief in detail.
Graduation pattern: widening scope without losing the account
The graduation pattern answers "how much do I trust it?"
Phase 1: Read-only. The agent pulls signals and sends briefs. No MCP write calls. Monday brief loop only. Run for two weeks.
Phase 2: Drafts paused. The agent proposes actions but everything requires human approval. Run for two to four weeks.
Phase 3: Auto-execute with tight caps. The frequency auto-pause loop goes autonomous, but only for ad sets spending below a daily cap (e.g., $500/day). Above that threshold, it still goes to Slack.
Phase 4: Autonomous on defined scope. Fatigue pauses run fully autonomous at any spend level. Hook drafts still require approval. Budget adjustments remain human-gated.
Never skip phases. One bad autonomous decision on a high-spend campaign costs more than a month of careful trust-building saves.
The automated meta ads budget allocation post covers the Phase 3/4 cap-setting logic. For a comparison against manual Ads Manager workflows, see Meta Ads MCP vs Ads Manager.
Observability: what the agent must record on every action
Every autonomous action the meta ads automation agent takes must write a structured log line before the action executes. If the action fails mid-execution, the log still exists.
Minimum required fields per log line:
- Timestamp (ISO 8601 UTC)
- Loop name (FATIGUE-PAUSE, HOOK-DRAFT, BRIEF)
- Ad set or campaign ID affected
- Action taken (PAUSED, DRAFT-CREATED, ESCALATED, NO-ACTION)
- Trigger condition (the specific threshold or signal that fired)
- Reversibility flag and spend at time of action
Store logs in append-only JSONL format, one file per loop, rotated weekly, retained 90 days. The log is also the input for the Monday brief — the agent reads its own action history from the last 7 days when composing the "Your account" section, closing the feedback loop.
For the adlibrary-side of observability, ad-timeline-analysis gives you the historical view. Cross-reference log timestamps against adlibrary timelines to validate whether the signals were predictive. The performance tracking dashboard shows how this log structure feeds into a reporting layer. See also: ad data for AI agents.
Failure modes that look like success
These are the ways a claude code cron meta ads agent appears to be working while it's slowly degrading your account.
Silent drift. The delegation contract was written for Month 1. By Month 3, your ICP has shifted and CPA targets have been revised. The agent is making decisions against stale parameters — correctly according to the old rules. Fix: schedule a contract review every 30 days.
Scope creep. Phase 3 went well, so you quietly moved more ad sets into the autonomous tier without updating the contract document. Fix: every scope change goes through a formal update — edit the prompt file, commit it, note the date.
Alert fatigue. The Slack escalation channel fires 30 messages a day. Nobody reads them. An actual escalation gets buried. Fix: audit escalation rate weekly. Above 5 per day means the draft/escalate boundary is miscalibrated.
The dead zone. The cron job silently fails — process errors, API token expires, adlibrary credentials rotate — and nobody notices. Fix: the Monday brief is the canary. If it doesn't arrive by 08:15, page yourself.
For adlibrary credential rotation patterns, see adlibrary workflows for media buyers. The broader marketing ops patterns post covers how these failure modes appear across different tool stacks. See also: automated social media advertising.
Frequently asked questions
How do I know when to kill the agent and revert to manual?
Kill it when the Monday brief's accuracy drops — meaning you consistently disagree with the proposed agenda or find its account summary incorrect. That's the signal the contract is miscalibrated beyond quick repair. Revert, audit the logs, and rebuild the delegation contract from scratch with the lessons. A well-designed agent should be easy to kill: all state lives in logs, all actions are reversible or were pre-approved. Killing it costs you automation, not your account.
Can I run this on Advantage+ campaigns?
With Advantage+, Meta controls more variables autonomously — audience, placement, and sometimes creative. Your agent's autonomous scope should be narrower on Advantage+ campaigns because the interaction between your agent's actions and Meta's own optimization is harder to predict. Treat all Advantage+ ad sets as "Draft" bucket at minimum during Phase 2 and 3. Only move them to autonomous in Phase 4 if you have 90 days of log history showing clean behavior.
What happens if the Meta Ads MCP auth token expires mid-loop?
The agent will fail on the MCP call, catch the auth error, and escalate to Slack with the message and the specific action it was attempting. No partial actions are taken — the MCP protocol at mcp.facebook.com/ads requires a valid session for every call, and an expired token means no call goes through. The escalation message includes the log line of what was pending so you can run it manually or after re-auth. Build the error handler into the prompt, not as a code wrapper.
How many loops can one Claude Code cron agent handle?
The three loops here — fatigue, hook-draft, Monday brief — are scoped to run sequentially within a single Claude Code session triggered by cron. Four-hour cadence is enough for fatigue and hook-draft; the Monday brief runs separately. Adding a fourth loop requires its own cron entry and its own prompt file. Don't collapse loops into a single mega-prompt — the delegation contract for each loop is different. See Claude Code agentic marketing workflows for the modular prompt architecture.
Do I need the Anthropic API or just Claude Code?
Claude Code is the runtime — it handles the session, tool calls, and MCP connections. The Anthropic API is what Claude Code calls under the hood. For scheduled cron runs you need a Claude Code API key with sufficient rate limits. Budget roughly 50-100 tool calls per fatigue loop run depending on account size. The automated ad launching post covers the API cost structure for high-frequency runs.
Bottom line
The contract is the product. Write it before you write the cron. A meta ads automation agent that can decide, draft, and escalate within a clear scope pauses fatigued ads while you sleep, surfaces competitor angles before you've opened your laptop, and briefs you Monday morning with a prioritized agenda. An agent without a contract is scheduled chaos with good logging. Build the three loops here, run Phase 1 for two weeks, and widen scope only when the track record earns it.
Originally inspired by mcp.facebook.com. Independently researched and rewritten.
Further Reading
Related Articles

Agentic Marketing Workflows with Claude Code: From One-Off Scripts to Always-On Agents
Build agentic marketing workflows with Claude Code: a 4-stage progression from a simple prompt to a memory-equipped agent with tool-use and approval gates.

Claude Code Agents for Media Buyers: Hands-Off Ad Operations in 2026
Build Claude Code agents for ad fatigue detection, pacing checks, anomaly alerts, and competitor angle surfacing. Subagent architecture for media buyers.
Claude Code + AdLibrary API: Building Agentic Marketing Workflows That Actually Ship
Build unattended competitor intelligence workflows using Claude Code and the AdLibrary API. Includes real API call patterns, two worked examples, and observability practices.

Claude Code + adlibrary API: End-to-End Competitor Intelligence Workflows
Run five Claude Code workflows against the adlibrary API for automated competitor monitoring: Slack alerts, bulk teardowns, hook extraction across 500 ads, monthly landscape reports, and new entrant detection.

Claude Code for Marketing Ops: Automating Reports, Data Pipelines, and Weekly Reviews
Automate your weekly marketing ops with Claude Code — GA4 pulls, ad spend reconciliation, budget pacing, and Slack delivery. Real code included.

Meta Ads Campaign Automation: What to Trust, What to Override, and Where the Algorithm Breaks
Four layers of Meta campaign automation mapped — Advantage+, automated rules, bid strategy, and budget allocation. Learn where the algorithm wins and where human judgment still matters.

What Your Meta Ads Dashboard Must Show in 2026: Required Views Beyond the CPA Chart
Most Meta ads dashboards only show CPA and ROAS. Here are the 4 required views your dashboard is missing — learning phase, delivery diagnostics, frequency velocity, and CAPI signal quality.