ai newsMi., 4. Nov.
EilmeldungKI-Update: Nein zu Rechenzentren, Anthropic warnt, Google-Zwang, KI-Mythen

Instagram Skill for Claude Code: Make, Check, Preview and Schedule Instagram Posts From Your Agent

Instagram skill for Claude Code, free and MIT licensed: Instagram Skill lets your agent turn an idea, a link, notes, your photos or a video into finished Instagram posts (carousels, single images, Reels and Stories), check every file against Instagram's current limits, show you the feed and the gri

dev.toMittwoch 13:47 · 04.11.11 Min. Lesezeit
Bild: dev.to

Instagram skill for Claude Code, free and MIT licensed: Instagram Skill lets your agent turn an idea, a link, notes, your photos or a video into finished Instagram posts (carousels, single images, Reels and Stories), check every file against Instagram's current limits, show you the feed and the grid, and schedule them after you say yes. It also works in Codex, Cursor and OpenClaw.

Everything up to posting runs on your own computer with Python, Pillow and ffmpeg. There is no paid API. This post covers what the skill does, how to install it, the example in the repo, and then the parts that are code: the file checker, the preview, per-account versions and time zones, and the rules it uses to learn from your results.

npx skills add social-media-skills/instagram-skill -g -a claude-code -y Enter fullscreen mode Exit fullscreen mode Repo: github.com/social-media-skills/instagram-skill

The example week in the repo, for "Earth in Numbers", a made-up science account. Figures from the USGS Water Science School; Earth photo NASA Blue Marble 2012 (no endorsement by NASA or USGS is implied). The Reel is the account's own 16-second animated short, made for the example from the same USGS figures.

An agent skill is a folder with a SKILL.md that tells an agent like Claude Code how to do a job. Most Claude Instagram help stops at text: a hook, a caption, some hashtags, and "now design the post yourself". Then the post fails on details nobody checked: a PNG the API won't take, a 3:4 photo it rejects, a Reel title under the caption, a cover the grid cuts in half, six hashtags where Instagram now allows five.

This skill ships the scripts that make and check the posts, so the agent produces real files, not advice:

Posting through the Instagram API yourself means setting up a Meta app and its permissions. The skill posts through WoopSocial 's MCP server instead, so your agent gets Instagram tools without a Meta app of your own. Disclosure: the skill is maintained by Frank Heijdenrijk and the team behind WoopSocial. The free plan covers 2 social accounts. Setup for every agent is at woopsocial.com/agents.

An MCP alone gives the agent a "post" call. The skill adds what comes before it: making the media, checking it, the preview, per-account versions and the learning loop. Through WoopSocial it can post feed images, carousels, Reels (with a cover, and as Trial Reels when your account qualifies) and Stories, now or scheduled, and validate each post first.

Some things can't be set this way: collaborators, location, music, alt text and first comments. The skill writes them into a checklist per post so you add them in the app. WoopSocial doesn't write captions or edit media; the skill does that on your computer and you approve it. If you'd rather not connect anything, you get the files, captions and schedule to post yourself.

Instagram posting through any API needs a Business or Creator account. Switching is free in the app.

npx skills add social-media-skills/instagram-skill -g -a claude-code -y Enter fullscreen mode Exit fullscreen mode Codex, Cursor and other agents: run npx skills add social-media-skills/instagram-skill and pick your agent, or copy skills/instagram-skill/ into your agent's skills folder.

OpenClaw: openclaw skills install @social-media-skills/instagram-skill

Requirements: Python 3.9 or newer with Pillow, and ffmpeg for anything with video. pillow-heif is optional, for iPhone.heic photos. python3 scripts/check_setup.py prints what's missing and the install command for your system. CI runs the full pipeline on macOS, Windows and Ubuntu.

The repo has one full run in examples/water-week/. "Earth in Numbers" is a made-up science account with an English profile (@earthinnumbers, New York) and a Spanish one (@latierraennumeros, Madrid). The brief, shortened:

You: A week of posts for @earthinnumbers (New York, followers online around 12:30) and the Spanish account @latierraennumeros (Madrid, 13:30) about Earth's water. Real numbers. Our animated short about the air is attached.

