DEV Community

Cover image for Instagram Carousel Skill for Claude Code: Write, Render and Post Carousels From Your Agent
Frank Heijdenrijk
Frank Heijdenrijk

Posted on

Instagram Carousel Skill for Claude Code: Write, Render and Post Carousels From Your Agent

The Instagram carousel skill is a free, MIT-licensed agent skill that lets Claude Code, Claude, Codex, Cursor and OpenClaw plan, write, render and post Instagram carousels. It picks a format, writes the cover and the slides, renders 1080x1350 JPEGs on your machine with a small Python script, writes alt text and a caption, and posts the carousel once you say yes. No headless browser, no image API, no credits.

Repo: github.com/social-media-skills/instagram-carousel-skill

Six slides rendered by the Instagram carousel skill: a serif cover, a numbered rule, a myth vs fact slide, a recap list, an app screenshot slide and a tweet-style card

Slides from the two example carousels in the repo. The brand "plodd" and its app screenshot are made up.

What the skill fixes

Most carousels that don't get saved fail in the same places, and each one maps to a rule in the skill:

  • The cover names a topic ("Habit tips") instead of a result or a tension. The skill writes 10 covers of 8 words or fewer and you pick one.
  • Slide 2 only works after slide 1. Instagram may show a carousel again, starting at slide 2, to people who scrolled past it. The skill writes slide 2 so it works as a cover on its own.
  • Too many words. One idea per slide, headlines of 8 words or fewer, body text of 30 words or fewer.
  • Template chrome. No progress bars, no slide numbers, no logo on every slide. A small name and handle in the corner, and a small arrow on the cover only.
  • A last slide with three asks. One ask, matched to the goal: send, save, comment or link.

Install the Instagram carousel skill

npx skills add social-media-skills/instagram-carousel-skill -g -a claude-code -y
Enter fullscreen mode Exit fullscreen mode

Other agents:

  • OpenClaw (ClawHub): openclaw skills install @social-media-skills/instagram-carousel-skill
  • GitHub CLI: gh skill install social-media-skills/instagram-carousel-skill instagram-carousel-skill
  • Gemini CLI: gemini extensions install https://github.com/social-media-skills/instagram-carousel-skill
  • Codex, Cursor and others: npx skills add social-media-skills/instagram-carousel-skill and pick your agent.
  • Claude (claude.ai): download the zip from the latest GitHub release and upload it under Customize > Skills.

Rendering needs Python 3.8+ and Pillow (pip install pillow). The fonts ship in the repo.

What happens when you ask for a carousel

A prompt like "Make an Instagram carousel for my habit tracker about not giving up after a missed day" starts a fixed sequence:

  1. Context. The agent reads brand notes in the workspace if they exist, or asks once: who the account is for, whether this carousel should get saved, get sent or bring people to a link, what you know that your audience doesn't, which screenshots or photos you have, and what must not be said.
  2. Format and cover. It picks a format for the goal and writes 10 covers. You choose one; the others go into covers.md for later tests.
  3. Slides. One idea per slide, the product shown once near the end with a real screenshot, a last slide with one ask, a keyword-first caption with at most 5 hashtags, and one sentence of alt text per slide.
  4. Honesty check. Every claim must be something you did, saw or can show. The agent never writes your first-person stories, user counts or results for you.
  5. Render and review. It writes carousel.json, runs the renderer, opens every slide and the contact sheet, and fixes each warning.
  6. Post. It shows you the slides, caption, account and time, and posts only after a clear yes.
  7. Read back. A few days later it pulls the post's numbers and logs them next to the format and cover.

The renderer

scripts/render_carousel.py turns a JSON spec into slides. It uses Pillow only, renders at 2x and downscales for sharp text, and bundles Inter and Instrument Serif under the SIL Open Font License. This is a shortened version of the spec behind the editorial example:

{
  "theme": {"preset": "editorial", "mode": "light", "headline_font": "serif",
            "name": "plodd", "handle": "@plodd.app", "avatar": "avatar.png"},
  "slides": [
    {"type": "cover", "title": "Missed a day?\nYour habit is *fine*.",
     "kicker": "4 rules for people who restart every Monday", "alt": "..."},
    {"type": "step", "number": "1", "title": "One missed day is noise. *Two* is a pattern.",
     "body": "Protect one line: never miss twice in a row.", "alt": "..."},
    {"type": "myth", "myth": "A habit takes 21 days", "fact": "Closer to *66 days*.",
     "source": "Lally et al., European Journal of Social Psychology, 2010", "alt": "..."},
    {"type": "screenshot", "title": "plodd counts your *week*",
     "body": "Miss Wednesday. Still a good week.", "image": "screens/plodd-week.png", "alt": "..."},
    {"type": "cta", "title": "Send this to the friend who restarts every Monday.", "alt": "..."}
  ]
}
Enter fullscreen mode Exit fullscreen mode
python3 scripts/render_carousel.py carousel.json --out carousel/
Enter fullscreen mode Exit fullscreen mode

