@praise25/meta-mcp-server 0.1.0

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 (103) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +292 -0
  3. package/dist/config.d.ts +15 -0
  4. package/dist/config.js +46 -0
  5. package/dist/constants.d.ts +21 -0
  6. package/dist/constants.js +28 -0
  7. package/dist/context.d.ts +9 -0
  8. package/dist/context.js +8 -0
  9. package/dist/errors.d.ts +41 -0
  10. package/dist/errors.js +90 -0
  11. package/dist/helpers/cache.d.ts +6 -0
  12. package/dist/helpers/cache.js +28 -0
  13. package/dist/helpers/format.d.ts +17 -0
  14. package/dist/helpers/format.js +28 -0
  15. package/dist/helpers/graph-client.d.ts +56 -0
  16. package/dist/helpers/graph-client.js +169 -0
  17. package/dist/helpers/schema.d.ts +30 -0
  18. package/dist/helpers/schema.js +69 -0
  19. package/dist/index.d.ts +2 -0
  20. package/dist/index.js +36 -0
  21. package/dist/logger.d.ts +3 -0
  22. package/dist/logger.js +18 -0
  23. package/dist/server.d.ts +7 -0
  24. package/dist/server.js +14 -0
  25. package/dist/tools/ads/get-account.d.ts +29 -0
  26. package/dist/tools/ads/get-account.js +45 -0
  27. package/dist/tools/ads/get-creative.d.ts +29 -0
  28. package/dist/tools/ads/get-creative.js +37 -0
  29. package/dist/tools/ads/get-insights.d.ts +129 -0
  30. package/dist/tools/ads/get-insights.js +151 -0
  31. package/dist/tools/ads/list-accounts.d.ts +54 -0
  32. package/dist/tools/ads/list-accounts.js +59 -0
  33. package/dist/tools/ads/list-ads.d.ts +53 -0
  34. package/dist/tools/ads/list-ads.js +59 -0
  35. package/dist/tools/ads/list-adsets.d.ts +49 -0
  36. package/dist/tools/ads/list-adsets.js +54 -0
  37. package/dist/tools/ads/list-campaigns.d.ts +45 -0
  38. package/dist/tools/ads/list-campaigns.js +64 -0
  39. package/dist/tools/ads/list-custom-audiences.d.ts +41 -0
  40. package/dist/tools/ads/list-custom-audiences.js +41 -0
  41. package/dist/tools/business/list-assets.d.ts +37 -0
  42. package/dist/tools/business/list-assets.js +136 -0
  43. package/dist/tools/business/list-businesses.d.ts +37 -0
  44. package/dist/tools/business/list-businesses.js +81 -0
  45. package/dist/tools/business/list-system-users.d.ts +41 -0
  46. package/dist/tools/business/list-system-users.js +73 -0
  47. package/dist/tools/catalog/get-diagnostics.d.ts +29 -0
  48. package/dist/tools/catalog/get-diagnostics.js +26 -0
  49. package/dist/tools/catalog/list-products.d.ts +45 -0
  50. package/dist/tools/catalog/list-products.js +49 -0
  51. package/dist/tools/catalog/list.d.ts +54 -0
  52. package/dist/tools/catalog/list.js +48 -0
  53. package/dist/tools/instagram/get-account.d.ts +29 -0
  54. package/dist/tools/instagram/get-account.js +34 -0
  55. package/dist/tools/instagram/get-audience-demographics.d.ts +41 -0
  56. package/dist/tools/instagram/get-audience-demographics.js +46 -0
  57. package/dist/tools/instagram/get-media-insights.d.ts +29 -0
  58. package/dist/tools/instagram/get-media-insights.js +43 -0
  59. package/dist/tools/instagram/list-accounts.d.ts +33 -0
  60. package/dist/tools/instagram/list-accounts.js +63 -0
  61. package/dist/tools/instagram/list-media.d.ts +41 -0
  62. package/dist/tools/instagram/list-media.js +42 -0
  63. package/dist/tools/meta/graph-read.d.ts +33 -0
  64. package/dist/tools/meta/graph-read.js +71 -0
  65. package/dist/tools/overview/business-overview.d.ts +49 -0
  66. package/dist/tools/overview/business-overview.js +188 -0
  67. package/dist/tools/pages/get-insights.d.ts +41 -0
  68. package/dist/tools/pages/get-insights.js +49 -0
  69. package/dist/tools/pages/get-post-insights.d.ts +29 -0
  70. package/dist/tools/pages/get-post-insights.js +36 -0
  71. package/dist/tools/pages/get.d.ts +29 -0
  72. package/dist/tools/pages/get.js +50 -0
  73. package/dist/tools/pages/list-posts.d.ts +53 -0
  74. package/dist/tools/pages/list-posts.js +54 -0
  75. package/dist/tools/pages/list-reviews.d.ts +41 -0
  76. package/dist/tools/pages/list-reviews.js +37 -0
  77. package/dist/tools/pages/list-videos.d.ts +41 -0
  78. package/dist/tools/pages/list-videos.js +40 -0
  79. package/dist/tools/pages/list.d.ts +41 -0
  80. package/dist/tools/pages/list.js +39 -0
  81. package/dist/tools/pixels/get-stats.d.ts +41 -0
  82. package/dist/tools/pixels/get-stats.js +34 -0
  83. package/dist/tools/pixels/list.d.ts +41 -0
  84. package/dist/tools/pixels/list.js +38 -0
  85. package/dist/tools/register.d.ts +3 -0
  86. package/dist/tools/register.js +82 -0
  87. package/dist/tools/shared.d.ts +20 -0
  88. package/dist/tools/shared.js +55 -0
  89. package/dist/tools/token/health.d.ts +17 -0
  90. package/dist/tools/token/health.js +59 -0
  91. package/dist/tools/token/inspect.d.ts +26 -0
  92. package/dist/tools/token/inspect.js +88 -0
  93. package/dist/tools/whatsapp/get-analytics.d.ts +57 -0
  94. package/dist/tools/whatsapp/get-analytics.js +66 -0
  95. package/dist/tools/whatsapp/list-phone-numbers.d.ts +41 -0
  96. package/dist/tools/whatsapp/list-phone-numbers.js +35 -0
  97. package/dist/tools/whatsapp/list-templates.d.ts +45 -0
  98. package/dist/tools/whatsapp/list-templates.js +44 -0
  99. package/dist/tools/whatsapp/list-wabas.d.ts +54 -0
  100. package/dist/tools/whatsapp/list-wabas.js +48 -0
  101. package/dist/types/meta.d.ts +46 -0
  102. package/dist/types/meta.js +1 -0
  103. package/package.json +74 -0
