instagram-mcp
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| IG_PORT | No | 3000 | |
| IG_APP_ID | No | Meta app id (token exchange/refresh, appsecret_proof, debug_token) | |
| IG_ENV_FILE | No | Env-file location override (default: XDG path) | |
| IG_AUTH_MODE | No | ig-login | fb-login; alias IG_AUTH_PATH (inferred fb-login when IG_APP_ID+IG_APP_SECRET are set) | |
| IG_HTTP_HOST | No | 127.0.0.1 | |
| IG_LOG_LEVEL | No | debug | info | warn | error | info |
| IG_MAX_ITEMS | No | fetchAll hard item cap | 200 |
| IG_TRANSPORT | No | stdio | http | stdio |
| IG_ACCOUNT_ID | No | IG professional-account ID (skip a lookup / disambiguate) | |
| IG_APP_SECRET | No | Meta app secret (secret) | |
| IG_HTTP_TOKEN | No | HTTP bearer token (secret; constant-time compare) | |
| IG_TIMEOUT_MS | No | Per-request timeout for Graph calls | 30000 |
| IG_WRITE_MODE | No | preview | apply (standing consent for writes) | preview |
| IG_PRETTY_JSON | No | Pretty-print JSON results | false |
| IG_ACCESS_TOKEN | Yes | The account's long-lived token, whichever auth path (secret) | |
| IG_PACKAGES_DENY | No | Packages to remove after profile resolution | |
| IG_TOOL_PACKAGES | No | core | reader | publisher | all, or an explicit list | core |
| IG_WRITE_JOURNAL | No | Applied-write audit log (default: $XDG_STATE_HOME/instagram-mcp-ai/writes.jsonl) | |
| IG_ACTIVE_PROFILE | No | Profile used when a tool call passes no account | default |
| IG_MAX_CONCURRENT | No | Per-host concurrency semaphore | 4 |
| IG_ALLOW_DESTRUCTIVE | No | Second gate for irreversible ops (delete_comment) | false |
| IG_PACKAGES_READONLY | No | Packages forced read-only | |
| IG_REFRESH_AFTER_DAYS | No | Path-A auto-refresh threshold | 45 |
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
} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| instagram_get_accountA | Fetch the profile of the operated Instagram professional account: username, display name, biography, website, profile-picture URL, and follower / following / media counts. Read-only (GET /{ig-id}). Fields the account hides or that Meta omits are simply absent. Username, name, biography and website are account-controlled free text and are returned inside an untrusted content fence. |
| instagram_token_statusA | Report the active credential: auth path (A = ig-login / B = fb-login), whether a token is configured, the resolved account ID, and — on Path B, via debug_token — validity, granted scopes, absolute expiry and days-left (with a refresh warning as the threshold nears). Path A has no token-introspection endpoint, so expiry is reported honestly as unknown. Read-only. |
| instagram_list_commentsA | List the top-level comments on a media object, newest first, cursor-paginated, with threaded replies expanded inline under |
| instagram_get_commentA | Fetch a single comment by id, including its moderation state (hidden), parent/media context, and inline replies. Comment text and usernames are returned as fenced, untrusted text. Fields Instagram does not disclose are omitted rather than nulled; a deleted comment returns an error. |
| instagram_list_tagged_mediaA | List media the operated account has been TAGGED IN (the /tags edge), newest first, cursor-paginated. Note: tags are not @mentions — this lists posts where another account tagged this account in the media, not posts that @mention it (pull-based @mention discovery is a separate, Path-B-only capability). Captions and usernames are returned as fenced, untrusted text. |
| instagram_reply_to_commentA | Post a threaded reply under an existing comment (POST /{comment-id}/replies). Preview by default; re-run with apply:true (or set IG_WRITE_MODE=apply) to perform the reply. |
| instagram_create_commentA | Post a new top-level comment on a media object (POST /{media-id}/comments). Preview by default; re-run with apply:true (or set IG_WRITE_MODE=apply) to perform the comment. |
| instagram_hide_commentA | Hide a comment (POST /{comment-id}?hide=true) — reversible moderation, preferred over delete. Idempotent: hiding an already-hidden comment leaves it hidden. Preview by default; re-run with apply:true (or set IG_WRITE_MODE=apply) to perform the change. |
| instagram_unhide_commentA | Unhide a previously hidden comment (POST /{comment-id}?hide=false). Idempotent: unhiding a visible comment leaves it visible. Preview by default; re-run with apply:true (or set IG_WRITE_MODE=apply) to perform the change. |
| instagram_delete_commentA | Permanently delete a comment (DELETE /{comment-id}). IRREVERSIBLE — prefer instagram_hide_comment for moderation you may want to undo. Double-gated: it runs only with apply:true AND IG_ALLOW_DESTRUCTIVE=true; otherwise it stays a preview. |
| instagram_get_account_insightsA | Account-level insights for the operated Instagram professional account (GET /{ig-id}/insights). Uses the post-2025 views-centric metric set. Returns aggregated totals by default; time ranges are bounded by Meta's 90-day retention. |
| instagram_get_media_insightsA | Insights for a single media object (GET /{media-id}/insights). The valid metric set varies by media_product_type; supply media_product_type to have invalid combinations rejected client-side. Insights on media created before the account became professional, or on an expired story, may return empty or error. |
| instagram_get_audience_demographicsA | Follower / engaged-audience demographics for the operated account (GET /{ig-id}/insights with metric_type=total_value). Requires a timeframe and an account with at least 100 followers; below that threshold Meta returns an error naming the 100-follower rule. |
| instagram_get_online_followersA | Hourly distribution of when the account's followers are online (GET /{ig-id}/insights?metric=online_followers&period=lifetime). Data covers the last 30 days only. This metric is on the deprecation watch-list (present in the legacy reference, absent from the current docs tree) and may return a "metric no longer available" error in future API versions. |
| instagram_list_mediaA | List the operated account's own media (feed posts, reels, stories, albums), newest first, cursor-paginated. Returns a single page by default; set fetchAll to aggregate pages up to the server's item cap (IG_MAX_ITEMS), in which case paging.truncated is true if more media remained. Captions are returned as fenced, untrusted text. Some fields (like_count, media_url, counts on stories) may be absent when Instagram does not disclose them. |
| instagram_get_mediaA | Fetch a single media object by id, including its carousel children (album items) under |
| instagram_set_comments_enabledA | Toggle whether a media object accepts new comments (POST /{media-id}?comment_enabled=true|false). Idempotent: setting the value it already has is a no-op. Preview by default; re-run with apply:true (or set IG_WRITE_MODE=apply) to perform the change. |
| instagram_create_media_containerA | Phase 1 of publishing: create a media container that Instagram ingests from a public HTTPS URL. This does NOT publish — poll instagram_get_container_status until FINISHED, then call instagram_publish_media with the returned container id. Omit media_type for a single feed image; set REELS/STORIES/CAROUSEL otherwise. Media format, size, and duration are validated by Instagram on fetch (the server never downloads the URL), so only URL form and caption limits are checked here. |
| instagram_get_container_statusA | Read a media container's processing state: status_code is IN_PROGRESS, FINISHED, ERROR, EXPIRED, or PUBLISHED. Publish only once it is FINISHED. IN_PROGRESS means keep polling (do not re-create); ERROR/EXPIRED means re-create the container. Read-only. |
| instagram_publish_mediaA | Phase 2 of publishing: publish a media container that has finished processing, returning the new media id. The container must be FINISHED (see instagram_get_container_status). This is never auto-retried — a repeated publish costs quota and posts a duplicate; retry only after confirming the previous call did not already publish. |
| instagram_get_publishing_limitA | Report the account's content-publishing usage against its rolling-window quota. quota_usage is how many posts have been published in the window (a carousel counts as one); quota_total is read live from Instagram (the documented number varies, so it is never hardcoded) and remaining is derived only when the total is known. Read-only. |
| instagram_post_imageA | Publish a single feed image, or a 2–10 image carousel, in one call: create the container(s), wait for processing, then publish. Preview (the default) performs nothing. If processing exceeds the poll budget the result is status=in_progress with a resume_container_id — re-run with apply:true and resumeContainerId to finish (never create a new post, which would duplicate it). Image format, byte size, and dimensions are validated by Instagram on fetch, not here. |
| instagram_post_reelA | Publish a reel in one call: create the REELS container, wait for processing (reels can take a while), then publish. Preview performs nothing. If processing exceeds the poll budget the result is status=in_progress with a resume_container_id — re-run with apply:true and resumeContainerId to finish (never create a new post). Video duration, codec, and size are validated by Instagram on fetch, not here. |
| instagram_post_storyA | Publish a photo or video story in one call: create the STORIES container, wait for processing, then publish. Provide exactly one of imageUrl or videoUrl. Preview performs nothing. If processing exceeds the poll budget the result is status=in_progress with a resume_container_id — re-run with apply:true and resumeContainerId to finish (never create a new post). Stories expire after 24 hours. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/IvanBBaev/instagram-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server