zuckerbot-mcp

Run Facebook ad campaigns from any AI agent. Generate ads, research competitors, analyze markets, and launch Meta campaigns via API.

🤖 ZuckerBot

Facebook Ads infrastructure for developers, terminal users, and AI agents.

Build, launch, and manage Meta ad campaigns programmatically. ZuckerBot wraps the Meta Marketing API into a clean REST API, human CLI, and MCP server so AI agents and developers can run Facebook and Instagram ads without touching Business Manager.

npm version License: MIT MCP Registry

Quick Start

npm install -g zuckerbot-mcp
export ZUCKERBOT_API_KEY=zb_live_your_key_here

zuckerbot preview https://example.com

Get your API key at zuckerbot.ai/developer. Keys use the format zb_live_ (production) or zb_test_ (sandbox).

After global install, the package gives you:

  • zuckerbot for the human-facing CLI
  • zuckerbot-mcp for MCP server mode
  • zuckerbot serve as an alternative way to start MCP mode from the unified CLI

What It Does

  • Campaign generation - Give it a URL, get back a full ad strategy with targeting, budget, and copy
  • Ad creative generation - AI-generated ad media via Seedream/Imagen images or Kling videos, plus copy via Claude
  • Campaign management - Launch, pause, and resume campaigns on the Meta Marketing API
  • Performance tracking - Real-time metrics from Meta: impressions, clicks, spend, leads, CPL
  • Per-business CAPI config - Map CRM stages to Meta standard events, ingest webhook events, and monitor delivery status
  • Audience portfolios - Copy shared audience templates into business-owned tier budgets and launch linked campaigns
  • Conversion feedback - Feed lead quality back to Meta's algorithm to improve targeting
  • Market research - Competitor ad analysis, review intelligence, and market benchmarks
  • API key provisioning - Create and manage API keys programmatically

Human CLI

Run campaigns directly from your terminal:

zuckerbot preview https://example.com
zuckerbot create https://example.com --budget 2000 --objective leads
zuckerbot launch camp_abc123
zuckerbot status camp_abc123
zuckerbot meta status

Key command groups:

  • preview, create, launch, status, pause, resume
  • creatives, conversion
  • research reviews, research competitors, research market
  • meta status, meta accounts, meta select-account, meta pages, meta select-page, meta credentials
  • serve to start MCP server mode from the same CLI

API Endpoints

Base URL: https://zuckerbot.ai/api/v1/

MethodPathDescription
POST/campaigns/previewGenerate ad preview from a URL (no Meta account needed)
POST/campaigns/createCreate full campaign with strategy, targeting, and creatives
POST/campaigns/:id/launchLaunch a draft campaign on Meta (creates real ads, billed: 5 credits)
POST/campaigns/:id/pausePause or resume a live campaign
GET/campaigns/:id/performanceGet real-time campaign metrics from Meta
POST/campaigns/:id/conversionsSend lead quality feedback to Meta's conversion API
GET/capi/configGet the business-scoped CAPI config and webhook URL
PUT/capi/configUpdate the business-scoped CAPI config
POST/capi/config/testSend a synthetic CAPI test event and log it as a test
POST/capi/eventsIngest CRM lifecycle webhook events into the CAPI pipeline
GET/capi/statusGet 7-day and 30-day CAPI delivery and attribution status
POST/portfolios/createCreate a business-owned audience portfolio from a template
GET/portfolios/:idGet a portfolio and its tier campaign linkage
PUT/portfolios/:idUpdate a portfolio's tier config and budget
POST/portfolios/:id/rebalanceDry-run or apply a portfolio rebalance
POST/portfolios/:id/launchLaunch one campaign per active portfolio tier
GET/portfolios/:id/performanceGet tier-by-tier portfolio performance
POST/research/reviewsGet review intelligence for a business
POST/research/competitorsAnalyze competitor ads in a category and location
POST/research/marketGet market size, trends, and ad benchmarks
POST/creatives/generateGenerate ad copy and images independently (free, monthly capped)
GET/meta/statusCheck whether stored Meta credentials are complete
GET/meta/credentialsResolve the selected Meta ad account and page for launches
GET/meta/ad-accountsList accessible Meta ad accounts and show the selected one
POST/meta/select-ad-accountSelect the active Meta ad account, clear the stored page, and auto-select the pixel if only one exists
GET/pixelsList accessible Meta pixels for the selected ad account and show the selected one
POST/pixels/selectSelect the active Meta pixel for conversion tracking
GET/meta/pagesList accessible Facebook pages and show the selected one
POST/meta/select-pageSelect the active Facebook page for future launches
POST/keys/createCreate a new API key

