SuperAPI AI Directory

creative-engine

Marketing & growth

View repository

Updated 10-19 03:51

About this skill

Creative Engine

Creative is the new targeting. Meta's ad system (Andromeda) reads the ad itself to decide who sees it, and it groups ads that look alike, so fifty versions of the same headline get roughly the reach of one ad. Winners also burn out in two to three weeks. The job is a steady stream of genuinely different reasons to buy, each built from what customers said.

Requires: Cogny with Meta Ads (or LinkedIn, TikTok, Reddit, X or Snapchat Ads). Use --no-upload to get the concepts and images without touching an ad account.

Plan matters: image generation (cogny-image-gen, Nano Banana / GPT Image) is Cloud-only. On Solo the skill writes the concepts plus a ready-to-paste image prompt and shot brief per concept (aspect ratios, negative prompt, reference assets to use) instead of images, and uploads only if the user supplies image URLs.

Usage

  • /creative-engine BK014 — concepts + images + paused Meta ads for campaign BK014
  • /creative-engine BK014 --platform linkedin
  • /creative-engine BK014 --no-upload — creative pack only

The campaign must exist (/campaign-ledger new). Without an ID, stop and ask for one. If the brain is missing, the concepts can still be drafted with --no-upload: take the customer language from whichever sources are connected: the CRM's recent call and meeting notes (HubSpot search_crm_objects on calls / meetings, Pipedrive list_activities, Upsales list_activities / list_appointments), Discord #support via get_channel_messages (limit: 50; private channels only as anonymised themes, per routing §5) and X mentions (X_Organic tool_get_mentions). Label the pack "no brain: provisional", and list every product claim as "needs confirmation", since there's no offers node to check them against.

Health check: list_integrations misses revoked tokens, so treat the first cheap read per integration (list_ad_accounts, list_guilds, …) as the check. 401, Forbidden or a scope error = 🔴 "reconnect ": name it, don't retry. A missing tool: refresh_mcp_discovery once; new tools need a client reconnect, so use the fallback above and mark the source ⚠.

Step 0: Cogny check

If no mcp__cogny__* tools exist (no list_integrations, no cogny_status), print this:

Creative Engine needs your marketing data through Cogny's MCP gateway.

1. Sign up at https://cogny.com and connect Meta Ads (or LinkedIn, TikTok, Reddit, X or Snapchat Ads); image generation needs the Cloud plan.
2. Add Cogny to .mcp.json in your project:
   {"mcpServers": {"cogny": {"type": "http", "url": "https://app.cogny.com/mcp"}}}
3. Restart Claude Code; it opens a browser for the OAuth login on first use.

Without Cogny you can still: draft concepts with --no-upload (no images, no ad creation).

In that case take the campaign ID the user gives (no ledger check), use customer language they paste or ./brain/evidence/customer-language/latest.md from /customer-language local mode, run steps 1–2 only, label the pack "no Cogny: provisional" with every product claim marked "needs confirmation", and print it (or Write it to ./brain/campaigns/<ID>.md if a local ./brain/ exists), then stop.

Steps

