ig_get_media_insights
Retrieve analytics for any Instagram media post by providing its media ID. Access metrics like views, reach, saved, shares, likes, comments, reposts, and reels skip rate to evaluate post performance.
Instructions
Get insights/analytics for a specific media post. Note: 'impressions' and 'video_views' were deprecated in v22.0 — use 'views' instead. Available metrics: views, reach, saved, shares, likes, comments, reposts, reels_skip_rate.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| media_id | Yes | Media ID | |
| metric | No | Comma-separated metrics (default: views,reach,saved,shares). For REEL add: likes,comments,reposts,reels_skip_rate |
Implementation Reference
- src/tools/instagram/media.ts:67-84 (handler)The handler function for the 'ig_get_media_insights' tool. It accepts a media_id (required) and an optional metric string (default: 'views,reach,saved,shares'). It calls the Meta API GET /{media_id}/insights with the specified metrics and returns the insights data as JSON.
// ─── ig_get_media_insights ─────────────────────────────────── server.tool( "ig_get_media_insights", "Get insights/analytics for a specific media post. Note: 'impressions' and 'video_views' were deprecated in v22.0 — use 'views' instead. Available metrics: views, reach, saved, shares, likes, comments, reposts, reels_skip_rate.", { media_id: z.string().describe("Media ID"), metric: z.string().optional().describe("Comma-separated metrics (default: views,reach,saved,shares). For REEL add: likes,comments,reposts,reels_skip_rate"), }, async ({ media_id, metric }) => { try { const m = metric || "views,reach,saved,shares"; const { data, rateLimit } = await client.ig("GET", `/${media_id}/insights`, { metric: m }); return { content: [{ type: "text", text: JSON.stringify({ ...data as object, _rateLimit: rateLimit }, null, 2) }] }; } catch (error) { return { content: [{ type: "text", text: `Get media insights failed: ${error instanceof Error ? error.message : String(error)}` }], isError: true }; } } ); - src/tools/instagram/media.ts:71-74 (schema)Input schema for the tool: media_id (string, required) and metric (string, optional, description mentions default and REEL-specific metrics).
{ media_id: z.string().describe("Media ID"), metric: z.string().optional().describe("Comma-separated metrics (default: views,reach,saved,shares). For REEL add: likes,comments,reposts,reels_skip_rate"), }, - src/tools/instagram/media.ts:5-105 (registration)The tool is registered via 'server.tool("ig_get_media_insights", ...)' inside the registerIgMediaTools function, which is exported and called from src/index.ts (line 43) with the McpServer instance.
export function registerIgMediaTools(server: McpServer, client: MetaClient): void { // ─── ig_get_media_list ─────────────────────────────────────── server.tool( "ig_get_media_list", "Get list of media published on the Instagram account.", { limit: z.number().optional().describe("Number of results (max 100, default 25)"), after: z.string().optional().describe("Pagination cursor for next page"), before: z.string().optional().describe("Pagination cursor for previous page"), }, async ({ limit, after, before }) => { try { const params: Record<string, unknown> = { fields: "id,caption,media_type,media_url,permalink,thumbnail_url,timestamp,like_count,comments_count", }; if (limit) params.limit = limit; if (after) params.after = after; if (before) params.before = before; const { data, rateLimit } = await client.ig("GET", `/${client.igUserId}/media`, params); return { content: [{ type: "text", text: JSON.stringify({ ...data as object, _rateLimit: rateLimit }, null, 2) }] }; } catch (error) { return { content: [{ type: "text", text: `Get media list failed: ${error instanceof Error ? error.message : String(error)}` }], isError: true }; } } ); // ─── ig_get_media ──────────────────────────────────────────── server.tool( "ig_get_media", "Get details of a specific Instagram media post.", { media_id: z.string().describe("Media ID"), fields: z.string().optional().describe("Comma-separated fields (default: id,caption,media_type,media_url,permalink,timestamp,like_count,comments_count)"), }, async ({ media_id, fields }) => { try { const f = fields || "id,caption,media_type,media_url,permalink,thumbnail_url,timestamp,like_count,comments_count"; const { data, rateLimit } = await client.ig("GET", `/${media_id}`, { fields: f }); return { content: [{ type: "text", text: JSON.stringify({ ...data as object, _rateLimit: rateLimit }, null, 2) }] }; } catch (error) { return { content: [{ type: "text", text: `Get media failed: ${error instanceof Error ? error.message : String(error)}` }], isError: true }; } } ); // ─── ig_delete_media ───────────────────────────────────────── server.tool( "ig_delete_media", "Delete an Instagram media post (posts, carousels, reels, stories). This action is irreversible. Requires instagram_manage_contents permission.", { media_id: z.string().describe("Media ID to delete"), }, async ({ media_id }) => { try { const { data, rateLimit } = await client.ig("DELETE", `/${media_id}`); return { content: [{ type: "text", text: JSON.stringify({ success: true, ...data as object, _rateLimit: rateLimit }, null, 2) }] }; } catch (error) { return { content: [{ type: "text", text: `Delete media failed: ${error instanceof Error ? error.message : String(error)}` }], isError: true }; } } ); // ─── ig_get_media_insights ─────────────────────────────────── server.tool( "ig_get_media_insights", "Get insights/analytics for a specific media post. Note: 'impressions' and 'video_views' were deprecated in v22.0 — use 'views' instead. Available metrics: views, reach, saved, shares, likes, comments, reposts, reels_skip_rate.", { media_id: z.string().describe("Media ID"), metric: z.string().optional().describe("Comma-separated metrics (default: views,reach,saved,shares). For REEL add: likes,comments,reposts,reels_skip_rate"), }, async ({ media_id, metric }) => { try { const m = metric || "views,reach,saved,shares"; const { data, rateLimit } = await client.ig("GET", `/${media_id}/insights`, { metric: m }); return { content: [{ type: "text", text: JSON.stringify({ ...data as object, _rateLimit: rateLimit }, null, 2) }] }; } catch (error) { return { content: [{ type: "text", text: `Get media insights failed: ${error instanceof Error ? error.message : String(error)}` }], isError: true }; } } ); // ─── ig_toggle_comments ────────────────────────────────────── server.tool( "ig_toggle_comments", "Enable or disable comments on an Instagram media post.", { media_id: z.string().describe("Media ID"), enabled: z.boolean().describe("true to enable comments, false to disable"), }, async ({ media_id, enabled }) => { try { const { data, rateLimit } = await client.ig("POST", `/${media_id}`, { comment_enabled: enabled, }); return { content: [{ type: "text", text: JSON.stringify({ success: true, comment_enabled: enabled, ...data as object, _rateLimit: rateLimit }, null, 2) }] }; } catch (error) { return { content: [{ type: "text", text: `Toggle comments failed: ${error instanceof Error ? error.message : String(error)}` }], isError: true }; } } ); } - src/services/meta-client.ts:76-85 (helper)The MetaClient.ig() method is the helper that makes the actual HTTP GET request to the Facebook Graph API (v25.0). The handler calls 'client.ig("GET", `/${media_id}/insights`, { metric: m })' which builds and sends the request.
async ig( method: string, path: string, params?: Record<string, unknown> ): Promise<ClientResponse> { if (!this.config.instagramAccessToken) { throw new Error("INSTAGRAM_ACCESS_TOKEN is not configured."); } return this.request(IG_BASE, this.config.instagramAccessToken, method, path, params); }