Hosted Instagram MCP server from HasData. Public profile and post-feed tools by handle, structured JSON, for Claude, Cursor and any MCP client.
- ✓Open-source license (MIT)
- ✓Actively maintained (<30d)
- ✓Clear description
- ✓Topics declared
- ✓Documented (README)
git clone https://github.com/HasData/instagram-mcp{
"mcpServers": {
"instagram-mcp": {
"command": "node",
"args": ["/path/to/instagram-mcp/dist/index.js"]
}
}
}MCP Servers overview
# Instagram MCP Server
A hosted Model Context Protocol (MCP) server that gives Claude, Cursor, Windsurf and any other MCP client two read-only Instagram tools. Look up a public profile by handle, and walk its public post feed, as structured JSON.
It reads public data about accounts. It does not act as an account. There is nothing to connect and no account of yours involved anywhere in the flow.
```
https://mcp.hasdata.com/api/mcp?apis=instagram
```
[](https://github.com/HasData/instagram-mcp/actions/workflows/contract.yml)
[](https://modelcontextprotocol.io)
[](#tools)
[](LICENSE)
## Contents
- [What you need](#what-you-need)
- [Quick start](#quick-start)
- [Example prompts](#example-prompts)
- [Tools](#tools)
- [Errors and failure paths](#errors-and-failure-paths)
- [Pricing, free tier and limits](#pricing-free-tier-and-limits)
- [Tool selection](#tool-selection)
- [How it compares](#how-it-compares)
- [FAQ](#faq)
- [HasData links](#hasdata-links)
- [Development](#development)
- [Contributing](#contributing)
- [License](#license)
## What you need
An MCP client that speaks streamable HTTP with custom headers. A HasData API key from the [dashboard](https://app.hasdata.com/sign-up?utm_source=github&utm_medium=syndication&utm_campaign=instagram-mcp), free to create with no card, and the trial covers 100 calls. Nothing else. This is a remote server. There is no package to install, no container to run and no local process that has to stay up.
## Quick start
| | |
| :--- | :--- |
| URL | `https://mcp.hasdata.com/api/mcp?apis=instagram` |
| Transport | HTTP, streamable |
| Auth header | `x-api-key: HASDATA_API_KEY` |
The server URL is the same for every client. We run it hands-on in Claude Code and Claude Desktop. The other blocks follow each client's own documented format for a remote server.
Clients with OAuth support can add the same URL as a connector and sign in without putting a key in a config file.
<details>
<summary><b>Claude Code</b></summary>
```bash
claude mcp add --transport http instagram "https://mcp.hasdata.com/api/mcp?apis=instagram" \
--header "x-api-key: HASDATA_API_KEY"
```
</details>
<details>
<summary><b>Claude Desktop</b></summary>
Claude Desktop loads only local (stdio) servers from its config file, so a remote server is reached through the `mcp-remote` bridge. Node has to be on the machine.
`claude_desktop_config.json`:
```json
{
"mcpServers": {
"instagram": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"https://mcp.hasdata.com/api/mcp?apis=instagram",
"--header",
"x-api-key:HASDATA_API_KEY"
]
}
}
}
```
The `x-api-key:` value carries no space after the colon. Claude Desktop passes the argument without a shell, and a space splits the header. A client with OAuth support can instead add the URL as a custom connector and skip the bridge.
</details>
<details>
<summary><b>Cursor</b></summary>
`.cursor/mcp.json`:
```json
{
"mcpServers": {
"instagram": {
"url": "https://mcp.hasdata.com/api/mcp?apis=instagram",
"headers": { "x-api-key": "HASDATA_API_KEY" }
}
}
}
```
</details>
<details>
<summary><b>Windsurf</b></summary>
`~/.codeium/windsurf/mcp_config.json`:
```json
{
"mcpServers": {
"instagram": {
"serverUrl": "https://mcp.hasdata.com/api/mcp?apis=instagram",
"headers": { "x-api-key": "HASDATA_API_KEY" }
}
}
}
```
</details>
<details>
<summary><b>Cline</b></summary>
```json
{
"mcpServers": {
"instagram": {
"url": "https://mcp.hasdata.com/api/mcp?apis=instagram",
"type": "streamableHttp",
"headers": { "x-api-key": "HASDATA_API_KEY" },
"disabled": false
}
}
}
```
</details>
<details>
<summary><b>VS Code</b></summary>
`.vscode/mcp.json`:
```json
{
"servers": {
"instagram": {
"type": "http",
"url": "https://mcp.hasdata.com/api/mcp?apis=instagram",
"headers": { "x-api-key": "HASDATA_API_KEY" }
}
}
}
```
</details>
<details>
<summary><b>Gemini CLI</b></summary>
`~/.gemini/settings.json`:
```json
{
"mcpServers": {
"instagram": {
"httpUrl": "https://mcp.hasdata.com/api/mcp?apis=instagram",
"headers": { "x-api-key": "HASDATA_API_KEY" }
}
}
}
```
</details>
## Example prompts
Each of these is one tool call unless the count says otherwise.
> Pull the profile for `@nasa` and tell me the follower count, the category and every link in the bio.
*One call, 10 credits. For a public account the profile response already carries the twelve most recent posts, so a follow-up about recent activity needs no second call.*
> Compare `@nasa`, `@natgeo` and `@bbcearth` on followers, posts published and whether each is a business account.
*Three calls, 30 credits. One per handle.*
> Walk the last fifty posts from `@nasa` and list every hashtag with how often it appears.
*Five calls, 50 credits. Twelve posts arrive per call, and fifty takes five pages.*
> For the last twelve posts on `@natgeo`, give me likes, comments and the accounts mentioned in each caption.
*One call, 10 credits. Engagement counts and mentions come parsed in the post objects.*
Two things make these work. Hashtags and mentions arrive as arrays parsed out of the caption, and an agent counts them instead of running a regex over prose. And a profile lookup returns the recent feed in the same response. That is why so many research questions land in a single call.
## Tools
Two tools, both read-only, both keyed on a public account handle. Samples below are trimmed from real calls, and the numbers in them move as accounts post. Read them as shapes. Each tool name links to its endpoint reference.
The samples are the payload, not the whole response. A `tools/call` result carries one text block, and that text is itself JSON holding `url`, `status`, `text` and `json`, with the scraped data under `json`. From a raw JSON-RPC response the path is `result.content[0].text`, parsed, then `.json`. A chat client unwraps that for you and code talking to the endpoint directly does not.
### Get an Instagram profile
[`hasdata_instagram_profile_getInstagramProfile`](https://docs.hasdata.com/apis/instagram/profile?utm_source=github&utm_medium=syndication&utm_campaign=instagram-mcp)
One public profile by handle.
| Parameter | Type | Required | Notes |
| :--- | :--- | :--- | :--- |
| `handle` | string | yes | Username without the `@`, as it appears in the profile URL |
Returns `id`, `username`, `fullName`, `biography`, `businessCategory`, `verified`, `isBusinessAccount` and `isProfessionalAccount`, the counters `followersCount`, `followsCount`, `postsCount`, `highlightsCount` and `igtvVideoCount`, both `profilePicUrl` and `profilePicUrlHD`, and the arrays `latestPosts`, `latestIgtvVideos` and `relatedProfiles`.
The core identity fields and the follower and following counts come back for every public account. The fields beyond that depend on what the account itself exposes, so read the optional ones with a default.
> Links live in two fields that are not the same thing. `bioLinks` is the array of every link in the bio. `externalUrls` is a single string despite the plural name, and it holds the primary link, sometimes with a trailing slash the array version lacks. Read `bioLinks` when you want them all.
> `latestPosts` and `latestIgtvVideos` do not carry identical fields. Video entries add `taggedUsers`, and the post objects here omit the `productType` that the posts tool includes. Code that walks both arrays through one parser has to treat the extra keys as optional.
```json
{
"id": "528817151",
"username": "nasa",
"fullName": "NASA",
"biography": "Making the seemingly impossible, possible. ✨",
"businessCategory": "Government Agencies",
"bioLinks": [
"https://www.nasa.gov",
"https://science.nasa.gov/mission/roman-space-telescope/",
"http://intern.nasa.gov"
],
"externalUrls": "https://www.nasa.gov/",
"followersCount": 104397669,
"followsCount": 92,
"postsCount": 4887,
"verified": true,
"isBusinessAccount": true,
"latestPosts": [ "…twelve most recent posts, same shape as the posts tool…" ],
"relatedProfiles": [
{ "id": "…", "username": "…", "fullName": "…", "profilePicUrl": "…" }
]
}
```
`relatedProfiles` is Instagram's own suggestion list for the account and runs to a few dozen entries. It is a cheap way to widen a competitor set without guessing handles.
### Get Instagram posts
[`hasdata_instagram_posts_getInstagramPosts`](https://docs.hasdata.com/apis/instagram/posts?utm_source=github&utm_medium=syndication&utm_campaign=instagram-mcp)
The public post feed for one handle, page by page.
| Parameter | Type | Required | Notes |
| :--- | :--- | :--- | :--- |
| `handle` | string | yes | Username without the `@` |
| `limit` | number | | Approximate ceiling on posts in one response. Twelve is the real maximum, and larger values do not fetch more |
| `nextPageToken` | string | | The `pagination.nextPageToken` from the previous response |
> `limit` is a rough cap rather than an exact count. Twelve posts is one Instagram page and the hard ceiling for a single call, and `limit: 50` returns twelve. Below the ceiling the count lands near the number you asked for without always matching it, and how near depends on the account. Measured on `@nasa`, a limit of 2 returned 4 posts, 6 returned 6, 11 returned 10 and 13 returned 12. Treat it as "no more than roughly this many" and read the array length rather than assuming it.
> The response repeats the account's identity fields alongside the posts. `username`, `id`, `fullName`, `verified` and What people ask about instagram-mcp
What is HasData/instagram-mcp?
+
HasData/instagram-mcp is mcp servers for the Claude AI ecosystem. Hosted Instagram MCP server from HasData. Public profile and post-feed tools by handle, structured JSON, for Claude, Cursor and any MCP client. It has 0 GitHub stars and its last recorded update is dated 2026-08-21.
How do I install instagram-mcp?
+
You can install instagram-mcp by cloning the repository (https://github.com/HasData/instagram-mcp) or following the README instructions on GitHub. ClaudeWave also provides quick install blocks on this page.
Is HasData/instagram-mcp safe to use?
+
Our security agent has analyzed HasData/instagram-mcp and assigned a Trust Score of 95/100 (tier: Verified). See the full breakdown of passed checks and flags on this page.
Who maintains HasData/instagram-mcp?
+
HasData/instagram-mcp is maintained by HasData. The last recorded GitHub activity is dated 2026-08-21, with 0 open issues.
Are there alternatives to instagram-mcp?
+
Yes. On ClaudeWave you can browse similar mcp servers at /categories/mcp, sorted by popularity or recent activity.
Deploy instagram-mcp to your cloud
Ship this repo to production in minutes. Each platform spins up its own environment with editable env vars.
Maintain this repo? Add a badge to your README
Drop the badge into your GitHub README to show it's tracked on ClaudeWave. Each badge links back to this page and reflects the live Trust Score.
[](https://claudewave.com/repo/hasdata-instagram-mcp)<a href="https://claudewave.com/repo/hasdata-instagram-mcp"><img src="https://claudewave.com/api/badge/hasdata-instagram-mcp" alt="Featured on ClaudeWave: HasData/instagram-mcp" width="320" height="64" /></a>More MCP Servers
Fair-code workflow automation platform with native AI capabilities. Combine visual building with custom code, self-host or cloud, 400+ integrations.
User-friendly AI Interface (Supports Ollama, OpenAI API, ...)
An open-source AI agent that brings the power of Gemini directly into your terminal.
Real-time global intelligence dashboard. AI-powered news aggregation, geopolitical monitoring, and infrastructure tracking in a unified situational awareness interface
The fastest path to AI-powered full stack observability, even for lean teams.
🕷️ An adaptive Web Scraping framework that handles everything from a single request to a full-scale crawl!