Table of Contents
- Why not build your own Instagram MCP server?
- Setup for each client
- Claude Code
- Cursor
- Codex
- Claude and ChatGPT
- What the agent does when you ask for a post
- Feed posts, carousels, Reels and Stories
- Keep the agent on drafts until you trust it
- One server for Instagram and the rest
- Muse, OpenClaw, Manus and other agents
- Try it
To post to Instagram from Claude Code, Cursor, Codex or another agent like Muse or OpenClaw, add the PublishQ MCP server and approve it in your browser. In Claude Code it's one command:
claude mcp add --transport http publishq https://publishq.com/mcpThen ask your agent something like "Post photo.jpg to my Instagram with a caption about today's launch." It uploads the photo and publishes it, or saves it as a draft if you'd rather check it first. Feed posts, carousels, Reels and Stories all work. You need an Instagram Business or Creator account, and you don't need a Meta developer app.

The rest is detail: the setup for each client, what the agent sends on every post, and how to keep it from posting things you didn't approve.
Why not build your own Instagram MCP server?
An MCP server is a set of tools an AI app can call by name, like "upload this file" or "publish this post at 9:00". Search for an Instagram one and you'll find three kinds:
| Approach | What you set up | Good for |
|---|---|---|
| Self-hosted Graph API wrapper | A Meta developer app, an access token you keep renewing, and a public URL for every image | Developers who want full control of the Meta side |
| Browser-session server | A browser extension that drives your logged-in Instagram tab | Reading DMs and profiles from your own session |
| Hosted publishing server (PublishQ) | One URL in your client, approved in the browser | Posting and scheduling, on Instagram and your other platforms |
The first one is where most people stall. Instagram's publishing API only takes media by public URL, so before your first post you need file hosting, a Meta app, a token and a login flow. Plan on a weekend for that.

With a hosted server you connect Instagram once in PublishQ, and the agent's tools already know how to upload a file, build a carousel and publish a Reel.
Setup for each client
First, connect your Instagram account in PublishQ. If it's a personal account, switch it in the Instagram app under Settings, Account type and tools, because Instagram only allows API publishing to Business and Creator accounts. MCP access is on every PublishQ plan, the Free plan included.
Claude Code
claude mcp add --transport http publishq https://publishq.com/mcpOpen /mcp in a session and choose Authenticate. PublishQ opens in your browser, you pick what the agent may do and click Approve.
Prefer running the server on your own machine? Sign in once with the CLI and add the local server:
npx @publishq/cli@latest login
claude mcp add publishq -- npx -y @publishq/mcp@latestWith --scope project it goes into a .mcp.json you can commit. There's no secret in it, so each teammate approves their own login. More examples are on the Claude Code Instagram page.
Cursor
Add this to ~/.cursor/mcp.json:
{
"mcpServers": {
"publishq": { "url": "https://publishq.com/mcp" }
}
}Cursor asks you to approve it in the browser the first time it connects. Prompts that work well in the editor are on the Cursor Instagram page.
Codex
npx @publishq/cli@latest login
codex mcp add publishq -- npx -y @publishq/mcp@latestCodex writes it to ~/.codex/config.toml under [mcp_servers.publishq], and codex mcp list shows whether it loaded. Codex is handy for batches, like scheduling a week of Instagram posts in one run.
Claude and ChatGPT
In Claude (web, desktop or mobile), go to Settings, Connectors, Add custom connector, and paste https://publishq.com/mcp. In ChatGPT, turn on developer mode in Settings and create an app with that URL and OAuth as the authentication. Every other client is covered in the PublishQ MCP docs.
What the agent does when you ask for a post
It makes three calls. publishq_list_accounts with the platform set to INSTAGRAM gets your account ID. publishq_upload_media uploads the photo or video: the local server reads a path on your disk, and the hosted server takes a public link or a file attached in the chat. Then publishq_create_post sends the caption, the media ID and the account.
This is what it sends for a Reel scheduled for Monday morning that also shows in your feed:
{
"content": "Behind the scenes of this week's build.",
"mediaIds": ["b7e1c0de-1111-2222-3333-444455556666"],
"accounts": [
{
"accountId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"platformSpecificSettings": { "contentType": "reels", "shareToFeed": true }
}
],
"scheduledAt": "2026-11-16T09:00:00Z"
}You won't write this yourself. The agent builds it from your sentence, and it can show you the call before making it if you ask.
Feed posts, carousels, Reels and Stories
It's the same publishq_create_post call every time. Only the media and one setting change:
| You want | Media | Setting on the Instagram account |
|---|---|---|
| Feed photo | 1 image | none |
| Carousel | 2 to 10 images or videos | none |
| Reel | 1 video | contentType: "reels" (optional, a single video goes out as a Reel anyway) |
| Story | 1 image or video | contentType: "story" |
Reels have a few extras. shareToFeed puts the Reel in your feed too, audioName names its audio track, and trialParams shows it to non-followers first as a trial Reel. PublishQ resizes and converts images for Instagram, so a PNG straight from your screenshots folder is fine. The Instagram API guide lists every option.
Keep the agent on drafts until you trust it
I'd start every agent on drafts. A post with no scheduledAt and no publishNow is saved as a draft and waits in PublishQ until you publish it, and a scheduled post can be edited or cancelled until it goes out.
It also helps to hide the tools the agent doesn't need. Most clients let you do that, so give it publishq_list_accounts, publishq_upload_media and publishq_create_post and leave publishq_delete_post out.
When Instagram refuses a post, the error names the account and the rule it broke. The agent can read that, fix the post and try again.
One server for Instagram and the rest
The same server posts to every account you connect in PublishQ: Instagram, TikTok, YouTube, LinkedIn, Facebook, Threads, Bluesky and X. "Post this Reel to Instagram" can become "post this video as a Reel, a TikTok and a YouTube Short, with a shorter caption on TikTok", and it's still one publishq_create_post call with three accounts in it.

An Instagram-only server stops at Instagram. With this one, the agent learns the tools once, and any platform you connect later works the same way.
Muse, OpenClaw, Manus and other agents
The same server works in any agent that can use MCP tools or run a command. Each of these pages has the setup and prompts for Instagram:
| Agent | Guide |
|---|---|
| Muse | Instagram from Muse |
| OpenClaw | Instagram from OpenClaw |
| Hermes Agent | Instagram from Hermes Agent |
| Manus | Instagram from Manus |
| Kiro | Instagram from Kiro |
| Gemini CLI | Instagram from Gemini CLI |
| Claude Cowork | Instagram from Claude Cowork |
For an agent that isn't listed, open publishq.com/agents and copy the line at the top of that page into your agent. It reads the page, sets itself up, and gives you a link to approve the login in your browser.
Try it
- Create a PublishQ account and connect your Instagram Business or Creator account.
- Add
https://publishq.com/mcpto Claude Code, Cursor, Codex, Claude or ChatGPT. - Ask your agent: "List my Instagram accounts, then draft a post with photo.jpg and a caption about it."
For more Instagram prompts and the arguments for each post type, see Post to Instagram with the PublishQ MCP server.