All endpoints require Authorization: Bearer zb_live_... except where noted.

MCP Server

ZuckerBot ships as an MCP server for AI agents that support the Model Context Protocol. Use zuckerbot-mcp directly, or zuckerbot serve if you want a single CLI entrypoint for both human and agent workflows.

Standalone with npx:

ZUCKERBOT_API_KEY=zb_live_your_key_here npx zuckerbot-mcp

Claude Desktop

Add to claude_desktop_config.json:

{
  "mcpServers": {
    "zuckerbot": {
      "command": "npx",
      "args": ["-y", "zuckerbot-mcp"],
      "env": {
        "ZUCKERBOT_API_KEY": "zb_live_your_key_here"
      }
    }
  }
}

Cursor

Add to .cursor/mcp.json:

{
  "mcpServers": {
    "zuckerbot": {
      "command": "npx",
      "args": ["-y", "zuckerbot-mcp"],
      "env": {
        "ZUCKERBOT_API_KEY": "zb_live_your_key_here"
      }
    }
  }
}

OpenClaw

/skill install zuckerbot

Or add to your OpenClaw MCP config:

{
  "mcpServers": {
    "zuckerbot": {
      "command": "npx",
      "args": ["-y", "zuckerbot-mcp"],
      "env": {
        "ZUCKERBOT_API_KEY": "zb_live_your_key_here"
      }
    }
  }
}

Environment Variables

VariableRequiredDefaultDescription
ZUCKERBOT_API_KEYYes-Your API key (zb_live_ or zb_test_ prefix)
ZUCKERBOT_API_URLNohttps://zuckerbot.ai/api/v1Override for self-hosted or staging

Code Examples

Generate a campaign preview

curl -X POST https://zuckerbot.ai/api/v1/campaigns/preview \
  -H "Authorization: Bearer zb_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example-yoga.com",
    "ad_count": 2
  }'

Returns AI-generated ad headlines, copy, and rationale for each variant. No Meta account required.

Generate ad creatives

curl -X POST https://zuckerbot.ai/api/v1/creatives/generate \
  -H "Authorization: Bearer zb_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "business_name": "Sunrise Yoga Studio",
    "description": "Hot yoga and meditation classes in Austin, TX",
    "count": 3,
    "image_count": 3,
    "style": "photo",
    "aspect_ratio": "1:1",
    "model": "auto",
    "quality": "fast",
    "use_market_intel": false
  }'

Returns ad copy variants with AI-generated media (images for Seedream/Imagen, short videos for Kling). quality: "ultra" is supported only when model: "kling".

Credits and Errors

  • Execution endpoints can return HTTP 402 with:
    • error.code = "insufficient_credits"
    • required_credits
    • current_balance
    • purchase_url
  • Validation 400 responses on selected endpoints include:
    • error.code
    • error.message
    • error.example_body
    • error.docs_url

Pricing

PlanPricePreviews/moRate Limit
Free$02510 req/min
Pro$49/mo50060 req/min
EnterpriseCustomCustom300 req/min

All plans include access to every endpoint. Get your API key.

Autonomous Execution (Approval Flow)

When ZuckerBot's campaign_optimizer agent detects anomalies, it logs recommended actions to automation_runs with status = "needs_approval". Approving a run now executes the actions against the Meta Graph API and records results back in automation_runs.output.

Credit billing:

  • POST /api/agents/execute-approval (approve): 1 credit per executable action
  • POST /api/v1/autonomous/execute: 3 credits per call
  • POST /api/v1/autonomous/run: 3 credits per run with actions

Approve a run (triggers real Meta API calls)

