Skip to main content
Glama
JainAditi09

instagram-mcp

by JainAditi09

instagram-mcp

An MCP server that wraps the Instagram API (Instagram Login flow): publish photos, reels, and stories (from a URL, a local file, or — via the included subagent — a local file hosted through Google Drive); read comments and performance insights; moderate comments; draft on-brand captions using MCP sampling; and schedule reels for later.

Built as a learning project after Anthropic's "Introduction to Model Context Protocol" course, to turn the course concepts into a real, working integration — not just tools, but resources, prompts, sampling, logging, progress notifications, and a Claude Code subagent on top.

For the full story — the Meta developer setup process and every problem hit along the way, plus a deeper design writeup of every MCP concept used and why — see docs/01-meta-developer-setup.md and docs/02-mcp-server-design.md.

Quick start

npm install
npm run build

Then set two environment variables (IG_USER_ID, IG_ACCESS_TOKEN) in your MCP client config — see Setup below for how to get them, and Connect it to Claude for where they go.

Related MCP server: meta-mcp

What's in this project

Path

What it is

src/instagram.ts

The actual Instagram API client — auth, GET/POST helpers, publishing flows, resumable upload. No MCP-specific code.

src/index.ts

The MCP layer — registers everything in instagram.ts as tools/resources/prompts with schemas.

.claude/agents/instagram-manager.md

A Claude Code subagent scoped to just this server (+ Google Drive), with judgment calls baked into its system prompt.

docs/01-meta-developer-setup.md

Narrative of the Meta app / token setup process, including every blocker hit and how it was resolved.

docs/02-mcp-server-design.md

Design writeup: problem statement, architecture, and an explanation of every MCP concept this project uses.

Setup

1. Account & app requirements

  • Your Instagram account must be a Business or Creator account. This project uses Instagram API with Instagram Login — the account authorizes the app directly, no Facebook Page needed.

  • Create a Meta app at https://developers.facebook.com/apps (Business type), add the Instagram product, and inside it choose "API setup with Instagram login."

  • Under App roles → Roles, add your Instagram account as an Instagram Tester, then accept the invite from inside the Instagram app itself (Settings → Apps and Websites → Tester Invites). The app can't authorize your account until this is accepted.

  • On the "API setup with Instagram login" page, step 1 lists required permissions: instagram_business_basic, instagram_business_manage_comments, instagram_business_manage_messages. Add two more via "Go to permissions and features": instagram_business_content_publish (needed for post_image/post_reel/post_story) and instagram_business_manage_insights (needed for get_media_insights).

See docs/01-meta-developer-setup.md if any of this goes sideways — it documents the specific errors this project hit (business portfolio blockers, "insufficient developer role," permission-name renames) and how each was fixed.

2. Get your credentials

On the same "API setup with Instagram login" page, under "2. Generate access tokens":

  1. Click Add account, log in as your Instagram account, and approve the permissions. This adds a row showing your account and its Instagram User ID (e.g. 17841471531885841) — that's your IG_USER_ID.

  2. Click Generate token in that row to get a token. If it's issued as long-lived (60 days) you're done. If it's short-lived, exchange it:

    GET https://graph.instagram.com/access_token
      ?grant_type=ig_exchange_token
      &client_secret={instagram-app-secret}
      &access_token={short-lived-token}

Long-lived tokens expire after 60 days — for real use you'd add a refresh job; not included here to keep this a learning-sized project.

If you add permissions after already generating a token, regenerate the token. A token only carries whatever permissions existed at the moment it was created — adding scopes afterward does nothing until you get a fresh one.

3. Configure environment variables

The server reads IG_USER_ID and IG_ACCESS_TOKEN from the environment — set these in your MCP client config (below), not in a committed .env file.

Connect it to Claude

Claude Desktop / Claude Code — add to your MCP config (claude_desktop_config.json or .mcp.json):

{
  "mcpServers": {
    "instagram": {
      "command": "node",
      "args": ["/absolute/path/to/instagram-mcp/dist/index.js"],
      "env": {
        "IG_USER_ID": "your-instagram-scoped-user-id",
        "IG_ACCESS_TOKEN": "your-long-lived-token"
      }
    }
  }
}

