instagram-mcp-server 1.6.6

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 (59) hide show
  1. package/.env.example +2 -0
  2. package/.github/dependabot.yml +50 -0
  3. package/.github/workflows/ci.yml +51 -0
  4. package/.github/workflows/release.yml +200 -0
  5. package/CONTRIBUTING.md +38 -0
  6. package/LICENSE +21 -0
  7. package/Makefile +16 -0
  8. package/README.md +141 -0
  9. package/dist/client.d.ts +57 -0
  10. package/dist/client.js +140 -0
  11. package/dist/client.test.d.ts +10 -0
  12. package/dist/client.test.js +212 -0
  13. package/dist/errors.d.ts +12 -0
  14. package/dist/errors.js +87 -0
  15. package/dist/errors.test.d.ts +9 -0
  16. package/dist/errors.test.js +164 -0
  17. package/dist/first-comment.test.d.ts +10 -0
  18. package/dist/first-comment.test.js +56 -0
  19. package/dist/handlers.test.d.ts +23 -0
  20. package/dist/handlers.test.js +355 -0
  21. package/dist/index.d.ts +49 -0
  22. package/dist/index.js +627 -0
  23. package/dist/lib/index.d.ts +6 -0
  24. package/dist/lib/index.js +5 -0
  25. package/dist/lib/insights.d.ts +55 -0
  26. package/dist/lib/insights.js +59 -0
  27. package/dist/rate-limiter.d.ts +72 -0
  28. package/dist/rate-limiter.js +219 -0
  29. package/dist/rate-limiter.test.d.ts +1 -0
  30. package/dist/rate-limiter.test.js +153 -0
  31. package/dist/response.d.ts +24 -0
  32. package/dist/response.js +35 -0
  33. package/dist/response.test.d.ts +1 -0
  34. package/dist/response.test.js +71 -0
  35. package/dist/sanitize.d.ts +17 -0
  36. package/dist/sanitize.js +27 -0
  37. package/dist/sanitize.test.d.ts +1 -0
  38. package/dist/sanitize.test.js +43 -0
  39. package/dist/tools.test.d.ts +14 -0
  40. package/dist/tools.test.js +188 -0
  41. package/package.json +32 -0
  42. package/src/client.test.ts +285 -0
  43. package/src/client.ts +204 -0
  44. package/src/errors.test.ts +299 -0
  45. package/src/errors.ts +108 -0
  46. package/src/first-comment.test.ts +75 -0
  47. package/src/handlers.test.ts +460 -0
  48. package/src/index.ts +960 -0
  49. package/src/lib/index.ts +6 -0
  50. package/src/lib/insights.ts +182 -0
  51. package/src/rate-limiter.test.ts +185 -0
  52. package/src/rate-limiter.ts +257 -0
  53. package/src/response.test.ts +80 -0
  54. package/src/response.ts +43 -0
  55. package/src/sanitize.test.ts +52 -0
  56. package/src/sanitize.ts +35 -0
  57. package/src/tools.test.ts +251 -0
  58. package/tsconfig.json +15 -0
  59. package/vitest.config.ts +10 -0