# Replace <JWT> with the user's Supabase JWT and <RUN_ID> with the automation_runs UUID

curl -X POST https://zuckerbot.ai/api/agents/execute-approval \
  -H "Authorization: Bearer <JWT>" \
  -H "Content-Type: application/json" \
  -d '{
    "run_id": "a1b2c3d4-...",
    "action": "approve"
  }'

Example response:

{
  "run_id": "a1b2c3d4-...",
  "action": "approve",
  "status": "completed",
  "execution_summary": "2/3 actions succeeded, 1 failed/skipped",
  "execution_results": [
    {
      "action_type": "pause_campaign",
      "campaign_id": "uuid-of-campaign",
      "campaign_name": "Spring Promo",
      "ok": true,
      "status": "paused",
      "detail": { "meta_campaign_id": "23843..." }
    },
    {
      "action_type": "reduce_budget",
      "campaign_id": "uuid-of-another",
      "campaign_name": "Winter Sale",
      "ok": true,
      "status": "budget_updated",
      "detail": { "previous_budget_cents": 5000, "new_budget_cents": 3500, "pct_change": -0.3 }
    },
    {
      "action_type": "refresh_creative",
      "campaign_id": "uuid-...",
      "campaign_name": "Brand Awareness",
      "ok": false,
      "status": "unsupported",
      "error": "\"refresh_creative\" requires human action and cannot be automated"
    }
  ]
}

Dismiss a run

curl -X POST https://zuckerbot.ai/api/agents/execute-approval \
  -H "Authorization: Bearer <JWT>" \
  -H "Content-Type: application/json" \
  -d '{ "run_id": "a1b2c3d4-...", "action": "dismiss" }'

What executes vs. what doesn't

Action typeExecutableWhat happens
pause_campaignYesPOST /{meta_campaign_id} status=PAUSED; DB status → paused
reduce_budgetYesPOST /{meta_adset_id} daily_budget=new_cents; DB daily_budget_cents updated
increase_budgetYesSame as reduce_budget with positive pct_change
shift_budgetYesIncreases winner's budget by 30%; paired with a pause on the loser
refresh_creativeNoReturns unsupported — trigger the creative_director agent separately
monitorNoReturns no_action — informational only

Budget safety

  • Floor: $5 (500 cents). No ad set budget will be set below this.
  • Cap: defaults to $100 (10 000 cents/day). Override by adding max_daily_budget_cents to the business's automation_config row.
  • Formula: clamp(current_budget × (1 + pct_change), min=500, max=10000)

Prerequisites

  • Business must have facebook_access_token stored in the businesses table.
  • Campaigns must have meta_campaign_id (for pause) and meta_adset_id (for budget) — written automatically on campaign launch via /api/v1/campaigns/:id/launch.

Autonomous Mode (MVP)

Autonomous Mode runs a closed-loop policy on your campaigns: metrics → evaluate → act → log. The cron dispatcher calls it every 4 hours for any business that has an enabled policy.

Environment variables

VariableRequiredDescription
CRON_SECRETYesShared secret for authenticating the cron dispatcher. Set in Vercel and in your cron schedule trigger.

Set CRON_SECRET in your Vercel project settings (Settings → Environment Variables) and pass it as Authorization: Bearer <CRON_SECRET> when calling /api/cron/dispatch-agents or /api/v1/autonomous/run directly.

New endpoints

MethodPathAuthDescription
POST/autonomous/policies/upsertAPI keyCreate or update autonomous policy for a business
GET/autonomous/metricsAPI keyGet normalized campaign metrics
POST/autonomous/evaluateAPI keyEvaluate policy and return action list (supports dry_run)
POST/autonomous/executeAPI keyExecute a list of actions and log results (billed: 3 credits/call)
POST/autonomous/runCRON_SECRETInternal: evaluate + execute + log in one call (billed: 3 credits/call)

Database migration

Run the migration to create the autonomous_policies table:

supabase db push
# or apply manually:
psql $DATABASE_URL -f supabase/migrations/20260228_autonomous_mode.sql

1. Create a policy

