instamcp 2.1.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. instamcp-2.1.1/LICENSE +21 -0
  2. instamcp-2.1.1/PKG-INFO +338 -0
  3. instamcp-2.1.1/README.md +304 -0
  4. instamcp-2.1.1/instagram_mcp/__init__.py +806 -0
  5. instamcp-2.1.1/instagram_mcp/__main__.py +5 -0
  6. instamcp-2.1.1/instagram_mcp/account_pool.py +119 -0
  7. instamcp-2.1.1/instagram_mcp/agents.py +908 -0
  8. instamcp-2.1.1/instagram_mcp/batch_runner.py +833 -0
  9. instamcp-2.1.1/instagram_mcp/cache.py +262 -0
  10. instamcp-2.1.1/instagram_mcp/challenge.py +143 -0
  11. instamcp-2.1.1/instagram_mcp/client.py +6527 -0
  12. instamcp-2.1.1/instagram_mcp/config.py +326 -0
  13. instamcp-2.1.1/instagram_mcp/cookie_manager.py +371 -0
  14. instamcp-2.1.1/instagram_mcp/delay.py +99 -0
  15. instamcp-2.1.1/instagram_mcp/exceptions.py +200 -0
  16. instamcp-2.1.1/instagram_mcp/exporter.py +715 -0
  17. instamcp-2.1.1/instagram_mcp/formatter.py +3236 -0
  18. instamcp-2.1.1/instagram_mcp/media_cache.py +68 -0
  19. instamcp-2.1.1/instagram_mcp/models.py +2154 -0
  20. instamcp-2.1.1/instagram_mcp/monitor.py +276 -0
  21. instamcp-2.1.1/instagram_mcp/oauth_manager.py +277 -0
  22. instamcp-2.1.1/instagram_mcp/parser.py +1295 -0
  23. instamcp-2.1.1/instagram_mcp/proxy_manager.py +533 -0
  24. instamcp-2.1.1/instagram_mcp/rate_limiter.py +338 -0
  25. instamcp-2.1.1/instagram_mcp/scheduler.py +232 -0
  26. instamcp-2.1.1/instagram_mcp/session_manager.py +113 -0
  27. instamcp-2.1.1/instagram_mcp/tools.py +5476 -0
  28. instamcp-2.1.1/instamcp.egg-info/PKG-INFO +338 -0
  29. instamcp-2.1.1/instamcp.egg-info/SOURCES.txt +61 -0
  30. instamcp-2.1.1/instamcp.egg-info/dependency_links.txt +1 -0
  31. instamcp-2.1.1/instamcp.egg-info/entry_points.txt +2 -0
  32. instamcp-2.1.1/instamcp.egg-info/requires.txt +13 -0
  33. instamcp-2.1.1/instamcp.egg-info/top_level.txt +1 -0
  34. instamcp-2.1.1/pyproject.toml +56 -0
  35. instamcp-2.1.1/setup.cfg +4 -0
  36. instamcp-2.1.1/tests/test_account_pool.py +95 -0
  37. instamcp-2.1.1/tests/test_agents.py +188 -0
  38. instamcp-2.1.1/tests/test_analyze_comments.py +123 -0
  39. instamcp-2.1.1/tests/test_batch_runner.py +389 -0
  40. instamcp-2.1.1/tests/test_cache.py +599 -0
  41. instamcp-2.1.1/tests/test_challenge.py +63 -0
  42. instamcp-2.1.1/tests/test_client.py +1494 -0
  43. instamcp-2.1.1/tests/test_config.py +135 -0
  44. instamcp-2.1.1/tests/test_cookie_manager.py +202 -0
  45. instamcp-2.1.1/tests/test_dm_tools.py +248 -0
  46. instamcp-2.1.1/tests/test_exceptions.py +108 -0
  47. instamcp-2.1.1/tests/test_exporter.py +287 -0
  48. instamcp-2.1.1/tests/test_final_push.py +69 -0
  49. instamcp-2.1.1/tests/test_formatter.py +455 -0
  50. instamcp-2.1.1/tests/test_live_anonymous_full.py +882 -0
  51. instamcp-2.1.1/tests/test_media_cache.py +98 -0
  52. instamcp-2.1.1/tests/test_models.py +362 -0
  53. instamcp-2.1.1/tests/test_monitor.py +156 -0
  54. instamcp-2.1.1/tests/test_new_tools.py +667 -0
  55. instamcp-2.1.1/tests/test_oauth_manager.py +130 -0
  56. instamcp-2.1.1/tests/test_parser.py +1892 -0
  57. instamcp-2.1.1/tests/test_parser_extra.py +57 -0
  58. instamcp-2.1.1/tests/test_proxy_manager.py +187 -0
  59. instamcp-2.1.1/tests/test_rate_limiter.py +89 -0
  60. instamcp-2.1.1/tests/test_scheduler.py +192 -0
  61. instamcp-2.1.1/tests/test_session_manager.py +101 -0
  62. instamcp-2.1.1/tests/test_tools.py +730 -0
  63. instamcp-2.1.1/tests/test_upload.py +499 -0
