Create ads from Claude
Your agent briefs, renders and iterates video and image ads on your own account
Two ways in: install the open source skill pack in your terminal, or add the connector inside claude.ai.
The skill pack for Claude Code and Cursor
A folder of skills your agent reads before it works. It writes the brief, calls Novoads on your account, and brings the finished render back into the session.
Paste this into Claude Code or Cursor
Open an empty folder and paste the line below. Your agent clones the pack, runs setup, and stops at the one step only you can do: pasting your Novoads API key.
https://github.com/novoads/agent-skills help me set this upThen describe the ad you want in your own words, and hand over your product photo.
Prefer the terminal?
The same setup by hand. Setup asks for the Novoads API key you create in Settings under Developer, and checks the connection before it finishes.
git clone https://github.com/novoads/agent-skills.gitcd agent-skills./scripts/setup.shJust want to read the skills first? npx skills add https://novoads.ai pulls the skill files on their own, for a look. The full pack, with its scripts and your key, still comes from one of the two paths above.
Open source. Every skill, prompt and check sits in a public repository, readable before you run any of it.
Claude Code and Cursor. One pack, the same commands, whichever terminal your team already works in.
Priced before it runs. Every render is quoted by a live estimate that reads your balance first, so nothing is spent by surprise.
novoads/agent-skillsView on GitHubOr connect Novoads inside claude.ai
The second way in. You add one URL as a connector and sign in with OAuth, so this path issues no API key at all.
- 1
Copy the connector URL
You will paste this into Claude in the next step.
https://novoads.ai/api/mcp - 2
Open Claude connectors
Settings → Connectors → Add custom connector, then paste it in.
- 3
Sign in and start
OAuth, no API key. Approve two permissions, then ask for an ad.
What Claude does with it
Not a protocol diagram. The calls a real run makes, in order, next to what they produced.
You
Here is our black tee. Make a vertical ad in Spanish, someone at home talking to camera. Tell me what it costs before you spend anything.
tee-black.jpgClaude
Pricing it first.
estimate_cost
3.4 credits, checked against your balance. Nothing charged, no job created.
generate_video
Un joven en casa, luz natural de ventana, sostiene la cámara con una mano y habla directo al lente sobre su camiseta negra con el logo circular.
Returns a jobId right away. The render outlives the call, so it does not hold the connection open.
Claude
Here it is. Vertical, native audio in Spanish, ready for Reels or TikTok.
Result
A real ad made with Novoads. The call beside it is the live tool contract: those parameter names and bounds are exactly what the server accepts.
9 tools, and what each one costs you
4 of them spend credits. The rest read, price and report, which is what makes a chain running unattended safe to start.
Prepare
Get your real asset in, and read what is already working in someone else's. Reading an ad charges a flat fee; the upload does not.
upload_assetSpends nothingReturns a presigned URL for an image or video, plus the assetId that identifies it in every later call.
analyze_adSpends creditsTurns an uploaded ad into a structured read: summary, hook boundary, beats, on-screen text, casting and layout zones.
list_caption_presetsSpends nothingThe subtitle styles generate_captions can burn in, each with its price tier. Reads only, and calling it costs nothing.
Create
Every call in this group charges. All of them validate the prompt before a credit moves.
generate_videoSpends creditsSubmits a video render and returns a jobId immediately. The prompt is validated before any credit is charged.
generate_imageSpends creditsGenerates a static ad image and returns the image URLs and a jobId.
generate_captionsSpends creditsBurns subtitles into a finished video, in the style you name. It works on a clip generated here or on one you uploaded.
Price and track
Quote before you commit, then follow the job. None of these cost anything to call.
estimate_costSpends nothingWhat a generation would cost, your balance, and whether it covers it. Spends nothing and creates no job.
get_generationSpends nothingStatus, progress and, once finished, a time-limited output URL for one job.
list_generationsSpends nothingYour recent jobs, newest first. The recovery path for when the response carrying the jobId is the thing that got lost.
- Video model
- Seedance 2.0 by default
- Length
- 4 to 30s on Seedance 2.5, up to 13 credits
- Image model
- 3 models, 0.3–1 credits each
- Formats
- 6 aspect ratios, 11 languages
The free call checks your prompt before you spend
Every rule below was measured on a render that came back wrong, not reasoned from a model card. `estimate_cost` runs all of them for free and hands back what it found. It is advice: nothing here refuses a generation, and nothing here changes the price.
Video prompts: 8 checks
What a prompt that wasted a render was missing.
banned_polishBreaks the renderRejected: polish words (cinematic, cinematográfico, perfecto, 8k, masterpiece). A valid prompt names the light source, the surface and the flaw.
back_referenceBreaks the renderRejected: back-references to an earlier shot's actor ("the same woman", "la misma mujer"). Seedance re-casts on every cut, so the actor tag is repeated verbatim.
missing_actor_descriptorBreaks the renderRequired in every shot: an actor descriptor. Established once in 37-53 chars (age band, gender, wardrobe), then repeated as an 11-30 char tag, word for word.
chained_motionBreaks the renderRejected: chained motion ("then", "y luego", "em seguida"). One action per shot; a second beat renders as a smear.
bullety_promptBreaks the renderRejected: bullets and field:value pairs. Seedance reads flowing prose; a labelled list renders as literal on-screen text.
label_without_holdCosmeticA visible label, package or screen needs the labelHold clause, or its printed text comes back garbled.
no_spoken_lineBreaks the renderRequired: the spoken line in double quotes, or a statement that the shot is silent / b-roll / voiceover. A silent talking head bills in full.
no_aspect_ratioCosmeticThe aspect ratio belongs at the end. Vertical 9:16 is the format for Reels, TikTok and Stories.
Image prompts: 3 checks
Same idea, on the image side.
banned_polishBreaks the renderRejected: polish words (cinematic, cinematográfico, perfecto, 8k, masterpiece). A valid prompt names the light source, the surface and the flaw.
blank_labelBreaks the renderRejected: unbranded and blank-label products. A valid prompt names the real brand, with its photo passed via upload_asset + referenceAssetIds.
unfilled_placeholderBreaks the renderRejected: unfilled [PLACEHOLDER] tokens left over from a template.
The wording above is exactly what comes back in `warnings`, in English, whatever language your ad is in. Generating never runs these — only `estimate_cost` does, and only to tell you.
What we built on top of it
Four skills we run in-house, each one a chain over the same seven tools.
novoads-pixar-adOne product in, one stylized 3D animated ad out. Picture and spoken lines from a single generation call.
clone-hookReads a competitor's video hook down to the signal that ends it, then rebuilds that hook with your product and your actor.
clone-static-adReads a static ad's layout zones and copy hierarchy, then rebuilds the structure around your product.
spy-competitor-adsPulls what a competitor is currently running and reports the pattern behind it, not just the files.
These are instructions, not software. The judgement lives in the skill; the rendering happens here, on your account. Several are open source on GitHub, so you can read the folder before you trust it.
Questions a developer actually has
If the answer you need is not here, ask Pablo directly. He answers.
Message us on WhatsApp
Your first ad, today.
Try 3 days for $1. Cancel anytime. No sales calls.
Made in LatAm · WhatsApp support · Commercial rights included.
Rather ask first? Chat with Pablo on WhatsApp