agentsclimarketplace

Canvora

Skill canvora/canvora-mcp/skills/canvora

Create on-brand visuals (social posts, carousels, decks, ads, documents) from any text, URL, or PDF via Canvora. 100+ formats, native generation in 150+ languages, per-client brand kits. Use when the user asks to create, generate, or design visual content for social media, marketing, or presentations.From its SKILL.md

Install
npx -y skills add canvora/canvora-mcp --skill canvora

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

8.9 KB, ~2.2k tokens by cl100k_base, as published. Nobody here has run it

Canvora — on-brand visuals as a shell command

Canvora turns text, URLs, docs, and PDFs into finished visuals: single images (10 credits) and multi-slide carousels/decks (15 credits per slide) in 100+ formats, generated natively in 150+ languages. Brand kits keep every output in the client's colors, fonts, logo, and tone.

Setup (once)

  1. npm install -g @canvora/cli (Node 18+, zero dependencies; v1.2+ for localize/variations/edit)
  2. Get an API key: canvora.ai → Integrations → API Keys (all plans, incl. Free)
  3. export CANVORA_API_KEY=vd_...

Verify: canvora credits --json returns the account balance.

Creating visuals

Always pass --json: results print to stdout as JSON, progress goes to stderr.

# From a short concept (Canvora plans it: detects language, develops the items)
canvora generate --idea "5 tips for remote work" \
  --format linkedin_carousel_portrait --slides linkedin_carousel_portrait=5 --wait --json

# From YOUR full content (used as the source material; needs 50+ chars)
canvora generate --input "$FULL_POST_TEXT" --format instagram_post --wait --json

# From a URL (blog post, landing page - content is extracted automatically)
canvora generate --url https://example.com/post \
  --format instagram_post,quote_card --wait --json

# From a PDF or DOCX (the URL must be PUBLICLY fetchable - no localhost/private links)
canvora generate --file-url https://example.com/report.pdf \
  --format presentation_slide --slides presentation_slide=8 --wait --json

Also available: --title "Q3 launch" (names the generation in the dashboard) and --resolution 4K (paid plans; default 2K).

The final JSON contains generation.outputs[], each with a stable CDN fileUrl you can post, embed, or download.

Choosing the input mode

  • --idea: a concept, not content ("5 tips for X"). Canvora runs a planning pass: detects the language, invents the substance, maps items to slides.
  • --input: the user already wrote the content (50+ chars). It is used as source material; wording is respected, not reinvented.
  • --url / --file-url: content is extracted from the page/PDF/DOCX first.
  • Rule of thumb: if the user hands you finished text, use --input; if they hand you a topic, use --idea; if they hand you a link or file, pass it directly instead of copy-pasting its text.

Choosing formats

The live catalog is the source of truth - do not guess format IDs:

canvora formats --json

Each entry has id, dimensions, category (social, marketing, document, presentation, advertising, infographic, email, landing_page), is_carousel, and a description that includes recommendations (e.g. the LinkedIn carousel marked "recommended", pitch_deck "for investors"). Match the user's intent against category + description and pick accordingly. Carousel-flagged formats take --slides.

