Skip to main content
Glama
README.md
# Instagram_agent_mcp

Official-API Instagram writer for humans **and** AI agents. No API key — it reuses
[`ig-agent`](https://github.com/PixelFred0/ig-agent-cli)'s stored long-lived token.

Two entry points, one logic core:

| File | What |
|---|---|
| `ig-write` | Zero-dependency Python CLI (stdlib only). Post / reel / story / carousel / delete / like |
| `ig-mcp-server.py` | MCP stdio server wrapping `ig-write` — 11 tools for agentic mode (Claude Code, Cursor, …) |

## Prereqs

- Python 3.10+
- An Instagram **Business/Creator** account connected via `ig-agent`:
  ```bash
  npm install -g ig-agent
  ig-agent auth login     # or: ig-agent auth exchange --redirect-uri ... --code ...
  ig-agent auth status    # check granted scopes
  ```
- For MCP mode: `pip install -r requirements.txt`

## Scopes

| Action | Scope |
|---|---|
| post / reel / story / carousel | `instagram_business_content_publish` |
| like / unlike | `instagram_manage_engagement` (Apr 2026 Like API) |
| delete | `instagram_manage_contents` (Dec 2025 Delete API) |

`ig-write me` + `ig-write <cmd>` surface a clear re-auth hint when a scope is missing.
Like/delete/unlike fail **fast without an API call** when ig-agent's recorded
grant lacks the scope. **Notes has no official Meta API** and is intentionally
not included.

## Known limitations (Instagram Login path)

- `instagram_manage_engagement` (like) and `instagram_manage_contents`
  (delete) were observed **not granted** via Instagram Login OAuth (Apr/Dec 2026
  APIs) — Meta's docs place Like under the Facebook-Login app path, and Delete
  may need one too and/or app review. The tool tells you this instead of a raw
  `subcode=33`.
- Stories: no stickers/polls/links/music via API; expire after 24 h.
- Reels: original audio only; `media_type` reads back as `VIDEO`
  (`media_product_type` says `REEL`/`STORY`).
- Media must be a **public https URL** — Meta cURLs it. Local files need
  hosting first (e.g. `catbox.moe`). Story images: JPEG, 9:16 (1080×1920) best.
- No scheduling, no caption edit after publish, no Notes/Likes-bulk endpoints.

## CLI usage

```bash
./ig-write me
./ig-write post --image-url https://example.com/pic.jpg --caption "hello"
./ig-write reel --video-url https://example.com/clip.mp4 --caption "hi"
./ig-write story --image-url https://example.com/pic.jpg
./ig-write story --video-url https://example.com/clip.mp4
./ig-write carousel-item --image-url https://example.com/a.jpg   # -> container id
./ig-write carousel --children CID1,CID2 --caption "swipe"
./ig-write publish --creation-id <container_id>
./ig-write status --container-id <container_id>
./ig-write delete --media-id <media_id>
./ig-write like --media-id <id>
./ig-write unlike --comment-id <id>
```

Media must be on a **public https URL**. Flow per command:
create container → poll `status_code=FINISHED` → `media_publish`.
`--container-only` stops after step 1 (container expires in 24 h).
Limits: ~100 API publishes / rolling 24 h.

## MCP (agentic mode)

```bash
pip install -r requirements.txt
```

Client config (stdio):

```json
{
  "mcpServers": {
    "ig-write": {
      "command": "python3",
      "args": ["/path/to/Instagram_agent_mcp/ig-mcp-server.py"]
    }
  }
}
```

Tools: `ig_me, ig_post, ig_reel, ig_story, ig_carousel_item, ig_carousel,
ig_publish, ig_container_status, ig_delete, ig_like, ig_unlike`.
The token is read from your local ig-agent config — no extra login.

## Remote (Vercel) — recommended

A remote MCP server for Claude (custom connector) and ChatGPT lives in
[`vercel/`](./vercel) — Node serverless functions on Vercel Hobby (free):

- MCP over Streamable HTTP at `/mcp` (stateless), hand-rolled OAuth 2.1
  single-user login (`ADMIN_PASSWORD`) + dynamic client registration
- Same 17 tools as below (publishing + analytics + image generation);
  every write defaults to `dry_run=true`; 95/24h publish cap
- Vercel KV (token/OAuth state) + Vercel Blob (public image URLs) +
  Vercel Cron (30-day token refresh); images via free Pollinations/HF
- Minimal `/api/rest/*` + `/api/openapi.json` for Custom GPT Actions

Deploy: import the repo with Root Directory `vercel`, add KV + Blob in the
dashboard, set env vars, redeploy. Full walkthrough:
[`vercel/README_DEPLOY_VERCEL.md`](./vercel/README_DEPLOY_VERCEL.md).

## Remote (Cloudflare) — alternative

A remote MCP server for Claude (custom connector) and ChatGPT lives in
[`worker/`](./worker) — TypeScript on Cloudflare Workers (free plan):

- MCP over Streamable HTTP at `/mcp` (stateless, no Durable Objects),
  OAuth 2.1 single-user login (`ADMIN_PASSWORD`), dynamic client registration
- Ports all Python publishing tools (`container → poll FINISHED → media_publish`)
  **plus** analytics (`ig_account_insights`, `ig_list_media`, `ig_media_insights`,
  `ig_get_comments`/`ig_reply_comment`, `ig_audience_demographics`,
  `ig_best_posting_time`) and image generation (`ig_generate_image`,
  `ig_generate_and_post` via Workers AI flux-1-schnell → KV)
- Every write tool defaults to `dry_run=true` (preview; publish only when
  `dry_run=false`); 95/24h publish safety cap; KV token storage with 30-day
  cron refresh; minimal `/api/*` REST + `/openapi.json` for Custom GPT Actions
- Like/unlike/delete are intentionally **not** ported (scopes not grantable on
  the Instagram Login path)

Deploy: `cd worker && ./scripts/setup.sh`, set secrets, `wrangler deploy`.
Full walkthrough (Meta app, Claude connector, ChatGPT Actions, test prompts):
[`worker/README_DEPLOY.md`](./worker/README_DEPLOY.md).

## Layout

```
Instagram_agent_mcp/
├── ig-write           # CLI (stdlib only, executable)
├── ig-mcp-server.py   # MCP server (needs: pip install mcp)
├── test_ig_write.py   # stdlib unit tests (no network)
├── requirements.txt
├── README.md
└── LICENSE
```

## Troubleshooting

| Symptom | Fix |
|---|---|
| `stored token expired` | `ig-agent auth refresh` (or login again) |
| `authorised without "instagram_manage_…"` | Re-auth with that scope; see Known limitations |
| `container … ERROR/EXPIRED` | Media URL not fetchable or wrong spec — check public URL + format |
| `timed out waiting for container` | Large video still processing — rerun `status`, then `publish` |
| MCP `Connection closed` on start | `pip install -r requirements.txt` (needs `mcp` v1 or v2) |

## Disclaimer

Uses Meta's official Instagram Graph API only. Media URLs must be public;
respect Meta's rate limits and ToS — this is for your own accounts, not for
serving end-user generation. Tested against `graph.instagram.com v26.0`.