Skip to main content
Glama
instagram-mcp-server

instagram-mcp-server

by qaassimq

instagram-mcp-server

npm version CI

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 4

  • stdio 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.

instagram_login (default)

facebook_login

Host

graph.instagram.com

graph.facebook.com

Facebook Page required

No

Yes — and you must admin it

Scope family

instagram_business_*

instagram_* + pages_*

Tools registered

37

42

Publishing, comments, DMs

✅

✅

Account and media insights

✅

✅

Mentions (read + reply)

✅

✅

Hashtag search

❌

✅

Business discovery (competitors)

❌

✅

Product tagging / Shopping

❌

✅

Delete media

❌

✅

total_views / total_likes / total_comments metrics

❌

✅

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-server

Run 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-server

From source:

git clone https://github.com/qaassimq/instagram-mcp-server.git
cd instagram-mcp-server
npm install
npm run build

3. Create the Meta app and get a token

Instagram Login path

  1. In the App Dashboard, create an app and add the Instagram product.

  2. Under Instagram → API setup with Instagram Login, connect your Instagram professional account.

  3. In step 3 of that page, click Generate token next to your account. Copy the IGAA... token.

  4. Request these permissions for your app: instagram_business_basic, instagram_business_content_publish, instagram_business_manage_comments, instagram_business_manage_messages.

Facebook Login path

  1. Add the Instagram product and use API setup with Facebook Login.

  2. Link your Instagram professional account to a Facebook Page you administer.

  3. 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.

  4. Run the server once and call instagram_list_pages to find your Instagram account ID, then set it as IG_USER_ID.

4. Configure

cp .env.example .env
# fill in IG_ACCESS_TOKEN, and IG_USER_ID if using facebook_login

5. 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/mcp

The 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   # interactive

Tools

Account and auth (4–5)

Tool

Notes

instagram_get_account

Profile plus a capability report for the active mode. Call this first.

instagram_get_publishing_limit

Quota used of the 100-post / 24h cap

instagram_get_token_info

debug_token on facebook_login; liveness check on instagram_login

instagram_refresh_token

Extends a long-lived token. Returns it — does not persist it.

instagram_list_pages

facebook_login only. Finds your IG_USER_ID.

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-test

Design notes worth knowing if you extend it:

  • createServer() returns a fresh McpServer every call. createMcpHandler invokes 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 GraphClient lives at module scope and is closed over, so the factory stays cheap.

  • Tools are gated at registration, not at call time. In instagram_login mode the model never sees instagram_search_hashtag, so it cannot waste a turn discovering it does not work. instagram_get_account reports 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. GraphError exposes isAuthError / isPermissionError / isRateLimited for programmatic branching.

  • The token goes in the Authorization header 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

MIT

Available Tools

37 tools
instagram_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 CommentA
DestructiveIdempotent

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 AccountA
Read-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 InsightsA
Read-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 DemographicsA
Read-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 CommentA
Read-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 StatusA
Read-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 ConversationA
Read-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 MediaA
Read-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 ChildrenA
Read-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 InsightsA
Read-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 CommentA
Read-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 MediaA
Read-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 LimitA
Read-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 StoriesA
Read-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 InfoA
Read-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 CommentA
Idempotent

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 RepliesA
Read-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 CommentsA
Read-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 ConversationsA
Read-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 MediaA
Read-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 CatalogA
Read-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 StoriesA
Read-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 MediaA
Read-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 SeenA
Idempotent

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_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 CommentsA
Idempotent

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

    A3.9/5.0

    Scored across 37 tools

    Disambiguation4/5

    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.

    Naming Consistency5/5

    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.

    Tool Count2/5

    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.

    Completeness4/5

    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

    ActivityMaintained
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • F
      license
      A
      quality
      C
      maintenance
      Enables posting and managing Instagram content (photos, reels, stories, carousels) and interacting with media and comments via Instagram Graph API.
      10
      7 npm
      -
    • A
      license
      A
      quality
      C
      maintenance
      Enables publishing photos, reels, and stories to Instagram, reading and moderating comments, fetching performance insights, drafting captions via MCP sampling, and scheduling reels for later.
      13
      28 npm
      MIT
    • A
      license
      B
      quality
      B
      maintenance
      Enables 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.
      29
      MIT
    • F
      license
      Not graded
      quality
      A
      maintenance
      Enables 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.
      -