Restart Claude Desktop / Claude Code after saving. You should see the instagram server's tools available in a new conversation.

Note on config file locations: newer Claude Desktop builds may manage connectors through the in-app Settings UI instead of a hand-edited file, or may only expose custom-connector fields for remote (https://) servers, not local stdio ones like this. If you don't see a claude_desktop_config.json being read, look for a Developer settings section with an Edit Config button — that's the one that accepts this JSON.

Tools exposed

Tool

Description

list_media

Recent posts/reels with basic counts

get_media_insights

Reach, likes, comments, saves, (video) shares/views

get_comments

Comments on a media item

reply_to_comment

Public reply to a comment

hide_comment

Hide/unhide a comment

delete_comment

Permanently delete a comment

post_image

Publish a single photo (public URL)

post_reel

Publish a Reel from a public URL or a local file (handles the container → upload/poll → publish flow, reports progress)

post_story

Publish a 24h story (public URL)

schedule_reel

Queue a Reel to publish at a future time (see Scheduling)

list_scheduled_posts

List queued reels and their status

cancel_scheduled_post

Cancel a pending scheduled reel

suggest_caption

Uses MCP sampling to ask the connected client's model for 3 caption options, grounded in the account's recent captions

Resources exposed

URI

Description

instagram://media

The account's most recent media, as a browsable resource (not just a tool call)

instagram://media/{media_id}/comments

Comments on a specific media item, addressed by URI

instagram://scheduled

The current in-memory queue of scheduled reels

Prompts exposed

Prompt

Description

weekly_engagement_review

A ready-made prompt (optionally takes post_count) that has the model pull recent posts + insights and summarize what's working

MCP concepts this project demonstrates

Beyond basic tools, this server exercises the rest of the MCP surface:

  • Resourcesinstagram://media and instagram://media/{id}/comments let a client browse/attach Instagram data directly, the same way it would browse a file, rather than only getting data back from a tool call.

  • Promptsweekly_engagement_review is a reusable prompt template the client can surface (e.g. as a slash command) instead of the user having to type out the same multi-step instruction each time.

  • Samplingsuggest_caption calls server.server.createMessage(...), which asks the client's model (whatever Claude the person is running) to generate text, using account context this server already has. The server never calls its own separate LLM API key — it borrows the client's model via the protocol.

  • Logging & progress notifications — every mutating tool call sends structured log messages via sendLoggingMessage. post_reel additionally sends notifications/progress updates while it polls Instagram's video processing status (which can take 30s–2min), so a client that supports progress UI can show real-time status instead of a silent hang.

See docs/02-mcp-server-design.md for the full writeup of why each of these was built the way it was.

Local file uploads (post_reel with video_path)

post_reel accepts either video_url (public URL) or video_path (an absolute path to a file on this machine). For a local file, the server uploads the raw bytes directly to Meta's servers via the resumable upload flow (rupload.facebook.com) — no need to host the file publicly yourself.

One honest caveat: Meta's docs describe this resumable path as intended for apps using "Facebook Login for Business," and this project uses Instagram Login instead. In practice it works for most Instagram Login apps too, but if post_reel with video_path fails with a permission or host error, the fallback is to host the file somewhere public and use video_url instead (see the Drive-based workflow below for one way to do that without leaving the conversation).

post_image and post_story don't have a local-file option — Instagram's photo/story publishing API has no resumable-upload equivalent for images, so these two tools still require a public image_url/video_url.

Local assets for any post type: the instagram-manager subagent

For a workflow where you just hand over a local file — photo, reel, or story — and don't want to think about hosting at all, use the included Claude Code subagent instead of calling the tools directly:

.claude/agents/instagram-manager.md

This subagent has access to both mcp__instagram (this server) and a Google Drive connector, and is instructed to: upload the local file to Drive → set it to link-shareable → build a direct-download URL → call the matching Instagram tool with that URL. It also knows to fall back to post_reel's video_path if a Drive-hosted reel fails (large video files can hit Google's virus-scan interstitial, which serves an HTML warning page instead of raw bytes).