*word* sets a word in the accent colour, ~~words~~ strikes out a myth, and \n places a line break where the headline reads best.

Slide types: cover (text, photo or screenshot), text, step, list (recap or checklist), myth, stat (needs a source), tweet, photo, screenshot, beforeafter, cta.

Presets:

Preset Look Good for
editorial light or dark Paper or near-black background, serif or heavy sans headlines, one accent Step-by-step, frameworks, lists
notes light or dark Plain phone-notes look Honest lists, lessons, lo-fi posts
tweet light or dark Tweet-card thread with your own name, handle and avatar Opinions, short lessons

Output: slide-01.jpg and onward at 1080x1350 sRGB JPEG, plus:

  • contact-sheet.png: every slide on one image, for review.
  • cover-grid.png: the cover cropped the way the 3:4 profile grid shows it.
  • manifest.json: byte size, alt text and text per slide, plus warnings.

The warnings are the part that saves review time: text below the size floor, too many words on a slide, a stat with no source, a missing alt text, and (with opencv-python installed) text sitting on a face. When text doesn't fit at the floor, the fix is to split the slide, not to shrink it.

Why 1080x1350 and JPEG

Meta's content publishing API accepts JPEG only, with an aspect ratio between 4:5 and 1.91:1, and crops every carousel item to the ratio of the first one. So 4:5 at 1080x1350 is the tallest size that posts through the API, and every slide is rendered at exactly that size. The Instagram app has accepted 3:4 (1080x1440) since May 2025 but the API still rejects it; set "ratio": "3:4" only for slides you will upload by hand.

The type scale is set for phone reading, not for a desktop preview: a 1080 px slide shows at roughly a third of its width on a phone, so body text sits at 54 px with a floor of 40, and slide headlines at 128 px serif or 96 px sans.

The renderer has no agent dependency. You can call it from a script, a CI job or a cron task with your own spec.

Posting through WoopSocial

Posting goes through the WoopSocial MCP server, a social media API for AI agents. The skill is maintained by Frank Heijdenrijk and the team behind WoopSocial. The free plan covers 2 social accounts with posting, scheduling and analytics included. Setup for each agent is at woopsocial.com/agents.

The posting step, in tool calls:

  1. social_accounts_list to check the connection. If Instagram isn't connected, oauth_create_authorization returns a link for you to approve.
  2. For each slide, media_uploads_create_session with the exact byte size from manifest.json, then python3 scripts/upload_parts.py session.json carousel/slide-01.jpg, then media_uploads_complete_session. Media IDs stay in slide order.
  3. One post with all media IDs, postType: POST, the caption, and PUBLISH_NOW, SCHEDULE_FOR_LATER or DRAFT.
  4. posts_validate, then the confirmation: contact sheet, caption, account and time with timezone. posts_create runs only after your yes, and posts_get reports the result.

For several Instagram accounts, each account gets its own cover and variant instead of the identical carousel.

WoopSocial doesn't write captions, crop media or set alt text, collaborators or music on Instagram. The skill writes the caption and alt text itself, and after posting it tells you to paste each slide's alt text from manifest.json into the app (Edit > Edit alt text). If you'd rather not connect anything, it hands over the slides, caption and alt text and stops there.

Reading the results

After 3 to 7 days the agent calls social_account_posts_list, which returns the stored post metrics Instagram reports (views, likes, comments, saves, shares) with their collection date. A missing number is logged as "not reported", never as zero. Instagram's API reports per post, not per slide, so per-slide views stay in the app.

Each carousel goes into carousels.md with its date, format and cover, and the next step comes from comparing it with the account's own recent posts:

Saves Shares Next carousel
High High Same format, new topic
High Low Useful but not shareable: try a send-style last slide
Low High Shareable but thin: add a step or a checklist slide
Low Low Change the cover first, then the format

What makes it different

  • It covers the full job in one skill: format, copy, render, alt text, caption, posting and the results log.
  • It renders exact 1080x1350 JPEGs with Pillow, so there is no browser to install and no PNG for the API to reject.
  • It checks the cover the way the profile grid shows it, not only at full size.
  • It writes slide 2 for the second chance, and it refuses invented numbers, reviews and stories.

What it won't do

  • Promise reach, saves or followers.
  • Invent results, testimonials, user counts or first-person stories.
  • Fake likes or view counts on tweet cards, or make a card look like someone else posted it.
  • Post anything before you approve the exact slides, caption and account.

The skill is MIT-licensed: github.com/social-media-skills/instagram-carousel-skill. More free skills for social media work are at social-media-skills.com.

If you render a carousel with it, which preset did you start with, and what did the warnings catch?

Top comments (0)