Repository navigation
Releases
v0.8.0
Added
-
--help/-hprint usage and exit 0; an unknown subcommand or flag exits 2
instead of starting the stdio server (0.7.0 treated every argument as a start). -
scripts/build-mcpb.shbuilds a lean MCPB bundle (~3 MB) from the npm tarball
contents plus production dependencies. -
scripts/live-qa.mjsanddocs/live-qa.md: one-command live verification of
T-E1–T-E4 and the open[verify]probes, read-only unless--writeis confirmed. -
server.jsondeclaresIG_AUTH_MODE,IG_WRITE_MODEandIG_TOOL_PACKAGES. -
List, media, comment and insights results report what was left out
(omittedWithoutId,omittedValues,repliesTruncated,paging.truncated)
instead of dropping it silently. -
discover_business: newmediaAfterinput andmediaPagingoutput. The
nested media edge now reportstruncated: truewith anaftercursor when
Instagram returned one; pass it back asmediaAfter(sent as
media.after(<cursor>)) to read the next page of the profile's media
(CC-DATA-116). -
Composite publish previews (
post_image,post_reel,post_story) now show
details.caption.excerpt(flattened, cut after 200 code points with…) and
details.media_hosts(the distinct hosts Instagram will fetch from; never the
path, query or userinfo) (CC-PUB-60). -
A resume (
resumeContainerId) that also receives media inputs now warns, in the
preview and the applied result, that those inputs are ignored and names them
(CC-PUB-59). -
token_statusanddoctorreport anexpiring_soonstate (adoctorWARN)
when the Path B data-access window closes within 7 days. -
instagram_list_stories: a read-only tool (packagemedia) that lists the
account's live stories fromGET /{ig-user-id}/stories. It is paged like
instagram_list_media, captions are fenced, and it covers only Instagram's
24-hour window. The tool count goes from 28 to 29 (CC-DATA-119). -
manifest.json(MCPB) now declares atoolsarray — every tool of theall
surface with its first-sentence summary — so Claude Desktop's Extensions detail
pane lists the tools. It is generated from the registry bynpm run gen:manifest
and locked by a drift gate intest/release/mcpb-manifest.test.ts. -
The MCPB bundle has been built (
scripts/build-mcpb.sh, 3.4 MB) and smoke-tested
locally: the unzipped bundle starts asmanifest.jsonlaunches it and lists its
tools over stdio without any network call.
Changed
-
Breaking for clients that parsed it: an error result no longer carries
structuredContent.error. SDK clients validated that envelope against the
tool's output schema and turned every typed error into-32602; the typed
error is now the text lineInstagram error (<kind>): <message> (code N, subcode M). -
An unresolved MCPB placeholder (
${user_config.X}) in anIG_*variable is
treated as unset. -
The MCPB manifest pins
IG_AUTH_MODE(defaultig-login), so filling both app
fields no longer switches a Path-A token tofb-login. -
The recorded token expiry is bound to a fingerprint of the token it was written
for; a record for a different token is ignored. -
The Claude Code plugin moved to
plugins/instagram-mcp-ai/and the marketplace
entry now reads"source": "./plugins/instagram-mcp-ai". With"source": "./"
Claude Code copied the whole repo into its plugin cache and rannpm cion the
rootpackage.json, about 88 MB of dev dependencies per install. The plugin
directory holds nopackage.json, so the cached copy is a few kilobytes.
/plugin marketplace add IvanBBaev/instagram-mcpis unchanged. -
Migrated to MCP TypeScript SDK v2 (
npx @modelcontextprotocol/codemod v1-to-v2
plus hand fixes). Runtime dependencies:@modelcontextprotocol/sdk1.x is
replaced by@modelcontextprotocol/serverand@modelcontextprotocol/node
(the Node HTTP adapter for Streamable HTTP), andzodgoes from 3 to 4. The
tool names, profiles, arguments and output fields are unchanged. User-visible
in the publishedtools/listschemas:$schemais now JSON Schema draft
2020-12 (was draft-07); integer fields with no declared bound advertise the
safe-integer range asminimum/maximum; open (passthrough) objects publish
additionalProperties: {}instead oftrue; record-shaped fields add
propertyNames: {"type": "string"}; the recursive comment shape is published
once under$defsand referenced by$ref; and theuserTagsitem object no
longer advertisesadditionalProperties: false(unknown keys in a tag were,
and still are, dropped rather than rejected). Input-validation messages now use
zod 4's wording (e.g.Invalid input: expected string, received number). -
A bare
IG_TOKEN_EXPIRES_ATrecord (<seconds>with no token fingerprint) is
still read, buttoken_statusanddoctornow report it as unverified in every
dated state,validandneverincluded, instead of presenting it as a fact
about the current token (CC-AUTH-70). -
The Path A expiry note now reads "This is the expiry
login/refreshrecorded
in … for this token." -
A JSON text block now has key-name masking too: an
access_tokenvalue that
was masked only instructuredContentis now[REDACTED]in the text as well
(CC-DATA-104). -
summarizeDataAccessExpiryinsrc/api/account.tsis the one place that reads
data_access_expires_at, and bothtoken_statusanddoctoruse it, so the two
diagnostics cannot disagree (CC-AUTH-77). -
README lists the
--app-id/--app-secretlogin options;docs/auth.md§2 links the setup guide instead of a "future README". -
A still-image URL field (feed image, story image, reel cover) whose URL ends in
a video extension now draws its own warning ("suggests a video, but this field
takes a still image") instead of the non-JPEG one (CC-PUB-23). -
instagram_post_image,instagram_post_reelandinstagram_post_storyreturn
their warnings aswarningson every applied result (published,
already_published,in_progress), not only in the preview (CC-PUB-25). -
A relative config directory now resolves against the config home, not the
process working directory (CC-CFG-11). -
The untrusted-text renderer blanks invisible renderers in its visible-text view
(CC-DATA-126), and a fenced block defangs near-miss delimiters to⟦…⟧instead
of the old[ /UNTRUSTED]rewrite (CC-DATA-125). -
The error-text token stripper and the secret redactor now share one set of
token-shape backstops (src/core/token-shapes.ts) (CC-PROC-19). -
instagram_set_comments_enabledbelongs to thecommentspackage instead of
media, so package allow, deny and read-only selection treat it as a comments
tool (CC-PROC-9). -
instagram_discover_businesspublishesidas required. A profile-less answer,
or a profile without a usable id, is now anupstreamerror instead of a
note-only or id-less result (CC-DATA-32, supersedes CC-DATA-79). -
The
mediaAfterdescription states that a cursor taken from a different
username is not detected (CC-DATA-133).
Removed
- The unused
text()result builder insrc/mcp/result.ts; every tool result is
JSON (CC-DATA-114). - The unused
needsRefreshhelper incore/refresh.ts; refresh stays
operator-driven (CC-AUTH-67).
Fixed
- Redaction of the
loginfailure line, stray expiry records, and missing
quota_usageno longer read as 0 — seedocs/corner-cases.mdaudit waves 5–7. - A single-page listing (
list_media,list_stories,list_comments,
list_tagged_media,get_hashtag_media) that Instagram answers with the same
cursor it was sent now reportstruncated: truewith the same-cursor note the
fetchAllwalk uses, instead of offering that cursor as the next page and
inviting an endless re-read of one page (CC-DATA-134). instagram_get_account_insightswithmetric_type: "time_series"now defaults to
reach, the only account metric Instagram serves as a time series, and refuses
any other metric with it before a call; a baretime_seriesused to request all
eleven metrics and always fail (CC-INS-25).instagram_get_account_insightsnow refuses asinceafteruntilinstead of
forwarding the inverted window (CC-INS-26).instagram_get_audience_demographicsnow sendsperiod=lifetime, which Meta
marks required (CC-INS-27).loginno longer waits forever on a token endpoint that accepts the connection
and never answers: each OAuth exchange now has the same 30 s timeout as
refresh(CC-AUTH-72).loginno longer follows a redirect from a token endpoint. A 307/308 on the
Instagram code exchange used to re-send the app secret and the authorization
code to the redirect target; likerefresh, it now fails instead
(CC-AUTH-73).- A
Retry-Aftervalue that is neither delta-seconds nor an IMF-fixdate (1.5,
-1,+5,60,) now falls back to exponential backoff. V8 read these as
dates in 2001 or 1960, so the retry fired with no delay (CC-RATE-17). - A media URL (
imageUrls,imageUrl,videoUrl,coverUrl) containing a
control character is refused as not a well-formed https URL. The parser silently
dropped a trailing newline or a tab/LF inside the host, so the URL was judged
valid while the raw string, sent to Graph unchanged, named a different host
(CC-PUB-57). IG_PRETTY_JSON=truenow pretty-prints the text block of every tool, and of the
write gate's preview and refusal results; 25 of the 28 tools used to ignore it
(CC-DATA-30, CC-DATA-112).token_statusno longer reports a Path Bdata_access_expires_atof0as a
data-access window that closed in 1970;dataAccessExpiresAtis absent, as when
Meta omits the field (CC-DATA-113).loginandrefreshrecord the expiry when Meta quotesexpires_inas a
canonical non-negative integer string; any other string still leaves no record
(CC-AUTH-69).- A Path B
debug_tokenexpires_atoutside th...
v0.7.0 — first published release
First published release of instagram-mcp-ai, an MCP server for the Instagram Graph API.
0.7.0 rather than 0.1.0 because the feature surface is complete. What separates it from 1.0.0 is validation against live accounts, not missing functionality.
What's in it
- 28 tools across five packages — account, media, insights, publishing, comments, plus Facebook-login-only discovery. Package profiles:
core(25, default),reader(15),publisher(21),all(28). - Both auth paths — Instagram Login (
graph.instagram.com) and Facebook Login (graph.facebook.com, withappsecret_proof). Graph API pinned tov25.0. - Write gate — every write is preview-by-default and needs
applyto execute; irreversible deletes are double-gated;media_publishis never auto-retried. - CLI —
login(loopback OAuth with a checkedstate),doctor(token validity, scope inventory, publishing quota, usage headroom, app mode),refresh. - Transports — stdio by default with stdout purity guarded, plus an opt-in loopback-bound Streamable HTTP transport with a constant-time bearer check.
- Security — hard SSRF host allowlist, secret redaction covering runtime-minted tokens and
appsecret_proofHMACs, and a prompt-injection fence around all untrusted Instagram content.
Quality
1248 offline tests, 100% line/branch/function/statement coverage, and fifteen modules driven to full mutation kill — every surviving mutant either killed by a behavioural assertion or documented in source as provably unobservable. Zero advisories in the runtime dependency tree.
Known limitation
No tool has been exercised against a live Instagram account by CI. The suite is offline by construction, so what is proven is behaviour against recorded Graph shapes, not against Meta's live responses.
Install
npx instagram-mcp-ai@0.7.0
See docs/setup-guide.md for Meta app configuration.