To use it: copy the file into ~/.claude/agents/ (available in every project) or your project's own .claude/agents/, then check that the mcp__google-drive name in its frontmatter matches whatever your Drive connector is actually named in your Claude Code config (claude mcp list). See docs/02-mcp-server-design.md §6–7 for the full reasoning behind this design (why it's a subagent concern and not server code).

Scheduling (schedule_reel)

Instagram's API has no native "publish later" — real scheduling of organic posts only exists inside Meta's own Business Suite UI, not the API. So schedule_reel holds the job in this server's memory and fires it with a timer at the right time.

This means scheduled posts only fire while this MCP server process stays alive — i.e. while Claude Desktop (or whatever client launched it) stays open. Quitting the app cancels anything still pending. It's fine for same-session or same-day scheduling ("post this in 2 hours"); it is not a durable schedule you can set and then close your laptop on.

For real "survive a reboot, fire while I'm asleep" scheduling, you'd want a system-level mechanism instead — a cron job or macOS launchd task that invokes a small standalone script (reusing src/instagram.ts's postReel) at the target time, independent of Claude Desktop's process lifecycle. Not implemented here, to keep this project at learning-project scope.

Notes / gotchas carried over from the Graph API itself

  • post_image/post_story still need a public URL — no local-file option for those two (see above). post_reel is the exception, via video_path.

  • Reels take time to process. post_reel polls the container's status_code until it's FINISHED before publishing (Meta recommends polling for up to ~5 minutes; most reels finish in 30s–2min).

  • Rate limit: 25 published posts per rolling 24h window, shared across photos/reels/stories.

  • Reel eligibility for the Reels tab needs 9:16 aspect ratio and 5–90s duration; longer/differently-shaped video still publishes but as a regular video post.

  • Metric names have drifted. Instagram merged impressions/plays into a single views metric — if insights calls ever start failing across every post consistently, suspect a metric-name mismatch before assuming it's a permissions issue.

Next steps to extend this

  • Real persistent scheduling via a generated cron/launchd job.

  • A create_carousel_post tool (multi-image, same container/publish pattern as post_image but with children params).

  • Native local-file support for post_image/post_story in server code (would still need some public-hosting step, since Instagram has no resumable upload for photos — possibly a short-lived local HTTP endpoint via a tunnel, as an alternative to the subagent's Drive-based approach).

  • Account-level insights (follower count, profile views) via a resource.

  • Token refresh handling instead of manual 60-day renewal.

  • An automatic retry/fallback wrapper around Drive-hosted post_reel calls, instead of relying on the subagent's prompt-level instruction to notice and react to a failure.

  • Swap the manual env vars for a proper OAuth flow if you want other people to connect their own accounts to this server.

A
license - permissive license
A
quality
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables AI assistants to manage Instagram Business accounts by automating content publishing, scheduling posts, and analyzing performance metrics. Supports posts, stories, reels, and carousels with detailed audience insights and hashtag discovery.
  • A
    license
    A
    quality
    C
    maintenance
    Enables AI assistants to manage Instagram and Threads accounts — publish content, handle comments, view insights, search hashtags, and manage DMs through the Meta Graph API.
    59
    46
    10
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables reading, publishing, commenting, direct messaging, and pulling insights from Instagram Business or Creator accounts via the Graph API.
    6
    MIT
  • A
    license
    A
    quality
    A
    maintenance
    Connects Claude Desktop and other MCP clients to the Instagram Graph API for reading analytics, managing comments, and publishing photos, carousels, and reels.
    11
    83
    MIT

View all related MCP servers

Related MCP Connectors

  • Instagram for AI agents: publish, read comments and DMs, insights, and engage from your account.

  • Social media MCP: publish, schedule & analyze posts on TikTok, Instagram, YouTube, LinkedIn & X

  • Create, schedule and publish social posts to TikTok, Instagram, Facebook and YouTube.

View all MCP Connectors

Latest Blog Posts

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/JainAditi09/personal-insta-manager'

If you have feedback or need assistance with the MCP directory API, please join our Discord server