Agent: Mon: a carousel, "All of Earth's water in a 1-liter bottle": pour out the oceans and 35 ml is left; every river is less than a tenth of a drop. Spanish slides for the Spanish account. A Story an hour before asks the question.

Tue: a single image, 55% of the water under our feet is salty. Wed: your short as a Reel (English only), cover picked from its sharpest frames; nothing sits under Instagram's caption or buttons. Checks: everything passes.

Preview: preview/index.html. Enter fullscreen mode Exit fullscreen mode Each post carries its own fact, so nothing is posted twice. The carousel walks through the bottle: the cover, "35 ml is all that's left once you pour out the oceans", where those 35 ml are (ice 17.4, groundwater 16.9, permafrost 0.22, lakes 0.13, the rest 0.03 ml), "25 ml is fresh water: 17.4 ml ice, 7.6 ml underground", "0.002 ml for every river: less than a tenth of one drop", and a save ask.

The single image says 55% of groundwater is saline (USGS: 12.87 of 23.4 million km³). The Reel, the account's own 16-second animated short, says 6 times more water floats in the air than flows in every river.

The folder holds the plan, the slides in both languages, the Reel cover sheets, the preview page, schedule.md and one WoopSocial request per post and account. Seven posts in all, and every figure comes from the USGS Water Science School with the source in the caption.

ig_check.py reads the plan and checks every file and caption. The limits sit in one dict at the top, with the date they were checked, so updating them is a one-line change:

# Checked 2026-11-04 against Meta's content publishing docs and Instagram's own announcements. LIMITS = { " image_min_w ": 320, " image_max_w ": 1440, " image_bytes ": 8 * 1024 * 1024, " feed_min_ratio ": 0.8, " feed_max_ratio ": 1.91, # width / height " carousel_min ": 2, " carousel_max ": 20, " reel_min_s ": 3, " reel_max_s ": 15 * 60, " reel_bytes ": 300 * 1024 * 1024, " story_min_s ": 3, " story_max_s ": 60, " story_bytes ": 100 * 1024 * 1024, " carousel_video_max_s ": 60, " fps_min ": 23, " fps_max ": 60, " caption_chars ": 2200, " hashtags ": 5, " mentions ": 20, " fold_chars ": 125, } Enter fullscreen mode Exit fullscreen mode A few of these surprise people. The API takes JPEG only, so a PNG screenshot or an iPhone HEIC fails.

Feed images must be between 4:5 and 1.91:1, so a 3:4 photo (which the app accepts) is rejected through the API. Every carousel item is shown at the first item's shape. Five hashtags is Instagram's cap since December 2025.

Videos go through ffprobe: container, codec, 8-bit pixel format, HDR, frame rate, length, audio and size. 10-bit and HDR phone video is a common cause of grey or failed Reels, so the checker flags it and re-encodes it. Screen recordings with a variable frame rate get a warning, because re-encoding them to a constant 30 fps avoids audio drift.

Captions are checked for length, hashtags, mentions, links (not clickable in captions), a first line longer than the roughly 125 characters the feed shows before "... more", and two accounts opening with the same line.

--fix never touches your originals. It writes fixed copies to fixed/, points the plan at them and keeps a plan.json.bak:

python3 scripts/ig_check.py plan.json # report python3 scripts/ig_check.py plan.json --fix # fixed copies in fixed/, plan updated, originals kept Enter fullscreen mode Exit fullscreen mode The exit code is 1 while errors remain, so the agent runs it until it gets 0. Anything it can't fix safely (a video that needs trimming, a photo too small to scale up) comes back as an error with the reason in plain words.

The interesting case is landscape footage for a Reel. Filling 9:16 from 16:9 throws away most of the width, and padding with a blurred copy looks like a repost. So the checker refuses to guess once the loss is 12% or more:

if kind == " video " and fmt in ( " reel ", " story " ) and loss >= 0.12: report ( " error ", pid, label, f " this video would lose { loss:. 0 % } of its width to fill 9:16. Check reel.py frames, then: " " reframe it on the subject in an editor; or --fit crop when the subject stays in the middle; or give the " " post a \" frame \": { \" title \": \"... \" } for a framed Reel (video full width under a headline) " ) Enter fullscreen mode Exit fullscreen mode A framed Reel puts the video full width on a plain 1080x1920 background in a colour sampled from the clip's edges, with the hook as a headline above it. The headline sits below the top bar (the top 14%) and the video above the caption area (the bottom 35%), the safe zones Meta publishes for Reels. Nothing is cut off.