Combos worth knowing (these span formats, so the catalog can't tell you):

  • Announcing something: announcement_card + instagram_post + instagram_story
  • Promoting an article: blog_header + og_image + a carousel from the same URL
  • Ad campaign: ad_square + ad_landscape + ad_portrait (covers all placements)
  • A claim + its proof: a carousel plus stat_card or testimonial_card from the same source

Batching: one generation can carry several formats (--format instagram_post,linkedin_post,quote_card) - all outputs come from the same source with a consistent look, and cost is simply the sum (10/visual, 15/slide). Prefer one batched call over several separate ones. One instance per format per call: for 3 different Instagram posts, run 3 calls with 3 different ideas (not instagram_post,instagram_post).

Slide counts (carousel formats only)

--slides <format>=<n> (1-10, default 5). If the idea or content promises N items ("5 tips", "6 formas", "7 steps"), set --slides to N so each item gets its own slide - or N+1 if you also want a cover. If you omit it, Canvora fits the items into 5 slides (combining or stretching as needed).

Brand kits

canvora brands --json lists the account's brand kits. Pass one with --brand <uuid> so outputs use that client's colors, fonts, and logo. If the user names a client or brand, ALWAYS look up and pass their kit - it is the difference between on-brand output and generic output.

Styles and language

--style sets the aesthetic. Pick from the user's tone:

  • corporate, professional, B2B -> corporate or minimal
  • friendly, consumer, lifestyle -> playful or creative
  • premium, luxury -> elegant or dark
  • loud, promotional -> bold
  • default / unsure -> modern

Language is detected from your input automatically - a Spanish idea yields a Spanish carousel, natively generated (not translated). To force a specific language (e.g. an English brief for a Turkish audience), pass --language tr or --language Turkish.

Recipes for common asks

# "Promote this blog post" - full promo set from one URL
canvora generate --url $POST_URL \
  --format blog_header,instagram_carousel,linkedin_post --slides instagram_carousel=6 \
  --brand $BRAND --wait --json

# "Weekly content in English and Spanish" - run twice, native each time
canvora generate --idea "3 mistakes first-time founders make" --format instagram_carousel --slides instagram_carousel=4 --wait --json
canvora generate --idea "3 errores de los fundadores primerizos" --format instagram_carousel --slides instagram_carousel=4 --wait --json

# "Turn this report into a deck"
canvora generate --file-url $PDF_URL --format presentation_slide --slides presentation_slide=8 --wait --json

# "Make an ad set for this product page"
canvora generate --url $PRODUCT_URL --format ad_square,ad_landscape,ad_portrait --brand $BRAND --wait --json

Budgeting and errors

  • Check before large jobs: canvora credits --json (10 credits per visual, 15 per slide; a 5-slide carousel = 75 credits).
  • Exit code 0 = success, 1 = failure (message on stderr), 2 = usage error.
  • Failed generations refund automatically; safe to retry on exit 1 unless the error says the request was declined by content safety checks (those are terminal - do not retry).
  • --wait times out after 600s by default (override with --timeout); the generation keeps running server-side and canvora status <id> retrieves it. NEVER re-run generate after a timeout - that creates a NEW paid generation. Poll canvora status <id> instead.
  • Rate limit: 20 generation requests/minute. For big batches, run sequentially with --wait rather than firing them all at once.
  • Free-plan outputs carry a watermark; paid plans export clean. If the user asks why there is a watermark, that is the reason.
  • Everything you create also lands in the user's Canvora dashboard for review and editing - tell the user where to find it.

Delivering carousels: slide order matters

Each output in generation.outputs[] has a sortOrder field. When posting or downloading carousel/deck slides, ALWAYS sort by sortOrder first - outputs can complete out of order, and a scrambled carousel ruins the story.

Refining existing visuals (NEVER regenerate from scratch)

When the user wants to change something about a visual you already made, regenerating loses the design and costs full credits. Use these instead (each costs the 10-credit edit rate per visual; they need the Visual Editor feature - Starter plan or an active Campaign Pack; a 403 means the plan lacks it, not an auth problem):

# Same design, different language - the layout survives, only text changes
canvora localize <generationId> --language es --wait --json

# Fresh takes on the same generation. NOTE: --count is PER OUTPUT -
# count 2 on a 5-slide carousel makes 10 new images (100 credits).
canvora variations <generationId> --count 2 --wait --json

# Natural-language edit of ONE output. Without --yes it prints Canvora's
# interpretation of your instruction for confirmation; add --yes to execute.
canvora edit <outputId> --prompt "make the headline bigger" --yes --json

If edit replies "needs clarification", re-run with a more specific prompt.

Exact wording: when the user's text must appear verbatim (quotes, taglines, slogans), generate with --input "the exact text" --exact - this disables rewording.

What the CLI does NOT do (yet)

PDF/PPTX/ZIP export is not a CLI command - point the user to their Canvora dashboard, or to the Canvora MCP server (https://api.canvora.ai/mcp) which exposes export as a tool for MCP-capable agents.

Other commands

canvora status <generationId> --json      # progress + output URLs
canvora download <generationId> --dir ./  # save files locally

What ships with it

Read from the repository

Just SKILL.md. No reference files, no scripts.

Keep looking

Skills are one crate of 326,144. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.