curl -X POST https://zuckerbot.ai/api/v1/autonomous/policies/upsert \
  -H "Authorization: Bearer zb_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "business_id": "uuid-of-your-business",
    "target_cpa": 25,
    "pause_multiplier": 2.5,
    "scale_multiplier": 0.7,
    "max_daily_budget": 150,
    "scale_pct": 0.2,
    "min_conversions_to_scale": 3
  }'

Policy fields:

FieldDefaultDescription
target_cparequiredTarget cost-per-acquisition in dollars
pause_multiplier2.5Pause campaign if cpa > target_cpa × pause_multiplier
scale_multiplier0.7Scale campaign if cpa < target_cpa × scale_multiplier
frequency_cap3.5Pause if ad frequency exceeds this (requires Meta insights)
max_daily_budget100Safety cap — never scale a budget above this dollar amount
scale_pct0.2Increase budget by this fraction on scale (0.2 = +20%)
min_conversions_to_scale3Minimum conversions required before scaling

2. Fetch metrics

curl "https://zuckerbot.ai/api/v1/autonomous/metrics?business_id=uuid" \
  -H "Authorization: Bearer zb_live_your_key_here"

Returns a normalized array with campaign_id, name, status, daily_budget, spend_today, impressions, clicks, conversions, cpa, ctr, cpc, frequency.

Note: spend_today is the lifetime spend stored in the DB (written when you call GET /campaigns/:id/performance). It is used as a proxy for same-day spend. For precise daily numbers, call the performance endpoint to sync from Meta first. frequency is always null in the MVP — it requires a live Meta Insights API call not currently wired into this endpoint.

3. Evaluate (dry run)

curl -X POST https://zuckerbot.ai/api/v1/autonomous/evaluate \
  -H "Authorization: Bearer zb_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{"business_id": "uuid", "dry_run": true}'

Returns { policy, actions[], summary, dry_run: true }. No changes are made.

4. Execute

curl -X POST https://zuckerbot.ai/api/v1/autonomous/execute \
  -H "Authorization: Bearer zb_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "business_id": "uuid",
    "actions": [
      {
        "type": "pause",
        "campaign_id": "internal-uuid",
        "meta_campaign_id": "23843...",
        "reason": "CPA $62.50 exceeds pause threshold"
      }
    ]
  }'

Each action result includes { ok, status, error?, meta? }. Results are logged to automation_runs with agent_type = "autonomous_loop".

Supported actions:

  • pause — Sets Meta campaign status to PAUSED. Requires meta_campaign_id.
  • scale — Increases the ad set's daily_budget by scale_pct, capped at max_daily_budget. Requires meta_adset_id. If meta_adset_id is not stored, returns status: "not_supported" with a clear message.

5. Cron integration

The cron dispatcher (POST /api/cron/dispatch-agents) automatically dispatches autonomous/run for every business that has an enabled autonomous policy and at least one active campaign. It now honours each business's evaluation_frequency_hours value instead of using a single hardcoded 4-hour loop.

To trigger manually:

curl -X POST https://zuckerbot.ai/api/v1/autonomous/run \
  -H "Authorization: Bearer $CRON_SECRET" \
  -H "Content-Type: application/json" \
  -d '{"business_id": "uuid"}'

Safety guarantees

  • Minimum budget: Never sets a daily budget below $5.
  • Maximum budget: Scales are always capped to max_daily_budget from the policy.
  • Spend threshold: Pause rules only apply to campaigns with > $5 lifetime spend (to avoid acting on brand-new campaigns).
  • One rule per campaign per cycle: A campaign is only evaluated for the first matching rule (pause takes priority over scale).
  • Idempotent: Calling execute twice with the same action is safe — Meta ignores status updates that are already in the target state.

Known gaps / not yet implemented

GapStatus
Real-time spend_today from Meta InsightsNot implemented. Use stored DB value as proxy.
Ad frequency dataNot implemented. Requires GET /{adset_id}/insights?fields=frequency.
Creative evolution on pause/scaleLogged as creative_evolution_not_implemented in run output.
Per-adset budget update when meta_adset_id is missingReturns not_supported with instructions.

Links

License

MIT - see LICENSE

Server Terkait