Instagram MCP: publish photos, carousels and Reels
An Instagram MCP guide for Mellow Hub: account requirements, Instagram vs Facebook login, tested post inputs, scheduling and fixes for common validation errors.
By Mellow · UpdatedCan an AI assistant publish to Instagram through MCP?
Yes, when the assistant has an authorized publishing tool and an eligible connected Instagram account. Mellow Hub exposes those tools at https://www.mellow.world/mcp. A compatible remote MCP client can validate a post, schedule it within the owner’s delegation, and read its final destination result.
Start with the account and one actual draft. MCP is the tool connection; Instagram still decides whether the account, permissions and media can publish. This guide covers Mellow Hub. For planning your own Instagram content on iPhone or the web, see the separate Mellow planning guide.
What Instagram account do I need?
Use a professional Instagram account: Business or Creator. A personal account is not eligible for this publishing API flow. In Hub, open Accounts, choose Instagram and complete the account connection yourself.
| Login choice | What to prepare |
|---|---|
| Instagram login | The direct login route. Meta’s Instagram Login API does not require a linked Facebook Page. |
| Facebook login | The professional Instagram account linked to a Facebook Page, with the appropriate Page access. |
These are different authorization paths. Choose the path that matches your account setup; completing one does not grant every permission in the other. Meta’s official Instagram API collection documents the distinction. The managed connection used by Hub is described in Post for Me’s account requirements.
Stories need an additional eligibility check: Meta’s Facebook Login documentation limits Story publishing to Business accounts. A format appearing in Hub’s input rules does not establish that your account can publish it. Confirm the connected account and its delivery result before relying on that format.
Connect the assistant and check its authority
- Connect your Instagram account in Hub. The returned channel ID identifies that connection; an Instagram username is not a substitute.
- Add Hub’s endpoint in a client that supports remote MCP over Streamable HTTP. Follow its OAuth flow, or use an owner-created Hub key if that client supports it. Setup and availability depend on the client. Keep credentials in its secure configuration.
- On Hub’s OAuth consent screen, choose permissions, channels, mode, daily ceiling and expiry. Review mode prepares work for a person’s approval. Autopilot permits publishing within the delegation. View or revoke the resulting access in Agents.
- Call
whoamiandlist_channels. Check the actual mode and use the returned Instagram channel ID. Readlist_platformsfor the current rules. - Prepare reachable media. Use
register_mediato inspect an existing public URL, orrequest_upload_urlfor uploading a local file. Keep the resulting URL reachable through the planned publication time.
For the full connection sequence and result contract, use the MCP workflow guide. Adding a connector or pasting a prompt alone does not authorize an Instagram account. The same connection publishes to YouTube and Threads.
Connect Mellow Hub in Claude with read-only access first
In a Claude account where custom connectors are available, open Customize → Connectors → Add custom connector. Use the name Mellow Hub and remote MCP server URL https://www.mellow.world/mcp. If you already added it, use that existing connector. Claude can discover the authentication settings from this address.
| Connection setting | Value |
|---|---|
| Transport | Streamable HTTP |
| Authentication | Always required |
| OAuth client | Register automatically using DCR; no client secret to copy. |
- Open the connector and select Connect. Sign in to Mellow if asked. The consent screen should identify the requesting application as Claude.
- For a first check, leave only
channels:readandposts:readselected. These allow reading the connection and validating an input. They do not allow uploading media, creating posts or publishing. - Choose your specific Instagram channel and review mode. Set a short expiry, such as one day, and a daily ceiling. An empty channel selection is refused; access to future channels requires an explicit choice.
- Review and approve that delegation yourself. After returning to Claude, confirm that the connector is connected. Ask it to call
whoami, thenlist_channelsfor the permitted channel ID. Check the granted scopes, channels and expiry in Hub’s access list: a client may display only the tool’s text summary, which does not include every structured field.
Use only Mellow Hub. Call whoami, then list_channels.
Use the one Instagram channel I authorized. Call validate_post twice with
caption "Mellow test - example only": first with media [], then with
media ["https://example.com/test.jpg"]. These are illustrative inputs.
Do not fetch the URL or read existing posts. Report each validation result.
Do not create, schedule, cancel or publish anything.When Claude asks to use a tool, inspect its name and input before allowing the call. For this check, allow each call once. The example URL tests input rules only; it is not a real image to publish. Validation does not download the media or prove Instagram delivery.
What the live connection check returned
On September 9, 2026, one real Claude web connection completed OAuth with only channels:read posts:read, one Instagram channel, review mode and a one-day expiry. Claude called whoami, list_channels and validate_post twice. We inspected the tool responses as well as the assistant’s summary.
| Input | Observed result |
|---|---|
| Caption with no media | Rejected: Instagram needs at least one media item. |
| Same caption with the illustrative image URL | Passed the input check for one channel. |
No post was created or published in this check. We then revoked the test grant in Agents and verified that both its access and refresh tokens were revoked. This proves that particular connection and validation workflow, not publication to Instagram or compatibility with every client configuration.
For your own draft, supply a real caption and reachable media. If a later task needs writing, approve a new delegation with the required permissions. Refreshing a token does not extend its chosen access expiry.
Choose the format before validating
Hub currently enforces a caption limit of 2,200 characters and an overall range of 1–10 media items for Instagram. Placements narrow that range. These are Hub’s enforced input rules; they can be more conservative than Instagram’s own editor.
| Post | Hub placement | Input to prepare |
|---|---|---|
| Feed photo | timeline | One image. |
| Photo carousel | timeline | Two to 10 images in the order you want. |
| Reel | reels | Exactly one video. shareToFeed controls sharing to the main feed. |
| Story | stories | Exactly one image or video, subject to account eligibility. |
Hub currently rejects a mixture of recognized image and video URLs in one post. Use a single media type for its carousel input. That is a Hub limitation, not a claim that Instagram itself never supports mixed carousels.
Placement behavior is documented by Post for Me. File size, codecs, aspect ratio and duration still need to satisfy Instagram. Hub does not download the file. For an MP4 or MOV it reads the header and adds a note when the length, frame or size is outside what Instagram’s API publishes; it does not read codecs. A URL without a recognizable extension can leave its media type unknown.
Three post inputs you can adapt
Pass one of these objects as the arguments to validate_post. Replace the sample channel ID, media URLs, caption and 2030 timestamp with your own values. The date is intentionally illustrative; use an explicit UTC Z or timezone offset. These payloads are checked against Hub’s parser and validator, using a synthetic channel. They are not live Instagram publication receipts.
One feed photo
{
"channels": [
"spc_your_instagram_channel"
],
"scheduledAt": "2030-01-15T10:00:00Z",
"caption": "A closer look at the glaze on this cup.",
"media": [
"https://cdn.example.com/your-cup.jpg"
],
"options": {
"instagram": {
"placement": "timeline"
}
}
}An ordered photo carousel
{
"channels": [
"spc_your_instagram_channel"
],
"scheduledAt": "2030-01-15T10:00:00Z",
"caption": "From clay to finished cup, in three stages.",
"media": [
"https://cdn.example.com/your-clay.jpg",
"https://cdn.example.com/your-process.jpg",
"https://cdn.example.com/your-cup.jpg"
],
"options": {
"instagram": {
"placement": "timeline"
}
}
}One Reel
{
"channels": [
"spc_your_instagram_channel"
],
"scheduledAt": "2030-01-15T10:00:00Z",
"caption": "How this handle is attached.",
"media": [
"https://cdn.example.com/your-process.mp4"
],
"options": {
"instagram": {
"placement": "reels",
"shareToFeed": true
}
}
}A real media URL must be reachable by the publishing service when it is fetched. Meta describes this requirement in its content publishing reference. A local path, a private drive link or an expired signed URL is not a usable replacement.
Fix the reported issue before creating the post
Read ok, issues and notes in the validation result. A successful HTTP request can still carry ok: false. The issue names the affected channel and field.
| Issue code | What to change |
|---|---|
channel_not_connected | Finish connecting the account and use its returned channel ID. |
media_required | Attach media; Instagram cannot publish a text-only post through this workflow. |
media_too_many | Reduce the set to Hub’s current maximum of 10; a Reel or Story has a smaller allowance. |
reel_media_count | Use one video per Reel. To make several Reels, prepare separate posts. |
reel_needs_video | Supply video for a Reel, or choose the feed placement for photos. |
story_media_count | Use one item per Story request. |
media_kinds_mixed | Keep recognized images and videos in separate Hub posts. |
caption_too_long | Shorten the caption to 2,200 characters or fewer. |
Try the free post checker before connecting an account. It uses the same input rules with sample destinations. Authenticated validation checks actual connected channels; neither result guarantees eventual provider delivery.
Schedule once and verify the Instagram result
After a valid check, call create_post with the same intended post and a stable idempotencyKey, such as ceramics-instagram-reel-slot-001. Creating is the step that prepares or schedules the actual publication. In review mode it waits for approval; in autopilot it may proceed at the chosen time. Check the current plan allowance first.
Keep the returned post ID. If the create response is lost, retry the same request with the same key. Do not generate a new key just because of a timeout. A changed post needs a new key.
Call get_post and inspect the Instagram entry in targets. Read its final status, public URL or error. A Hub post being accepted is not proof that Instagram published it. For a multi-network request, another destination may succeed while Instagram fails.
For server integrations using HTTP directly, the REST scheduling recipe gives the equivalent requests and idempotency header. For a first setup, connect your Instagram channel and validate one draft before preparing a recurring schedule.