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
npx -y skills add canvora/canvora-mcp --skill canvoraAssembled 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)
npm install -g @canvora/cli(Node 18+, zero dependencies; v1.2+ for localize/variations/edit)- Get an API key: canvora.ai → Integrations → API Keys (all plans, incl. Free)
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_cardortestimonial_cardfrom 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 ->
corporateorminimal - friendly, consumer, lifestyle ->
playfulorcreative - premium, luxury ->
elegantordark - 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).
--waittimes out after 600s by default (override with--timeout); the generation keeps running server-side andcanvora status <id>retrieves it. NEVER re-rungenerateafter a timeout - that creates a NEW paid generation. Pollcanvora status <id>instead.- Rate limit: 20 generation requests/minute. For big batches, run
sequentially with
--waitrather 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.