Instagram Profile MCP Server
Pricing
Pay per event + usage
Instagram Profile MCP Server
MCP server exposing Instagram profile data as 5 agent tools — followers/following, specific list, network expansion, keyword & location discovery. Connect Claude Desktop, Cursor, ChatGPT to /mcp. Pay-per-profile pricing — $0.01 per analyzed profile. Same data + pricing as the parent scraper.
Pricing
Pay per event + usage
Rating
0.0
(0)
Developer
Andrey Afanasenko
Actor stats
0
Bookmarked
1
Total users
0
Monthly active users
a day ago
Last modified
Categories
Share
Connect Claude Desktop, Cursor, or ChatGPT to live Instagram profile data via 5 narrow tools — followers/following extraction, specific-list enrichment, network expansion, keyword/hashtag discovery, and location discovery. $0.01 per profile, $0.10 per followers/following list.
Same data and pricing as the parent Instagram Profile Scraper — but exposed as Model Context Protocol tools so your AI agent picks the right one by intent. Beyond what Instagram's official Graph API offers (which only returns your own business accounts): full bio, contacts, engagement rate, business category, language, Reels analytics, and 38 enrichment columns per row.
What it does
Given an Instagram handle (or list of handles, seed accounts, keywords, or location), returns enriched profile records — bio, contacts, engagement metrics, post captions, language detection, and Reels analytics — same 38-column shape as the parent scraper. Each tool is one Apify run; results land in the run's default dataset.
Output sample (one row, 38 columns)
{"Account": "https://instagram.com/cristiano","Source": "Direct Input","Full Name": "Cristiano Ronaldo","Followers Count": 615000000,"Following Count": 568,"Biography": "SIUUUbscribe to my YT channel","Email": "press@example.com","Email Source": "contact_button","Phone": "+1 555 123 4567","External URL": "https://www.cristianoronaldo.com","Category": "Athlete","Profile Picture": "https://instagram.fagx1-1.fna.fbcdn.net/...","Address": "N/A","Reels Count": 142,"Last Reel (Days Ago)": 7,"Median Views": 4200000,"Avg Likes": 1420000,"Avg Comments": 8400,"Views/Followers Ratio": "0.68%","Posts per Month": 8.4,"Total Posts": 3654,"Detected Language": "English","Last Post Within (Days)": 3,"Median ER": "1.42%","Quality": "Good"}
⚡ Quick start
- Connect from your AI client (Standby
/mcp) — see "Connect from Claude Desktop / Cursor / ChatGPT" below. The actor stays warm and answers in sub-second after the first call. - Or click Run in the Apify Console — pick
Mode 2: Analyze a Specific List of Accounts, leave the demo input (openai, claudeai), and click Start. Output capped at 10 profiles for ~$0.10 trial cost. - Or POST programmatically to
apify.com/acts/.../runswith{"operationMode": "analyzeSpecificAccounts", "specificUsernamesList": ["claudeai"]}.
🧭 How to use it (in one screen)
- Choose Operation Mode: Followers/Following · Specific List · Network Expansion · Keyword Discovery · Location Discovery.
- Inside Selected Mode: enter a handle (e.g.
claudeai), seed list, keyword, or location → set the per-mode cap. - Tuning: ⚙️ Data Extraction (post fetch / contact deep search / language detection) + 🔬 Advanced Filtering (followers / engagement / contact info / recent activity).
→ 💡 Tips & Best Practices for cost, performance, and data-quality patterns.
🤖 Connect from Claude Desktop / Cursor / ChatGPT
The MCP server lives at https://<actor-id>.apify.actor/mcp. Auth via Apify token (query param or Bearer header).
Claude Desktop
Add to your claude_desktop_config.json:
{"mcpServers": {"instagram": {"command": "npx","args": ["-y","@modelcontextprotocol/server-fetch","https://instagram-profile-scraper-mcp-server.apify.actor/mcp?token=<YOUR_APIFY_TOKEN>"]}}}
Restart Claude Desktop. Five tools appear: instagram_analyze_followers_following, instagram_analyze_specific_accounts, instagram_network_expansion, instagram_keyword_discovery, instagram_location_discovery.
Cursor / ChatGPT / other MCP clients
Point them at https://<actor-id>.apify.actor/mcp with Authorization: Bearer <YOUR_APIFY_TOKEN>. Streamable HTTP transport requires the header Accept: application/json, text/event-stream on every POST.
Curl smoke
TOKEN=<YOUR_APIFY_TOKEN>curl -sS -X POST "https://<actor-id>.apify.actor/mcp?token=$TOKEN" \-H "Content-Type: application/json" -H "Accept: application/json, text/event-stream" \-d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'
▶ Run as a regular Apify actor
The actor also accepts a normal INPUT_SCHEMA via apify call / Console / API. Pick a mode + provide its required field(s):
{"operationMode": "analyzeSpecificAccounts","specificUsernamesList": ["claudeai"],"extractEmail": true,"analyzeQuality": true}
All 5 modes are supported in regular-run as well as MCP. See .actor/input_schema.json for every field.
💰 Pay-per-event pricing
Same as the parent scraper. Charged on event emission — pay only for what you get.
| Event | Price (USD) | When charged |
|---|---|---|
PROFILE_ANALYZED | $0.01 | per profile successfully retrieved + analyzed |
USER_LIST_FETCHED | $0.10 | per follower OR following list dump (Mode 1 only) |
Demo input cap: when you leave the example seed (natgeo / openai, claudeai / openai) at default with no maxCount, the run is capped at 10 profiles — a $0.10 max trial on any plan.
Free vs paid
| Free plan | Paid plan | |
|---|---|---|
| Profiles / run | 50 | unlimited (50 per MCP call) |
| Mode 1 targets | 3 | unlimited |
| Modes 3/4/5 discovery | 5 | unlimited (50 per MCP call) |
masked (j***@a***.com) | full address | |
| Reels analytics, view/follower ratio | not applied | applied |
searchDepth=2 (Mode 3) | not available | available |
🔒 Storage records
Every run writes the same 5 records as the parent scraper:
| Key | Format | Purpose |
|---|---|---|
RUN_SUMMARY | JSON | profiles found / enriched / skipped, email-resolution stats, plan, durationSeconds, MCP tool-call count |
SKIPPED_ACCOUNTS | JSON | per-username list of skips with reason + category (filter / not_found / private / error) |
FREE_LIMITS_APPLIED | JSON | which FREE-plan ceilings hit (profile cap, target cap, expansion cap) — empty on paid |
USER_MESSAGE | JSON | onboarding banner / test-run notice — optional |
status.html | HTML | live progress dashboard (Apify Console Output tab) |
Standby instances aggregate counters across all tool calls in the same instance and flush every 10 calls + on Actor.exit.
🛠️ Programmatic API
Trigger the actor as a regular run:
curl -X POST "https://api.apify.com/v2/acts/instagram-profile-scraper-mcp-server/runs?token=$TOKEN" \-H "Content-Type: application/json" \-d '{"operationMode":"analyzeSpecificAccounts","specificUsernamesList":["claudeai"]}'
Read the dataset:
$curl "https://api.apify.com/v2/datasets/<datasetId>/items?token=$TOKEN&format=json"
💡 Tips & Best Practices
Getting Maximum Results
- Start with one handle per mode to validate filter shape — Mode 2 with a single username gives the cheapest first signal.
- Layer filters in this order: follower range → contact info → category/keyword. Earlier filters cut profiles before expensive enrichment.
- For Mode 4 keyword discovery, combine
searchQueries(broader Instagram account search) withsearchHashtags(top-post authors, biased toward larger accounts) to widen the funnel. - For Mode 5 location discovery, use
City, Countryformat (e.g.London, UK) — the country hint disambiguates same-named cities.
Cost Optimization
- Use Apify's Run options panel (Maximum cost per run) to cap a run at any USD amount. Independent of the per-event pricing.
- Set
maxCountrealistically per mode — most discovery sources return hundreds of candidates. Free plan ceiling (50 / 3 / 5 by mode) acts as a backstop. - Tri-state filters (
accountType,mustBeVerified,categoryFilter) drop matches before paid analysis. - Skip
extractPosts/searchContactsInPostswhen you only need follower counts and bio — those toggles add a per-profile media fetch.
Performance
- The actor uses concurrency 16 against the upstream API by default; this matches the rate limit observed in production.
- Mode 5 (Location Discovery) is the slowest mode because it resolves each seed via a place-name search before fetching tagged media. Pre-resolving to a numeric place ID (paste the integer instead of
City, Country) skips the search step. - Standby instances stay warm across MCP tool calls — the second tool call in a session is faster than the first.
Data Quality
- The 38-column dataset has many nullable fields — check
Email/Reels Count/Median ERaren't all "N/A" on a sample row before scaling. - "Mutual Follow" column appears only when Mode 1 has both
analyzeFollowersANDanalyzeFollowingenabled. - "Tagged Location" column appears only in Mode 5.
- "Matched By" column appears when
categoryFilterorkeywordsis active — values:category,keyword,both. - Free-plan emails are masked (
j***@a***.com) — the underlying value is correct on the paid plan.
❓ FAQ
Why a separate actor instead of the parent's modes? The MCP wrapper presents 5 narrow tools — agents can pick by intent. The parent actor uses one INPUT_SCHEMA with a mode enum, which is fine for humans but unwieldy for AI clients reading a tool catalog.
Same dataset shape as parent? Yes — 38 columns, same titles, same example values.
Same pricing as parent? Yes — $0.01 per profile + $0.10 per list dump, mirroring the parent 1:1.
Does Standby cost extra? Standby billing is per actor compute time, not per MCP tool call. Idle Standby instances stop after a few minutes of no traffic.
Will agents auto-discover this on mcp.apify.com? Yes once the actor is public + categorized as MCP_SERVERS. Indexing happens within ~1 hour of publish.
🔗 Related actors
| Actor | Description |
|---|---|
| instagram-profile-scraper | Parent scraper — same data + pricing, full INPUT_SCHEMA flow |
| instagram-followers-scraper | Lighter spinoff — followers/following only, single mode |
| instagram-related-profiles-scraper | Lighter spinoff — Network Expansion only, single mode |
⚠️ Disclaimer
This actor scrapes only public Instagram profile data. Respect Instagram's Terms of Service and applicable data-protection regulations (GDPR, CCPA) when handling collected data. The MCP wrapper does not change what data is collected — same surface as the parent scraper.