Metadata-Version: 2.3
Name: igsight-mcp
Version: 0.1.0
Summary: MCP server to read and analyze Instagram posts and profiles for AI agents
Author: Vinícius Hugenthobler
License: MIT
Requires-Dist: fastmcp>=2.0.0
Requires-Dist: httpx>=0.28.0
Requires-Dist: instaloader>=4.14
Requires-Dist: pydantic>=2.10
Requires-Dist: yt-dlp>=2025.1
Requires-Python: >=3.11
Project-URL: Homepage, https://github.com/vinihuge/igsight-mcp
Project-URL: Repository, https://github.com/vinihuge/igsight-mcp
Project-URL: Issues, https://github.com/vinihuge/igsight-mcp/issues
Description-Content-Type: text/markdown

# igsight-mcp

MCP server to read and analyze Instagram posts and profiles for AI agents.

Inspired by [smorand/mcp-instagram](https://github.com/smorand/mcp-instagram) (MIT). See [NOTICE](NOTICE) for attribution details.

PyPI: [igsight-mcp](https://pypi.org/project/igsight-mcp/)

## Quickstart

### Prerequisites

| Requirement | Notes |
| --- | --- |
| **Python ≥ 3.11** | Matches `requires-python` in the package |
| **ffmpeg** and **ffprobe** | On your `PATH`; needed for video/reel frame sampling and audio extraction |
| **Transcription (optional)** | Set `IGSIGHT_TRANSCRIBE_*` for Groq, OpenAI, or compatible Whisper APIs on video/reel posts |

Install ffmpeg from your OS package manager (for example `brew install ffmpeg`, `apt install ffmpeg`, or [ffmpeg.org](https://ffmpeg.org/download.html)).

### Run the server

The MCP server speaks **stdio**. Most clients launch it for you via config (below). To run manually:

```bash
uvx igsight-mcp
```

From a git checkout:

```bash
uvx --from . igsight-mcp
```

### Verify setup

After configuring your MCP client, call **`check_auth`** (no arguments). It reports cookie file status, ffmpeg, transcription config, cache paths, and built-in rate limits—**without returning secret values** (API keys and cookie contents are never echoed).

Fix any items in `warnings` (for example missing cookies file, loose file permissions, or datacenter IP hints) before calling **`get_post`**.

Example first **`get_post`** prompt in your client:

> Use the get_post tool on `https://www.instagram.com/p/SHORTCODE/` with default settings.

## MCP client configuration

Use the same command everywhere:

```json
"command": "uvx",
"args": ["igsight-mcp"]
```

Add an **`env`** block for `IGSIGHT_*` variables (paths shown are examples—adjust for your machine).

### Shared `env` example

```json
"env": {
  "IGSIGHT_COOKIES_FILE": "/home/you/.config/igsight/cookies.txt",
  "IGSIGHT_CACHE_DIR": "/home/you/.cache/igsight-mcp",
  "IGSIGHT_CACHE_TTL": "3600",
  "IGSIGHT_TRANSCRIBE_BASE_URL": "https://api.groq.com/openai/v1",
  "IGSIGHT_TRANSCRIBE_API_KEY": "your-api-key-here",
  "IGSIGHT_TRANSCRIBE_MODEL": "whisper-large-v3-turbo"
}
```

Transcription is optional; omit the three `IGSIGHT_TRANSCRIBE_*` keys to skip speech-to-text.

### Claude Desktop

Edit **`claude_desktop_config.json`**:

| OS | Path |
| --- | --- |
| macOS | `~/Library/Application Support/Claude/claude_desktop_config.json` |
| Windows | `%APPDATA%\Claude\claude_desktop_config.json` |

```json
{
  "mcpServers": {
    "igsight": {
      "command": "uvx",
      "args": ["igsight-mcp"],
      "env": {
        "IGSIGHT_COOKIES_FILE": "/home/you/.config/igsight/cookies.txt"
      }
    }
  }
}
```

Restart Claude Desktop after saving.

### Cursor

**Project** (repository root): `.cursor/mcp.json`

**Global**: `~/.cursor/mcp.json` (macOS/Linux) or `%USERPROFILE%\.cursor\mcp.json` (Windows)

```json
{
  "mcpServers": {
    "igsight": {
      "command": "uvx",
      "args": ["igsight-mcp"],
      "env": {
        "IGSIGHT_COOKIES_FILE": "/home/you/.config/igsight/cookies.txt"
      }
    }
  }
}
```

Reload MCP servers from Cursor settings after editing.

### Grok Bot

In Grok Bot MCP settings, add a **stdio** server with command **`uvx`**, arguments **`["igsight-mcp"]`**, and the same **`env`** keys as above (UI labels vary; the transport is stdio JSON-RPC).

### Generic stdio MCP JSON

```json
{
  "mcpServers": {
    "igsight": {
      "command": "uvx",
      "args": ["igsight-mcp"],
      "env": {
        "IGSIGHT_COOKIES_FILE": "/path/to/cookies.txt",
        "IGSIGHT_CACHE_DIR": "/path/to/cache",
        "IGSIGHT_CACHE_TTL": "3600",
        "IGSIGHT_TRANSCRIBE_BASE_URL": "https://api.openai.com/v1",
        "IGSIGHT_TRANSCRIBE_API_KEY": "sk-...",
        "IGSIGHT_TRANSCRIBE_MODEL": "whisper-1"
      }
    }
  }
}
```

## Tools

| Tool | Inputs | Outputs |
| --- | --- | --- |
| **`health_check()`** | _(none)_ | `status` (`"ok"`), `version` (package version string), `message` (short status text) |
| **`get_post(url, max_frames=6, transcribe=True)`** | `url` — Instagram post or reel URL (or shortcode forms resolved by the server). `max_frames` — key frames for video/reel (clamped to **1–20**; out-of-range values adjust with a **warning**). `transcribe` — when `true`, attempt speech-to-text on video/reel if transcription env is configured. | **Structured content:** `kind` (`photo` \| `carousel` \| `video` \| `reel`), `shortcode`, `author`, `caption`, `hashtags`, `mentions`, `timestamp`, `local_paths`, `warnings`, optional `likes`, `comments_count`. **Video/reel extras:** `duration`, `transcript` (`text`, `language`, `segments[]` with `start`/`end`/`text`) when transcription succeeds. **Content blocks:** JPEG **`ImageContent`** for each carousel slide or sampled frame. Partial failures (download, ffmpeg, transcription) append human-readable strings to **`warnings`** without failing the whole tool when possible. |
| **`analyze_profile(handle, n=12)`** | `handle` — `@username` or profile URL. `n` — recent posts to analyze (clamped to **1–50**; larger requests add a **warning**). | Profile fields: `username`, `full_name`, `bio`, `external_url`, `verified`, `followers`, `following`, `posts_count`. Analytics: `posts` (summaries), `mix` (% photo/carousel/video/reel), `posting_frequency` (`posts_per_week`, `avg_gap_days`, active weekdays/hours UTC), `engagement` (`avg_likes`, `avg_comments`, `engagement_rate`), `top_posts`, `recurring_hashtags`, `recurring_keywords`, `first_caption_lines`, `warnings`. |
| **`check_auth()`** | _(none)_ | `cookies_loaded`, `cookies_file` (path only, or `null`), `cookies_valid` (`true`/`false`/`null`), `ffmpeg_available`, `transcription_backend`, `transcription_configured`, `cache_dir`, `cache_ttl_seconds`, `rate_limit` (built-in limiter settings), `warnings`. Never includes API keys or cookie values. |

## Environment variables

All configuration uses **`IGSIGHT_*`** environment variables (there is no separate config file). Defaults match the implementation in `src/igsight_mcp/core/`.

| Variable | Default | Description |
| --- | --- | --- |
| **`IGSIGHT_COOKIES_FILE`** | _(unset)_ | Path to a Netscape-format cookies file. Optional for many public posts; recommended for reliable access. See [docs/cookies.md](docs/cookies.md). |
| **`IGSIGHT_CACHE_DIR`** | `~/.cache/igsight-mcp` | Root directory for JSON caches (posts, transcripts, `get_post` media metadata). |
| **`IGSIGHT_CACHE_TTL`** | `3600` | Cache entry lifetime in seconds. Invalid values fall back to `3600`. `0` disables TTL reads (effectively no cache reuse). |
| **`IGSIGHT_TRANSCRIBE_BASE_URL`** | _(empty)_ | OpenAI-compatible API base URL, without trailing slash. Required with API key and model to enable transcription. |
| **`IGSIGHT_TRANSCRIBE_API_KEY`** | _(empty)_ | Bearer token for the transcription API. Never logged or returned by **`check_auth`**. |
| **`IGSIGHT_TRANSCRIBE_MODEL`** | _(empty)_ | Model id for `/audio/transcriptions`. |

There are **no** `IGSIGHT_*` rate-limit overrides; limits are fixed in code and reported by **`check_auth`** under `rate_limit`:

| Field | Default |
| --- | --- |
| `min_interval_seconds` | `3.0` |
| `max_interval_seconds` | `5.0` |
| `hourly_budget` | `200` |
| `bucket_capacity` | `1.0` |
| `refill_seconds` | `4.0` |

### Transcription examples

**Groq**

```json
"IGSIGHT_TRANSCRIBE_BASE_URL": "https://api.groq.com/openai/v1",
"IGSIGHT_TRANSCRIBE_API_KEY": "gsk_...",
"IGSIGHT_TRANSCRIBE_MODEL": "whisper-large-v3-turbo"
```

**OpenAI**

```json
"IGSIGHT_TRANSCRIBE_BASE_URL": "https://api.openai.com/v1",
"IGSIGHT_TRANSCRIBE_API_KEY": "sk-...",
"IGSIGHT_TRANSCRIBE_MODEL": "whisper-1"
```

Alternative OpenAI model example: `gpt-4o-mini-transcribe` (if your account exposes it on the same API).

All three transcription variables must be set together; otherwise video/reel posts still return frames but add a transcription warning.

## Cookies

See **[docs/cookies.md](docs/cookies.md)** for exporting Netscape `cookies.txt`, `chmod 600`, secondary accounts, and keeping cookies out of git.

## Account safety and rate limits

**igsight-mcp** is built for **occasional, read-only** agent use—not bulk scraping.

- **Built-in rate limiting** spaces Instagram requests (roughly 3–5 seconds jitter between calls, token bucket, and an hourly budget of 200 requests). Hitting limits raises a rate-limit error; wait and retry.
- **No bulk scraping** — do not loop thousands of profiles or posts through the tools.
- **Avoid datacenter IPs** — Instagram often blocks cloud VPS IPs. Prefer a home or office network where you normally use Instagram. **`check_auth`** warns when common cloud environment variables are detected.
- Use a **secondary account** and exported cookies rather than hammering anonymous endpoints.

## Legal and terms of use

**Not affiliated with, endorsed by, or sponsored by Meta Platforms, Inc. Instagram is a trademark of Meta.**

You are responsible for complying with Instagram’s Terms of Use, applicable copyright law, and privacy rules. This project provides **read-only** access to public (or session-allowed) content for personal/agent assistance. Do not use it to harass users, bypass paywalls, or redistribute media against creators’ rights. Respect creators and platform policies.

## Demo

<!-- TODO: Record a short demo GIF (Claude Desktop or Cursor calling get_post on a public post) and save as docs/assets/demo.gif -->

![Demo: get_post in an MCP client](https://raw.githubusercontent.com/vinihuge/igsight-mcp/main/docs/assets/demo.gif)

## Development

Requires [uv](https://docs.astral.sh/uv/). See [CONTRIBUTING.md](CONTRIBUTING.md).

```bash
uv sync --all-groups
make check          # ruff, mypy --strict, pytest
uv run igsight-mcp  # stdio MCP server
uvx --from . igsight-mcp
```

## Support the project

If igsight-mcp saves you time, consider sponsoring on [GitHub Sponsors](https://github.com/sponsors/vinihuge).

### Crypto

Always double-check the network before sending; funds sent on the wrong network may be lost.

| Network | Address | QR |
| --- | --- | --- |
| Bitcoin (BTC) | `bc1qfm4mhns9j4s589lhc9xq6asxpf5x93vhxkdlnn` | ![Bitcoin QR](https://raw.githubusercontent.com/vinihuge/igsight-mcp/main/assets/donate/btc.png) |
| EVM (Ethereum, BNB Smart Chain, Arbitrum; ETH and USDC/USDT on those networks) | `0x816895DFd46328258Bc11E133bD6d659Ccd0E323` | ![EVM QR](https://raw.githubusercontent.com/vinihuge/igsight-mcp/main/assets/donate/evm.png) |
| Solana (SOL, USDC) | `7zvKEwXR5KpbwoorQ4JhjhPSDDkwujKu7tN4BSeAq3Ci` | ![Solana QR](https://raw.githubusercontent.com/vinihuge/igsight-mcp/main/assets/donate/solana.png) |
| Tron (TRX, USDT TRC-20) | `TRk3jC7FjkDpLyHThVogP5pPeeufkSTQ7C` | ![Tron QR](https://raw.githubusercontent.com/vinihuge/igsight-mcp/main/assets/donate/tron.png) |

---

Built by Vinícius · creator of [WeTrackWise](https://wetrackwise.com)
