instagram-mcp
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| INSTAGRAM_MCP_DM_ENABLED | No | Set to '1' to enable Direct Message tools (requires App Review) | |
| INSTAGRAM_MCP_IG_USER_ID | Yes | Numeric Instagram Business Account ID | |
| INSTAGRAM_MCP_ACCESS_TOKEN | Yes | Long-lived access token with instagram_basic, instagram_content_publish, instagram_manage_comments, instagram_manage_insights permissions |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": true
} |
| logging | {} |
| prompts | {
"listChanged": false
} |
| resources | {
"subscribe": false,
"listChanged": false
} |
| extensions | {
"io.modelcontextprotocol/ui": {}
} |
| experimental | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| healthcheckA | Verify the MCP is configured + ready: accounts present, token backend, Graph reachability. Does a live GET on the default account's profile if one is configured. Safe to call anytime; never mutates. Returns ok=false with a hint when no account is set. |
| list_accountsA | List configured Instagram accounts (labels + ig_user_id + default flag). Never returns tokens. |
| add_accountA | Store an Instagram Business/Creator account for use by every tool. label a short key you choose (e.g. "onde", "mycelium", "client-acme")
access_token a long-lived Instagram Graph API token (stored in the OS keychain)
ig_user_id the Instagram Business Account id (numeric)
app_secret optional Meta app secret — enables appsecret_proof call hardening
make_default set true to make this the account used when The token is written to the macOS keychain (or a chmod-600 file fallback) and is NEVER echoed back or logged. |
| set_default_accountA | Set which configured account is used when a tool's |
| remove_accountB | Remove a configured account + delete its stored token from the keychain. |
| account_infoB | Live profile snapshot for one account: username, name, followers, media count, etc. |
| get_profileC | Return the account's public profile fields (followers, follows, media count, bio, website). |
| list_mediaA | List recent media (posts/reels) for the account, newest first. limit 1-100 (default 25). |
| get_mediaB | Return full fields for one media object by id (caption, type, permalink, like/comment counts). |
| get_account_insightsB | Account-level analytics (reach, impressions, profile views, follower count). metrics: comma-separated Graph metric names (default reach,impressions,profile_views, follower_count). period: day|week|days_28|lifetime. Exact available metrics vary by Graph API version; on a mismatch the Meta error names the correct metric. |
| get_media_insightsA | Per-post analytics (reach, saves, likes, comments, shares, total interactions). metrics override is comma-separated; defaults suit feed posts. Reels/stories expose different metrics (e.g. plays, navigation) — pass them explicitly if needed. |
| get_audience_insightsA | Follower demographics (age, gender, country, city). Requires the account to have >=100 followers (Meta privacy floor) — below that the Graph returns an error, surfaced cleanly. Newer Graph versions use metric= follower_demographics with metric_type=total_value + breakdown=age|gender|country|city and a timeframe (last_14_days|last_30_days|last_90_days|prev_month) for engaged-audience metrics. All are override-able. |
| publishing_limitB | Remaining posts in the rolling 24h publishing quota (Instagram caps API posts/day). |
| publish_imageA | Publish a single image to the feed. image_url must be a PUBLIC https URL (Instagram fetches the bytes itself). caption <= 2200 chars. Two-step Graph flow (create container -> publish) handled internally. |
| publish_videoB | Publish a video to the feed. video_url must be a PUBLIC https URL. Video containers process asynchronously; this polls status up to 90s before publishing. |
| publish_reelA | Publish a Reel. video_url must be a PUBLIC https URL. share_to_feed also surfaces the reel in the main grid. cover_url (optional) sets the thumbnail. Reel containers process asynchronously (polled up to 90s). |
| publish_carouselA | Publish a multi-image carousel (2-10 images). Each image_url must be a PUBLIC https URL. Creates one child container per image (is_carousel_item) then a CAROUSEL parent, then publishes. |
| publish_storyB | Publish a Story (image OR video). Exactly one of image_url / video_url, PUBLIC https. |
| get_commentsB | List comments on a media object (text, username, timestamp, like_count, hidden). |
| reply_to_commentA | Reply to a comment. message <= 2200 chars. Returns the new comment id. |
| hide_commentB | Hide (or unhide) a comment from public view. hide=false unhides. |
| delete_commentA | Permanently delete a comment you own (or a comment on your media). Irreversible. |
| search_hashtagA | Resolve a hashtag name to its Graph id (needed before get_hashtag_media). |
| get_hashtag_mediaA | Recent or top media for a hashtag id. edge=top_media|recent_media. limit 1-100. Get the hashtag_id from search_hashtag first. Subject to Meta's 30-unique-hashtags per-7-days query limit per account. |
| get_mentionsB | List recent media where the account is @-mentioned (tags edge). |
| business_discoveryA | Public profile + (optionally) recent media for ANY business/creator account by username. Read-only competitor/prospect research via the business_discovery edge. Only works for Professional accounts (not personal). with_media pulls up to media_limit recent posts. |
| list_conversationsB | List Instagram DM conversations. REQUIRES Meta App Review (instagram_manage_messages). |
| get_messagesC | Read messages in a DM conversation. REQUIRES Meta App Review (instagram_manage_messages). |
| send_messageA | Send a DM. REQUIRES Meta App Review + the 24-hour standard-messaging window. recipient_id is the IGSID (Instagram-scoped user id) of the recipient. Outside the 24h customer-service window a paid message tag is required (not handled here). |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
TDQS
Scored across 29 tools
Most tools have clearly distinct purposes (e.g., separate publish tools for image, video, reel, carousel, story; separate comment management tools). However, 'account_info' and 'get_profile' both return profile data with overlapping descriptions, causing potential confusion.
The majority follow a consistent verb_noun pattern (list_, add_, get_, publish_, etc.). Minor deviations include 'account_info' (noun_verb), 'business_discovery' (noun_noun), and 'publishing_limit' (gerund_noun), but these are not overly disruptive.
29 tools is on the higher end for a single domain, but each tool covers a distinct part of the Instagram Graph API (accounts, publishing, insights, comments, DMs, hashtags, mentions). The scope justifies the count, though it could be slightly trimmed.
The tool set covers most major Instagram API operations: account management, publishing (multiple formats), insights, comments, hashtags, mentions, and DMs. Missing update/delete for media and limited user search, but core workflows are well-covered.