instagram-mcp-server
Provides tools for interacting with Meta's official Instagram Platform APIs, including publishing images, reels, stories, and carousels; managing media, comments, and direct messages; retrieving account, media, story, and audience insights; and handling mentions and discovery features such as hashtag search and business discovery in the facebook_login mode.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@instagram-mcp-server Publish this image to Instagram with caption 'New arrivals'"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
instagram-mcp-server
An MCP server for Meta's official Instagram Platform APIs. 37–42 tools covering publishing, media, comments, direct messages, insights, and discovery.
No private endpoints, no scraping, no session cookies, no username/password login.
Every call goes to graph.instagram.com or graph.facebook.com with an OAuth token
you issued yourself.
TypeScript, MCP SDK v2 (
@modelcontextprotocol/server), Zod 4stdio and Streamable HTTP transports
Graph API v26.0 by default, pinnable
Supports both of Meta's Instagram configurations from one codebase
Which auth mode do you want?
Meta ships two different Instagram APIs. This server implements both; IG_AUTH_MODE
picks one at startup, and only the tools that mode can actually serve get registered.
|
| |
Host |
|
|
Facebook Page required | No | Yes — and you must admin it |
Scope family |
|
|
Tools registered | 37 | 42 |
Publishing, comments, DMs | ✅ | ✅ |
Account and media insights | ✅ | ✅ |
Mentions (read + reply) | ✅ | ✅ |
Hashtag search | ❌ | ✅ |
Business discovery (competitors) | ❌ | ✅ |
Product tagging / Shopping | ❌ | ✅ |
Delete media | ❌ | ✅ |
| ❌ | ✅ |
Pick instagram_login if your users should be able to connect with just an
Instagram account. The onboarding is dramatically simpler and it is Meta's
forward-looking path.
Pick facebook_login if you need hashtag research, competitor lookup, or
Shopping tags. There is no way to get those on the Instagram Login path — it is a
Meta product decision, not a gap in this server.
You can run two instances side by side with different modes if you need both.
Related MCP server: instagram-mcp
Setup
1. Requirements
Node.js 20.3 or newer
An Instagram professional account — Business or Creator. Personal accounts cannot reach the Graph API at all.
A Meta app at developers.facebook.com
2. Install
Nothing to install ahead of time. MCP clients can launch it straight from npm:
npx -y @qaassim/instagram-mcp-serverRun on its own, it exits and reports that IG_ACCESS_TOKEN is required. That is
expected. Your MCP client supplies the token through env (see step 5).
To install it globally instead:
npm install -g @qaassim/instagram-mcp-server
instagram-mcp-serverFrom source:
git clone https://github.com/qaassimq/instagram-mcp-server.git
cd instagram-mcp-server
npm install
npm run build3. Create the Meta app and get a token
Instagram Login path
In the App Dashboard, create an app and add the Instagram product.
Under Instagram → API setup with Instagram Login, connect your Instagram professional account.
In step 3 of that page, click Generate token next to your account. Copy the
IGAA...token.Request these permissions for your app:
instagram_business_basic,instagram_business_content_publish,instagram_business_manage_comments,instagram_business_manage_messages.
Facebook Login path
Add the Instagram product and use API setup with Facebook Login.
Link your Instagram professional account to a Facebook Page you administer.
Generate a long-lived User or Page token with:
instagram_basic,instagram_content_publish,instagram_manage_comments,instagram_manage_insights,instagram_manage_messages,instagram_manage_contents,pages_show_list,pages_read_engagement,business_management.Run the server once and call
instagram_list_pagesto find your Instagram account ID, then set it asIG_USER_ID.
4. Configure
cp .env.example .env
# fill in IG_ACCESS_TOKEN, and IG_USER_ID if using facebook_login5. Register with a client
Claude Desktop (claude_desktop_config.json) or any stdio MCP client:
{
"mcpServers": {
"instagram": {
"command": "npx",
"args": ["-y", "@qaassim/instagram-mcp-server"],
"env": {
"IG_ACCESS_TOKEN": "IGAA...",
"IG_AUTH_MODE": "instagram_login"
}
}
}
}From a source checkout, use "command": "node" and
"args": ["/absolute/path/to/instagram-mcp-server/dist/index.js"] instead.
For a remote deployment:
TRANSPORT=http PORT=3000 npm start
# -> http://127.0.0.1:3000/mcpThe HTTP handler validates Host and Origin on localhost binds. Add bearer auth
before exposing it beyond localhost — see requireBearerAuth in the
SDK authorization docs.
The token in IG_ACCESS_TOKEN grants write access to a real Instagram account;
an unauthenticated public endpoint hands that to anyone who finds it.
6. Verify
npm run smoke # 19 checks, no live credentials needed
npx @modelcontextprotocol/inspector node dist/index.js # interactiveTools
Account and auth (4–5)
Tool | Notes |
| Profile plus a capability report for the active mode. Call this first. |
| Quota used of the 100-post / 24h cap |
|
|
| Extends a long-lived token. Returns it — does not persist it. |
|
|
Publishing (7)
instagram_publish_image · instagram_publish_reel · instagram_publish_story ·
instagram_publish_carousel · instagram_create_container ·
instagram_get_container_status · instagram_publish_container
The four high-level tools run Meta's whole create → process → publish flow. If video
processing outlasts wait_seconds they return the container ID instead of failing,
so an upload is never lost — finish it with instagram_get_container_status then
instagram_publish_container. instagram_create_container is the escape hatch for
parameters the high-level tools do not expose.
Media (5–6)
instagram_list_media · instagram_get_media · instagram_get_media_children ·
instagram_list_stories · instagram_list_tagged_media ·
instagram_delete_media (facebook_login only)
Comments (8)
instagram_list_comments · instagram_get_comment ·
instagram_list_comment_replies · instagram_create_comment ·
instagram_reply_to_comment · instagram_hide_comment ·
instagram_delete_comment · instagram_toggle_media_comments
Direct messages (5)
instagram_list_conversations · instagram_get_conversation ·
instagram_send_message · instagram_send_media_message · instagram_mark_seen
instagram_get_conversation reports whether the 24-hour reply window is still open,
so you can tell a refusal from a policy limit before you try to send.
Insights (5)
instagram_list_metric_catalog · instagram_get_account_insights ·
instagram_get_media_insights · instagram_get_audience_demographics ·
instagram_get_story_insights
Metric names change between Graph API versions and an unsupported metric or an
invalid metric/breakdown pair is a hard API error. instagram_list_metric_catalog
makes no API call and lists exactly what is valid, so the model looks names up
instead of guessing. Invalid pairs are rejected locally, before the round-trip.
instagram_get_story_insights reads every live story in one call — story insights
disappear with the story after 24 hours.
Discovery (3–6)
instagram_get_mentioned_comment · instagram_get_mentioned_media ·
instagram_reply_to_mention
and on facebook_login only: instagram_search_hashtag ·
instagram_get_hashtag_media · instagram_business_discovery
There is no "list all mentions" tool, because Meta has no such endpoint. Mentions
are delivered to your app through the mentions webhook field and then read by ID.
Without a webhook you cannot discover mentions through the API. Photo tags are a
different edge and can be listed — that is instagram_list_tagged_media.
Limitations you inherit from the Graph API
None of these are implementation gaps. They are Meta's constraints, and no MCP wrapper can route around them.
Account type. Instagram professional accounts only. Personal accounts have no Graph API access whatsoever.
App Review. Serving only your own business needs no review — Standard Access
covers it. The moment your app touches another business's account you need
Advanced Access, which means App Review: app icon, privacy policy, category, test
credentials, and an English screencast per permission. instagram_manage_messages
is the one that bites first, so DMs will not work for third parties until you pass
review.
Publishing. 100 API-published posts per rolling 24 hours, per account; a carousel
counts as one. JPEG is the only supported image format. Media must sit at a public
HTTPS URL that returns the file directly — Meta fetches it server-side, so local
paths, authenticated URLs, redirects and expiring signed URLs all fail. No filters,
no Shopping tags, no branded-content tags. alt_text works on image posts but not
on reels or stories.
Rate limits. Instagram Platform endpoints run on a Business Use Case limit of
4800 × impressions per 24 hours, where impressions is how many times the account's
content hit a screen in the last day. A low-reach account is a low-quota account —
your budget scales with the audience you already have, not with your needs. Business
Discovery and Hashtag Search sit outside this and fall under standard Platform Rate
Limits instead.
Hashtag search. 30 unique hashtags per rolling 7 days per account. Resolve a
hashtag to its ID once and reuse the ID. recent_media only covers the last 24
hours, and personal-account posts are never returned.
Insights. Carousel albums have no per-child insights. Audience demographics are
withheld below roughly 100 followers (an empty result, not an error). impressions
was replaced by views for media created after 2024-07-02.
Messaging. A standard reply is only allowed within 24 hours of the user's last
message. The HUMAN_AGENT tag extends that to 7 days. Unsolicited DMs are not
possible. Recipients are addressed by Instagram-scoped ID (IGSID) from a conversation
or webhook — never by public username.
Version churn. Meta retires a Graph API version roughly two years after release;
v26.0 shipped 2026-07-29. Pin IG_API_VERSION and treat upgrades as recurring work.
Architecture
src/
index.ts createServer() factory + transport selection
config.ts environment resolution, auth-mode validation
constants.ts every documented Meta constraint, cited to its doc
graph.ts dual-host client, error mapping, cursor pagination
format.ts markdown/JSON switch, character-limit guard, renderers
tools/
account.ts identity, capabilities, quota, token lifecycle
publishing.ts container create → poll → publish
media.ts feed, single media, carousel children, stories, tags
comments.ts read and moderate
messaging.ts Instagram Direct
insights.ts account, media, demographics, stories, metric catalog
discovery.ts mentions, hashtags, business discovery
scripts/
smoke.ts 19-check self-testDesign notes worth knowing if you extend it:
createServer()returns a freshMcpServerevery call.createMcpHandlerinvokes it per HTTP request; a shared instance passes manual testing and then fails under concurrency with-32603. The smoke test fires concurrent HTTP requests specifically to catch that regression.The
GraphClientlives at module scope and is closed over, so the factory stays cheap.Tools are gated at registration, not at call time. In
instagram_loginmode the model never seesinstagram_search_hashtag, so it cannot waste a turn discovering it does not work.instagram_get_accountreports what is missing and why.Error text is written for the model. Meta's own message is preserved, the numeric code is kept, and a recovery sentence plus the failing call site are appended.
GraphErrorexposesisAuthError/isPermissionError/isRateLimitedfor programmatic branching.The token goes in the
Authorizationheader on reads and in the form body on writes, so it never lands in a logged query string on a mutation.Responses stay under 25,000 characters by returning fewer items, never by truncating text — the pagination cursor is suppressed when items are dropped so nothing is silently skipped.
License
Available Tools
37 toolsinstagram_create_commentComment on MediaA
Post a new top-level comment on one of the account's own media objects.
To answer someone else's comment use instagram_reply_to_comment instead — a reply threads under theirs and notifies them.
Inputs: message (required), media_id (required).
instagram_create_containerCreate Media ContainerA
Low-level escape hatch: create a media container with arbitrary parameters, without publishing it.
Prefer instagram_publish_image / _reel / _story / _carousel, which run the whole flow. Use this when you need a parameter those tools do not expose, or when assembling a carousel from children that were created earlier.
Returns the container ID. Publish it with instagram_publish_container.
Inputs: caption, children, image_url, video_url, +4 more.
instagram_delete_commentDelete CommentADestructiveIdempotent
Permanently delete a comment.
Works on comments the account authored, and on comments by others on the account's own media. This cannot be undone — instagram_hide_comment is the reversible alternative.
Inputs: comment_id (required).
instagram_get_accountGet AccountARead-onlyIdempotent
Get the authenticated Instagram professional account's profile, and the server's active capabilities.
Returns username, account type, follower/following/media counts, bio and website, plus which Meta auth mode this server is running in and what that mode cannot do.
Call this first in a new session: it tells you the account ID to pass to other tools and whether hashtag search and business discovery are available at all.
Inputs: account_id, response_format.
instagram_get_account_insightsGet Account InsightsARead-onlyIdempotent
Get account-level insights: reach, views, interactions, likes, comments, shares, saves, follows and profile link taps.
Defaults to the full interaction metric set for the last 7 days as totals. Narrow with metrics, or split a metric with breakdown (one metric at a time when using a breakdown).
For audience age/city/country/gender use instagram_get_audience_demographics instead.
Examples:
"how did we do last week" -> defaults
"reach split by followers vs non-followers" -> metrics=["reach"], breakdown="follow_type"
Inputs: since, until, metrics, breakdown, +3 more.
instagram_get_audience_demographicsGet Audience DemographicsARead-onlyIdempotent
Get the follower or engaged-audience breakdown by age, city, country or gender.
These are lifetime metrics and a breakdown is mandatory. Meta withholds demographics for accounts under roughly 100 followers, which comes back as an empty result rather than an error.
Example: "where are our followers" -> metric="follower_demographics", breakdown="country"
Inputs: breakdown (required), metric, timeframe, account_id, +1 more.
instagram_get_commentGet CommentARead-onlyIdempotent
Get one comment by ID, including its text, author, like count and hidden state.
Inputs: comment_id (required), response_format.
instagram_get_container_statusGet Container StatusARead-onlyIdempotent
Check whether a media container is ready to publish.
status_code is one of: EXPIRED — not published within 24 hours of creation ERROR — processing failed FINISHED — ready to publish IN_PROGRESS — still processing PUBLISHED — already published
Meta advises polling about once a minute for no more than five minutes.
Inputs: container_id (required).
instagram_get_conversationGet ConversationARead-onlyIdempotent
Read the messages in one conversation, newest first.
Note the 24-hour rule before replying: a standard reply is only allowed within 24 hours of the user's most recent message. Check the newest created_time to see whether the window is still open.
Inputs: conversation_id (required), limit, response_format.
instagram_get_mediaGet MediaARead-onlyIdempotent
Get one media object by ID, with caption, type, engagement counts and permalink.
Use instagram_list_media to find IDs. For a carousel, instagram_get_media_children lists the individual photos and videos inside it.
Inputs: media_id (required), fields, response_format.
instagram_get_media_childrenGet Carousel ChildrenARead-onlyIdempotent
List the individual images and videos inside a carousel post.
Only meaningful for media whose media_type is CAROUSEL_ALBUM. Note that Meta serves no per-child insights — insights exist only for the carousel as a whole.
Inputs: media_id (required), response_format.
instagram_get_media_insightsGet Media InsightsARead-onlyIdempotent
Get per-post insights for one media object.
The valid metric set depends on the media type, so pass media_product_type and the right defaults are used: FEED for posts and carousels, REELS for reels, STORY for stories. Carousel albums report only whole-post figures — Meta serves no per-child insights.
Example: "how did the latest reel do" -> media_id from instagram_list_media, media_product_type="REELS"
Inputs: media_id (required), metrics, response_format, media_product_type.
instagram_get_mentioned_commentGet Mentioned CommentARead-onlyIdempotent
Read a comment in which the account was @mentioned, by comment ID.
Meta provides no endpoint that lists mentions — they are delivered to your app through the "mentions" webhook field, and this tool reads one once you have its ID. If you have no webhook configured, you cannot discover mentions through the API at all.
Reply with instagram_reply_to_mention.
Inputs: comment_id (required), account_id, response_format.
instagram_get_mentioned_mediaGet Mentioned MediaARead-onlyIdempotent
Read a media object whose caption @mentions the account, by media ID.
As with mentioned comments, Meta delivers these through the "mentions" webhook rather than a list endpoint. Photo tags are a different edge — use instagram_list_tagged_media for those, which does support listing.
Inputs: media_id (required), account_id, response_format.
instagram_get_publishing_limitGet Publishing LimitARead-onlyIdempotent
Check how much of the 100-post / 24-hour API publishing quota the account has used.
Meta counts a carousel as one post. Call this before a bulk publish run, and after a publish failure that might be quota exhaustion rather than a bad request.
Inputs: account_id, response_format.
instagram_get_story_insightsGet Insights for All Live StoriesARead-onlyIdempotent
Read insights for every story currently live on the account, in one call.
Stories vanish after 24 hours and their insights go with them, so this is the tool for catching a day's story performance before it is lost. Equivalent to instagram_list_stories followed by instagram_get_media_insights on each result.
Inputs: account_id, response_format.
instagram_get_token_infoGet Token InfoARead-onlyIdempotent
Inspect the configured access token: its type, scopes, and expiry.
On the facebook_login path this calls debug_token and needs IG_APP_ID and IG_APP_SECRET. On the instagram_login path Meta exposes no debug endpoint, so this verifies the token by reading the account and reports what it can.
Use it to diagnose a permission error before assuming a tool is broken.
Inputs: response_format.
instagram_hide_commentHide or Unhide CommentAIdempotent
Hide a comment from public view, or unhide one.
Hiding is reversible and leaves the comment visible to its author — prefer it to deletion for borderline content. Use instagram_delete_comment only for comments on the account's own media that should be gone for good.
Inputs: comment_id (required), hide.
instagram_list_comment_repliesList Comment RepliesARead-onlyIdempotent
List the replies to one top-level comment.
Instagram supports exactly one level of nesting, so replies have no replies of their own.
Inputs: comment_id (required), after, limit, response_format.
instagram_list_commentsList CommentsARead-onlyIdempotent
List top-level comments on one of the account's media objects.
Replies are nested one level deeper — use instagram_list_comment_replies for a specific thread. Hidden comments are included with hidden=true.
Example: "what are people saying on our latest post" -> first instagram_list_media, then this with that media_id
Inputs: media_id (required), after, limit, response_format.
instagram_list_conversationsList ConversationsARead-onlyIdempotent
List Instagram Direct conversations in the account's inbox, most recently updated first.
Each entry carries the participant IGSIDs needed to send a message. Requires the messaging permission with Advanced Access.
Example: "any new DMs?" -> limit=10, then instagram_get_conversation on the ones with unread_count > 0
Inputs: after, limit, account_id, response_format.
instagram_list_mediaList MediaARead-onlyIdempotent
List the account's published media, newest first.
Returns one page with a cursor. Covers feed posts, reels and carousels; stories are separate (instagram_list_stories) because they expire.
Use this to find media IDs for instagram_get_media_insights, instagram_list_comments, or instagram_get_media.
Example: "what did we post recently" -> limit=10
Inputs: after, limit, fields, account_id, +1 more.
instagram_list_metric_catalogList Metric CatalogARead-onlyIdempotent
List every insight metric this server can request, which surface it applies to, and which breakdowns each one accepts. Makes no API call.
Read this before calling instagram_get_account_insights or instagram_get_media_insights with custom metrics — an unsupported metric or an invalid metric/breakdown pair is a hard API error, not an empty result.
Inputs: response_format.
instagram_list_storiesList Active StoriesARead-onlyIdempotent
List the account's currently live stories.
Stories expire 24 hours after posting, so this returns only what is live right now. Story insights come from instagram_get_media_insights with media_product_type="STORY".
Inputs: account_id, response_format.
instagram_list_tagged_mediaList Tagged MediaARead-onlyIdempotent
List media published by other accounts in which this account was tagged.
Different from mentions: this is the photo-tag edge, not @mentions in captions or comments. Use instagram_list_mentions for those.
Inputs: after, limit, account_id, response_format.
instagram_mark_seenMark Conversation SeenAIdempotent
Mark the conversation with a user as read, which clears its unread badge.
Use it after processing an inbox so the same messages are not reprocessed as new.
Inputs: recipient_id (required), account_id.
instagram_publish_carouselPublish CarouselA
Publish a carousel of 2-20 images and/or videos as one post.
This creates a child container per item, waits for any video children to process, then creates and publishes the carousel container. The whole carousel counts as a single post against the publishing quota.
Example: "post these three photos as one post" -> items=[{image_url:"..."},{image_url:"..."},{image_url:"..."}]
Inputs: items (required), caption, account_id, location_id, +3 more.
instagram_publish_containerPublish ContainerA
Publish a media container that is already FINISHED.
Use this to complete a publish that was interrupted, or after assembling a carousel with instagram_create_container. Publishing a container that is still IN_PROGRESS fails; check instagram_get_container_status first.
Inputs: container_id (required), account_id.
instagram_publish_imagePublish ImageA
Publish a single image to the Instagram feed.
The image must be a JPEG served from a public HTTPS URL that returns the file directly — no redirects, no authentication, no HTML wrapper. Meta fetches it server-side, so a local path or a signed URL that expires will fail.
For two or more images in one post use instagram_publish_carousel. For video use instagram_publish_reel.
Example: "post this photo with the caption 'new drop'" -> image_url="https://cdn.example.com/a.jpg", caption="new drop"
Inputs: image_url (required), caption, alt_text, user_tags, +4 more.
instagram_publish_reelPublish ReelA
Publish a video as a Reel.
Reels are the only way to publish video to the feed — Instagram converted standalone feed video to Reels. The video must be at a public HTTPS URL; Meta downloads and transcodes it, which takes time, so this tool waits for processing before publishing.
If processing outlasts wait_seconds the tool returns the container ID instead of failing; finish with instagram_get_container_status then instagram_publish_container.
Specs: MOV or MP4, 3s-15min, aspect ratio 0.01:1 to 10:1, up to 1GB.
Inputs: video_url (required), caption, cover_url, user_tags, +8 more.
instagram_publish_storyPublish StoryA
Publish an image or video story. Stories expire after 24 hours.
Supply exactly one of image_url or video_url. Stickers, polls, links and music cannot be added through the API — Meta exposes none of those on the publishing endpoint.
Inputs: image_url, video_url, account_id, wait_seconds.
instagram_refresh_tokenRefresh Access TokenA
Extend the configured long-lived access token and return the new one.
instagram_login: refreshes an Instagram long-lived token for another 60 days. The token must be at least 24 hours old and not yet expired. facebook_login: exchanges the token for a fresh long-lived one; needs IG_APP_ID and IG_APP_SECRET.
This does NOT write the new token anywhere. Save the returned value into IG_ACCESS_TOKEN yourself, or the next restart uses the old one.
Inputs: no named parameters.
instagram_reply_to_commentReply to CommentA
Reply to a comment, threaded underneath it.
Only top-level comments accept replies — Instagram allows a single level of nesting. Replying to a reply fails; reply to its parent_id instead.
Inputs: message (required), comment_id (required).
instagram_reply_to_mentionReply to MentionA
Reply to a mention of the account on someone else's media.
Pass comment_id to reply to the specific comment that mentioned you; omit it to leave a new top-level comment on the media instead. The media's owner must allow comments.
Inputs: message (required), media_id (required), account_id, comment_id.
instagram_send_media_messageSend Media MessageB
Send an image, video, or audio attachment as a direct message.
The URL must be public HTTPS; Meta fetches it server-side. The same 24-hour window applies as for text messages.
Inputs: media_url (required), recipient_id (required), account_id, media_type.
instagram_send_messageSend Direct MessageA
Send a text message to an Instagram user.
Meta allows this only within 24 hours of that user's last message to the account. Outside the window, set tag="HUMAN_AGENT" to use the 7-day human-agent allowance; unsolicited messages are not possible at all.
Requires the messaging permission with Advanced Access. Get the recipient IGSID from instagram_list_conversations — a public username will not work.
Inputs: text (required), recipient_id (required), tag, account_id.
instagram_toggle_media_commentsEnable or Disable CommentsAIdempotent
Turn commenting on or off for one of the account's media objects.
Disabling hides the whole comment thread and blocks new comments. Existing comments return when it is re-enabled.
Inputs: enabled (required), media_id (required).
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 37 tools
Most tools have clearly distinct resource+action targets, and descriptions explicitly differentiate close pairs (hide vs delete comment, reply_to_comment vs create_comment, tagged media vs mentions). The main overlaps are the low-level container escape hatch (create_container/publish_container) versus the high-level publish_* tools, and get_media_insights versus get_story_insights, both of which are called out in the descriptions rather than left ambiguous.
Every tool uses the instagram_ prefix with snake_case verb_noun structure (publish_reel, list_comments, get_media_insights, reply_to_comment). Variants like mark_seen and toggle_media_comments still follow the same verb-first convention, so an agent can predict names reliably.
37 tools is heavy for a single-account publishing/insights server, well above the 25-tool threshold. Several groups could be consolidated (five publish variants, three token/auth tools, three mention tools), and the surface is large enough that an agent must read carefully to pick correctly.
Coverage is broad and coherent across publishing, media reading, comments, DMs, insights, mentions and auth — essentially the full Graph API surface for a professional account, including quota and token diagnostics. Minor gaps: instagram_list_tagged_media references an instagram_list_mentions tool that does not exist in this set, and there is no media-deletion capability (though Meta's API largely forbids it).
Maintenance
Related MCP Connectors
Instagram MCP for DM and comment automation, AI Agent and content publishing via Meta's official API
Publish to Instagram from chat — official Graph API, OAuth 2.1, free for your own posts.
Instagram for AI agents: publish, read comments and DMs, insights, and engage from your account.
Schedule Instagram reels, manage comment-to-DM automations, and read analytics
Related MCP Servers
- FlicenseAqualityCmaintenanceEnables posting and managing Instagram content (photos, reels, stories, carousels) and interacting with media and comments via Instagram Graph API.107 npm-
- AlicenseAqualityCmaintenanceEnables publishing photos, reels, and stories to Instagram, reading and moderating comments, fetching performance insights, drafting captions via MCP sampling, and scheduling reels for later.1328 npmMIT
- AlicenseBqualityBmaintenanceEnables reading, publishing, commenting on, and analyzing Instagram Business/Creator accounts through the official Graph API, with multi-account support and an optional self-hosted publishing panel.29MIT
- FlicenseNot gradedqualityAmaintenanceEnables AI applications to programmatically interact with Instagram Business accounts through the Graph API, covering profile and media retrieval, engagement insights, publishing images and videos, and reading or replying to direct messages. It exposes these capabilities as tools, resources, and prompts so clients can manage content and analyze performance through natural language.-