@cashtokenai/meta-mcp-server 1.0.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.
- package/LICENSE +21 -0
- package/README.md +294 -0
- package/dist/config.d.ts +39 -0
- package/dist/config.js +60 -0
- package/dist/constants.d.ts +21 -0
- package/dist/constants.js +28 -0
- package/dist/context.d.ts +9 -0
- package/dist/context.js +8 -0
- package/dist/errors.d.ts +41 -0
- package/dist/errors.js +120 -0
- package/dist/helpers/cache.d.ts +6 -0
- package/dist/helpers/cache.js +28 -0
- package/dist/helpers/format.d.ts +17 -0
- package/dist/helpers/format.js +28 -0
- package/dist/helpers/graph-client.d.ts +90 -0
- package/dist/helpers/graph-client.js +219 -0
- package/dist/helpers/schema.d.ts +30 -0
- package/dist/helpers/schema.js +69 -0
- package/dist/helpers/validate.d.ts +26 -0
- package/dist/helpers/validate.js +125 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +36 -0
- package/dist/logger.d.ts +3 -0
- package/dist/logger.js +18 -0
- package/dist/server.d.ts +7 -0
- package/dist/server.js +34 -0
- package/dist/tools/ads/get-account.d.ts +29 -0
- package/dist/tools/ads/get-account.js +45 -0
- package/dist/tools/ads/get-creative.d.ts +29 -0
- package/dist/tools/ads/get-creative.js +37 -0
- package/dist/tools/ads/get-insights.d.ts +129 -0
- package/dist/tools/ads/get-insights.js +153 -0
- package/dist/tools/ads/list-accounts.d.ts +54 -0
- package/dist/tools/ads/list-accounts.js +59 -0
- package/dist/tools/ads/list-ads.d.ts +53 -0
- package/dist/tools/ads/list-ads.js +59 -0
- package/dist/tools/ads/list-adsets.d.ts +49 -0
- package/dist/tools/ads/list-adsets.js +54 -0
- package/dist/tools/ads/list-campaigns.d.ts +45 -0
- package/dist/tools/ads/list-campaigns.js +64 -0
- package/dist/tools/ads/list-custom-audiences.d.ts +41 -0
- package/dist/tools/ads/list-custom-audiences.js +41 -0
- package/dist/tools/business/list-assets.d.ts +37 -0
- package/dist/tools/business/list-assets.js +136 -0
- package/dist/tools/business/list-businesses.d.ts +37 -0
- package/dist/tools/business/list-businesses.js +81 -0
- package/dist/tools/business/list-system-users.d.ts +41 -0
- package/dist/tools/business/list-system-users.js +73 -0
- package/dist/tools/catalog/get-diagnostics.d.ts +29 -0
- package/dist/tools/catalog/get-diagnostics.js +26 -0
- package/dist/tools/catalog/list-products.d.ts +45 -0
- package/dist/tools/catalog/list-products.js +49 -0
- package/dist/tools/catalog/list.d.ts +54 -0
- package/dist/tools/catalog/list.js +48 -0
- package/dist/tools/instagram/get-account.d.ts +29 -0
- package/dist/tools/instagram/get-account.js +34 -0
- package/dist/tools/instagram/get-audience-demographics.d.ts +45 -0
- package/dist/tools/instagram/get-audience-demographics.js +58 -0
- package/dist/tools/instagram/get-media-insights.d.ts +29 -0
- package/dist/tools/instagram/get-media-insights.js +49 -0
- package/dist/tools/instagram/list-accounts.d.ts +33 -0
- package/dist/tools/instagram/list-accounts.js +63 -0
- package/dist/tools/instagram/list-media.d.ts +41 -0
- package/dist/tools/instagram/list-media.js +42 -0
- package/dist/tools/meta/graph-read.d.ts +33 -0
- package/dist/tools/meta/graph-read.js +71 -0
- package/dist/tools/overview/business-overview.d.ts +49 -0
- package/dist/tools/overview/business-overview.js +235 -0
- package/dist/tools/overview/content-report.d.ts +57 -0
- package/dist/tools/overview/content-report.js +344 -0
- package/dist/tools/overview/latest-posts-summary.d.ts +41 -0
- package/dist/tools/overview/latest-posts-summary.js +189 -0
- package/dist/tools/pages/get-insights.d.ts +41 -0
- package/dist/tools/pages/get-insights.js +49 -0
- package/dist/tools/pages/get-post-insights.d.ts +33 -0
- package/dist/tools/pages/get-post-insights.js +47 -0
- package/dist/tools/pages/get.d.ts +29 -0
- package/dist/tools/pages/get.js +50 -0
- package/dist/tools/pages/list-posts.d.ts +53 -0
- package/dist/tools/pages/list-posts.js +62 -0
- package/dist/tools/pages/list-reviews.d.ts +41 -0
- package/dist/tools/pages/list-reviews.js +37 -0
- package/dist/tools/pages/list-videos.d.ts +41 -0
- package/dist/tools/pages/list-videos.js +40 -0
- package/dist/tools/pages/list.d.ts +41 -0
- package/dist/tools/pages/list.js +39 -0
- package/dist/tools/pixels/get-stats.d.ts +41 -0
- package/dist/tools/pixels/get-stats.js +34 -0
- package/dist/tools/pixels/list.d.ts +41 -0
- package/dist/tools/pixels/list.js +41 -0
- package/dist/tools/register.d.ts +3 -0
- package/dist/tools/register.js +95 -0
- package/dist/tools/shared.d.ts +45 -0
- package/dist/tools/shared.js +137 -0
- package/dist/tools/token/health.d.ts +17 -0
- package/dist/tools/token/health.js +65 -0
- package/dist/tools/token/inspect.d.ts +26 -0
- package/dist/tools/token/inspect.js +88 -0
- package/dist/tools/whatsapp/get-analytics.d.ts +57 -0
- package/dist/tools/whatsapp/get-analytics.js +66 -0
- package/dist/tools/whatsapp/list-phone-numbers.d.ts +41 -0
- package/dist/tools/whatsapp/list-phone-numbers.js +35 -0
- package/dist/tools/whatsapp/list-templates.d.ts +45 -0
- package/dist/tools/whatsapp/list-templates.js +44 -0
- package/dist/tools/whatsapp/list-wabas.d.ts +54 -0
- package/dist/tools/whatsapp/list-wabas.js +48 -0
- package/dist/types/meta.d.ts +46 -0
- package/dist/types/meta.js +1 -0
- package/package.json +77 -0
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { assertAllowed } from "../../config.js";
|
|
3
|
+
import { MetaError } from "../../errors.js";
|
|
4
|
+
import { jsonBlock, toolError, toolResult } from "../../helpers/format.js";
|
|
5
|
+
import { paginationShape } from "../../helpers/schema.js";
|
|
6
|
+
export const inputSchema = z
|
|
7
|
+
.object({
|
|
8
|
+
...paginationShape,
|
|
9
|
+
fields: z
|
|
10
|
+
.array(z.string())
|
|
11
|
+
.default([
|
|
12
|
+
"id",
|
|
13
|
+
"name",
|
|
14
|
+
"verification_status",
|
|
15
|
+
"primary_page",
|
|
16
|
+
"created_time",
|
|
17
|
+
"updated_time",
|
|
18
|
+
"timezone_id",
|
|
19
|
+
])
|
|
20
|
+
.describe("Fields to request on each business."),
|
|
21
|
+
})
|
|
22
|
+
.strict();
|
|
23
|
+
export const definition = {
|
|
24
|
+
name: "meta_business_list",
|
|
25
|
+
title: "List Meta businesses visible to the token",
|
|
26
|
+
description: `Lists every Business Manager the configured access token can see — via GET /me/businesses.
|
|
27
|
+
|
|
28
|
+
Typical usage: call this once at the start of a session to discover available business IDs, then pass the chosen ID to meta_business_list_assets / meta_business_list_system_users.
|
|
29
|
+
|
|
30
|
+
Respects META_ALLOWED_BUSINESS_IDS: if set, filters the response to that allowlist.`,
|
|
31
|
+
inputSchema: inputSchema.shape,
|
|
32
|
+
annotations: {
|
|
33
|
+
readOnlyHint: true,
|
|
34
|
+
destructiveHint: false,
|
|
35
|
+
idempotentHint: true,
|
|
36
|
+
openWorldHint: true,
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
export async function handler(input, ctx) {
|
|
40
|
+
try {
|
|
41
|
+
const params = {
|
|
42
|
+
fields: input.fields.join(","),
|
|
43
|
+
limit: input.limit,
|
|
44
|
+
after: input.after,
|
|
45
|
+
};
|
|
46
|
+
const opts = { path: "me/businesses", params };
|
|
47
|
+
const { data, pages, nextAfter } = input.auto_paginate
|
|
48
|
+
? await ctx.graph.getAllPages(opts)
|
|
49
|
+
: await singlePage(ctx, opts);
|
|
50
|
+
const allowlist = ctx.config.allowedBusinessIds;
|
|
51
|
+
const filtered = allowlist ? data.filter((b) => allowlist.has(b.id)) : data;
|
|
52
|
+
// Sanity-check that whatever survived the allowlist is allowed.
|
|
53
|
+
for (const b of filtered)
|
|
54
|
+
assertAllowed("business", b.id, ctx.config);
|
|
55
|
+
const structured = {
|
|
56
|
+
count: filtered.length,
|
|
57
|
+
pages_fetched: pages,
|
|
58
|
+
next_after: nextAfter,
|
|
59
|
+
businesses: filtered,
|
|
60
|
+
filtered_by_allowlist: Boolean(allowlist),
|
|
61
|
+
};
|
|
62
|
+
return toolResult(structured, jsonBlock(structured));
|
|
63
|
+
}
|
|
64
|
+
catch (err) {
|
|
65
|
+
const e = err instanceof MetaError ? err : new MetaError(err.message);
|
|
66
|
+
return toolError(e.message, e.hint, {
|
|
67
|
+
code: e.code,
|
|
68
|
+
subcode: e.subcode,
|
|
69
|
+
fbtrace_id: e.fbtraceId,
|
|
70
|
+
http_status: e.httpStatus,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
async function singlePage(ctx, opts) {
|
|
75
|
+
const page = await ctx.graph.get(opts);
|
|
76
|
+
return {
|
|
77
|
+
data: Array.isArray(page.data) ? page.data : [],
|
|
78
|
+
pages: 1,
|
|
79
|
+
nextAfter: page.paging?.cursors?.after,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { ToolContext } from "../../context.js";
|
|
3
|
+
export declare const inputSchema: z.ZodObject<{
|
|
4
|
+
fields: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
5
|
+
limit: z.ZodDefault<z.ZodNumber>;
|
|
6
|
+
after: z.ZodOptional<z.ZodString>;
|
|
7
|
+
auto_paginate: z.ZodDefault<z.ZodBoolean>;
|
|
8
|
+
business_id: z.ZodString;
|
|
9
|
+
}, "strict", z.ZodTypeAny, {
|
|
10
|
+
fields: string[];
|
|
11
|
+
business_id: string;
|
|
12
|
+
limit: number;
|
|
13
|
+
auto_paginate: boolean;
|
|
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_business_list_system_users";
|
|
25
|
+
readonly title: "List system users attached to a business";
|
|
26
|
+
readonly description: "Lists the system-user (server/software) identities under a Business Manager.\n\nSystem users are non-human identities used for API access. This tool helps diagnose which identity owns the token in use (cross-reference with meta_token_inspect).\n\nReads /{business_id}/system_users.";
|
|
27
|
+
readonly inputSchema: {
|
|
28
|
+
fields: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
29
|
+
limit: z.ZodDefault<z.ZodNumber>;
|
|
30
|
+
after: z.ZodOptional<z.ZodString>;
|
|
31
|
+
auto_paginate: z.ZodDefault<z.ZodBoolean>;
|
|
32
|
+
business_id: 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,73 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { assertAllowed } from "../../config.js";
|
|
3
|
+
import { MetaError } from "../../errors.js";
|
|
4
|
+
import { jsonBlock, toolError, toolResult } from "../../helpers/format.js";
|
|
5
|
+
import { metaIdSchema, paginationShape } from "../../helpers/schema.js";
|
|
6
|
+
export const inputSchema = z
|
|
7
|
+
.object({
|
|
8
|
+
business_id: metaIdSchema.describe("Business Manager ID."),
|
|
9
|
+
...paginationShape,
|
|
10
|
+
fields: z
|
|
11
|
+
.array(z.string())
|
|
12
|
+
.default(["id", "name", "role", "finance_role", "ip_role"])
|
|
13
|
+
.describe("Fields to return for each system user."),
|
|
14
|
+
})
|
|
15
|
+
.strict();
|
|
16
|
+
export const definition = {
|
|
17
|
+
name: "meta_business_list_system_users",
|
|
18
|
+
title: "List system users attached to a business",
|
|
19
|
+
description: `Lists the system-user (server/software) identities under a Business Manager.
|
|
20
|
+
|
|
21
|
+
System users are non-human identities used for API access. This tool helps diagnose which identity owns the token in use (cross-reference with meta_token_inspect).
|
|
22
|
+
|
|
23
|
+
Reads /{business_id}/system_users.`,
|
|
24
|
+
inputSchema: inputSchema.shape,
|
|
25
|
+
annotations: {
|
|
26
|
+
readOnlyHint: true,
|
|
27
|
+
destructiveHint: false,
|
|
28
|
+
idempotentHint: true,
|
|
29
|
+
openWorldHint: true,
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
export async function handler(input, ctx) {
|
|
33
|
+
assertAllowed("business", input.business_id, ctx.config);
|
|
34
|
+
try {
|
|
35
|
+
const opts = {
|
|
36
|
+
path: `${input.business_id}/system_users`,
|
|
37
|
+
params: {
|
|
38
|
+
fields: input.fields.join(","),
|
|
39
|
+
limit: input.limit,
|
|
40
|
+
after: input.after,
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
if (input.auto_paginate) {
|
|
44
|
+
const { data, pages, nextAfter } = await ctx.graph.getAllPages(opts);
|
|
45
|
+
const structured = {
|
|
46
|
+
business_id: input.business_id,
|
|
47
|
+
count: data.length,
|
|
48
|
+
pages_fetched: pages,
|
|
49
|
+
next_after: nextAfter,
|
|
50
|
+
system_users: data,
|
|
51
|
+
};
|
|
52
|
+
return toolResult(structured, jsonBlock(structured));
|
|
53
|
+
}
|
|
54
|
+
const page = await ctx.graph.get(opts);
|
|
55
|
+
const structured = {
|
|
56
|
+
business_id: input.business_id,
|
|
57
|
+
count: Array.isArray(page.data) ? page.data.length : 0,
|
|
58
|
+
pages_fetched: 1,
|
|
59
|
+
next_after: page.paging?.cursors?.after,
|
|
60
|
+
system_users: page.data ?? [],
|
|
61
|
+
};
|
|
62
|
+
return toolResult(structured, jsonBlock(structured));
|
|
63
|
+
}
|
|
64
|
+
catch (err) {
|
|
65
|
+
const e = err instanceof MetaError ? err : new MetaError(err.message);
|
|
66
|
+
return toolError(e.message, e.hint, {
|
|
67
|
+
code: e.code,
|
|
68
|
+
subcode: e.subcode,
|
|
69
|
+
fbtrace_id: e.fbtraceId,
|
|
70
|
+
http_status: e.httpStatus,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { ToolContext } from "../../context.js";
|
|
3
|
+
export declare const inputSchema: z.ZodObject<{
|
|
4
|
+
catalog_id: z.ZodString;
|
|
5
|
+
fields: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
6
|
+
}, "strict", z.ZodTypeAny, {
|
|
7
|
+
fields: string[];
|
|
8
|
+
catalog_id: string;
|
|
9
|
+
}, {
|
|
10
|
+
catalog_id: string;
|
|
11
|
+
fields?: string[] | undefined;
|
|
12
|
+
}>;
|
|
13
|
+
export type Input = z.infer<typeof inputSchema>;
|
|
14
|
+
export declare const definition: {
|
|
15
|
+
readonly name: "meta_catalog_get_diagnostics";
|
|
16
|
+
readonly title: "Get catalog diagnostics";
|
|
17
|
+
readonly description: "Surfaces catalog issues: disapproved items, missing required fields, GTIN problems, image errors. Pair with meta_catalog_list_products to see affected items.";
|
|
18
|
+
readonly inputSchema: {
|
|
19
|
+
catalog_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,26 @@
|
|
|
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
|
+
catalog_id: metaIdSchema,
|
|
7
|
+
fields: z
|
|
8
|
+
.array(z.string())
|
|
9
|
+
.default([
|
|
10
|
+
"diagnostics{severity,type,title,description,affected_items,affected_channels}",
|
|
11
|
+
"product_count",
|
|
12
|
+
"feed_count",
|
|
13
|
+
])
|
|
14
|
+
.describe("Diagnostics fields. Meta surfaces issues like missing images, disapproved items, incomplete GTIN, etc."),
|
|
15
|
+
})
|
|
16
|
+
.strict();
|
|
17
|
+
export const definition = {
|
|
18
|
+
name: "meta_catalog_get_diagnostics",
|
|
19
|
+
title: "Get catalog diagnostics",
|
|
20
|
+
description: `Surfaces catalog issues: disapproved items, missing required fields, GTIN problems, image errors. Pair with meta_catalog_list_products to see affected items.`,
|
|
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, { path: input.catalog_id, params: { fields: input.fields.join(",") } });
|
|
26
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
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
|
+
catalog_id: z.ZodString;
|
|
8
|
+
fields: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
9
|
+
filter: z.ZodOptional<z.ZodString>;
|
|
10
|
+
}, "strict", z.ZodTypeAny, {
|
|
11
|
+
fields: string[];
|
|
12
|
+
catalog_id: string;
|
|
13
|
+
limit: number;
|
|
14
|
+
auto_paginate: boolean;
|
|
15
|
+
filter?: string | undefined;
|
|
16
|
+
after?: string | undefined;
|
|
17
|
+
}, {
|
|
18
|
+
catalog_id: string;
|
|
19
|
+
fields?: string[] | undefined;
|
|
20
|
+
filter?: string | undefined;
|
|
21
|
+
limit?: number | undefined;
|
|
22
|
+
after?: string | undefined;
|
|
23
|
+
auto_paginate?: boolean | undefined;
|
|
24
|
+
}>;
|
|
25
|
+
export type Input = z.infer<typeof inputSchema>;
|
|
26
|
+
export declare const definition: {
|
|
27
|
+
readonly name: "meta_catalog_list_products";
|
|
28
|
+
readonly title: "List products in a catalog";
|
|
29
|
+
readonly 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).";
|
|
30
|
+
readonly inputSchema: {
|
|
31
|
+
limit: z.ZodDefault<z.ZodNumber>;
|
|
32
|
+
after: z.ZodOptional<z.ZodString>;
|
|
33
|
+
auto_paginate: z.ZodDefault<z.ZodBoolean>;
|
|
34
|
+
catalog_id: z.ZodString;
|
|
35
|
+
fields: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
36
|
+
filter: z.ZodOptional<z.ZodString>;
|
|
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<import("../../helpers/format.js").ToolTextResult>;
|
|
@@ -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
|
+
business_id: string;
|
|
13
|
+
limit: number;
|
|
14
|
+
auto_paginate: boolean;
|
|
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,45 @@
|
|
|
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
|
+
period: z.ZodDefault<z.ZodEnum<["lifetime", "day"]>>;
|
|
9
|
+
timeframe: z.ZodDefault<z.ZodEnum<["last_14_days", "last_30_days", "last_90_days", "prev_month", "this_month", "this_week"]>>;
|
|
10
|
+
}, "strict", z.ZodTypeAny, {
|
|
11
|
+
ig_user_id: string;
|
|
12
|
+
metric: "follower_demographics" | "engaged_audience_demographics" | "reached_audience_demographics";
|
|
13
|
+
period: "day" | "lifetime";
|
|
14
|
+
breakdown: "age" | "gender" | "country" | "city" | "audience_city";
|
|
15
|
+
metric_type: "total_value" | "time_series";
|
|
16
|
+
timeframe: "this_month" | "last_14_days" | "last_30_days" | "last_90_days" | "prev_month" | "this_week";
|
|
17
|
+
}, {
|
|
18
|
+
ig_user_id: string;
|
|
19
|
+
metric?: "follower_demographics" | "engaged_audience_demographics" | "reached_audience_demographics" | undefined;
|
|
20
|
+
period?: "day" | "lifetime" | undefined;
|
|
21
|
+
breakdown?: "age" | "gender" | "country" | "city" | "audience_city" | undefined;
|
|
22
|
+
metric_type?: "total_value" | "time_series" | undefined;
|
|
23
|
+
timeframe?: "this_month" | "last_14_days" | "last_30_days" | "last_90_days" | "prev_month" | "this_week" | undefined;
|
|
24
|
+
}>;
|
|
25
|
+
export type Input = z.infer<typeof inputSchema>;
|
|
26
|
+
export declare const definition: {
|
|
27
|
+
readonly name: "meta_ig_get_audience_demographics";
|
|
28
|
+
readonly title: "Get IG audience demographics";
|
|
29
|
+
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\nUSE FOR: \"audience demographics\", \"age / gender / country / city breakdown of my followers\", \"who follows me\", \"audience profile\".\n\nRequirements:\n1. Token has 'instagram_manage_insights' scope (the insights app / META_INSIGHTS_* token).\n2. The IG Business account must have ≥ 100 followers — below that Meta returns empty for privacy.\n3. Meta requires period='lifetime' for demographics metrics (sent automatically by this tool).\n\nIf you see '(#10) Application does not have permission', the configured app lacks instagram_manage_insights — relay the hint. If you see '(#100) period is required', upgrade the server (fixed in v0.1.11+).";
|
|
30
|
+
readonly inputSchema: {
|
|
31
|
+
ig_user_id: z.ZodString;
|
|
32
|
+
metric: z.ZodDefault<z.ZodEnum<["follower_demographics", "engaged_audience_demographics", "reached_audience_demographics"]>>;
|
|
33
|
+
breakdown: z.ZodDefault<z.ZodEnum<["age", "gender", "country", "city", "audience_city"]>>;
|
|
34
|
+
metric_type: z.ZodDefault<z.ZodEnum<["total_value", "time_series"]>>;
|
|
35
|
+
period: z.ZodDefault<z.ZodEnum<["lifetime", "day"]>>;
|
|
36
|
+
timeframe: z.ZodDefault<z.ZodEnum<["last_14_days", "last_30_days", "last_90_days", "prev_month", "this_month", "this_week"]>>;
|
|
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<import("../../helpers/format.js").ToolTextResult>;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { assertAllowed } from "../../config.js";
|
|
3
|
+
import { metaIdSchema } from "../../helpers/schema.js";
|
|
4
|
+
import { runGetViaInsightsApp } 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
|
+
period: z
|
|
21
|
+
.enum(["lifetime", "day"])
|
|
22
|
+
.default("lifetime")
|
|
23
|
+
.describe("Required by Meta for demographics metrics — almost always 'lifetime'. Omitting it triggers '(#100) The parameter period is required'."),
|
|
24
|
+
timeframe: z
|
|
25
|
+
.enum(["last_14_days", "last_30_days", "last_90_days", "prev_month", "this_month", "this_week"])
|
|
26
|
+
.default("last_30_days")
|
|
27
|
+
.describe("Required for demographics metrics."),
|
|
28
|
+
})
|
|
29
|
+
.strict();
|
|
30
|
+
export const definition = {
|
|
31
|
+
name: "meta_ig_get_audience_demographics",
|
|
32
|
+
title: "Get IG audience demographics",
|
|
33
|
+
description: `Reads demographic breakdown of an IG Business account's followers, engaged audience, or reached audience. Use breakdown='age'|'gender'|'country'|'city' to slice.
|
|
34
|
+
|
|
35
|
+
USE FOR: "audience demographics", "age / gender / country / city breakdown of my followers", "who follows me", "audience profile".
|
|
36
|
+
|
|
37
|
+
Requirements:
|
|
38
|
+
1. Token has 'instagram_manage_insights' scope (the insights app / META_INSIGHTS_* token).
|
|
39
|
+
2. The IG Business account must have ≥ 100 followers — below that Meta returns empty for privacy.
|
|
40
|
+
3. Meta requires period='lifetime' for demographics metrics (sent automatically by this tool).
|
|
41
|
+
|
|
42
|
+
If you see '(#10) Application does not have permission', the configured app lacks instagram_manage_insights — relay the hint. If you see '(#100) period is required', upgrade the server (fixed in v0.1.11+).`,
|
|
43
|
+
inputSchema: inputSchema.shape,
|
|
44
|
+
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
|
45
|
+
};
|
|
46
|
+
export async function handler(input, ctx) {
|
|
47
|
+
assertAllowed("ig_user", input.ig_user_id, ctx.config);
|
|
48
|
+
return runGetViaInsightsApp(ctx, {
|
|
49
|
+
path: `${input.ig_user_id}/insights`,
|
|
50
|
+
params: {
|
|
51
|
+
metric: input.metric,
|
|
52
|
+
period: input.period,
|
|
53
|
+
breakdown: input.breakdown,
|
|
54
|
+
metric_type: input.metric_type,
|
|
55
|
+
timeframe: input.timeframe,
|
|
56
|
+
},
|
|
57
|
+
});
|
|
58
|
+
}
|
|
@@ -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
|
+
media_id: string;
|
|
8
|
+
metrics: 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, views, saves, likes, comments, shares, total_interactions, profile_visits, follows.\n\n**Requirements (in order of frequency-of-failure):**\n1. Token has 'instagram_manage_insights' scope.\n2. **The configured app must be approved for Standard Access on `instagram_manage_insights` via Meta App Review.** In development tier, Meta returns `(#10) Application does not have permission for this action` for the IG insights endpoints — even if the scope is on the token. This applies to media insights AND audience demographics. Track the App Review request and surface this to the operator; this tool is functioning correctly when it returns that error.\n3. The IG account must be Business or Creator (not personal).\n\n**Metric / media-type compatibility (post v22 deprecations):**\n- IMAGE / CAROUSEL_ALBUM: reach, saved, likes, comments, shares, total_interactions, profile_visits\n- VIDEO / REELS: views, reach, likes, comments, shares, saved, total_interactions ('impressions' is deprecated, use 'views')\n- STORY: views, reach, replies, navigation, profile_visits, follows (impressions is deprecated; use views)\n\nIf you see code (#100) \"metric not supported for media type\", narrow the metrics list to the matching subset above. If you see code (#10), it's almost always App Review (#2 above).";
|
|
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>;
|