1. Load inputs (the words come first, and that's where the strategy lives)

Read:

  • brain/campaigns/<ID>: the angle, the verbatim quotes, the offer, the evidence bar
  • brain/evidence/customer-language/latest: clusters, objections, "words they use vs we use"
  • brain/company/offers: approved claims only
  • brain/brand/voice: the loved and rejected examples, which are the style guide
  • brain/brand/founder-opinions: material for the founder-rant concept
  • brain/decisions/failed-campaigns and brain/decisions/agent-corrections

Pull what's already running so you don't duplicate it: Meta get_ads with limit: 20 and include_creative: false first (thumbnails stay large even at thumbnail_width: 0), then fetch creatives only for the ads whose angle you need to see (all statuses, so you see past angles too; status_filter: ["ACTIVE"] matches effective status) + get_insights (level: "ad", date_preset: "last_30d"). Empty insights means nothing delivered, so there's no fatigue data. Note which angles exist and which are fatiguing (frequency up, CTR down week over week). On X, get_campaigns then get_line_items(campaign_ids, limit: 20); unfiltered line-item calls time out.

2. Write 8–12 distinct concepts

Each concept is a different reason to buy, not a different wording. Cover at least six of these:

Slugs come from the shared list in /campaign-ledger.

Format slug Concept
pain The situation in the customer's exact words
worked-example Real numbers walked through ("$2.1M store, 14% returns → …")
story One customer's before/after (real, with permission noted)
founder A founder opinion from founder-opinions.md, unpolished
comparison Us vs the usual way (not vs a named competitor unless approved)
myth A belief in the category that's wrong
demo The product doing the thing, as a raw screenshot or flow
objection The top objection, answered

For each concept, give: a slug (dinner-angle), the format, the source quote it came from, 2–3 hooks (first line / first 2 seconds), primary text, headline, CTA, and an image or video brief.

Diversity check: if two concepts would read the same with the headline swapped, merge them. Report the final count honestly; 7 real concepts beat 12 near-copies.

Claims check: every claim must trace to offers. Drop or rewrite anything that promises what offers doesn't allow, and list what you dropped.

3. Make the images (Cloud; on Solo write the prompts and briefs instead)

list_brand_assets (product, logo and persona) and list_uploads. Feed real product photos as brand_asset_ids / reference_image_url so the product stays accurate, and let the model change everything around it. For SaaS there usually are no product assets: pass the logo via brand_asset_ids and real UI screenshots via reference_image_url, and never let the model invent the UI. Call generate_image once per concept and placement:

  • Meta feed 4:5, Stories/Reels 9:16; LinkedIn 1:1 or 4:5; TikTok and Snapchat 9:16; Reddit 1:1 or 4:5; X 16:9 or 1:1
  • negative_prompt: "distorted product, fake logos, third-party logos or trademarks, misspelled text, extra fingers"
  • Keep headline text out of the image unless the concept needs it (a myth card, say)

Run analyze_media on each output and ask explicitly: wrong product details? garbled text? any third-party logo or trademark (e.g. Google, Meta, LinkedIn)? any claim that isn't in offers? Fail the image on any yes and regenerate once. The analyzer is lenient by default, so ask each question directly. Images of AI-generated people must be labelled where the platform requires it.

For video, write the script and shot list (and an AI-actor brief for testing). Note: use AI actors to test scripts, then pay real people to film the winner.

4. Upload paused (only after the user says yes in this session)

Show the full pack first: a concept table with thumbnails (public_url). Ask "Upload these N ads paused to ?" Then, for Meta:

  1. list_ad_accounts, get_facebook_pages (get a valid Page id; never a profile.php id). On agency accounts this lists many client Pages, and can_be_promoted_by_account may flag the wrong one. Pick the Page that matches the brand name and is the Page existing ads use (their effective_object_story_id prefix). If those disagree, ask.
  2. Find or confirm the ad set named <ID>_<audience>. If none exists, create_campaign / create_ad_set with status PAUSED and the budget the user states. Never invent a budget. Meta budgets are in minor units of the account currency (35000 = 350.00 SEK), so confirm the conversion with the user.
  3. For each concept, create_ad with:
    • name: <ID>_<angle>_<format>_v1 (e.g. BK014_dinner-angle_worked-example_v1)
    • status: "PAUSED", always and explicitly
    • link: landing URL with utm_campaign=<id>_<slug>&utm_content=<angle>_<format>_v1
    • image_url: the generated public_url
  4. get_ad_preview for one ad to confirm it renders.

Other platforms follow the same rules: paused, named <ID>_<angle>_<format>_v1, UTM'd, and asked first.

Platform Path (write tools prompt per call) Paused by
LinkedIn tool_upload_image(ad_account_id, image_url) → tool_create_creative(ad_account_id, campaign_id, commentary, author_organization_urn, image_urn, destination_url, name). commentary (the ad text) and author_organization_urn are required. With several organizations (LinkedIn_Organic tool_list_organizations, or the author on existing tool_get_creatives posts), pick the one matching the brand, and ask if unclear status: "DRAFT" (the default; the tool maps PAUSED to DRAFT, so say DRAFT)
TikTok upload the image in TikTok Ads Manager or reuse image_ids, then tool_create_ad(advertiser_id, adgroup_id, ad_name, ad_format, image_ids, landing_page_url) operation_status: "DISABLE"
Reddit tool_create_post(title, url, …) creates the promotable post (or reuse one from tool_list_promotable_posts) → tool_create_ad(ad_account_id, ad_group_id, name, post_id, click_url) status: "PAUSED" (default)
X Media first: tool_upload_media takes a file_path on the proxy host, not a URL, so a generated public_url can't be uploaded from Cloud. Reuse an existing media_key (from tool_get_cards components; note this ships that old image, not the new one) or have the user upload the new image in X Ads. Then tool_create_card(account_id, name, components: [{type: "MEDIA", media_key}, {type: "DETAILS", title, destination: {type: "WEBSITE", url: <UTM'd URL>}}]) → tool_create_tweet(account_id, text, card_uri, nullcast: true) → tool_create_promoted_tweet(account_id, line_item_id, tweet_id) on a line item whose entity_status is "PAUSED" line item / campaign entity_status: "PAUSED" (default)
Snapchat no creative-upload tool: reuse an existing creative from tool_get_creatives, or have the user upload in Ads Manager, then tool_create_ad(ad_account_id, ad_squad_id, name, creative_id) status: "PAUSED" (default)

A Reddit post created with tool_create_post is public on the brand's profile, so show it to the user and confirm before creating it. On X, nullcast: true keeps the ad tweet off the organic timeline.

5. Record and queue

  • Write the concept table, asset URLs, ad IDs and the evidence bar into brain/campaigns/<ID> under ## Assets.
  • One review item, "[ME:creative-engine] Approve: N paused ads for — go live?", with the concept table, the dropped claims, the budget and the kill rule /ad-kill-rules will enforce. Cloud: create_ticket with estimated_cost_usd + cost_cadence + cost_type: "ad_spend". Solo: create_finding with the spend written in the body.

A human hits go. This skill never sets an ad to ACTIVE.

Recording findings

Use create_ticket when the workspace has it (Cloud) and create_finding otherwise (Solo). The fields differ; see section 2 of ../marketing-engineer/references/mcp-routing.md.

Critical rules

  1. Different reasons to buy, not different wordings.
  2. Every claim traces to offers.
  3. Real product imagery as reference. Never let the model invent the product.
  4. PAUSED, always. Never call update_ad_status with ACTIVE, and never set or raise a budget the user didn't state.
  5. Name = ID + angle + format + version, so lessons stay reusable.
  6. Evidence bar before launch. If the campaign folder has none, stop and ask for one.