
Meta does not ship an MCP server for organic Instagram. Its only first-party MCP server is the Meta Ads MCP, whose Instagram tools boost posts and nothing more, while community servers wrap the Instagram API around one long-lived token. The Instagram API itself covers publishing, comments, DMs and insights for professional accounts. This guide compares what each option lets a social agent do, the logins and tokens each one puts you on, and how to serve many brands' accounts in production.
Your agent needs to work inside your customers' Instagram accounts: publish a carousel at 9am, hide a spam comment the moment it lands, send a private reply to someone asking about an order, or tell a brand manager which reels drove the most saves last month. You go looking for an Instagram Model Context Protocol (MCP) server and find a crowd of them on registries, plus a Meta-hosted MCP server that turns out to be for ads. Meta ships the Instagram API, three login configurations, webhooks, and an Ads MCP. It does not ship an Instagram MCP server. That shapes the whole decision: the MCP options are either first-party and ads-only, or full-featured and unofficial. Here's how to pick.
There is no official Instagram MCP server for organic content. The nearest first-party server is the Meta Ads MCP server, which Meta describes as "a Meta-hosted Model Context Protocol server" at https://mcp.facebook.com/ads. Meta announced it in April 2026 as part of its ads AI connectors. Its tools fall into seven groups: reporting, ad creation and management, catalogs, signals and datasets, help, A/B tests and lift studies, and activity logs. Its ad creation tools include an Instagram section with three entries: ads_get_ig_accounts lists Business or Creator accounts linked to an ad account, ads_get_ig_media lists boost-eligible media, and ads_boost_ig_post will "turn an existing organic Instagram post into a boosted ad." That's the full Instagram surface.
Auth on the Ads MCP is Facebook Login for Business, or a user or Employee system user access token sent as a Bearer token. The token needs ads_mcp_management plus ads_read or ads_management, according to Meta's get started guide. Owning a Meta app is optional for Claude, and the guide does not mention Dynamic Client Registration (DCR).
For organic work, the community filled the gap. AleemHaider/instagram-mcp is a FastMCP server with 24 tools across profile and media, hashtags, publishing (including publish_reel, publish_story, and publish_carousel), comments, DMs, and insights. It reads IG_USER_ID and IG_ACCESS_TOKEN from the environment and recommends a Page access token that "never expires." jlbadano/ig-mcp has 8 tools, needs FACEBOOK_APP_ID, FACEBOOK_APP_SECRET, INSTAGRAM_ACCESS_TOKEN, and INSTAGRAM_BUSINESS_ACCOUNT_ID, and uses a 60-day token. Both launch as local processes from a client config. Both are thin wrappers over the Instagram API, which is the good case. Some servers on registries log in with a username and password against Instagram's private mobile API instead, which puts the account at risk of a ban.
The Instagram Platform serves Instagram professional accounts, meaning Business and Creator accounts. Personal accounts lost API access when Meta ended the Instagram Basic Display API on December 4, 2024. The API covers content publishing, comment moderation, mentions, messaging, media and account insights, hashtag search, and business discovery. Meta documents three setups:
The table makes the gap plain. Meta's own MCP server and the organic Instagram API barely overlap: one is for spending money on posts, the other is for making and managing them. The community servers cover most of the organic surface, but they are one developer's wrapper, pinned to a Graph API version they chose (v21.0 for AleemHaider, v19.0 for jlbadano), with no webhook path.
Publishing on the raw API is a three-step state machine. You create a container from a publicly hosted JPEG or video URL, poll its status_code until it reads FINISHED (Meta suggests "once per minute, for no more than 5 minutes"), then call media_publish with the container ID. A carousel adds a container per child, up to 10, before the parent. Containers expire after 24 hours unpublished. AleemHaider's publish_reel and publish_carousel fold that sequence into one tool call, which is the main thing a community server does for a model. Writing the schema is the hard part. Not the API call.
The Meta Ads MCP makes a different job easier: it resolves ad accounts, Pages, and linked Instagram accounts for you (ads_get_ad_accounts, ads_get_ig_accounts) and turns "boost my best reel from last week to people in Austin" into a handful of tool calls. Meta says new ad objects are created paused, which is a sensible guard for a model with a credit card.
The tradeoff is ownership. Meta owns the Ads MCP tool list and can change it under you. A community server is owned by whoever maintains the repository, and you inherit their choices on retries, rate limits, and which permissions they ask for.
On the Meta Ads MCP path, auth is Facebook Login for Business in the browser, or a user or system user token you supply. The identity is the Facebook user who signed in, and what they can reach is decided by their roles in Meta Business Manager. That's a reasonable model for ads. It doesn't help an organic agent, because none of the tools publish or moderate.
On the community MCP path, auth is whatever token you paste into an environment variable. AleemHaider's README walks you through exchanging a short-lived user token for a long-lived one (about 60 days), then pulling the Page's access_token, which Meta says does "not have an expiration date." That token sits in a .env file or a client config on someone's laptop. Every user of that server acts as that one Page.
On the direct API path, you run OAuth yourself. With Instagram Login, the user authorizes at https://www.instagram.com/oauth/authorize, the one-hour code is exchanged at https://api.instagram.com/oauth/access_token for a short-lived token, and you trade that at graph.instagram.com/access_token for a long-lived token valid for 60 days. You refresh it with refresh_access_token once it is at least 24 hours old, and Meta is blunt about the failure mode: "Tokens that have not been refreshed in 60 days will expire and can no longer be refreshed." With Facebook Login, you get a user token that expires in hours, exchange it for a roughly 60-day token, and derive Page tokens from it.
Then comes access level. Standard Access only works for accounts you own or manage, or that have a role on your app. To serve your customers' accounts, you need Advanced Access, which "requires App Review and Business Verification." Plan for that before you promise a launch date.
What the user can't do, the agent can't do. On Instagram that holds only when each brand's account authorizes your app separately and your agent uses that account's token.
In a multi-tenant B2B agent, MCP's OAuth flow gives you a token per user and the direct API gives you a credential per user. In neither case does the path itself solve storage, rotation, or revocation; those are infrastructure problems regardless of which path you choose.
Instagram sharpens this because the account is the brand. A social media tool serving 200 brands holds 200 Instagram professional accounts' publishing rights. A token mixed up between two tenants doesn't leak a report; it posts one brand's product launch on a competitor's feed, or sends a DM from the wrong account. The community servers can't express this at all: one process, one IG_ACCESS_TOKEN, one account.
Recommended reading: access control for multi-tenant AI agents
On the Meta Ads MCP path, Meta hosts the server and owns the schemas. You own the gap: everything organic. You also own the risk of an agent that can activate spend, since ads_activate_entity switches an item to active.
On the community MCP path, you own the server process, its Python dependencies, its pinned Graph API version, and the token on disk. When Meta deprecates the version the server targets, you patch it or wait for the maintainer.
On the API path, you own the full lifecycle, and Instagram has more moving parts than most APIs:
Use an Instagram MCP server when:
Use the Instagram API when:
Both paths hand you an Instagram credential per account. Neither hands you a vault. A social tool serving 200 brands, with 3 accounts each, holds 600 tokens. With Instagram Login, each is a 60-day token that dies for good if it goes 60 days without a refresh, and can't be refreshed until it is 24 hours old. With Facebook Login, the Page tokens your agent prefers have no expiration date at all, which makes each one a standing grant to publish as that brand until someone revokes it. Every one must be stored encrypted, kept out of logs and LLM context, mapped to exactly one account and one customer, and deleted when the customer churns or the user removes your app.
The MCP path changes the shape, not the problem. The Ads MCP holds a Business Manager login per user. A community server holds one token per process, so isolating 600 accounts means 600 processes or a fork that adds per-request tokens. The tempting shortcut is one agency-level Page token wired into a shared server. Fewer secrets, larger blast radius: one leak lets anyone post as every brand behind it.
Scalekit's instagram connector runs the OAuth flow, stores each account's token in the token vault, and refreshes it, so the MCP vs API decision doesn't change your auth infrastructure. Your agent passes an identifier; credentials never touch the agent runtime or the LLM context.
Recommended reading: how to handle token refresh for AI agents
Scalekit's instagram connector is an API-path connector built by Scalekit with 30 tools: 21 read, 8 write, and 1 destructive (instagram_comment_delete). It covers profile and media, the two-step publish flow, comments and replies, Direct conversations and sends, account and media insights, hashtags, business discovery, mentions, tags, stories, and oEmbed. It authenticates with OAuth 2.0 through Facebook Login, so each connected account must be a Business or Creator account linked to a Facebook Page.
In the Scalekit dashboard, go to AgentKit > Connections and create an Instagram connection. The name you give it is the connection_name your code passes, and the string must match the dashboard exactly. This is the most common integration error.
Scalekit's shared credentials work for testing. For production, create a Meta app of the Business type, add the Instagram Graph API and Facebook Login products, paste the connection's redirect URI into Facebook Login > Settings > Valid OAuth Redirect URIs, and enter the App ID and App secret as the connection's Client ID and Client Secret. To serve accounts you don't own, that Meta app needs Advanced Access, so budget time for App Review and Business Verification. Copy SCALEKIT_ENVIRONMENT_URL, SCALEKIT_CLIENT_ID, and SCALEKIT_CLIENT_SECRET from Developers > API Credentials into .env.
get_or_create_connected_account returns the connected account for an identifier. If it is not ACTIVE, get_authorization_link returns the Facebook Login link the user opens once to grant your app access to their Instagram professional account. Scalekit stores the resulting token; your code never receives it. Most tools also take an ig_user_id, the Instagram professional account ID. With Facebook Login, that ID is the instagram_business_account field on the user's Page, and you can read it once through Scalekit's API proxy and store it with the user. The connector page doesn't document the proxy's Graph API version, so if the path below returns an error, check the response body before assuming the account isn't linked.
This is not a catalog load. The agent asks for the tools this connected account is authorized to call, then narrows them to the six a performance analyst needs. All six are read-only. instagram_media_publish, instagram_message_send, and instagram_comment_delete never reach the model, so a reporting question can't turn into a post, a DM, or a deleted comment.
The loop runs until the model stops requesting tools. Every call runs with this user's Instagram token, against the one account they connected.
For pipelines, skip the model. execute_tool runs one tool with a fixed input and returns data plus an execution_id you can log. The first job publishes an approved post from a content calendar: it checks the quota, creates a container, waits for FINISHED, and publishes. The image URL must be a public JPEG.
The second job is a webhook handler. Meta posts a comments event to your endpoint; the handler verifies X-Hub-Signature-256 with your Meta App Secret, looks up which customer owns the Instagram account in entry[].id, and hides comments that match a blocklist. A comment asking about an order gets a private reply instead, which moves the conversation to DMs.
The webhook subscription itself isn't a connector tool, and the connector page lists no Scalekit triggers for Instagram. You configure the comments field on your own Meta app, which needs to be Live with Advanced Access, and point it at your endpoint. Meta retries for up to 36 hours, so store handled comment IDs and skip repeats: hiding an already hidden comment is harmless, but a second private reply is not. No MCP option has an equivalent for this step.
The instagram connector has 30 tools. At roughly 200 tokens each, that is about 6,000 tokens of definitions before the agent does any work. Accuracy is the sharper problem: a model choosing among instagram_comment_reply_create, instagram_comment_private_reply_create, and instagram_message_send picks the wrong one more often than a model holding only the one it needs, and on Instagram the wrong one is public. A community manager assistant that also holds instagram_media_publish can post on a misread instruction. The fix is not better prompting. It is surface reduction. A Scalekit virtual MCP server declares exactly which tools an agent role can see, and session tokens keep each run bound to one user's connected accounts. Docs: set up a virtual MCP server.
One server definition serves every brand. Before each run, check that the user's accounts are active and mint a short-lived session token scoped to them. Any MCP client that speaks Streamable HTTP can connect; this example uses langchain-mcp-adapters (pip install langchain-mcp-adapters) and passes the token as a Bearer header.
The agent sees seven tools instead of 30 plus everything Slack exposes. The endpoint is static; the identity is per user. This is the piece the community servers are missing: a remote MCP endpoint with organic Instagram tools where every run acts as a different brand's account, with no token in a config file.
Every execute_tool call returns an execution_id, and every execution is attributed to a connected account, which maps to one user at one customer. When a brand asks who hid 40 comments on Tuesday's launch post, or which run sent a private reply that upset a customer, the answer is a lookup, not an investigation.
Instagram's own record is thinner than you'd expect. A post published through the API, a hidden comment, or a sent DM is attributed to the professional account and your Meta app, not to the person in your product who asked for it. If a team of five social managers shares one connected account, Instagram can't tell them apart, so your execution log is the only place that records who asked. On a community MCP server with one Page token, there is no attribution at all beyond "the token did it." Shared credentials are a single-user solution. They do not survive a second user.
Recommended reading: audit trails for agent auth
If your agent is a marketer's assistant for paid work, reporting on campaigns and boosting organic posts with a human approving spend, Meta's Ads MCP is the only first-party MCP option, and it is good at that job. If you want a model managing one account you own from a desktop client, a community server like AleemHaider/instagram-mcp works, as long as you accept an unofficial wrapper and a token on disk. If your agent publishes on a schedule, moderates comments from webhooks, answers DMs inside the 24-hour window, or serves many brands, build against the Instagram API, where you choose the login path, the tools, and the retry behavior. Either way, you hold a token per Instagram account that can publish as that brand, sometimes with no expiry, and that's what needs production-grade infrastructure.
Not for organic content. Meta's only first-party MCP server is the Meta Ads MCP, announced in April 2026, and its Instagram tools list linked accounts, list boost-eligible media and boost an existing post. It cannot publish, reply to a comment or answer a DM. Every organic Instagram MCP server is a community project.
The good ones are thin wrappers over the Instagram API, but they run locally, read one long-lived token from an environment variable and act as one account, pinned to a Graph API version their maintainer chose. Some servers on registries log in with a username and password against Instagram's private mobile API, which risks a ban.
Only professional accounts, meaning Business and Creator accounts. Personal accounts lost API access when Meta ended the Basic Display API in December 2024. To serve accounts you do not own or manage, your Meta app needs Advanced Access, which requires App Review and Business Verification.
With Instagram Login, a long-lived token lasts 60 days and can be refreshed once it is at least 24 hours old, and a token not refreshed within 60 days expires for good. With Facebook Login, a user token is exchanged for a roughly 60-day token, and the Page tokens derived from it have no expiration date.
Use the API for scheduled publishing, comment moderation driven by webhooks, private replies and DMs inside the 24-hour window, business discovery, and serving many brands' accounts under Advanced Access. Use the Meta Ads MCP for boosting and ads reporting, or a community server for one account you own.
Scalekit's Instagram connector exposes 30 tools over the Instagram API with OAuth through Facebook Login. Each user connects their Business or Creator account once, and Scalekit stores and refreshes the token so the agent never sees it. You narrow tools per agent role and serve them through a virtual MCP server, one brand per run.
Browse the Scalekit Instagram connector and the Instagram connector docs with the full tool list. See Scalekit pricing, or talk to us.