@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,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
+ page_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
+ page_id: string;
14
+ after?: string | undefined;
15
+ }, {
16
+ page_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_page_list_reviews";
25
+ readonly title: "List Page ratings / reviews";
26
+ readonly description: "Lists ratings and reviews (where the Page supports recommendations). Requires 'pages_read_user_content' scope. Useful for sentiment analysis and customer-experience reporting.";
27
+ readonly inputSchema: {
28
+ limit: z.ZodDefault<z.ZodNumber>;
29
+ after: z.ZodOptional<z.ZodString>;
30
+ auto_paginate: z.ZodDefault<z.ZodBoolean>;
31
+ page_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,37 @@
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
+ page_id: metaIdSchema,
8
+ fields: z
9
+ .array(z.string())
10
+ .default([
11
+ "created_time",
12
+ "reviewer",
13
+ "rating",
14
+ "recommendation_type",
15
+ "review_text",
16
+ "has_rating",
17
+ "has_review",
18
+ "open_graph_story",
19
+ ])
20
+ .describe("Review fields."),
21
+ ...paginationShape,
22
+ })
23
+ .strict();
24
+ export const definition = {
25
+ name: "meta_page_list_reviews",
26
+ title: "List Page ratings / reviews",
27
+ description: `Lists ratings and reviews (where the Page supports recommendations). Requires 'pages_read_user_content' scope. Useful for sentiment analysis and customer-experience reporting.`,
28
+ inputSchema: inputSchema.shape,
29
+ annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
30
+ };
31
+ export async function handler(input, ctx) {
32
+ assertAllowed("page", input.page_id, ctx.config);
33
+ return runList(ctx, {
34
+ path: `${input.page_id}/ratings`,
35
+ params: { fields: input.fields.join(","), limit: input.limit, after: input.after },
36
+ }, { auto_paginate: input.auto_paginate, after: input.after, limit: input.limit }, { page_id: input.page_id });
37
+ }
@@ -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
+ page_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
+ page_id: string;
14
+ after?: string | undefined;
15
+ }, {
16
+ page_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_page_list_videos";
25
+ readonly title: "List Page videos";
26
+ readonly description: "Lists videos uploaded to a Page (including live broadcasts). Pair with meta_page_get_post_insights on the owning post for video-view analytics, or drill into individual video IDs for per-video metrics.";
27
+ readonly inputSchema: {
28
+ limit: z.ZodDefault<z.ZodNumber>;
29
+ after: z.ZodOptional<z.ZodString>;
30
+ auto_paginate: z.ZodDefault<z.ZodBoolean>;
31
+ page_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,40 @@
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
+ page_id: metaIdSchema,
8
+ fields: z
9
+ .array(z.string())
10
+ .default([
11
+ "id",
12
+ "title",
13
+ "description",
14
+ "created_time",
15
+ "updated_time",
16
+ "length",
17
+ "permalink_url",
18
+ "source",
19
+ "status",
20
+ "views",
21
+ "live_status",
22
+ ])
23
+ .describe("Video fields."),
24
+ ...paginationShape,
25
+ })
26
+ .strict();
27
+ export const definition = {
28
+ name: "meta_page_list_videos",
29
+ title: "List Page videos",
30
+ description: `Lists videos uploaded to a Page (including live broadcasts). Pair with meta_page_get_post_insights on the owning post for video-view analytics, or drill into individual video IDs for per-video metrics.`,
31
+ inputSchema: inputSchema.shape,
32
+ annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
33
+ };
34
+ export async function handler(input, ctx) {
35
+ assertAllowed("page", input.page_id, ctx.config);
36
+ return runList(ctx, {
37
+ path: `${input.page_id}/videos`,
38
+ params: { fields: input.fields.join(","), limit: input.limit, after: input.after },
39
+ }, { auto_paginate: input.auto_paginate, after: input.after, limit: input.limit }, { page_id: input.page_id });
40
+ }
@@ -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
+ source: z.ZodDefault<z.ZodEnum<["assigned", "accounts"]>>;
8
+ fields: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
9
+ }, "strict", z.ZodTypeAny, {
10
+ fields: string[];
11
+ limit: number;
12
+ auto_paginate: boolean;
13
+ source: "assigned" | "accounts";
14
+ after?: string | undefined;
15
+ }, {
16
+ fields?: string[] | undefined;
17
+ limit?: number | undefined;
18
+ after?: string | undefined;
19
+ auto_paginate?: boolean | undefined;
20
+ source?: "assigned" | "accounts" | undefined;
21
+ }>;
22
+ export type Input = z.infer<typeof inputSchema>;
23
+ export declare const definition: {
24
+ readonly name: "meta_page_list";
25
+ readonly title: "List Pages visible to the token";
26
+ readonly description: "Lists Facebook Pages this token/system-user can read. 'assigned' is the modern path for system users; 'accounts' is the classic /me/accounts edge (works for regular users).";
27
+ readonly inputSchema: {
28
+ limit: z.ZodDefault<z.ZodNumber>;
29
+ after: z.ZodOptional<z.ZodString>;
30
+ auto_paginate: z.ZodDefault<z.ZodBoolean>;
31
+ source: z.ZodDefault<z.ZodEnum<["assigned", "accounts"]>>;
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,39 @@
1
+ import { z } from "zod";
2
+ import { paginationShape } from "../../helpers/schema.js";
3
+ import { runList } from "../shared.js";
4
+ export const inputSchema = z
5
+ .object({
6
+ source: z
7
+ .enum(["assigned", "accounts"])
8
+ .default("assigned")
9
+ .describe("'assigned' → /me/assigned_pages (system-user-specific). 'accounts' → /me/accounts (classic Pages edge)."),
10
+ fields: z
11
+ .array(z.string())
12
+ .default([
13
+ "id",
14
+ "name",
15
+ "category",
16
+ "category_list",
17
+ "about",
18
+ "fan_count",
19
+ "followers_count",
20
+ "verification_status",
21
+ "link",
22
+ "website",
23
+ "tasks",
24
+ ])
25
+ .describe("Page fields."),
26
+ ...paginationShape,
27
+ })
28
+ .strict();
29
+ export const definition = {
30
+ name: "meta_page_list",
31
+ title: "List Pages visible to the token",
32
+ description: `Lists Facebook Pages this token/system-user can read. 'assigned' is the modern path for system users; 'accounts' is the classic /me/accounts edge (works for regular users).`,
33
+ inputSchema: inputSchema.shape,
34
+ annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
35
+ };
36
+ export async function handler(input, ctx) {
37
+ const path = input.source === "assigned" ? "me/assigned_pages" : "me/accounts";
38
+ return runList(ctx, { path, params: { fields: input.fields.join(","), limit: input.limit, after: input.after } }, { auto_paginate: input.auto_paginate, after: input.after, limit: input.limit }, { source: input.source });
39
+ }
@@ -0,0 +1,41 @@
1
+ import { z } from "zod";
2
+ import type { ToolContext } from "../../context.js";
3
+ export declare const inputSchema: z.ZodObject<{
4
+ pixel_id: z.ZodString;
5
+ aggregation: z.ZodDefault<z.ZodEnum<["event", "browser_type", "device_os", "event_source", "url"]>>;
6
+ start_time: z.ZodOptional<z.ZodString>;
7
+ end_time: z.ZodOptional<z.ZodString>;
8
+ event: z.ZodOptional<z.ZodString>;
9
+ }, "strict", z.ZodTypeAny, {
10
+ pixel_id: string;
11
+ aggregation: "url" | "event" | "browser_type" | "device_os" | "event_source";
12
+ start_time?: string | undefined;
13
+ end_time?: string | undefined;
14
+ event?: string | undefined;
15
+ }, {
16
+ pixel_id: string;
17
+ start_time?: string | undefined;
18
+ end_time?: string | undefined;
19
+ event?: string | undefined;
20
+ aggregation?: "url" | "event" | "browser_type" | "device_os" | "event_source" | undefined;
21
+ }>;
22
+ export type Input = z.infer<typeof inputSchema>;
23
+ export declare const definition: {
24
+ readonly name: "meta_pixel_get_stats";
25
+ readonly title: "Get pixel event stats";
26
+ readonly description: "Reads aggregated pixel event counts via /{pixel_id}/stats. Use aggregation='event' to see which events are firing, 'device_os' or 'browser_type' to profile traffic, 'url' to see top-firing pages. Useful for spotting CAPI drop-off versus browser events.";
27
+ readonly inputSchema: {
28
+ pixel_id: z.ZodString;
29
+ aggregation: z.ZodDefault<z.ZodEnum<["event", "browser_type", "device_os", "event_source", "url"]>>;
30
+ start_time: z.ZodOptional<z.ZodString>;
31
+ end_time: z.ZodOptional<z.ZodString>;
32
+ event: z.ZodOptional<z.ZodString>;
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,34 @@
1
+ import { z } from "zod";
2
+ import { metaIdSchema } from "../../helpers/schema.js";
3
+ import { runGet } from "../shared.js";
4
+ const AGGREGATION = z.enum(["event", "browser_type", "device_os", "event_source", "url"]);
5
+ export const inputSchema = z
6
+ .object({
7
+ pixel_id: metaIdSchema,
8
+ aggregation: AGGREGATION.default("event").describe("How to slice the stats."),
9
+ start_time: z.string().optional().describe("ISO date / Unix timestamp — start of window."),
10
+ end_time: z.string().optional().describe("ISO date / Unix timestamp — end of window."),
11
+ event: z
12
+ .string()
13
+ .optional()
14
+ .describe("Filter to one event name, e.g. 'Purchase', 'AddToCart'."),
15
+ })
16
+ .strict();
17
+ export const definition = {
18
+ name: "meta_pixel_get_stats",
19
+ title: "Get pixel event stats",
20
+ description: `Reads aggregated pixel event counts via /{pixel_id}/stats. Use aggregation='event' to see which events are firing, 'device_os' or 'browser_type' to profile traffic, 'url' to see top-firing pages. Useful for spotting CAPI drop-off versus browser events.`,
21
+ inputSchema: inputSchema.shape,
22
+ annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
23
+ };
24
+ export async function handler(input, ctx) {
25
+ return runGet(ctx, {
26
+ path: `${input.pixel_id}/stats`,
27
+ params: {
28
+ aggregation: input.aggregation,
29
+ start_time: input.start_time,
30
+ end_time: input.end_time,
31
+ event: input.event,
32
+ },
33
+ });
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
+ limit: z.ZodDefault<z.ZodNumber>;
5
+ after: z.ZodOptional<z.ZodString>;
6
+ auto_paginate: z.ZodDefault<z.ZodBoolean>;
7
+ business_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
+ business_id: string;
14
+ after?: string | undefined;
15
+ }, {
16
+ business_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_pixel_list";
25
+ readonly title: "List Meta Pixels under a business";
26
+ readonly description: "Lists Meta (Facebook) Pixels owned by a business via /{business_id}/owned_pixels. Includes last_fired_time so you can spot stale pixels. Requires 'business_management' or Marketing API access.";
27
+ readonly inputSchema: {
28
+ limit: z.ZodDefault<z.ZodNumber>;
29
+ after: z.ZodOptional<z.ZodString>;
30
+ auto_paginate: z.ZodDefault<z.ZodBoolean>;
31
+ business_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,38 @@
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.describe("Business Manager ID."),
8
+ fields: z
9
+ .array(z.string())
10
+ .default([
11
+ "id",
12
+ "name",
13
+ "code",
14
+ "is_created_by_business",
15
+ "is_unavailable",
16
+ "last_fired_time",
17
+ "creation_time",
18
+ "owner_ad_account",
19
+ "owner_business",
20
+ ])
21
+ .describe("Pixel fields."),
22
+ ...paginationShape,
23
+ })
24
+ .strict();
25
+ export const definition = {
26
+ name: "meta_pixel_list",
27
+ title: "List Meta Pixels under a business",
28
+ description: `Lists Meta (Facebook) Pixels owned by a business via /{business_id}/owned_pixels. Includes last_fired_time so you can spot stale pixels. Requires 'business_management' or Marketing API access.`,
29
+ inputSchema: inputSchema.shape,
30
+ annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
31
+ };
32
+ export async function handler(input, ctx) {
33
+ assertAllowed("business", input.business_id, ctx.config);
34
+ return runList(ctx, {
35
+ path: `${input.business_id}/owned_pixels`,
36
+ params: { fields: input.fields.join(","), limit: input.limit, after: input.after },
37
+ }, { auto_paginate: input.auto_paginate, after: input.after, limit: input.limit }, { business_id: input.business_id });
38
+ }
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import type { ToolContext } from "../context.js";
3
+ export declare function registerTools(server: McpServer, ctx: ToolContext): string[];
@@ -0,0 +1,82 @@
1
+ // Token + meta
2
+ import * as tokenInspect from "./token/inspect.js";
3
+ import * as tokenHealth from "./token/health.js";
4
+ import * as graphRead from "./meta/graph-read.js";
5
+ // Business discovery
6
+ import * as listBusinesses from "./business/list-businesses.js";
7
+ import * as listAssets from "./business/list-assets.js";
8
+ import * as listSystemUsers from "./business/list-system-users.js";
9
+ // Ads (Marketing API)
10
+ import * as adsListAccounts from "./ads/list-accounts.js";
11
+ import * as adsGetAccount from "./ads/get-account.js";
12
+ import * as adsListCampaigns from "./ads/list-campaigns.js";
13
+ import * as adsListAdsets from "./ads/list-adsets.js";
14
+ import * as adsListAds from "./ads/list-ads.js";
15
+ import * as adsGetInsights from "./ads/get-insights.js";
16
+ import * as adsGetCreative from "./ads/get-creative.js";
17
+ import * as adsListCustomAudiences from "./ads/list-custom-audiences.js";
18
+ // Pages
19
+ import * as pageList from "./pages/list.js";
20
+ import * as pageGet from "./pages/get.js";
21
+ import * as pageListPosts from "./pages/list-posts.js";
22
+ import * as pageGetPostInsights from "./pages/get-post-insights.js";
23
+ import * as pageGetInsights from "./pages/get-insights.js";
24
+ import * as pageListReviews from "./pages/list-reviews.js";
25
+ import * as pageListVideos from "./pages/list-videos.js";
26
+ // Instagram
27
+ import * as igListAccounts from "./instagram/list-accounts.js";
28
+ import * as igGetAccount from "./instagram/get-account.js";
29
+ import * as igListMedia from "./instagram/list-media.js";
30
+ import * as igGetMediaInsights from "./instagram/get-media-insights.js";
31
+ import * as igGetAudienceDemographics from "./instagram/get-audience-demographics.js";
32
+ // Pixels
33
+ import * as pixelList from "./pixels/list.js";
34
+ import * as pixelGetStats from "./pixels/get-stats.js";
35
+ // Catalog
36
+ import * as catalogList from "./catalog/list.js";
37
+ import * as catalogListProducts from "./catalog/list-products.js";
38
+ import * as catalogGetDiagnostics from "./catalog/get-diagnostics.js";
39
+ // WhatsApp
40
+ import * as whatsappListWabas from "./whatsapp/list-wabas.js";
41
+ import * as whatsappListPhoneNumbers from "./whatsapp/list-phone-numbers.js";
42
+ import * as whatsappListTemplates from "./whatsapp/list-templates.js";
43
+ import * as whatsappGetAnalytics from "./whatsapp/get-analytics.js";
44
+ // Overview
45
+ import * as businessOverview from "./overview/business-overview.js";
46
+ const TOOLS = [
47
+ // Token + meta (3)
48
+ tokenInspect, tokenHealth, graphRead,
49
+ // Business discovery (3)
50
+ listBusinesses, listAssets, listSystemUsers,
51
+ // Ads (8)
52
+ adsListAccounts, adsGetAccount, adsListCampaigns, adsListAdsets, adsListAds,
53
+ adsGetInsights, adsGetCreative, adsListCustomAudiences,
54
+ // Pages (7)
55
+ pageList, pageGet, pageListPosts, pageGetPostInsights, pageGetInsights,
56
+ pageListReviews, pageListVideos,
57
+ // Instagram (5)
58
+ igListAccounts, igGetAccount, igListMedia, igGetMediaInsights, igGetAudienceDemographics,
59
+ // Pixels (2)
60
+ pixelList, pixelGetStats,
61
+ // Catalog (3)
62
+ catalogList, catalogListProducts, catalogGetDiagnostics,
63
+ // WhatsApp (4)
64
+ whatsappListWabas, whatsappListPhoneNumbers, whatsappListTemplates, whatsappGetAnalytics,
65
+ // Overview (1)
66
+ businessOverview,
67
+ ].map((m) => m);
68
+ export function registerTools(server, ctx) {
69
+ const names = [];
70
+ for (const mod of TOOLS) {
71
+ server.registerTool(mod.definition.name, {
72
+ title: mod.definition.title,
73
+ description: mod.definition.description,
74
+ inputSchema: mod.definition.inputSchema,
75
+ annotations: mod.definition.annotations,
76
+ }, (async (args) => {
77
+ return mod.handler(args, ctx);
78
+ }));
79
+ names.push(mod.definition.name);
80
+ }
81
+ return names;
82
+ }
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Shared helpers used across domain tools — keeps each tool file focused on
3
+ * its endpoint instead of re-implementing boilerplate.
4
+ */
5
+ import type { ToolContext } from "../context.js";
6
+ import { type ToolTextResult } from "../helpers/format.js";
7
+ import type { GraphGetOptions } from "../helpers/graph-client.js";
8
+ export interface ListRunOpts {
9
+ auto_paginate?: boolean;
10
+ after?: string;
11
+ limit?: number;
12
+ }
13
+ /**
14
+ * Fetch one page or auto-paginate, normalize into a structured list payload,
15
+ * and translate errors. Use for simple `GET /{id}/{edge}` style tools.
16
+ */
17
+ export declare function runList<T>(ctx: ToolContext, opts: GraphGetOptions, pag: ListRunOpts, extra?: Record<string, unknown>): Promise<ToolTextResult>;
18
+ /** Run a single read and return a tool result. */
19
+ export declare function runGet<T>(ctx: ToolContext, opts: GraphGetOptions, extra?: Record<string, unknown>): Promise<ToolTextResult>;
20
+ export declare function errorResult(err: unknown): ToolTextResult;
@@ -0,0 +1,55 @@
1
+ import { MetaError } from "../errors.js";
2
+ import { jsonBlock, toolError, toolResult } from "../helpers/format.js";
3
+ /**
4
+ * Fetch one page or auto-paginate, normalize into a structured list payload,
5
+ * and translate errors. Use for simple `GET /{id}/{edge}` style tools.
6
+ */
7
+ export async function runList(ctx, opts, pag, extra = {}) {
8
+ try {
9
+ if (pag.auto_paginate) {
10
+ const { data, pages, nextAfter } = await ctx.graph.getAllPages(opts);
11
+ const structured = {
12
+ ...extra,
13
+ count: data.length,
14
+ pages_fetched: pages,
15
+ next_after: nextAfter,
16
+ items: data,
17
+ };
18
+ return toolResult(structured, jsonBlock(structured));
19
+ }
20
+ const page = await ctx.graph.get(opts);
21
+ const items = Array.isArray(page.data) ? page.data : [];
22
+ const structured = {
23
+ ...extra,
24
+ count: items.length,
25
+ pages_fetched: 1,
26
+ next_after: page.paging?.cursors?.after,
27
+ items,
28
+ };
29
+ return toolResult(structured, jsonBlock(structured));
30
+ }
31
+ catch (err) {
32
+ return errorResult(err);
33
+ }
34
+ }
35
+ /** Run a single read and return a tool result. */
36
+ export async function runGet(ctx, opts, extra = {}) {
37
+ try {
38
+ const data = await ctx.graph.get(opts);
39
+ const structured = { ...extra, data };
40
+ return toolResult(structured, jsonBlock(data));
41
+ }
42
+ catch (err) {
43
+ return errorResult(err);
44
+ }
45
+ }
46
+ export function errorResult(err) {
47
+ const e = err instanceof MetaError ? err : new MetaError(err.message);
48
+ return toolError(e.message, e.hint, {
49
+ code: e.code,
50
+ subcode: e.subcode,
51
+ fbtrace_id: e.fbtraceId,
52
+ http_status: e.httpStatus,
53
+ retryable: e.retryable,
54
+ });
55
+ }
@@ -0,0 +1,17 @@
1
+ import { z } from "zod";
2
+ import type { ToolContext } from "../../context.js";
3
+ export declare const inputSchema: z.ZodObject<{}, "strict", z.ZodTypeAny, {}, {}>;
4
+ export type Input = z.infer<typeof inputSchema>;
5
+ export declare const definition: {
6
+ readonly name: "meta_health_check";
7
+ readonly title: "Meta MCP health check";
8
+ readonly description: "End-to-end reachability probe:\n- Confirms the Graph API is reachable.\n- Confirms the configured token resolves to a valid identity (via /me).\n- Surfaces the latest rate-limit header snapshot from the Graph client.\n- Lists which allowlists are active (business / ad account / page / IG user).\n\nUse when a session starts, or when diagnosing why other tools are returning errors.";
9
+ readonly inputSchema: {};
10
+ readonly annotations: {
11
+ readonly readOnlyHint: true;
12
+ readonly destructiveHint: false;
13
+ readonly idempotentHint: true;
14
+ readonly openWorldHint: true;
15
+ };
16
+ };
17
+ export declare function handler(_input: Input, ctx: ToolContext): Promise<import("../../helpers/format.js").ToolTextResult>;
@@ -0,0 +1,59 @@
1
+ import { z } from "zod";
2
+ import { MetaError } from "../../errors.js";
3
+ import { jsonBlock, toolError, toolResult } from "../../helpers/format.js";
4
+ export const inputSchema = z.object({}).strict();
5
+ export const definition = {
6
+ name: "meta_health_check",
7
+ title: "Meta MCP health check",
8
+ description: `End-to-end reachability probe:
9
+ - Confirms the Graph API is reachable.
10
+ - Confirms the configured token resolves to a valid identity (via /me).
11
+ - Surfaces the latest rate-limit header snapshot from the Graph client.
12
+ - Lists which allowlists are active (business / ad account / page / IG user).
13
+
14
+ Use when a session starts, or when diagnosing why other tools are returning errors.`,
15
+ inputSchema: inputSchema.shape,
16
+ annotations: {
17
+ readOnlyHint: true,
18
+ destructiveHint: false,
19
+ idempotentHint: true,
20
+ openWorldHint: true,
21
+ },
22
+ };
23
+ export async function handler(_input, ctx) {
24
+ const started = Date.now();
25
+ try {
26
+ const me = await ctx.graph.get({
27
+ path: "me",
28
+ params: { fields: "id,name" },
29
+ noCache: true,
30
+ });
31
+ const structured = {
32
+ ok: true,
33
+ latency_ms: Date.now() - started,
34
+ identity: me,
35
+ api_version: ctx.config.apiVersion,
36
+ appsecret_proof_enabled: Boolean(ctx.config.appSecret),
37
+ rate_limit: ctx.graph.rateLimit,
38
+ allowlists: {
39
+ businesses: ctx.config.allowedBusinessIds ? [...ctx.config.allowedBusinessIds] : null,
40
+ ad_accounts: ctx.config.allowedAdAccountIds
41
+ ? [...ctx.config.allowedAdAccountIds]
42
+ : null,
43
+ pages: ctx.config.allowedPageIds ? [...ctx.config.allowedPageIds] : null,
44
+ ig_users: ctx.config.allowedIgUserIds ? [...ctx.config.allowedIgUserIds] : null,
45
+ },
46
+ };
47
+ return toolResult(structured, jsonBlock(structured));
48
+ }
49
+ catch (err) {
50
+ const e = err instanceof MetaError ? err : new MetaError(err.message);
51
+ return toolError(`Health check failed: ${e.message}`, e.hint, {
52
+ code: e.code,
53
+ subcode: e.subcode,
54
+ fbtrace_id: e.fbtraceId,
55
+ http_status: e.httpStatus,
56
+ latency_ms: Date.now() - started,
57
+ });
58
+ }
59
+ }