@@ -0,0 +1,49 @@
1
+ import { z } from "zod";
2
+ import { metaIdSchema, paginationShape } from "../../helpers/schema.js";
3
+ import { runList } from "../shared.js";
4
+ export const inputSchema = z
5
+ .object({
6
+ catalog_id: metaIdSchema,
7
+ fields: z
8
+ .array(z.string())
9
+ .default([
10
+ "id",
11
+ "retailer_id",
12
+ "name",
13
+ "description",
14
+ "price",
15
+ "currency",
16
+ "availability",
17
+ "condition",
18
+ "brand",
19
+ "category",
20
+ "url",
21
+ "image_url",
22
+ "review_status",
23
+ ])
24
+ .describe("Product fields."),
25
+ filter: z
26
+ .string()
27
+ .optional()
28
+ .describe("JSON filter string, e.g. '{\"availability\":{\"eq\":\"out of stock\"}}'"),
29
+ ...paginationShape,
30
+ })
31
+ .strict();
32
+ export const definition = {
33
+ name: "meta_catalog_list_products",
34
+ title: "List products in a catalog",
35
+ description: `Lists products with name, retailer_id, price, availability, review_status. Filter by availability/category via the 'filter' param (raw JSON string per Meta spec).`,
36
+ inputSchema: inputSchema.shape,
37
+ annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
38
+ };
39
+ export async function handler(input, ctx) {
40
+ return runList(ctx, {
41
+ path: `${input.catalog_id}/products`,
42
+ params: {
43
+ fields: input.fields.join(","),
44
+ limit: input.limit,
45
+ after: input.after,
46
+ filter: input.filter,
47
+ },
48
+ }, { auto_paginate: input.auto_paginate, after: input.after, limit: input.limit }, { catalog_id: input.catalog_id });
49
+ }
@@ -0,0 +1,54 @@
1
+ import { z } from "zod";
2
+ import type { ToolContext } from "../../context.js";
3
+ export declare const inputSchema: z.ZodObject<{
4
+ limit: z.ZodDefault<z.ZodNumber>;
5
+ after: z.ZodOptional<z.ZodString>;
6
+ auto_paginate: z.ZodDefault<z.ZodBoolean>;
7
+ business_id: z.ZodString;
8
+ scope: z.ZodDefault<z.ZodEnum<["owned", "client", "both"]>>;
9
+ fields: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
10
+ }, "strict", z.ZodTypeAny, {
11
+ fields: string[];
12
+ limit: number;
13
+ auto_paginate: boolean;
14
+ business_id: string;
15
+ scope: "owned" | "client" | "both";
16
+ after?: string | undefined;
17
+ }, {
18
+ business_id: string;
19
+ fields?: string[] | undefined;
20
+ limit?: number | undefined;
21
+ after?: string | undefined;
22
+ auto_paginate?: boolean | undefined;
23
+ scope?: "owned" | "client" | "both" | undefined;
24
+ }>;
25
+ export type Input = z.infer<typeof inputSchema>;
26
+ export declare const definition: {
27
+ readonly name: "meta_catalog_list";
28
+ readonly title: "List commerce catalogs under a business";
29
+ readonly description: "Lists product catalogs. Needs the Commerce / Catalog Management product added to the app and 'catalog_management' on the token.";
30
+ readonly inputSchema: {
31
+ limit: z.ZodDefault<z.ZodNumber>;
32
+ after: z.ZodOptional<z.ZodString>;
33
+ auto_paginate: z.ZodDefault<z.ZodBoolean>;
34
+ business_id: z.ZodString;
35
+ scope: z.ZodDefault<z.ZodEnum<["owned", "client", "both"]>>;
36
+ fields: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
37
+ };
38
+ readonly annotations: {
39
+ readonly readOnlyHint: true;
40
+ readonly destructiveHint: false;
41
+ readonly idempotentHint: true;
42
+ readonly openWorldHint: true;
43
+ };
44
+ };
45
+ export declare function handler(input: Input, ctx: ToolContext): Promise<{
46
+ content: {
47
+ type: "text";
48
+ text: string;
49
+ }[];
50
+ structuredContent: {
51
+ business_id: string;
52
+ sections: Record<string, unknown>[];
53
+ };
54
+ }>;
@@ -0,0 +1,48 @@
1
+ import { z } from "zod";
2
+ import { assertAllowed } from "../../config.js";
3
+ import { metaIdSchema, paginationShape } from "../../helpers/schema.js";
4
+ import { runList } from "../shared.js";
5
+ export const inputSchema = z
6
+ .object({
7
+ business_id: metaIdSchema,
8
+ scope: z.enum(["owned", "client", "both"]).default("owned"),
9
+ fields: z
10
+ .array(z.string())
11
+ .default([
12
+ "id",
13
+ "name",
14
+ "vertical",
15
+ "product_count",
16
+ "business",
17
+ "is_catalog_segment",
18
+ "feed_count",
19
+ ])
20
+ .describe("Catalog fields."),
21
+ ...paginationShape,
22
+ })
23
+ .strict();
24
+ export const definition = {
25
+ name: "meta_catalog_list",
26
+ title: "List commerce catalogs under a business",
27
+ description: `Lists product catalogs. Needs the Commerce / Catalog Management product added to the app and 'catalog_management' on the token.`,
28
+ inputSchema: inputSchema.shape,
29
+ annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
30
+ };
31
+ export async function handler(input, ctx) {
32
+ assertAllowed("business", input.business_id, ctx.config);
33
+ const edges = input.scope === "both"
34
+ ? ["owned_product_catalogs", "client_product_catalogs"]
35
+ : [`${input.scope}_product_catalogs`];
36
+ const sections = [];
37
+ for (const edge of edges) {
38
+ const r = await runList(ctx, {
39
+ path: `${input.business_id}/${edge}`,
40
+ params: { fields: input.fields.join(","), limit: input.limit, after: input.after },
41
+ }, { auto_paginate: input.auto_paginate, after: input.after, limit: input.limit }, { edge });
42
+ sections.push(r.structuredContent ?? { edge, error: "no data" });
43
+ }
44
+ return {
45
+ content: [{ type: "text", text: JSON.stringify({ business_id: input.business_id, sections }, null, 2) }],
46
+ structuredContent: { business_id: input.business_id, sections },
47
+ };
48
+ }
@@ -0,0 +1,29 @@
1
+ import { z } from "zod";
2
+ import type { ToolContext } from "../../context.js";
3
+ export declare const inputSchema: z.ZodObject<{
4
+ ig_user_id: z.ZodString;
5
+ fields: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
6
+ }, "strict", z.ZodTypeAny, {
7
+ fields: string[];
8
+ ig_user_id: string;
9
+ }, {
10
+ ig_user_id: string;
11
+ fields?: string[] | undefined;
12
+ }>;
13
+ export type Input = z.infer<typeof inputSchema>;
14
+ export declare const definition: {
15
+ readonly name: "meta_ig_get_account";
16
+ readonly title: "Get Instagram Business account profile";
17
+ readonly description: "Reads username, name, bio, website, follower/following counts, media_count, profile picture for an IG Business account.";
18
+ readonly inputSchema: {
19
+ ig_user_id: z.ZodString;
20
+ fields: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
21
+ };
22
+ readonly annotations: {
23
+ readonly readOnlyHint: true;
24
+ readonly destructiveHint: false;
25
+ readonly idempotentHint: true;
26
+ readonly openWorldHint: true;
27
+ };
28
+ };
29
+ export declare function handler(input: Input, ctx: ToolContext): Promise<import("../../helpers/format.js").ToolTextResult>;
@@ -0,0 +1,34 @@
1
+ import { z } from "zod";
2
+ import { assertAllowed } from "../../config.js";
3
+ import { metaIdSchema } from "../../helpers/schema.js";
4
+ import { runGet } from "../shared.js";
5
+ export const inputSchema = z
6
+ .object({
7
+ ig_user_id: metaIdSchema.describe("Instagram Business Account ID (from meta_ig_list_accounts)."),
8
+ fields: z
9
+ .array(z.string())
10
+ .default([
11
+ "id",
12
+ "username",
13
+ "name",
14
+ "biography",
15
+ "website",
16
+ "followers_count",
17
+ "follows_count",
18
+ "media_count",
19
+ "profile_picture_url",
20
+ ])
21
+ .describe("IG account profile fields."),
22
+ })
23
+ .strict();
24
+ export const definition = {
25
+ name: "meta_ig_get_account",
26
+ title: "Get Instagram Business account profile",
27
+ description: `Reads username, name, bio, website, follower/following counts, media_count, profile picture for an IG Business account.`,
28
+ inputSchema: inputSchema.shape,
29
+ annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
30
+ };
31
+ export async function handler(input, ctx) {
32
+ assertAllowed("ig_user", input.ig_user_id, ctx.config);
33
+ return runGet(ctx, { path: input.ig_user_id, params: { fields: input.fields.join(",") } });
34
+ }
@@ -0,0 +1,41 @@
1
+ import { z } from "zod";
2
+ import type { ToolContext } from "../../context.js";
3
+ export declare const inputSchema: z.ZodObject<{
4
+ ig_user_id: z.ZodString;
5
+ metric: z.ZodDefault<z.ZodEnum<["follower_demographics", "engaged_audience_demographics", "reached_audience_demographics"]>>;
6
+ breakdown: z.ZodDefault<z.ZodEnum<["age", "gender", "country", "city", "audience_city"]>>;
7
+ metric_type: z.ZodDefault<z.ZodEnum<["total_value", "time_series"]>>;
8
+ timeframe: z.ZodDefault<z.ZodEnum<["last_14_days", "last_30_days", "last_90_days", "prev_month", "this_month", "this_week"]>>;
9
+ }, "strict", z.ZodTypeAny, {
10
+ metric: "follower_demographics" | "engaged_audience_demographics" | "reached_audience_demographics";
11
+ ig_user_id: string;
12
+ breakdown: "age" | "gender" | "country" | "city" | "audience_city";
13
+ metric_type: "total_value" | "time_series";
14
+ timeframe: "this_month" | "last_14_days" | "last_30_days" | "last_90_days" | "prev_month" | "this_week";
15
+ }, {
16
+ ig_user_id: string;
17
+ metric?: "follower_demographics" | "engaged_audience_demographics" | "reached_audience_demographics" | undefined;
18
+ breakdown?: "age" | "gender" | "country" | "city" | "audience_city" | undefined;
19
+ metric_type?: "total_value" | "time_series" | undefined;
20
+ timeframe?: "this_month" | "last_14_days" | "last_30_days" | "last_90_days" | "prev_month" | "this_week" | undefined;
21
+ }>;
22
+ export type Input = z.infer<typeof inputSchema>;
23
+ export declare const definition: {
24
+ readonly name: "meta_ig_get_audience_demographics";
25
+ readonly title: "Get IG audience demographics";
26
+ readonly description: "Reads demographic breakdown of an IG Business account's followers, engaged audience, or reached audience. Use breakdown='age'|'gender'|'country'|'city' to slice.\n\nRequires 'instagram_manage_insights'. Only IG Business accounts with at least 100 followers return data — below that threshold Meta returns empty results for privacy.";
27
+ readonly inputSchema: {
28
+ ig_user_id: z.ZodString;
29
+ metric: z.ZodDefault<z.ZodEnum<["follower_demographics", "engaged_audience_demographics", "reached_audience_demographics"]>>;
30
+ breakdown: z.ZodDefault<z.ZodEnum<["age", "gender", "country", "city", "audience_city"]>>;
31
+ metric_type: z.ZodDefault<z.ZodEnum<["total_value", "time_series"]>>;
32
+ timeframe: z.ZodDefault<z.ZodEnum<["last_14_days", "last_30_days", "last_90_days", "prev_month", "this_month", "this_week"]>>;
33
+ };
34
+ readonly annotations: {
35
+ readonly readOnlyHint: true;
36
+ readonly destructiveHint: false;
37
+ readonly idempotentHint: true;
38
+ readonly openWorldHint: true;
39
+ };
40
+ };
41
+ export declare function handler(input: Input, ctx: ToolContext): Promise<import("../../helpers/format.js").ToolTextResult>;
@@ -0,0 +1,46 @@
1
+ import { z } from "zod";
2
+ import { assertAllowed } from "../../config.js";
3
+ import { metaIdSchema } from "../../helpers/schema.js";
4
+ import { runGet } from "../shared.js";
5
+ const METRIC_TYPE = z.enum(["total_value", "time_series"]);
6
+ const BREAKDOWN = z.enum(["age", "gender", "country", "city", "audience_city"]);
7
+ export const inputSchema = z
8
+ .object({
9
+ ig_user_id: metaIdSchema,
10
+ metric: z
11
+ .enum([
12
+ "follower_demographics",
13
+ "engaged_audience_demographics",
14
+ "reached_audience_demographics",
15
+ ])
16
+ .default("follower_demographics")
17
+ .describe("Which audience cohort."),
18
+ breakdown: BREAKDOWN.default("age").describe("Demographic dimension."),
19
+ metric_type: METRIC_TYPE.default("total_value"),
20
+ timeframe: z
21
+ .enum(["last_14_days", "last_30_days", "last_90_days", "prev_month", "this_month", "this_week"])
22
+ .default("last_30_days")
23
+ .describe("Required for demographics metrics."),
24
+ })
25
+ .strict();
26
+ export const definition = {
27
+ name: "meta_ig_get_audience_demographics",
28
+ title: "Get IG audience demographics",
29
+ description: `Reads demographic breakdown of an IG Business account's followers, engaged audience, or reached audience. Use breakdown='age'|'gender'|'country'|'city' to slice.
30
+
31
+ Requires 'instagram_manage_insights'. Only IG Business accounts with at least 100 followers return data — below that threshold Meta returns empty results for privacy.`,
32
+ inputSchema: inputSchema.shape,
33
+ annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
34
+ };
35
+ export async function handler(input, ctx) {
36
+ assertAllowed("ig_user", input.ig_user_id, ctx.config);
37
+ return runGet(ctx, {
38
+ path: `${input.ig_user_id}/insights`,
39
+ params: {
40
+ metric: input.metric,
41
+ breakdown: input.breakdown,
42
+ metric_type: input.metric_type,
43
+ timeframe: input.timeframe,
44
+ },
45
+ });
46
+ }
@@ -0,0 +1,29 @@
1
+ import { z } from "zod";
2
+ import type { ToolContext } from "../../context.js";
3
+ export declare const inputSchema: z.ZodObject<{
4
+ media_id: z.ZodString;
5
+ metrics: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
6
+ }, "strict", z.ZodTypeAny, {
7
+ metrics: string[];
8
+ media_id: string;
9
+ }, {
10
+ media_id: string;
11
+ metrics?: string[] | undefined;
12
+ }>;
13
+ export type Input = z.infer<typeof inputSchema>;
14
+ export declare const definition: {
15
+ readonly name: "meta_ig_get_media_insights";
16
+ readonly title: "Get Instagram media insights";
17
+ readonly description: "Per-media metrics: reach, impressions, saves, likes, comments, shares, profile visits, follows-from-post. Requires 'instagram_manage_insights' scope.\n\nDifferent media types support different metric sets:\n- IMAGE/CAROUSEL_ALBUM: impressions, reach, saved, likes, comments, shares, profile_visits\n- VIDEO (Reels): plays, reach, likes, comments, shares, saved, total_interactions\n- STORY: impressions, reach, replies, exits, taps_forward, taps_back (use meta_ig_get_story_insights-style metrics)\n\nIf a metric is unsupported for the media type, Meta returns code 100 — retry with a narrower metric list.";
18
+ readonly inputSchema: {
19
+ media_id: z.ZodString;
20
+ metrics: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
21
+ };
22
+ readonly annotations: {
23
+ readonly readOnlyHint: true;
24
+ readonly destructiveHint: false;
25
+ readonly idempotentHint: true;
26
+ readonly openWorldHint: true;
27
+ };
28
+ };
29
+ export declare function handler(input: Input, ctx: ToolContext): Promise<import("../../helpers/format.js").ToolTextResult>;
@@ -0,0 +1,43 @@
1
+ import { z } from "zod";
2
+ import { metaIdSchema } from "../../helpers/schema.js";
3
+ import { runGet } from "../shared.js";
4
+ export const inputSchema = z
5
+ .object({
6
+ media_id: metaIdSchema.describe("IG media ID."),
7
+ metrics: z
8
+ .array(z.string())
9
+ .default([
10
+ "impressions",
11
+ "reach",
12
+ "saved",
13
+ "likes",
14
+ "comments",
15
+ "shares",
16
+ "total_interactions",
17
+ "profile_visits",
18
+ "follows",
19
+ "profile_activity",
20
+ ])
21
+ .describe("IG media metrics. For Reels prefer 'plays, reach, likes, comments, shares, saved, total_interactions'. Some metrics are media_type-specific — if a metric isn't supported for the media type, Meta returns an error."),
22
+ })
23
+ .strict();
24
+ export const definition = {
25
+ name: "meta_ig_get_media_insights",
26
+ title: "Get Instagram media insights",
27
+ description: `Per-media metrics: reach, impressions, saves, likes, comments, shares, profile visits, follows-from-post. Requires 'instagram_manage_insights' scope.
28
+
29
+ Different media types support different metric sets:
30
+ - IMAGE/CAROUSEL_ALBUM: impressions, reach, saved, likes, comments, shares, profile_visits
31
+ - VIDEO (Reels): plays, reach, likes, comments, shares, saved, total_interactions
32
+ - STORY: impressions, reach, replies, exits, taps_forward, taps_back (use meta_ig_get_story_insights-style metrics)
33
+
34
+ If a metric is unsupported for the media type, Meta returns code 100 — retry with a narrower metric list.`,
35
+ inputSchema: inputSchema.shape,
36
+ annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
37
+ };
38
+ export async function handler(input, ctx) {
39
+ return runGet(ctx, {
40
+ path: `${input.media_id}/insights`,
41
+ params: { metric: input.metrics.join(",") },
42
+ });
43
+ }
@@ -0,0 +1,33 @@
1
+ import { z } from "zod";
2
+ import type { ToolContext } from "../../context.js";
3
+ export declare const inputSchema: z.ZodObject<{
4
+ limit: z.ZodDefault<z.ZodNumber>;
5
+ after: z.ZodOptional<z.ZodString>;
6
+ auto_paginate: z.ZodDefault<z.ZodBoolean>;
7
+ }, "strict", z.ZodTypeAny, {
8
+ limit: number;
9
+ auto_paginate: boolean;
10
+ after?: string | undefined;
11
+ }, {
12
+ limit?: number | undefined;
13
+ after?: string | undefined;
14
+ auto_paginate?: boolean | undefined;
15
+ }>;
16
+ export type Input = z.infer<typeof inputSchema>;
17
+ export declare const definition: {
18
+ readonly name: "meta_ig_list_accounts";
19
+ readonly title: "List Instagram Business accounts reachable via Pages";
20
+ readonly description: "Walks the Pages visible to the token (/me/assigned_pages) and, for each, resolves the linked Instagram Business account via 'instagram_business_account'. This is the modern discovery path — the /owned_instagram_accounts business edge is unreliable.\n\nRequires 'instagram_basic' scope on the token and 'Analyze Instagram account' task on each IG.";
21
+ readonly inputSchema: {
22
+ limit: z.ZodDefault<z.ZodNumber>;
23
+ after: z.ZodOptional<z.ZodString>;
24
+ auto_paginate: z.ZodDefault<z.ZodBoolean>;
25
+ };
26
+ readonly annotations: {
27
+ readonly readOnlyHint: true;
28
+ readonly destructiveHint: false;
29
+ readonly idempotentHint: true;
30
+ readonly openWorldHint: true;
31
+ };
32
+ };
33
+ export declare function handler(input: Input, ctx: ToolContext): Promise<import("../../helpers/format.js").ToolTextResult>;
@@ -0,0 +1,63 @@
1
+ import { z } from "zod";
2
+ import { MetaError } from "../../errors.js";
3
+ import { jsonBlock, toolError, toolResult } from "../../helpers/format.js";
4
+ import { paginationShape } from "../../helpers/schema.js";
5
+ export const inputSchema = z
6
+ .object({
7
+ ...paginationShape,
8
+ })
9
+ .strict();
10
+ export const definition = {
11
+ name: "meta_ig_list_accounts",
12
+ title: "List Instagram Business accounts reachable via Pages",
13
+ description: `Walks the Pages visible to the token (/me/assigned_pages) and, for each, resolves the linked Instagram Business account via 'instagram_business_account'. This is the modern discovery path — the /owned_instagram_accounts business edge is unreliable.
14
+
15
+ Requires 'instagram_basic' scope on the token and 'Analyze Instagram account' task on each IG.`,
16
+ inputSchema: inputSchema.shape,
17
+ annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
18
+ };
19
+ export async function handler(input, ctx) {
20
+ try {
21
+ // First, list the pages assigned to the token.
22
+ const pagesPage = await ctx.graph.get({
23
+ path: "me/assigned_pages",
24
+ params: { fields: "id,name", limit: input.limit, after: input.after },
25
+ });
26
+ const pages = Array.isArray(pagesPage.data) ? pagesPage.data : [];
27
+ // Resolve IG in parallel.
28
+ const results = await Promise.all(pages.map(async (p) => {
29
+ try {
30
+ const d = await ctx.graph.get({
31
+ path: p.id,
32
+ params: { fields: "id,name,instagram_business_account{id,username,name}" },
33
+ });
34
+ return {
35
+ page_id: p.id,
36
+ page_name: p.name,
37
+ instagram_business_account: d.instagram_business_account ?? null,
38
+ };
39
+ }
40
+ catch (err) {
41
+ const e = err instanceof MetaError ? err : new MetaError(err.message);
42
+ return { page_id: p.id, page_name: p.name, error: e.message, hint: e.hint };
43
+ }
44
+ }));
45
+ const linked = results.filter((r) => "instagram_business_account" in r && r.instagram_business_account);
46
+ const structured = {
47
+ pages_scanned: pages.length,
48
+ ig_accounts_found: linked.length,
49
+ links: results,
50
+ next_after: pagesPage.paging?.cursors?.after,
51
+ };
52
+ return toolResult(structured, jsonBlock(structured));
53
+ }
54
+ catch (err) {
55
+ const e = err instanceof MetaError ? err : new MetaError(err.message);
56
+ return toolError(e.message, e.hint, {
57
+ code: e.code,
58
+ subcode: e.subcode,
59
+ fbtrace_id: e.fbtraceId,
60
+ http_status: e.httpStatus,
61
+ });
62
+ }
63
+ }
@@ -0,0 +1,41 @@
1
+ import { z } from "zod";
2
+ import type { ToolContext } from "../../context.js";
3
+ export declare const inputSchema: z.ZodObject<{
4
+ limit: z.ZodDefault<z.ZodNumber>;
5
+ after: z.ZodOptional<z.ZodString>;
6
+ auto_paginate: z.ZodDefault<z.ZodBoolean>;
7
+ ig_user_id: z.ZodString;
8
+ fields: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
9
+ }, "strict", z.ZodTypeAny, {
10
+ fields: string[];
11
+ limit: number;
12
+ auto_paginate: boolean;
13
+ ig_user_id: string;
14
+ after?: string | undefined;
15
+ }, {
16
+ ig_user_id: string;
17
+ fields?: string[] | undefined;
18
+ limit?: number | undefined;
19
+ after?: string | undefined;
20
+ auto_paginate?: boolean | undefined;
21
+ }>;
22
+ export type Input = z.infer<typeof inputSchema>;
23
+ export declare const definition: {
24
+ readonly name: "meta_ig_list_media";
25
+ readonly title: "List Instagram media (posts, reels, stories)";
26
+ readonly description: "Lists media posted by an IG Business account. Includes caption, permalink, timestamp, like/comment counts. For per-media metrics (reach, impressions, saves, plays), pass each ID to meta_ig_get_media_insights.";
27
+ readonly inputSchema: {
28
+ limit: z.ZodDefault<z.ZodNumber>;
29
+ after: z.ZodOptional<z.ZodString>;
30
+ auto_paginate: z.ZodDefault<z.ZodBoolean>;
31
+ ig_user_id: z.ZodString;
32
+ fields: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
33
+ };
34
+ readonly annotations: {
35
+ readonly readOnlyHint: true;
36
+ readonly destructiveHint: false;
37
+ readonly idempotentHint: true;
38
+ readonly openWorldHint: true;
39
+ };
40
+ };
41
+ export declare function handler(input: Input, ctx: ToolContext): Promise<import("../../helpers/format.js").ToolTextResult>;
@@ -0,0 +1,42 @@
1
+ import { z } from "zod";
2
+ import { assertAllowed } from "../../config.js";
3
+ import { metaIdSchema, paginationShape } from "../../helpers/schema.js";
4
+ import { runList } from "../shared.js";
5
+ export const inputSchema = z
6
+ .object({
7
+ ig_user_id: metaIdSchema,
8
+ fields: z
9
+ .array(z.string())
10
+ .default([
11
+ "id",
12
+ "media_type",
13
+ "media_product_type",
14
+ "caption",
15
+ "media_url",
16
+ "thumbnail_url",
17
+ "permalink",
18
+ "timestamp",
19
+ "like_count",
20
+ "comments_count",
21
+ "is_comment_enabled",
22
+ "shortcode",
23
+ "owner",
24
+ ])
25
+ .describe("Media fields. For Reels add 'ig_id'; for carousels add 'children{...}'."),
26
+ ...paginationShape,
27
+ })
28
+ .strict();
29
+ export const definition = {
30
+ name: "meta_ig_list_media",
31
+ title: "List Instagram media (posts, reels, stories)",
32
+ description: `Lists media posted by an IG Business account. Includes caption, permalink, timestamp, like/comment counts. For per-media metrics (reach, impressions, saves, plays), pass each ID to meta_ig_get_media_insights.`,
33
+ inputSchema: inputSchema.shape,
34
+ annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
35
+ };
36
+ export async function handler(input, ctx) {
37
+ assertAllowed("ig_user", input.ig_user_id, ctx.config);
38
+ return runList(ctx, {
39
+ path: `${input.ig_user_id}/media`,
40
+ params: { fields: input.fields.join(","), limit: input.limit, after: input.after },
41
+ }, { auto_paginate: input.auto_paginate, after: input.after, limit: input.limit }, { ig_user_id: input.ig_user_id });
42
+ }
@@ -0,0 +1,33 @@
1
+ import { z } from "zod";
2
+ import type { ToolContext } from "../../context.js";
3
+ export declare const inputSchema: z.ZodObject<{
4
+ path: z.ZodString;
5
+ params: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<[z.ZodString, z.ZodNumber, z.ZodBoolean]>>>;
6
+ api_version: z.ZodOptional<z.ZodString>;
7
+ }, "strict", z.ZodTypeAny, {
8
+ path: string;
9
+ params?: Record<string, string | number | boolean> | undefined;
10
+ api_version?: string | undefined;
11
+ }, {
12
+ path: string;
13
+ params?: Record<string, string | number | boolean> | undefined;
14
+ api_version?: string | undefined;
15
+ }>;
16
+ export type Input = z.infer<typeof inputSchema>;
17
+ export declare const definition: {
18
+ readonly name: "meta_graph_read";
19
+ readonly title: "Arbitrary read-only Graph API call";
20
+ readonly description: "Escape-hatch for arbitrary GET requests against the Meta Graph API.\n\nThis tool exists so the assistant can reach fields and endpoints that do not yet have a dedicated tool wrapper — without ever sending a write. The underlying HTTP client is hard-wired to GET only; POST/PUT/DELETE are refused before the request leaves the process.\n\nRules:\n- Do NOT include 'access_token' or 'appsecret_proof' in params — they are added automatically.\n- Do NOT prefix the path with the API version.\n- Prefer dedicated tools (meta_business_list_assets, meta_ads_get_insights, …) when they exist. Use this as a last resort.";
21
+ readonly inputSchema: {
22
+ path: z.ZodString;
23
+ params: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<[z.ZodString, z.ZodNumber, z.ZodBoolean]>>>;
24
+ api_version: z.ZodOptional<z.ZodString>;
25
+ };
26
+ readonly annotations: {
27
+ readonly readOnlyHint: true;
28
+ readonly destructiveHint: false;
29
+ readonly idempotentHint: true;
30
+ readonly openWorldHint: true;
31
+ };
32
+ };
33
+ export declare function handler(input: Input, ctx: ToolContext): Promise<import("../../helpers/format.js").ToolTextResult>;