Framing is only for your own footage, so the post also needs "own_footage": true. Without it the checker warns: a headline or border around someone else's clip still reads as a repost to Instagram.

reel.py handles the rest of a Reel: frames picks sharp, well-lit cover candidates spread over the video into one sheet, cover writes a 1080x1920 JPEG cover with an optional title, and zones shades what Instagram's caption, buttons and top bar will cover. The example's Reel cover was picked from that frames sheet.

preview.py writes preview/index.html and the same thing as one preview.png the agent looks at before you do:

python3 scripts/preview.py plan.json --out preview/ --grid current-grid.png Enter fullscreen mode Exit fullscreen mode

Three things in it are easy to get wrong by eye:

Reels are shown at the middle 4:5 the main feed commonly shows (creators observe this crop; Meta doesn't document it). Stories are full screen.

Instagram's 2026 originality rules cover photos and carousels too, not only video, so the same media on a second account is likely seen as a repost of the first upload. In plan.json, a post has default media and a caption, and each target can replace them:

"targets": [ { "account": "en", "at": "2026-11-16T12:30" }, { "account": "es", "media": [ "slides/bottle-es/slide-01.jpg", "..." ], "caption": "¿Cuánta agua de la Tierra hay en los ríos?...", "at": "2026-11-16T13:30" } ] Enter fullscreen mode Exit fullscreen mode The checker warns when a second account has no media of its own, and when two accounts open with the same first line.

Each account has its own timezone and times, taken from its Insights. schedule.py gives every feed post a slot per account (one a day by default), converts the local time to UTC in the request and writes schedule.md. The example's Reel at 12:30 in New York becomes "scheduledFor": "2026-11-18T17:30:00Z". Without times it uses 12:00 and says so at the top of the schedule. It never claims a "best time".

Stories don't take a feed slot. A Story tied to a post with "with": {"post": "bottle", "minutes": -60} goes out an hour before that post on each account, so the example's teaser runs at 11:30 New York time and 12:30 Madrid time.

python3 scripts/schedule.py plan.json --start 2026-11-16 python3 scripts/schedule.py plan.json --bodies-only # after upload, with media IDs Enter fullscreen mode Exit fullscreen mode The agent uploads every file, writes the IDs into the plan, rebuilds the request bodies, validates each one, and posts only after a clear yes on the preview.

log.py record logs every post after it's created. A few days later, log.py results reads the post metrics back (views, likes, comments, saves, shares and reach, plus an optional insights.csv for what only the app shows, like follows and Reel watch time) and writes results.md. The rules are in the script's docstring, so it doesn't mislead:

Posts are ranked by sends, saves and follows per reach against the account's own median. Sends per reach is one of the main signals Adam Mosseri (head of Instagram) has named, with watch time and likes per reach. From that ranking the agent picks the next step from a small table in SKILL.md: same format with a new topic, add a checklist slide, end with a send-style ask, or change the cover first.

Yes. With this skill and WoopSocial's MCP connected, Claude Code, Codex, Cursor and OpenClaw can post and schedule Instagram posts after you approve each batch. Without a connection, the skill still makes, checks and previews everything.

No, it's a skill that uses WoopSocial's MCP server to post. The skill adds the media, the checks, the preview, per-account versions and the results.

Yes. One plan, one request per account, each with its own version of the post, its own caption and its own time zone.

No app can post to a personal account through Instagram's API. Switch to a free Creator or Business account in the app.

The grid shows 3:4, but the API only accepts 4:5 to 1.91:1. The skill renders 4:5 and keeps the cover text inside what the grid shows.

npx skills add social-media-skills/instagram-skill -g -a claude-code -y Enter fullscreen mode Exit fullscreen mode Then ask your agent for a week of posts about something you know well. The repo, the full example and every Instagram limit with its source: github.com/social-media-skills/instagram-skill. Issues and pull requests are welcome.

More free skills from the same team at social-media-skills.com.

Quelle: dev.to (dev.to). Original öffnen