package/.env.example ADDED
@@ -0,0 +1,2 @@
1
+ INSTAGRAM_ACCESS_TOKEN=your_long_lived_facebook_page_token_here
2
+ INSTAGRAM_BUSINESS_ACCOUNT_ID=your_17_digit_ig_business_account_id
@@ -0,0 +1,50 @@
1
+ version: 2
2
+ updates:
3
+ # npm dependencies
4
+ - package-ecosystem: "npm"
5
+ directory: "/"
6
+ schedule:
7
+ interval: "weekly"
8
+ day: "monday"
9
+ open-pull-requests-limit: 5
10
+ labels:
11
+ - "dependencies"
12
+ commit-message:
13
+ prefix: "chore(deps)"
14
+ groups:
15
+ dev-dependencies:
16
+ patterns:
17
+ - "typescript"
18
+ - "tsx"
19
+ - "vitest"
20
+ - "@types/*"
21
+ - "prettier"
22
+ update-types:
23
+ - "minor"
24
+ - "patch"
25
+ runtime-dependencies:
26
+ patterns:
27
+ - "@modelcontextprotocol/*"
28
+ - "zod"
29
+ update-types:
30
+ - "patch"
31
+
32
+ # GitHub Actions
33
+ - package-ecosystem: "github-actions"
34
+ directory: "/"
35
+ schedule:
36
+ interval: "weekly"
37
+ day: "monday"
38
+ open-pull-requests-limit: 3
39
+ labels:
40
+ - "dependencies"
41
+ - "github-actions"
42
+ commit-message:
43
+ prefix: "chore(deps)"
44
+ groups:
45
+ github-actions:
46
+ patterns:
47
+ - "*"
48
+ update-types:
49
+ - "minor"
50
+ - "patch"
@@ -0,0 +1,51 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ test-matrix:
11
+ runs-on: ubuntu-latest
12
+ strategy:
13
+ matrix:
14
+ node-version: ["20", "22"]
15
+
16
+ steps:
17
+ - uses: actions/checkout@v7
18
+
19
+ - name: Set up Node.js ${{ matrix.node-version }}
20
+ uses: actions/setup-node@v6
21
+ with:
22
+ node-version: ${{ matrix.node-version }}
23
+ cache: "npm"
24
+
25
+ - name: Install dependencies
26
+ run: npm ci
27
+
28
+ - name: Format check with prettier
29
+ run: npx prettier --check .
30
+
31
+ - name: Type check with tsc
32
+ run: npx tsc --noEmit
33
+
34
+ - name: Run tests
35
+ run: npm test
36
+
37
+ - name: Build
38
+ run: npm run build
39
+
40
+ test:
41
+ needs: [test-matrix]
42
+ runs-on: ubuntu-latest
43
+ if: always()
44
+ steps:
45
+ - name: Check test matrix status
46
+ run: |
47
+ if [ "${{ needs.test-matrix.result }}" != "success" ]; then
48
+ echo "Test matrix failed with result: ${{ needs.test-matrix.result }}"
49
+ exit 1
50
+ fi
51
+ echo "All tests passed!"
@@ -0,0 +1,200 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ workflow_dispatch:
7
+
8
+ permissions:
9
+ contents: write
10
+ packages: write
11
+
12
+ jobs:
13
+ release:
14
+ runs-on: ubuntu-latest
15
+ if: github.ref == 'refs/heads/main'
16
+
17
+ steps:
18
+ - name: Checkout code
19
+ uses: actions/checkout@v7
20
+ with:
21
+ fetch-depth: 0
22
+ token: ${{ secrets.RELEASE_TOKEN }}
23
+
24
+ - name: Check for skip-release marker
25
+ id: check_skip
26
+ run: |
27
+ SUBJECT=$(git log -1 --pretty=%s)
28
+ if echo "$SUBJECT" | grep -q '\[skip-release\]'; then
29
+ echo "skip=true" >> $GITHUB_OUTPUT
30
+ echo "Skipping release: $SUBJECT"
31
+ else
32
+ echo "skip=false" >> $GITHUB_OUTPUT
33
+ echo "Proceeding with release check: $SUBJECT"
34
+ fi
35
+
36
+ - name: Set up Node.js
37
+ if: steps.check_skip.outputs.skip != 'true'
38
+ uses: actions/setup-node@v6
39
+ with:
40
+ node-version: "20"
41
+ registry-url: "https://registry.npmjs.org"
42
+ cache: "npm"
43
+
44
+ - name: Install dependencies
45
+ if: steps.check_skip.outputs.skip != 'true'
46
+ run: npm ci
47
+
48
+ - name: Run tests
49
+ if: steps.check_skip.outputs.skip != 'true'
50
+ run: npm test
51
+
52
+ - name: Build
53
+ if: steps.check_skip.outputs.skip != 'true'
54
+ run: npm run build
55
+
56
+ - name: Configure Git
57
+ if: steps.check_skip.outputs.skip != 'true'
58
+ run: |
59
+ git config user.name "github-actions[bot]"
60
+ git config user.email "github-actions[bot]@users.noreply.github.com"
61
+
62
+ - name: Determine next version
63
+ id: version
64
+ if: steps.check_skip.outputs.skip != 'true'
65
+ run: |
66
+ CURRENT_VERSION=$(node -p "require('./package.json').version")
67
+ LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "")
68
+
69
+ echo "current_version=$CURRENT_VERSION" >> $GITHUB_OUTPUT
70
+
71
+ if [ -z "$LAST_TAG" ]; then
72
+ echo "new_release=true" >> $GITHUB_OUTPUT
73
+ echo "new_version=$CURRENT_VERSION" >> $GITHUB_OUTPUT
74
+ echo "bump=initial" >> $GITHUB_OUTPUT
75
+ echo "First release: $CURRENT_VERSION"
76
+ exit 0
77
+ fi
78
+
79
+ COMMITS=$(git log "$LAST_TAG"..HEAD --pretty=%s)
80
+
81
+ if [ -z "$COMMITS" ]; then
82
+ echo "No new commits since $LAST_TAG"
83
+ echo "new_release=false" >> $GITHUB_OUTPUT
84
+ exit 0
85
+ fi
86
+
87
+ BUMP=""
88
+ if echo "$COMMITS" | grep -qiE '^[a-z]+(\(.+\))?!:|BREAKING CHANGE'; then
89
+ BUMP="major"
90
+ elif echo "$COMMITS" | grep -qiE '^feat(\(.+\))?:'; then
91
+ BUMP="minor"
92
+ elif echo "$COMMITS" | grep -qiE '^(fix|perf|refactor)(\(.+\))?:'; then
93
+ BUMP="patch"
94
+ fi
95
+
96
+ if [ -z "$BUMP" ]; then
97
+ echo "No release-worthy commits (feat/fix/perf/refactor) since $LAST_TAG"
98
+ echo "new_release=false" >> $GITHUB_OUTPUT
99
+ exit 0
100
+ fi
101
+
102
+ IFS='.' read -r MAJOR MINOR PATCH <<< "$CURRENT_VERSION"
103
+ case "$BUMP" in
104
+ major) MAJOR=$((MAJOR + 1)); MINOR=0; PATCH=0 ;;
105
+ minor) MINOR=$((MINOR + 1)); PATCH=0 ;;
106
+ patch) PATCH=$((PATCH + 1)) ;;
107
+ esac
108
+ NEW_VERSION="$MAJOR.$MINOR.$PATCH"
109
+
110
+ echo "new_release=true" >> $GITHUB_OUTPUT
111
+ echo "new_version=$NEW_VERSION" >> $GITHUB_OUTPUT
112
+ echo "bump=$BUMP" >> $GITHUB_OUTPUT
113
+ echo "Detected $BUMP bump: $CURRENT_VERSION → $NEW_VERSION"
114
+
115
+ - name: Bump version in package.json
116
+ if: steps.version.outputs.new_release == 'true'
117
+ run: |
118
+ if [ "${{ steps.version.outputs.bump }}" = "initial" ]; then
119
+ git tag -a "v${{ steps.version.outputs.new_version }}" -m "Release v${{ steps.version.outputs.new_version }}"
120
+ else
121
+ npm version ${{ steps.version.outputs.new_version }} --no-git-tag-version
122
+ git add package.json package-lock.json
123
+ git commit -m "chore(release): ${{ steps.version.outputs.new_version }} [skip-release]"
124
+ git tag -a "v${{ steps.version.outputs.new_version }}" -m "Release v${{ steps.version.outputs.new_version }}"
125
+ fi
126
+
127
+ - name: Push version commit and tag
128
+ if: steps.version.outputs.new_release == 'true'
129
+ run: |
130
+ git push origin main --follow-tags
131
+
132
+ - name: Generate release notes
133
+ id: notes
134
+ if: steps.version.outputs.new_release == 'true'
135
+ run: |
136
+ LAST_TAG=$(git describe --tags --abbrev=0 HEAD~1 2>/dev/null || echo "")
137
+ NEW_VERSION="v${{ steps.version.outputs.new_version }}"
138
+
139
+ {
140
+ echo "notes<<RELEASE_NOTES_EOF"
141
+
142
+ if [ -n "$LAST_TAG" ]; then
143
+ echo "## What's Changed"
144
+ echo ""
145
+
146
+ FEATS=$(git log "$LAST_TAG"..HEAD~1 --pretty="- %s" | grep -iE '^\- feat' || true)
147
+ FIXES=$(git log "$LAST_TAG"..HEAD~1 --pretty="- %s" | grep -iE '^\- fix' || true)
148
+ OTHERS=$(git log "$LAST_TAG"..HEAD~1 --pretty="- %s" | grep -viE '^\- (feat|fix|chore\(release\))' || true)
149
+
150
+ if [ -n "$FEATS" ]; then
151
+ echo "### Features"
152
+ echo "$FEATS"
153
+ echo ""
154
+ fi
155
+ if [ -n "$FIXES" ]; then
156
+ echo "### Bug Fixes"
157
+ echo "$FIXES"
158
+ echo ""
159
+ fi
160
+ if [ -n "$OTHERS" ]; then
161
+ echo "### Other Changes"
162
+ echo "$OTHERS"
163
+ echo ""
164
+ fi
165
+
166
+ echo "**Full Changelog**: https://github.com/${{ github.repository }}/compare/$LAST_TAG...$NEW_VERSION"
167
+ else
168
+ echo "Initial release"
169
+ fi
170
+
171
+ echo "RELEASE_NOTES_EOF"
172
+ } >> $GITHUB_OUTPUT
173
+
174
+ - name: Create GitHub Release
175
+ if: steps.version.outputs.new_release == 'true'
176
+ env:
177
+ GH_TOKEN: ${{ secrets.RELEASE_TOKEN }}
178
+ run: |
179
+ gh release create "v${{ steps.version.outputs.new_version }}" \
180
+ --title "v${{ steps.version.outputs.new_version }}" \
181
+ --notes "${{ steps.notes.outputs.notes }}" \
182
+ --latest
183
+
184
+ - name: Publish to npm
185
+ if: steps.version.outputs.new_release == 'true'
186
+ env:
187
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
188
+ run: |
189
+ npm publish
190
+
191
+ - name: Release summary
192
+ if: steps.version.outputs.new_release == 'true'
193
+ run: |
194
+ echo "## Release Summary" >> $GITHUB_STEP_SUMMARY
195
+ echo "" >> $GITHUB_STEP_SUMMARY
196
+ echo "Released version: **v${{ steps.version.outputs.new_version }}** (${{ steps.version.outputs.bump }} bump)" >> $GITHUB_STEP_SUMMARY
197
+ echo "" >> $GITHUB_STEP_SUMMARY
198
+ echo "Published to:" >> $GITHUB_STEP_SUMMARY
199
+ echo "- GitHub Releases" >> $GITHUB_STEP_SUMMARY
200
+ echo "- npm (npx installable)" >> $GITHUB_STEP_SUMMARY
@@ -0,0 +1,38 @@
1
+ # Contributing
2
+
3
+ Thanks for your interest in contributing to Instagram MCP Server!
4
+
5
+ ## Getting Started
6
+
7
+ 1. Fork the repository
8
+ 2. Clone your fork: `git clone https://github.com/your-username/instagram-mcp-server.git`
9
+ 3. Install dependencies: `npm install`
10
+ 4. Create a feature branch: `git checkout -b feat/my-feature`
11
+
12
+ ## Development
13
+
14
+ ```bash
15
+ npm run dev # Run with tsx (hot reload)
16
+ npm run build # Compile TypeScript
17
+ npm test # Run tests
18
+ ```
19
+
20
+ ## Pull Requests
21
+
22
+ - Keep PRs focused on a single change
23
+ - Add tests for new functionality
24
+ - Make sure `npm test` and `npm run build` pass
25
+ - Use clear, descriptive commit messages
26
+
27
+ ## Reporting Issues
28
+
29
+ Open an issue with:
30
+
31
+ - What you expected to happen
32
+ - What actually happened
33
+ - Steps to reproduce
34
+ - Node.js version and OS
35
+
36
+ ## License
37
+
38
+ By contributing, you agree that your contributions will be licensed under the MIT License.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Luminary Lane
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.
package/Makefile ADDED
@@ -0,0 +1,16 @@
1
+ .PHONY: install build dev test clean
2
+
3
+ install:
4
+ npm install
5
+
6
+ build:
7
+ npm run build
8
+
9
+ dev:
10
+ npm run dev
11
+
12
+ test:
13
+ npm test
14
+
15
+ clean:
16
+ rm -rf dist node_modules
package/README.md ADDED
@@ -0,0 +1,141 @@
1
+ # Instagram MCP Server
2
+
3
+ [![MCP](https://img.shields.io/badge/MCP-1.0-blue)](https://modelcontextprotocol.io)
4
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.7-blue)](https://www.typescriptlang.org)
5
+ [![License](https://img.shields.io/badge/License-MIT-yellow)](LICENSE)
6
+
7
+ A Model Context Protocol (MCP) server that connects Claude Desktop (and other MCP clients) to the Instagram Graph API — read analytics, manage comments, publish photos, carousels, and reels.
8
+
9
+ ## Features
10
+
11
+ ### 11 Instagram Tools
12
+
13
+ **SENSE (read-only):**
14
+ | Tool | Description |
15
+ |------|-------------|
16
+ | `ig_get_account_insights` | Account insights: reach, follower growth, profile views over a period |
17
+ | `ig_get_post_insights` | Engagement metrics for a specific post: reach, likes, shares, saves |
18
+ | `ig_get_comments` | Comments on a post with username, timestamp, and replies |
19
+ | `ig_get_stories_insights` | Insights for an active story: reach, replies, interactions |
20
+ | `ig_get_audience_demographics` | Follower demographics: city, country, age/gender breakdown |
21
+ | `ig_get_hashtag_search` | Search public posts by hashtag (30 unique hashtags per 7-day window) |
22
+
23
+ **ACT (write):**
24
+ | Tool | Description |
25
+ |------|-------------|
26
+ | `ig_publish_photo` | Publish a photo post from a public URL |
27
+ | `ig_publish_carousel` | Publish a carousel (2-10 images) from public URLs |
28
+ | `ig_publish_reel` | Publish a reel (short video) from a public URL |
29
+ | `ig_reply_comment` | Reply to a comment on a post |
30
+ | `ig_delete_comment` | Delete a comment on one of your posts |
31
+
32
+ ### Built-in Reliability
33
+
34
+ - **Per-tenant rate limiting** — token-bucket rate limiter keyed by IG Business Account ID
35
+ - **Exponential backoff retry** — automatic retry with jitter for transient API errors
36
+ - **Container-based publishing** — create container → poll status → publish (handles async video processing)
37
+ - **Input sanitization** — strips zero-width characters, normalizes whitespace, truncates to API limits
38
+ - **Prompt injection protection** — wraps external API data in randomized markers
39
+
40
+ ## Quick Start
41
+
42
+ ### Prerequisites
43
+
44
+ - Node.js 18+
45
+ - An Instagram Business or Creator account connected to a Facebook Page
46
+ - A Facebook App with the Instagram Graph API enabled
47
+ - A long-lived Page Access Token
48
+
49
+ ### Getting Your Access Token
50
+
51
+ 1. Create a [Facebook App](https://developers.facebook.com/apps/)
52
+ 2. Add the **Instagram Graph API** product
53
+ 3. In [Graph API Explorer](https://developers.facebook.com/tools/explorer/), generate a Page Access Token with these permissions:
54
+ - `instagram_basic`, `instagram_content_publish`, `instagram_manage_comments`, `instagram_manage_insights`, `pages_show_list`, `pages_read_engagement`
55
+ 4. [Extend the token](https://developers.facebook.com/tools/debug/accesstoken/) to a long-lived token (60 days)
56
+
57
+ ### Installation
58
+
59
+ ```bash
60
+ git clone https://github.com/luminarylane/instagram-mcp-server.git
61
+ cd instagram-mcp-server
62
+ npm install
63
+ npm run build
64
+ ```
65
+
66
+ ### Configuration
67
+
68
+ **Claude Desktop (`claude_desktop_config.json`):**
69
+
70
+ ```json
71
+ {
72
+ "mcpServers": {
73
+ "instagram": {
74
+ "command": "node",
75
+ "args": ["/path/to/instagram-mcp-server/dist/index.js"],
76
+ "env": {
77
+ "INSTAGRAM_ACCESS_TOKEN": "your_long_lived_page_token",
78
+ "INSTAGRAM_BUSINESS_ACCOUNT_ID": "your_17_digit_ig_business_account_id"
79
+ }
80
+ }
81
+ }
82
+ }
83
+ ```
84
+
85
+ **Environment variables:**
86
+
87
+ | Variable | Required | Description |
88
+ | ------------------------------- | -------- | ------------------------------------- |
89
+ | `INSTAGRAM_ACCESS_TOKEN` | Yes\* | Long-lived Facebook Page Access Token |
90
+ | `INSTAGRAM_BUSINESS_ACCOUNT_ID` | Yes\* | 17-digit IG Business Account ID |
91
+
92
+ \*Can also be passed per-call via tool arguments.
93
+
94
+ ### Finding Your Business Account ID
95
+
96
+ Use the Graph API Explorer:
97
+
98
+ ```
99
+ GET /me/accounts?fields=instagram_business_account
100
+ ```
101
+
102
+ The `instagram_business_account.id` field is your Business Account ID.
103
+
104
+ ## Usage Examples
105
+
106
+ Once configured, ask Claude to:
107
+
108
+ - "Show me my Instagram account insights for the last 28 days"
109
+ - "What are the engagement metrics for my latest post?"
110
+ - "Get the comments on this post" (paste a media ID)
111
+ - "Show my follower demographics by country"
112
+ - "Publish this photo to Instagram" (provide a public image URL + caption)
113
+ - "Create a carousel post with these images"
114
+ - "Reply to this comment with 'Thanks!'"
115
+ - "Search recent posts with #startup"
116
+
117
+ ## Publishing
118
+
119
+ Photo and carousel publishing is synchronous — the tool returns once the post is live. Reel publishing is asynchronous — the server polls the container status until processing completes, then publishes.
120
+
121
+ All publish tools accept an optional `firstComment` parameter to add a comment immediately after publishing (commonly used for hashtags).
122
+
123
+ ## Rate Limiting
124
+
125
+ The server enforces per-account rate limits to stay within Instagram's API quotas. If you hit a rate limit, the tool will return an error with a suggested retry time. The built-in retry logic handles transient 429 responses automatically.
126
+
127
+ ## Contributing
128
+
129
+ 1. Fork the repo
130
+ 2. Create a feature branch (`git checkout -b feat/my-feature`)
131
+ 3. Make changes and run tests (`npm test`)
132
+ 4. Submit a pull request
133
+
134
+ ## License
135
+
136
+ MIT License — see [LICENSE](LICENSE) for details.
137
+
138
+ ## Acknowledgments
139
+
140
+ - [Anthropic](https://anthropic.com) for the MCP specification
141
+ - [Meta Graph API](https://developers.facebook.com/docs/instagram-api/) for the underlying Instagram API
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Instagram Graph API client.
3
+ *
4
+ * Raw fetch wrapper against https://graph.instagram.com/v22.0/.
5
+ * No SDK — keeps dependencies minimal (Occam's Razor).
6
+ * Client instances are cached by credential hash.
7
+ */
8
+ export interface Credentials {
9
+ accessToken: string;
10
+ accountId: string;
11
+ }
12
+ /**
13
+ * Get or create a cached Instagram client.
14
+ */
15
+ export declare function createClient(creds: Credentials): InstagramClient;
16
+ /**
17
+ * Graph API error format from Facebook/Instagram.
18
+ */
19
+ export interface GraphApiError {
20
+ error: {
21
+ message: string;
22
+ type: string;
23
+ code: number;
24
+ error_subcode?: number;
25
+ fbtrace_id?: string;
26
+ };
27
+ }
28
+ /**
29
+ * Error thrown for Graph API failures. Carries structured error data
30
+ * for suggestAction() to inspect.
31
+ */
32
+ export declare class InstagramApiError extends Error {
33
+ readonly status: number;
34
+ readonly code: number;
35
+ readonly errorSubcode?: number;
36
+ readonly errorType: string;
37
+ readonly retryAfter?: number;
38
+ constructor(status: number, apiError: GraphApiError["error"], retryAfter?: number);
39
+ }
40
+ export declare class InstagramClient {
41
+ readonly accessToken: string;
42
+ readonly accountId: string;
43
+ constructor(creds: Credentials);
44
+ /**
45
+ * Make a GET request to the Graph API.
46
+ */
47
+ get<T = unknown>(path: string, params?: Record<string, string>): Promise<T>;
48
+ /**
49
+ * Make a POST request to the Graph API.
50
+ */
51
+ post<T = unknown>(path: string, body?: Record<string, unknown>): Promise<T>;
52
+ /**
53
+ * Make a DELETE request to the Graph API.
54
+ */
55
+ delete<T = unknown>(path: string): Promise<T>;
56
+ private handleResponse;
57
+ }