instamcp-2.1.1/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 mpython77
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,338 @@
1
+ Metadata-Version: 2.4
2
+ Name: instamcp
3
+ Version: 2.1.1
4
+ Summary: Production-grade MCP server for Instagram — 79 tools: scraping, DMs, scheduling, uploads, social actions, sentiment analysis, multi-account pool
5
+ Author-email: mpython77 <notnightmarelabs1@gmail.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/mpython77/instagram-mcp
8
+ Project-URL: Repository, https://github.com/mpython77/instagram-mcp
9
+ Project-URL: Issues, https://github.com/mpython77/instagram-mcp/issues
10
+ Keywords: instagram,mcp,model-context-protocol,claude,scraping,social-media,instagram-api,anthropic
11
+ Classifier: Development Status :: 5 - Production/Stable
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Topic :: Internet :: WWW/HTTP :: Indexing/Search
19
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
20
+ Requires-Python: >=3.10
21
+ Description-Content-Type: text/markdown
22
+ License-File: LICENSE
23
+ Requires-Dist: mcp[cli]>=1.0.0
24
+ Requires-Dist: curl-cffi>=0.7.0
25
+ Requires-Dist: pydantic>=2.0.0
26
+ Requires-Dist: aiofiles>=23.0
27
+ Requires-Dist: Pillow>=10.0.0
28
+ Requires-Dist: uvloop>=0.20; sys_platform != "win32"
29
+ Provides-Extra: dev
30
+ Requires-Dist: pytest>=8.0; extra == "dev"
31
+ Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
32
+ Requires-Dist: pytest-mock>=3.12; extra == "dev"
33
+ Dynamic: license-file
34
+
35
+ # instagram-mcp
36
+
37
+ ![Python 3.10+](https://img.shields.io/badge/python-3.10%2B-blue) ![MCP](https://img.shields.io/badge/MCP-compatible-green) ![License: MIT](https://img.shields.io/badge/license-MIT-lightgrey) [![CI](https://github.com/mpython77/instagram-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/mpython77/instagram-mcp/actions/workflows/ci.yml) [![Docker](https://img.shields.io/badge/docker-ghcr.io-blue)](https://github.com/mpython77/instagram-mcp/pkgs/container/instagram-mcp)
38
+
39
+ Production-grade MCP server for Instagram. **79 tools** — 30 anonymous (no credentials), 48 authenticated, 1 auto-mode. Built on `curl_cffi` with Chrome TLS impersonation, adaptive rate limiting, smart caching, multi-account pool, and challenge/2FA resolver.
40
+
41
+ Works with **Claude Desktop**, **Claude Code**, and any MCP-compatible AI client.
42
+
43
+ ---
44
+
45
+ ## Auth Tiers
46
+
47
+ | Tier | Symbol | Requirement | Tools |
48
+ |------|--------|-------------|-------|
49
+ | Anonymous | 🌐 | None | 28 |
50
+ | Authenticated | 🔐 | `cookies.json` with valid Instagram session | 48 |
51
+ | Auto-mode | 🌐/🔐 | Anon by default, upgrades when cookies present | 1 |
52
+
53
+ ---
54
+
55
+ ## Installation
56
+
57
+ ```bash
58
+ git clone https://github.com/mpython77/instagram-mcp.git
59
+ cd instagram-mcp
60
+ pip install -e .
61
+ instagram-mcp
62
+ ```
63
+
64
+ With `uv`:
65
+
66
+ ```bash
67
+ uv sync && uv run --quiet instagram-mcp
68
+ ```
69
+
70
+ ### Cookie Setup
71
+
72
+ 1. Log in to Instagram in your browser.
73
+ 2. Install [Cookie-Editor](https://cookie-editor.com/) and navigate to `instagram.com`.
74
+ 3. Export cookies as **JSON**.
75
+ 4. Save as `cookies.json` in the project root, or set `INSTAGRAM_MCP_COOKIES=/path/to/file`.
76
+
77
+ > Use a dedicated account — not your personal account. Sessions expire; refresh `cookies.json` if you get 401 errors.
78
+
79
+ ---
80
+
81
+ ## MCP Config
82
+
83
+ ### Claude Desktop
84
+
85
+ **macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`
86
+ **Windows:** `%APPDATA%\Claude\claude_desktop_config.json`
87
+
88
+ ```json
89
+ {
90
+ "mcpServers": {
91
+ "instagram": {
92
+ "command": "instagram-mcp",
93
+ "env": {
94
+ "INSTAGRAM_MCP_COOKIES": "/absolute/path/to/cookies.json"
95
+ }
96
+ }
97
+ }
98
+ }
99
+ ```
100
+
101
+ With `uv`:
102
+
103
+ ```json
104
+ {
105
+ "mcpServers": {
106
+ "instagram": {
107
+ "command": "uv",
108
+ "args": ["run", "--project", "/path/to/instagram-mcp", "instagram-mcp"],
109
+ "env": {
110
+ "INSTAGRAM_MCP_COOKIES": "/absolute/path/to/cookies.json"
111
+ }
112
+ }
113
+ }
114
+ }
115
+ ```
116
+
117
+ ### Claude Code
118
+
119
+ ```bash
120
+ claude mcp add instagram instagram-mcp --env INSTAGRAM_MCP_COOKIES=/path/to/cookies.json
121
+ ```
122
+
123
+ ---
124
+
125
+ ## Docker
126
+
127
+ ```bash
128
+ docker run -d \
129
+ -e INSTAGRAM_MCP_COOKIES=/data/cookies.json \
130
+ -v /path/to/cookies.json:/data/cookies.json:ro \
131
+ -p 8000:8000 \
132
+ ghcr.io/mpython77/instagram-mcp:latest
133
+ ```
134
+
135
+ ---
136
+
137
+ ## Environment Variables
138
+
139
+ | Variable | Default | Description |
140
+ |----------|---------|-------------|
141
+ | `INSTAGRAM_MCP_COOKIES` | `""` | Path to `cookies.json` or `cookies.txt` |
142
+ | `INSTAGRAM_MCP_PROXIES` | `""` | Comma-separated proxy URLs (or use `proxies.txt`, one per line) |
143
+ | `INSTAGRAM_MCP_IMPERSONATE` | `chrome142` | curl_cffi impersonation profile |
144
+ | `INSTAGRAM_MCP_TIMEOUT` | `10` | Per-request timeout in seconds |
145
+ | `INSTAGRAM_MCP_EXPORT_DIR` | `./exports` | Auto-export directory for JSON results |
146
+ | `INSTAGRAM_MCP_TOOLSETS` | `all` | Comma-separated toolsets to enable: `profile`, `analysis`, `content`, `social_graph`, `batch`, `server` |
147
+ | `INSTAGRAM_MCP_HIDE_AUTH_WHEN_NO_COOKIES` | `""` | Set `1` to hide auth-only tools when no cookies are loaded |
148
+ | `INSTAGRAM_MCP_CACHE_DISABLED` | `""` | Set `1` to disable all caching |
149
+
150
+ ---
151
+
152
+ ## Tools
153
+
154
+ ### 🌐 Profile & Feed
155
+
156
+ | Tool | Description |
157
+ |------|-------------|
158
+ | `instagram_profile` | Profile metadata, feed tags (up to 12 posts), activity status |
159
+ | `instagram_feed_deep` | Paginated feed — up to 200 posts with date filtering |
160
+ | `instagram_bulk_check` | Check up to 20 accounts in parallel with activity status |
161
+ | `instagram_compare_profiles` | Side-by-side comparison of 2–5 accounts |
162
+
163
+ ### 🌐 Analysis
164
+
165
+ | Tool | Description |
166
+ |------|-------------|
167
+ | `instagram_analyze_engagement` | ER%, content mix, best posting days, top hashtags across up to 200 posts |
168
+ | `instagram_find_collab_network` | Map usertags, @mentions, co-authors, and paid sponsors across posts |
169
+ | `instagram_account_report` | Full profile + engagement + collab network in one call |
170
+ | `instagram_caption_analyze` | Caption patterns: avg length, hashtag density, emoji/CTA rates |
171
+ | `instagram_compare_followers` | Compare follower/following sets — find unfollowers or non-mutuals |
172
+ | `instagram_analyze_comments` | Sentiment analysis on comments — pos/neu/neg, emoji stats, keywords (EN/UZ/RU) |
173
+
174
+ ### 🌐 Content
175
+
176
+ | Tool | Description |
177
+ |------|-------------|
178
+ | `instagram_post` | Full post details: location (GPS + Maps), music, usertags, coauthors |
179
+ | `instagram_post_bulk` | Fetch up to 50 posts in parallel by shortcode or URL |
180
+ | `instagram_post_comments` | Fetch comments with likes and thread structure (up to 500) |
181
+
182
+ ### 🌐/🔐 Hashtag & Discovery
183
+
184
+ | Tool | Description |
185
+ |------|-------------|
186
+ | `instagram_hashtag` | Top posts for a hashtag — anon: 12 posts; auth: up to 300. Auto-upgrades. |
187
+ | `instagram_hashtag_deep` | Top accounts, content breakdown, best posting hour across up to 500 posts |
188
+ | `instagram_niche_top` | Account leaderboard for a hashtag ranked by engagement/post count/total likes |
189
+ | `instagram_hashtag_suggest` | Related hashtag suggestions by analyzing top posts under a seed tag |
190
+
191
+ ### 🌐 Threads
192
+
193
+ | Tool | Description |
194
+ |------|-------------|
195
+ | `instagram_threads_profile` | Profile metadata from Threads (threads.net) |
196
+ | `instagram_threads_posts` | Recent posts for a Threads user |
197
+
198
+ ### 🔐 Authenticated Feed & Activity
199
+
200
+ | Tool | Description |
201
+ |------|-------------|
202
+ | `instagram_home_feed` | Your authenticated home feed |
203
+ | `instagram_saved_posts` | Your bookmarked posts |
204
+ | `instagram_liked_posts` | Posts you have liked |
205
+ | `instagram_activity_feed` | Your recent activity notifications |
206
+ | `instagram_post_likers` | Users who liked a specific post (up to ~98) |
207
+
208
+ ### 🔐 Discovery
209
+
210
+ | Tool | Description |
211
+ |------|-------------|
212
+ | `instagram_similar_accounts` | Accounts Instagram considers similar (internal chaining API) |
213
+ | `instagram_search` | Search users + hashtags by keyword |
214
+ | `instagram_user_search` | User search with higher-quality ranking (authenticated API) |
215
+ | `instagram_user_id_lookup` | Look up a user's numeric ID by username |
216
+
217
+ ### 🔐 Social Graph
218
+
219
+ | Tool | Description |
220
+ |------|-------------|
221
+ | `instagram_followers_list` | Recent followers with mutual follow status |
222
+ | `instagram_following_list` | Full following list with close-friends detection |
223
+ | `instagram_user_followers` | Paginated followers for any user by numeric user_id |
224
+ | `instagram_user_following` | Paginated following for any user by numeric user_id |
225
+ | `instagram_tagged_by` | Posts by other accounts that tag this account |
226
+ | `instagram_reposts` | Content this account actively reposted |
227
+
228
+ ### 🔐 Media
229
+
230
+ | Tool | Description |
231
+ |------|-------------|
232
+ | `instagram_reels` | Account's reels with play counts (only tool that exposes `play_count`) |
233
+ | `instagram_stories` | Currently active stories (cached 2 min) |
234
+ | `instagram_highlights` | Highlights tray + optional story items inside |
235
+ | `instagram_audio_reels` | Reels using a specific audio track by `audio_cluster_id` |
236
+ | `instagram_location_posts` | Top posts at a location by Instagram location ID or name |
237
+ | `instagram_media_insights` | Impressions, reach, saves for your own posts (Business/Creator only) |
238
+
239
+ ### 🔐 Interactions
240
+
241
+ | Tool | Description |
242
+ |------|-------------|
243
+ | `instagram_post_like` | Like or unlike a post |
244
+ | `instagram_post_save` | Save or unsave (bookmark) a post |
245
+ | `instagram_post_comment` | Post a comment |
246
+ | `instagram_comment_reply` | Reply to a comment |
247
+ | `instagram_comment_like` | Like or unlike a comment |
248
+ | `instagram_comment_hide` | Hide a comment on your own post |
249
+ | `instagram_delete_comment` | Delete a comment |
250
+ | `instagram_toggle_comments` | Disable or enable comments on your post |
251
+ | `instagram_post_delete` | Delete one of your own posts |
252
+ | `instagram_follow_user` | Follow or unfollow a user |
253
+ | `instagram_block_user` | Block or unblock a user |
254
+ | `instagram_account_privacy` | Switch account between public and private |
255
+ | `instagram_edit_profile` | Edit bio, display name, website, email, or phone |
256
+ | `instagram_publish_story` | Publish a photo as a Story (24h) |
257
+ | `instagram_story_mark_seen` | Mark stories as viewed |
258
+ | `instagram_story_reply` | Reply to a story via DM |
259
+
260
+ ### 🔐 DM
261
+
262
+ | Tool | Description |
263
+ |------|-------------|
264
+ | `instagram_dm_inbox` | Read DM inbox (threads list) |
265
+ | `instagram_dm_thread` | Fetch messages in a specific thread |
266
+ | `instagram_dm_send` | Send a text message |
267
+ | `instagram_dm_send_photo` | Send a photo |
268
+ | `instagram_dm_send_video` | Send a video |
269
+ | `instagram_dm_media_messages` | Fetch media messages in a thread |
270
+ | `instagram_dm_react` | Add or remove an emoji reaction on a message |
271
+ | `instagram_dm_unsend` | Delete a sent message |
272
+ | `instagram_dm_mute` | Mute or unmute a thread |
273
+ | `instagram_dm_share_post` | Share a post to a DM thread |
274
+ | `instagram_dm_mark_seen` | Mark a thread as seen |
275
+
276
+ ### 🔐 Upload & Download
277
+
278
+ | Tool | Description |
279
+ |------|-------------|
280
+ | `instagram_upload_photo` | Upload 1–10 images as a post or carousel |
281
+ | `instagram_upload_reel` | Upload an MP4 as a Reel |
282
+ | `instagram_upload_video` | Upload an MP4 as a regular video post |
283
+ | `instagram_download` | Download all media from a post (single/video/carousel) to local disk |
284
+
285
+ ### 🔐 Broadcast & Automation
286
+
287
+ | Tool | Description |
288
+ |------|-------------|
289
+ | `instagram_broadcast_channel` | Read a creator's Broadcast Channel (info or messages) |
290
+ | `instagram_schedule` | Schedule posts for future publishing (`add`/`list`/`cancel`/`status`) |
291
+ | `instagram_monitor` | Poll accounts for new posts; fire webhooks on new post |
292
+ | `instagram_sessions` | Manage multiple accounts via `INSTAGRAM_MCP_COOKIES_<ALIAS>` env vars |
293
+ | `instagram_oauth` | Full Graph API OAuth 2.0 flow (`init_flow`/`exchange_code`/`refresh_token`/`status`) |
294
+
295
+ ### 🌐 Batch & Server
296
+
297
+ | Tool | Description |
298
+ |------|-------------|
299
+ | `instagram_batch_scrape` | Scrape up to 2000 profiles; `profile_only=True` gives 30–60× speedup |
300
+ | `instagram_server` | Diagnostics and cache management (`status`/`clear_cache`/`clear_user`/`reload_cookies`) |
301
+ | `instagram_submit_verification_code` | Submit SMS/Email/2FA code to resolve a pending checkpoint and restore the session |
302
+
303
+ ---
304
+
305
+ ## Limitations
306
+
307
+ - **Private accounts:** Feed, posts, stories, and highlights are not accessible without following the account.
308
+ - **Follower pagination:** Restricted to ~50 for other accounts; unlimited only for your own account.
309
+ - **Play counts:** Only `instagram_reels` exposes `play_count` — the standard feed API omits it.
310
+ - **Session expiry:** Cookies expire. Use `instagram_server action=reload_cookies` to refresh without restarting.
311
+ - **Write operations:** Like, comment, follow, upload, DM actions — rate limits apply. Avoid rapid consecutive writes.
312
+ - **Anonymous hashtag blocks:** Some hashtags (#swimwear, #fitness, etc.) block anonymous HTML scraping.
313
+ - **Account restrictions:** Comment, reply, and follow may return "something went wrong" on new or restricted accounts — this is Instagram-side, not a bug.
314
+
315
+ ---
316
+
317
+ ## FAQ
318
+
319
+ **Do I need to log in?**
320
+ No. 28 tools work anonymously with no credentials. 48 tools require `cookies.json`. `instagram_hashtag` auto-switches based on whether cookies are present.
321
+
322
+ **Why `curl_cffi` instead of `requests`?**
323
+ Instagram blocks `requests` and `aiohttp` at the TLS handshake level by JA3/JA4 fingerprint. `curl_cffi` impersonates Chrome's TLS stack, bypassing this check.
324
+
325
+ **How do I get play counts for reels?**
326
+ Use `instagram_reels`. The standard feed API (`instagram_feed_deep`) does not include `play_count`.
327
+
328
+ **What happens on rate limiting?**
329
+ The adaptive rate limiter detects 429s, backs off (×0.7 RPS), rotates proxy, and retries. After 5 consecutive 429s the circuit breaker opens for 60s.
330
+
331
+ **How do I use multiple Instagram accounts?**
332
+ Set `INSTAGRAM_MCP_COOKIES_<ALIAS>` env vars (e.g., `INSTAGRAM_MCP_COOKIES_BRAND=cookies_brand.json`). Use `instagram_sessions action=list` to see available sessions.
333
+
334
+ **Are `exports/` files safe to commit?**
335
+ No — they may contain PII. Add `exports/` to `.gitignore`.
336
+
337
+ **How do I refresh cookies without restarting?**
338
+ `instagram_server action=reload_cookies`
@@ -0,0 +1,304 @@
1
+ # instagram-mcp
2
+
3
+ ![Python 3.10+](https://img.shields.io/badge/python-3.10%2B-blue) ![MCP](https://img.shields.io/badge/MCP-compatible-green) ![License: MIT](https://img.shields.io/badge/license-MIT-lightgrey) [![CI](https://github.com/mpython77/instagram-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/mpython77/instagram-mcp/actions/workflows/ci.yml) [![Docker](https://img.shields.io/badge/docker-ghcr.io-blue)](https://github.com/mpython77/instagram-mcp/pkgs/container/instagram-mcp)
4
+
5
+ Production-grade MCP server for Instagram. **79 tools** — 30 anonymous (no credentials), 48 authenticated, 1 auto-mode. Built on `curl_cffi` with Chrome TLS impersonation, adaptive rate limiting, smart caching, multi-account pool, and challenge/2FA resolver.
6
+
7
+ Works with **Claude Desktop**, **Claude Code**, and any MCP-compatible AI client.
8
+
9
+ ---
10
+
11
+ ## Auth Tiers
12
+
13
+ | Tier | Symbol | Requirement | Tools |
14
+ |------|--------|-------------|-------|
15
+ | Anonymous | 🌐 | None | 28 |
16
+ | Authenticated | 🔐 | `cookies.json` with valid Instagram session | 48 |
17
+ | Auto-mode | 🌐/🔐 | Anon by default, upgrades when cookies present | 1 |
18
+
19
+ ---
20
+
21
+ ## Installation
22
+
23
+ ```bash
24
+ git clone https://github.com/mpython77/instagram-mcp.git
25
+ cd instagram-mcp
26
+ pip install -e .
27
+ instagram-mcp
28
+ ```
29
+
30
+ With `uv`:
31
+
32
+ ```bash
33
+ uv sync && uv run --quiet instagram-mcp
34
+ ```
35
+
36
+ ### Cookie Setup
37
+
38
+ 1. Log in to Instagram in your browser.
39
+ 2. Install [Cookie-Editor](https://cookie-editor.com/) and navigate to `instagram.com`.
40
+ 3. Export cookies as **JSON**.
41
+ 4. Save as `cookies.json` in the project root, or set `INSTAGRAM_MCP_COOKIES=/path/to/file`.
42
+
43
+ > Use a dedicated account — not your personal account. Sessions expire; refresh `cookies.json` if you get 401 errors.
44
+
45
+ ---
46
+
47
+ ## MCP Config
48
+
49
+ ### Claude Desktop
50
+
51
+ **macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`
52
+ **Windows:** `%APPDATA%\Claude\claude_desktop_config.json`
53
+
54
+ ```json
55
+ {
56
+ "mcpServers": {
57
+ "instagram": {
58
+ "command": "instagram-mcp",
59
+ "env": {
60
+ "INSTAGRAM_MCP_COOKIES": "/absolute/path/to/cookies.json"
61
+ }
62
+ }
63
+ }
64
+ }
65
+ ```
66
+
67
+ With `uv`:
68
+
69
+ ```json
70
+ {
71
+ "mcpServers": {
72
+ "instagram": {
73
+ "command": "uv",
74
+ "args": ["run", "--project", "/path/to/instagram-mcp", "instagram-mcp"],
75
+ "env": {
76
+ "INSTAGRAM_MCP_COOKIES": "/absolute/path/to/cookies.json"
77
+ }
78
+ }
79
+ }
80
+ }
81
+ ```
82
+
83
+ ### Claude Code
84
+
85
+ ```bash
86
+ claude mcp add instagram instagram-mcp --env INSTAGRAM_MCP_COOKIES=/path/to/cookies.json
87
+ ```
88
+
89
+ ---
90
+
91
+ ## Docker
92
+
93
+ ```bash
94
+ docker run -d \
95
+ -e INSTAGRAM_MCP_COOKIES=/data/cookies.json \
96
+ -v /path/to/cookies.json:/data/cookies.json:ro \
97
+ -p 8000:8000 \
98
+ ghcr.io/mpython77/instagram-mcp:latest
99
+ ```
100
+
101
+ ---
102
+
103
+ ## Environment Variables
104
+
105
+ | Variable | Default | Description |
106
+ |----------|---------|-------------|
107
+ | `INSTAGRAM_MCP_COOKIES` | `""` | Path to `cookies.json` or `cookies.txt` |
108
+ | `INSTAGRAM_MCP_PROXIES` | `""` | Comma-separated proxy URLs (or use `proxies.txt`, one per line) |
109
+ | `INSTAGRAM_MCP_IMPERSONATE` | `chrome142` | curl_cffi impersonation profile |
110
+ | `INSTAGRAM_MCP_TIMEOUT` | `10` | Per-request timeout in seconds |
111
+ | `INSTAGRAM_MCP_EXPORT_DIR` | `./exports` | Auto-export directory for JSON results |
112
+ | `INSTAGRAM_MCP_TOOLSETS` | `all` | Comma-separated toolsets to enable: `profile`, `analysis`, `content`, `social_graph`, `batch`, `server` |
113
+ | `INSTAGRAM_MCP_HIDE_AUTH_WHEN_NO_COOKIES` | `""` | Set `1` to hide auth-only tools when no cookies are loaded |
114
+ | `INSTAGRAM_MCP_CACHE_DISABLED` | `""` | Set `1` to disable all caching |
115
+
116
+ ---
117
+
118
+ ## Tools
119
+
120
+ ### 🌐 Profile & Feed
121
+
122
+ | Tool | Description |
123
+ |------|-------------|
124
+ | `instagram_profile` | Profile metadata, feed tags (up to 12 posts), activity status |
125
+ | `instagram_feed_deep` | Paginated feed — up to 200 posts with date filtering |
126
+ | `instagram_bulk_check` | Check up to 20 accounts in parallel with activity status |
127
+ | `instagram_compare_profiles` | Side-by-side comparison of 2–5 accounts |
128
+
129
+ ### 🌐 Analysis
130
+
131
+ | Tool | Description |
132
+ |------|-------------|
133
+ | `instagram_analyze_engagement` | ER%, content mix, best posting days, top hashtags across up to 200 posts |
134
+ | `instagram_find_collab_network` | Map usertags, @mentions, co-authors, and paid sponsors across posts |
135
+ | `instagram_account_report` | Full profile + engagement + collab network in one call |
136
+ | `instagram_caption_analyze` | Caption patterns: avg length, hashtag density, emoji/CTA rates |
137
+ | `instagram_compare_followers` | Compare follower/following sets — find unfollowers or non-mutuals |
138
+ | `instagram_analyze_comments` | Sentiment analysis on comments — pos/neu/neg, emoji stats, keywords (EN/UZ/RU) |
139
+
140
+ ### 🌐 Content
141
+
142
+ | Tool | Description |
143
+ |------|-------------|
144
+ | `instagram_post` | Full post details: location (GPS + Maps), music, usertags, coauthors |
145
+ | `instagram_post_bulk` | Fetch up to 50 posts in parallel by shortcode or URL |
146
+ | `instagram_post_comments` | Fetch comments with likes and thread structure (up to 500) |
147
+
148
+ ### 🌐/🔐 Hashtag & Discovery
149
+
150
+ | Tool | Description |
151
+ |------|-------------|
152
+ | `instagram_hashtag` | Top posts for a hashtag — anon: 12 posts; auth: up to 300. Auto-upgrades. |
153
+ | `instagram_hashtag_deep` | Top accounts, content breakdown, best posting hour across up to 500 posts |
154
+ | `instagram_niche_top` | Account leaderboard for a hashtag ranked by engagement/post count/total likes |
155
+ | `instagram_hashtag_suggest` | Related hashtag suggestions by analyzing top posts under a seed tag |
156
+
157
+ ### 🌐 Threads
158
+
159
+ | Tool | Description |
160
+ |------|-------------|
161
+ | `instagram_threads_profile` | Profile metadata from Threads (threads.net) |
162
+ | `instagram_threads_posts` | Recent posts for a Threads user |
163
+
164
+ ### 🔐 Authenticated Feed & Activity
165
+
166
+ | Tool | Description |
167
+ |------|-------------|
168
+ | `instagram_home_feed` | Your authenticated home feed |
169
+ | `instagram_saved_posts` | Your bookmarked posts |
170
+ | `instagram_liked_posts` | Posts you have liked |
171
+ | `instagram_activity_feed` | Your recent activity notifications |
172
+ | `instagram_post_likers` | Users who liked a specific post (up to ~98) |
173
+
174
+ ### 🔐 Discovery
175
+
176
+ | Tool | Description |
177
+ |------|-------------|
178
+ | `instagram_similar_accounts` | Accounts Instagram considers similar (internal chaining API) |
179
+ | `instagram_search` | Search users + hashtags by keyword |
180
+ | `instagram_user_search` | User search with higher-quality ranking (authenticated API) |
181
+ | `instagram_user_id_lookup` | Look up a user's numeric ID by username |
182
+
183
+ ### 🔐 Social Graph
184
+
185
+ | Tool | Description |
186
+ |------|-------------|
187
+ | `instagram_followers_list` | Recent followers with mutual follow status |
188
+ | `instagram_following_list` | Full following list with close-friends detection |
189
+ | `instagram_user_followers` | Paginated followers for any user by numeric user_id |
190
+ | `instagram_user_following` | Paginated following for any user by numeric user_id |
191
+ | `instagram_tagged_by` | Posts by other accounts that tag this account |
192
+ | `instagram_reposts` | Content this account actively reposted |
193
+
194
+ ### 🔐 Media
195
+
196
+ | Tool | Description |
197
+ |------|-------------|
198
+ | `instagram_reels` | Account's reels with play counts (only tool that exposes `play_count`) |
199
+ | `instagram_stories` | Currently active stories (cached 2 min) |
200
+ | `instagram_highlights` | Highlights tray + optional story items inside |
201
+ | `instagram_audio_reels` | Reels using a specific audio track by `audio_cluster_id` |
202
+ | `instagram_location_posts` | Top posts at a location by Instagram location ID or name |
203
+ | `instagram_media_insights` | Impressions, reach, saves for your own posts (Business/Creator only) |
204
+
205
+ ### 🔐 Interactions
206
+
207
+ | Tool | Description |
208
+ |------|-------------|
209
+ | `instagram_post_like` | Like or unlike a post |
210
+ | `instagram_post_save` | Save or unsave (bookmark) a post |
211
+ | `instagram_post_comment` | Post a comment |
212
+ | `instagram_comment_reply` | Reply to a comment |
213
+ | `instagram_comment_like` | Like or unlike a comment |
214
+ | `instagram_comment_hide` | Hide a comment on your own post |
215
+ | `instagram_delete_comment` | Delete a comment |
216
+ | `instagram_toggle_comments` | Disable or enable comments on your post |
217
+ | `instagram_post_delete` | Delete one of your own posts |
218
+ | `instagram_follow_user` | Follow or unfollow a user |
219
+ | `instagram_block_user` | Block or unblock a user |
220
+ | `instagram_account_privacy` | Switch account between public and private |
221
+ | `instagram_edit_profile` | Edit bio, display name, website, email, or phone |
222
+ | `instagram_publish_story` | Publish a photo as a Story (24h) |
223
+ | `instagram_story_mark_seen` | Mark stories as viewed |
224
+ | `instagram_story_reply` | Reply to a story via DM |
225
+
226
+ ### 🔐 DM
227
+
228
+ | Tool | Description |
229
+ |------|-------------|
230
+ | `instagram_dm_inbox` | Read DM inbox (threads list) |
231
+ | `instagram_dm_thread` | Fetch messages in a specific thread |
232
+ | `instagram_dm_send` | Send a text message |
233
+ | `instagram_dm_send_photo` | Send a photo |
234
+ | `instagram_dm_send_video` | Send a video |
235
+ | `instagram_dm_media_messages` | Fetch media messages in a thread |
236
+ | `instagram_dm_react` | Add or remove an emoji reaction on a message |
237
+ | `instagram_dm_unsend` | Delete a sent message |
238
+ | `instagram_dm_mute` | Mute or unmute a thread |
239
+ | `instagram_dm_share_post` | Share a post to a DM thread |
240
+ | `instagram_dm_mark_seen` | Mark a thread as seen |
241
+
242
+ ### 🔐 Upload & Download
243
+
244
+ | Tool | Description |
245
+ |------|-------------|
246
+ | `instagram_upload_photo` | Upload 1–10 images as a post or carousel |
247
+ | `instagram_upload_reel` | Upload an MP4 as a Reel |
248
+ | `instagram_upload_video` | Upload an MP4 as a regular video post |
249
+ | `instagram_download` | Download all media from a post (single/video/carousel) to local disk |
250
+
251
+ ### 🔐 Broadcast & Automation
252
+
253
+ | Tool | Description |
254
+ |------|-------------|
255
+ | `instagram_broadcast_channel` | Read a creator's Broadcast Channel (info or messages) |
256
+ | `instagram_schedule` | Schedule posts for future publishing (`add`/`list`/`cancel`/`status`) |
257
+ | `instagram_monitor` | Poll accounts for new posts; fire webhooks on new post |
258
+ | `instagram_sessions` | Manage multiple accounts via `INSTAGRAM_MCP_COOKIES_<ALIAS>` env vars |
259
+ | `instagram_oauth` | Full Graph API OAuth 2.0 flow (`init_flow`/`exchange_code`/`refresh_token`/`status`) |
260
+
261
+ ### 🌐 Batch & Server
262
+
263
+ | Tool | Description |
264
+ |------|-------------|
265
+ | `instagram_batch_scrape` | Scrape up to 2000 profiles; `profile_only=True` gives 30–60× speedup |
266
+ | `instagram_server` | Diagnostics and cache management (`status`/`clear_cache`/`clear_user`/`reload_cookies`) |
267
+ | `instagram_submit_verification_code` | Submit SMS/Email/2FA code to resolve a pending checkpoint and restore the session |
268
+
269
+ ---
270
+
271
+ ## Limitations
272
+
273
+ - **Private accounts:** Feed, posts, stories, and highlights are not accessible without following the account.
274
+ - **Follower pagination:** Restricted to ~50 for other accounts; unlimited only for your own account.
275
+ - **Play counts:** Only `instagram_reels` exposes `play_count` — the standard feed API omits it.
276
+ - **Session expiry:** Cookies expire. Use `instagram_server action=reload_cookies` to refresh without restarting.
277
+ - **Write operations:** Like, comment, follow, upload, DM actions — rate limits apply. Avoid rapid consecutive writes.
278
+ - **Anonymous hashtag blocks:** Some hashtags (#swimwear, #fitness, etc.) block anonymous HTML scraping.
279
+ - **Account restrictions:** Comment, reply, and follow may return "something went wrong" on new or restricted accounts — this is Instagram-side, not a bug.
280
+
281
+ ---
282
+
283
+ ## FAQ
284
+
285
+ **Do I need to log in?**
286
+ No. 28 tools work anonymously with no credentials. 48 tools require `cookies.json`. `instagram_hashtag` auto-switches based on whether cookies are present.
287
+
288
+ **Why `curl_cffi` instead of `requests`?**
289
+ Instagram blocks `requests` and `aiohttp` at the TLS handshake level by JA3/JA4 fingerprint. `curl_cffi` impersonates Chrome's TLS stack, bypassing this check.
290
+
291
+ **How do I get play counts for reels?**
292
+ Use `instagram_reels`. The standard feed API (`instagram_feed_deep`) does not include `play_count`.
293
+
294
+ **What happens on rate limiting?**
295
+ The adaptive rate limiter detects 429s, backs off (×0.7 RPS), rotates proxy, and retries. After 5 consecutive 429s the circuit breaker opens for 60s.
296
+
297
+ **How do I use multiple Instagram accounts?**
298
+ Set `INSTAGRAM_MCP_COOKIES_<ALIAS>` env vars (e.g., `INSTAGRAM_MCP_COOKIES_BRAND=cookies_brand.json`). Use `instagram_sessions action=list` to see available sessions.
299
+
300
+ **Are `exports/` files safe to commit?**
301
+ No — they may contain PII. Add `exports/` to `.gitignore`.
302
+
303
+ **How do I refresh cookies without restarting?**
304
+ `instagram_server action=reload_cookies`