openai-ads-mcp 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.
@@ -0,0 +1,240 @@
1
+ import { z } from "zod";
2
+ import { badRequest, budgetGuard, coerceList, getClientOrError, handleApiError, isRecord, ok, optionalParams, usdToMicros, validateIntRange, validateNonEmpty, validateOption, validateUnixTime, } from "../core.js";
3
+ const CAMPAIGN_STATES = new Set(["activate", "pause", "archive"]);
4
+ const CAMPAIGN_STATUSES = new Set(["active", "paused", "archived"]);
5
+ export function locationsPayload(locations) {
6
+ if (locations === undefined || locations === null)
7
+ return [null, null];
8
+ const [entries, error] = coerceList(locations, "locations");
9
+ if (error)
10
+ return [null, error];
11
+ const include = [];
12
+ for (const entry of entries ?? []) {
13
+ if (typeof entry === "string") {
14
+ include.push({ id: entry });
15
+ }
16
+ else if (isRecord(entry)) {
17
+ if (!entry.id)
18
+ return [null, badRequest("Each location object must include id.")];
19
+ include.push(entry);
20
+ }
21
+ else {
22
+ return [null, badRequest("locations must contain location ids or objects.")];
23
+ }
24
+ }
25
+ return [{ locations: { include } }, null];
26
+ }
27
+ export function buildCampaignBody(input) {
28
+ const body = {};
29
+ const create = input.create === true;
30
+ if (input.name !== undefined && input.name !== null) {
31
+ const error = validateNonEmpty("name", input.name, 3, 1000);
32
+ if (error)
33
+ return [null, error];
34
+ body.name = String(input.name).trim();
35
+ }
36
+ else if (create) {
37
+ return [null, badRequest("name is required.")];
38
+ }
39
+ const status = input.status ?? (create ? "paused" : undefined);
40
+ if (status !== undefined) {
41
+ if (!CAMPAIGN_STATUSES.has(status))
42
+ return [null, badRequest("status must be active, paused, or archived.")];
43
+ if (create && status !== "paused") {
44
+ return [null, badRequest("Create tools only create paused campaigns. Use set_campaign_state after review.")];
45
+ }
46
+ body.status = status;
47
+ }
48
+ if (input.budget_usd !== undefined && input.budget_usd !== null) {
49
+ const budgetUsd = Number(input.budget_usd);
50
+ const error = budgetGuard(budgetUsd, input.confirm_budget === true);
51
+ if (error)
52
+ return [null, error];
53
+ body.budget = { lifetime_spend_limit_micros: usdToMicros(budgetUsd) };
54
+ }
55
+ else if (create) {
56
+ return [null, badRequest("budget_usd is required.")];
57
+ }
58
+ if (input.description !== undefined)
59
+ body.description = input.description;
60
+ const startError = validateUnixTime("start_time", input.start_time);
61
+ if (startError)
62
+ return [null, startError];
63
+ const endError = validateUnixTime("end_time", input.end_time);
64
+ if (endError)
65
+ return [null, endError];
66
+ if (input.start_time !== undefined && input.start_time !== null)
67
+ body.start_time = Number(input.start_time);
68
+ if (input.end_time !== undefined && input.end_time !== null)
69
+ body.end_time = Number(input.end_time);
70
+ if (body.start_time !== undefined && body.end_time !== undefined && Number(body.end_time) <= Number(body.start_time)) {
71
+ return [null, badRequest("end_time must be after start_time.")];
72
+ }
73
+ if (input.mode !== undefined && input.mode !== null) {
74
+ if (input.mode !== "product_feed")
75
+ return [null, badRequest("mode must be product_feed when provided.")];
76
+ body.mode = input.mode;
77
+ }
78
+ const [targeting, targetingError] = locationsPayload(input.locations);
79
+ if (targetingError)
80
+ return [null, targetingError];
81
+ if (targeting)
82
+ body.targeting = targeting;
83
+ if (!Object.keys(body).length)
84
+ return [null, badRequest("Provide at least one field to update.")];
85
+ return [body, null];
86
+ }
87
+ async function listCampaigns(args) {
88
+ const limit = Number(args.limit ?? 20);
89
+ const limitError = validateIntRange("limit", limit, 1, 500);
90
+ if (limitError)
91
+ return limitError;
92
+ const { client, error } = getClientOrError();
93
+ if (error)
94
+ return error;
95
+ try {
96
+ return ok(await client.get("/campaigns", optionalParams({ limit, after: args.after, before: args.before, order: args.order ?? "desc" })));
97
+ }
98
+ catch (apiError) {
99
+ return handleApiError(apiError);
100
+ }
101
+ }
102
+ async function getCampaign(args) {
103
+ const error = validateNonEmpty("campaign_id", args.campaign_id);
104
+ if (error)
105
+ return error;
106
+ const { client, error: clientError } = getClientOrError();
107
+ if (clientError)
108
+ return clientError;
109
+ try {
110
+ return ok(await client.get(`/campaigns/${args.campaign_id}`));
111
+ }
112
+ catch (apiError) {
113
+ return handleApiError(apiError);
114
+ }
115
+ }
116
+ async function createCampaign(args) {
117
+ const [body, bodyError] = buildCampaignBody({ ...args, status: String(args.status ?? "paused"), create: true });
118
+ if (bodyError)
119
+ return bodyError;
120
+ const { client, error } = getClientOrError();
121
+ if (error)
122
+ return error;
123
+ try {
124
+ return ok(await client.post("/campaigns", body));
125
+ }
126
+ catch (apiError) {
127
+ return handleApiError(apiError);
128
+ }
129
+ }
130
+ async function updateCampaign(args) {
131
+ const campaignError = validateNonEmpty("campaign_id", args.campaign_id);
132
+ if (campaignError)
133
+ return campaignError;
134
+ const [body, bodyError] = buildCampaignBody(args);
135
+ if (bodyError)
136
+ return bodyError;
137
+ const { client, error } = getClientOrError();
138
+ if (error)
139
+ return error;
140
+ try {
141
+ return ok(await client.post(`/campaigns/${args.campaign_id}`, body));
142
+ }
143
+ catch (apiError) {
144
+ return handleApiError(apiError);
145
+ }
146
+ }
147
+ async function setCampaignState(args) {
148
+ const campaignError = validateNonEmpty("campaign_id", args.campaign_id);
149
+ if (campaignError)
150
+ return campaignError;
151
+ const state = String(args.state);
152
+ const stateError = validateOption("state", state, CAMPAIGN_STATES);
153
+ if (stateError)
154
+ return stateError;
155
+ const { client, error } = getClientOrError();
156
+ if (error)
157
+ return error;
158
+ try {
159
+ return ok(await client.post(`/campaigns/${args.campaign_id}/${state}`));
160
+ }
161
+ catch (apiError) {
162
+ return handleApiError(apiError);
163
+ }
164
+ }
165
+ const orderSchema = z.enum(["asc", "desc"]).default("desc");
166
+ const campaignStatusSchema = z.enum(["paused", "active"]).default("paused");
167
+ const updateCampaignStatusSchema = z.enum(["active", "paused", "archived"]).optional();
168
+ export const campaignTools = [
169
+ {
170
+ name: "list_campaigns",
171
+ description: "List campaigns in the authenticated ad account with cursor pagination.",
172
+ inputSchema: {
173
+ limit: z.number().int().default(20),
174
+ after: z.string().optional(),
175
+ before: z.string().optional(),
176
+ order: orderSchema,
177
+ },
178
+ argNames: ["limit", "after", "before", "order"],
179
+ handler: listCampaigns,
180
+ },
181
+ {
182
+ name: "get_campaign",
183
+ description: "Get one campaign by id.",
184
+ inputSchema: { campaign_id: z.string() },
185
+ argNames: ["campaign_id"],
186
+ handler: getCampaign,
187
+ },
188
+ {
189
+ name: "create_campaign",
190
+ description: "Create an OpenAI Ads campaign, safely paused by default, with a guarded lifetime budget.",
191
+ inputSchema: {
192
+ name: z.string(),
193
+ budget_usd: z.number(),
194
+ status: campaignStatusSchema,
195
+ description: z.string().optional(),
196
+ start_time: z.number().int().optional(),
197
+ end_time: z.number().int().optional(),
198
+ mode: z.enum(["product_feed"]).optional(),
199
+ locations: z.any().optional(),
200
+ confirm_budget: z.boolean().default(false),
201
+ },
202
+ argNames: ["name", "budget_usd", "status", "description", "start_time", "end_time", "mode", "locations", "confirm_budget"],
203
+ writes: true,
204
+ destructive: true,
205
+ openWorld: true,
206
+ handler: createCampaign,
207
+ },
208
+ {
209
+ name: "update_campaign",
210
+ description: "Update campaign fields. Budget changes use the same ceiling guard as create_campaign.",
211
+ inputSchema: {
212
+ campaign_id: z.string(),
213
+ name: z.string().optional(),
214
+ budget_usd: z.number().optional(),
215
+ status: updateCampaignStatusSchema,
216
+ description: z.string().optional(),
217
+ start_time: z.number().int().optional(),
218
+ end_time: z.number().int().optional(),
219
+ mode: z.enum(["product_feed"]).optional(),
220
+ locations: z.any().optional(),
221
+ confirm_budget: z.boolean().default(false),
222
+ },
223
+ argNames: ["campaign_id", "name", "budget_usd", "status", "description", "start_time", "end_time", "mode", "locations", "confirm_budget"],
224
+ writes: true,
225
+ destructive: true,
226
+ openWorld: true,
227
+ handler: updateCampaign,
228
+ },
229
+ {
230
+ name: "set_campaign_state",
231
+ description: "Activate, pause, or archive a campaign. Activation can start real spend when child layers are active.",
232
+ inputSchema: { campaign_id: z.string(), state: z.enum(["activate", "pause", "archive"]) },
233
+ argNames: ["campaign_id", "state"],
234
+ writes: true,
235
+ destructive: true,
236
+ openWorld: true,
237
+ handler: setCampaignState,
238
+ },
239
+ ];
240
+ //# sourceMappingURL=campaigns.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"campaigns.js","sourceRoot":"","sources":["../../src/tools/campaigns.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { type AdsToolDefinition, type JsonRecord } from "../core.js";
2
+ export declare function validateConversionEvents(events: unknown): [JsonRecord[] | null, string | null];
3
+ export declare const conversionTools: AdsToolDefinition[];
@@ -0,0 +1,195 @@
1
+ import { z } from "zod";
2
+ import { badRequest, coerceList, coerceStringList, conversionTimeBoundsMs, getClientOrError, handleApiError, isRecord, ok, optionalParams, validateIntRange, validateNonEmpty, } from "../core.js";
3
+ const ACTION_SOURCES = new Set(["web", "mobile_app", "offline", "physical_store", "phone_call", "email", "other"]);
4
+ function sourceIdsPayload(sourceIds) {
5
+ const [ids, error] = coerceStringList(sourceIds, "source_ids");
6
+ if (error)
7
+ return [null, error];
8
+ if (!ids?.length)
9
+ return [null, badRequest("source_ids must include at least one id.")];
10
+ return [ids, null];
11
+ }
12
+ async function manageConversions(args) {
13
+ const { client, error } = getClientOrError();
14
+ if (error)
15
+ return error;
16
+ try {
17
+ if (args.action === "create_pixel") {
18
+ const nameError = validateNonEmpty("name", args.name, 3, 1000);
19
+ if (nameError)
20
+ return nameError;
21
+ return ok(await client.post("/conversions/pixels", { name: args.name, client_type: args.client_type ?? "web" }));
22
+ }
23
+ if (args.action === "create_api_key") {
24
+ const nameError = validateNonEmpty("name", args.name, 3, 1000);
25
+ if (nameError)
26
+ return nameError;
27
+ return ok(await client.post("/conversions/api_keys", { name: args.name }));
28
+ }
29
+ if (args.action === "get_event_settings") {
30
+ const limit = Number(args.limit ?? 20);
31
+ const limitError = validateIntRange("limit", limit, 1, 500);
32
+ if (limitError)
33
+ return limitError;
34
+ return ok(await client.get("/conversions/event_settings", optionalParams({
35
+ limit,
36
+ after: args.after,
37
+ before: args.before,
38
+ order: args.order ?? "desc",
39
+ })));
40
+ }
41
+ if (args.action === "set_event_settings") {
42
+ const nameError = validateNonEmpty("name", args.name, 1, 1000);
43
+ if (nameError)
44
+ return nameError;
45
+ const eventError = validateNonEmpty("event_type", args.event_type, 1, 100);
46
+ if (eventError)
47
+ return eventError;
48
+ const attributionWindowDays = Number(args.attribution_window_days);
49
+ if (!Number.isFinite(attributionWindowDays) || attributionWindowDays < 1) {
50
+ return badRequest("attribution_window_days must be at least 1.");
51
+ }
52
+ const [sourceIds, sourceIdsError] = sourceIdsPayload(args.source_ids);
53
+ if (sourceIdsError)
54
+ return sourceIdsError;
55
+ const body = {
56
+ name: args.name,
57
+ event_type: args.event_type,
58
+ attribution_window_days: attributionWindowDays,
59
+ source_ids: sourceIds,
60
+ };
61
+ if (args.custom_event_name)
62
+ body.custom_event_name = args.custom_event_name;
63
+ return ok(await client.post("/conversions/event_settings", body));
64
+ }
65
+ if (args.action === "get_insights") {
66
+ const levelError = validateNonEmpty("aggregation_level", args.aggregation_level, 1, 100);
67
+ if (levelError)
68
+ return levelError;
69
+ const [timeRanges, timeRangesError] = coerceStringList(args.time_ranges, "time_ranges");
70
+ if (timeRangesError)
71
+ return timeRangesError;
72
+ const [entityIds, entityIdsError] = coerceStringList(args.entity_ids, "entity_ids");
73
+ if (entityIdsError)
74
+ return entityIdsError;
75
+ if (!timeRanges?.length || !entityIds?.length) {
76
+ return badRequest("time_ranges and entity_ids are required for get_insights.");
77
+ }
78
+ return ok(await client.post("/conversions/insights", {
79
+ aggregation_level: args.aggregation_level,
80
+ time_ranges: timeRanges,
81
+ entity_ids: entityIds,
82
+ }));
83
+ }
84
+ return badRequest(`Unknown action: ${String(args.action)}`);
85
+ }
86
+ catch (apiError) {
87
+ return handleApiError(apiError);
88
+ }
89
+ }
90
+ export function validateConversionEvents(events) {
91
+ const [parsed, error] = coerceList(events, "events");
92
+ if (error)
93
+ return [null, error];
94
+ if (!parsed?.length)
95
+ return [null, badRequest("events must include at least one event.")];
96
+ if (parsed.length > 1000)
97
+ return [null, badRequest("send_conversions accepts at most 1000 events per call.")];
98
+ const [earliest, latest] = conversionTimeBoundsMs();
99
+ const out = [];
100
+ for (const [index, event] of parsed.entries()) {
101
+ if (!isRecord(event))
102
+ return [null, badRequest(`events[${index}] must be an object.`)];
103
+ if (!event.id)
104
+ return [null, badRequest(`events[${index}].id is required.`)];
105
+ if (!event.type)
106
+ return [null, badRequest(`events[${index}].type is required.`)];
107
+ if (!Number.isInteger(event.timestamp_ms)) {
108
+ return [null, badRequest(`events[${index}].timestamp_ms must be an integer.`)];
109
+ }
110
+ const timestampMs = event.timestamp_ms;
111
+ if (timestampMs < earliest)
112
+ return [null, badRequest("events include a timestamp older than 7 days.")];
113
+ if (timestampMs > latest)
114
+ return [null, badRequest("events include a timestamp more than 10 minutes in the future.")];
115
+ const actionSource = String(event.action_source);
116
+ if (!ACTION_SOURCES.has(actionSource)) {
117
+ return [null, badRequest(`events[${index}].action_source must be one of ${[...ACTION_SOURCES].sort().join(", ")}.`)];
118
+ }
119
+ if (actionSource === "web" && !event.source_url) {
120
+ return [null, badRequest("source_url is required for web conversion events.")];
121
+ }
122
+ out.push(event);
123
+ }
124
+ return [out, null];
125
+ }
126
+ async function sendConversions(args) {
127
+ const pixelError = validateNonEmpty("pixel_id", args.pixel_id);
128
+ if (pixelError)
129
+ return pixelError;
130
+ const [events, eventsError] = validateConversionEvents(args.events);
131
+ if (eventsError)
132
+ return eventsError;
133
+ const { client, error } = getClientOrError();
134
+ if (error)
135
+ return error;
136
+ try {
137
+ return ok(await client.postConversions(String(args.pixel_id), events ?? []));
138
+ }
139
+ catch (apiError) {
140
+ return handleApiError(apiError);
141
+ }
142
+ }
143
+ export const conversionTools = [
144
+ {
145
+ name: "manage_conversions",
146
+ description: "Manage conversion pixels, API keys, event settings, and conversion reporting.",
147
+ inputSchema: {
148
+ action: z.enum(["create_pixel", "create_api_key", "get_event_settings", "set_event_settings", "get_insights"]),
149
+ name: z.string().optional(),
150
+ client_type: z.enum(["web"]).default("web"),
151
+ event_type: z.string().optional(),
152
+ custom_event_name: z.string().optional(),
153
+ attribution_window_days: z.number().int().optional(),
154
+ source_ids: z.any().optional(),
155
+ aggregation_level: z.string().optional(),
156
+ time_ranges: z.any().optional(),
157
+ entity_ids: z.any().optional(),
158
+ limit: z.number().int().default(20),
159
+ after: z.string().optional(),
160
+ before: z.string().optional(),
161
+ order: z.enum(["asc", "desc"]).default("desc"),
162
+ },
163
+ argNames: [
164
+ "action",
165
+ "name",
166
+ "client_type",
167
+ "event_type",
168
+ "custom_event_name",
169
+ "attribution_window_days",
170
+ "source_ids",
171
+ "aggregation_level",
172
+ "time_ranges",
173
+ "entity_ids",
174
+ "limit",
175
+ "after",
176
+ "before",
177
+ "order",
178
+ ],
179
+ writes: true,
180
+ handler: manageConversions,
181
+ },
182
+ {
183
+ name: "send_conversions",
184
+ description: "Send conversion events to the OpenAI conversion ingest host after local privacy-safe validation.",
185
+ inputSchema: {
186
+ pixel_id: z.string(),
187
+ events: z.any(),
188
+ },
189
+ argNames: ["pixel_id", "events"],
190
+ writes: true,
191
+ openWorld: true,
192
+ handler: sendConversions,
193
+ },
194
+ ];
195
+ //# sourceMappingURL=conversions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conversions.js","sourceRoot":"","sources":["../../src/tools/conversions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { type AdsToolDefinition } from "../core.js";
2
+ export declare const insightTools: AdsToolDefinition[];
@@ -0,0 +1,153 @@
1
+ import { z } from "zod";
2
+ import { badRequest, coerceJson, coerceStringList, getClientOrError, handleApiError, isRecord, jsonQueryList, okSized, optionalParams, validateIntRange, validateOption, } from "../core.js";
3
+ const INSIGHT_SCOPES = new Set(["account", "campaign", "ad_group", "ad"]);
4
+ const TIME_GRANULARITIES = new Set(["hourly", "daily", "monthly", "none"]);
5
+ const SEGMENTS = new Set(["product", "country", "device"]);
6
+ const FILTER_OPERATORS = new Set(["IN", "GREATER_THAN", "LESS_THAN"]);
7
+ function insightsPath(scope, entityId) {
8
+ if (scope === "account")
9
+ return ["/ad_account/insights", null];
10
+ if (!entityId)
11
+ return [null, badRequest("entity_id is required for campaign, ad_group, and ad insights.")];
12
+ if (scope === "campaign")
13
+ return [`/campaigns/${entityId}/insights`, null];
14
+ if (scope === "ad_group")
15
+ return [`/ad_groups/${entityId}/insights`, null];
16
+ if (scope === "ad")
17
+ return [`/ads/${entityId}/insights`, null];
18
+ return [null, badRequest("scope must be account, campaign, ad_group, or ad.")];
19
+ }
20
+ function oneTimeRange(value) {
21
+ if (value === undefined || value === null)
22
+ return [null, null];
23
+ if (typeof value === "string") {
24
+ const [parsed, error] = coerceJson(value, "time_range");
25
+ if (error)
26
+ return [null, error];
27
+ value = parsed;
28
+ }
29
+ if (isRecord(value))
30
+ return [[JSON.stringify(value)], null];
31
+ if (Array.isArray(value)) {
32
+ if (value.length !== 1)
33
+ return [null, badRequest("time_range accepts one range object.")];
34
+ let item = value[0];
35
+ if (typeof item === "string") {
36
+ const [parsed, error] = coerceJson(item, "time_range");
37
+ if (error)
38
+ return [null, error];
39
+ item = parsed;
40
+ }
41
+ if (!isRecord(item))
42
+ return [null, badRequest("time_range must contain an object.")];
43
+ return [[JSON.stringify(item)], null];
44
+ }
45
+ return [null, badRequest("time_range must be an object or JSON object string.")];
46
+ }
47
+ function validateFilters(value) {
48
+ const [encoded, error] = jsonQueryList(value, "filters");
49
+ if (error || encoded === null)
50
+ return [null, error];
51
+ for (const item of encoded) {
52
+ const parsed = JSON.parse(item);
53
+ if (!FILTER_OPERATORS.has(String(parsed.operator)))
54
+ return [null, badRequest("filter operator must be IN, GREATER_THAN, or LESS_THAN.")];
55
+ if (!("field" in parsed) || !("value" in parsed))
56
+ return [null, badRequest("Each filter must include field, operator, and value.")];
57
+ }
58
+ return [encoded, null];
59
+ }
60
+ function validateSort(value) {
61
+ const [encoded, error] = jsonQueryList(value, "sort");
62
+ if (error || encoded === null)
63
+ return [null, error];
64
+ for (const item of encoded) {
65
+ const parsed = JSON.parse(item);
66
+ if (!["asc", "desc"].includes(String(parsed.direction)))
67
+ return [null, badRequest("sort direction must be asc or desc.")];
68
+ if (!("field" in parsed))
69
+ return [null, badRequest("Each sort entry must include field and direction.")];
70
+ }
71
+ return [encoded, null];
72
+ }
73
+ async function getInsights(args) {
74
+ const scope = String(args.scope);
75
+ const scopeError = validateOption("scope", scope, INSIGHT_SCOPES);
76
+ if (scopeError)
77
+ return scopeError;
78
+ const timeGranularity = String(args.time_granularity ?? "daily");
79
+ const granularityError = validateOption("time_granularity", timeGranularity, TIME_GRANULARITIES);
80
+ if (granularityError)
81
+ return granularityError;
82
+ const limit = Number(args.limit ?? 20);
83
+ const limitError = validateIntRange("limit", limit, 1, 2000);
84
+ if (limitError)
85
+ return limitError;
86
+ const [path, pathError] = insightsPath(scope, args.entity_id);
87
+ if (pathError)
88
+ return pathError;
89
+ const [timeRanges, timeError] = oneTimeRange(args.time_range);
90
+ if (timeError)
91
+ return timeError;
92
+ const [segments, segmentsError] = coerceStringList(args.segments, "segments");
93
+ if (segmentsError)
94
+ return segmentsError;
95
+ if (segments && segments.length > 1)
96
+ return badRequest("segments supports at most one value.");
97
+ if (segments) {
98
+ const unknown = segments.filter((segment) => !SEGMENTS.has(segment));
99
+ if (unknown.length)
100
+ return badRequest(`Invalid segments: ${unknown.join(", ")}.`);
101
+ }
102
+ const [fields, fieldsError] = coerceStringList(args.fields, "fields");
103
+ if (fieldsError)
104
+ return fieldsError;
105
+ const [filters, filtersError] = validateFilters(args.filters);
106
+ if (filtersError)
107
+ return filtersError;
108
+ const [sort, sortError] = validateSort(args.sort);
109
+ if (sortError)
110
+ return sortError;
111
+ const { client, error } = getClientOrError();
112
+ if (error)
113
+ return error;
114
+ try {
115
+ return okSized(await client.get(path, optionalParams({
116
+ time_granularity: timeGranularity,
117
+ time_ranges: timeRanges,
118
+ segments,
119
+ fields,
120
+ filters,
121
+ sort,
122
+ limit,
123
+ after: args.after,
124
+ before: args.before,
125
+ })), String(args.response_format ?? "concise"), "Use after or before cursors, narrow time_range, or request fewer fields.");
126
+ }
127
+ catch (apiError) {
128
+ return handleApiError(apiError);
129
+ }
130
+ }
131
+ export const insightTools = [
132
+ {
133
+ name: "get_insights",
134
+ description: "Get performance insights for account, campaign, ad group, or ad scope. Supports fields, filters, sort, product/country/device segments, time ranges, and cursor pagination.",
135
+ inputSchema: {
136
+ scope: z.enum(["account", "campaign", "ad_group", "ad"]),
137
+ entity_id: z.string().optional(),
138
+ time_granularity: z.enum(["hourly", "daily", "monthly", "none"]).default("daily"),
139
+ time_range: z.any().optional(),
140
+ segments: z.any().optional(),
141
+ fields: z.any().optional(),
142
+ filters: z.any().optional(),
143
+ sort: z.any().optional(),
144
+ limit: z.number().int().default(20),
145
+ after: z.string().optional(),
146
+ before: z.string().optional(),
147
+ response_format: z.enum(["concise", "detailed"]).default("concise"),
148
+ },
149
+ argNames: ["scope", "entity_id", "time_granularity", "time_range", "segments", "fields", "filters", "sort", "limit", "after", "before", "response_format"],
150
+ handler: getInsights,
151
+ },
152
+ ];
153
+ //# sourceMappingURL=insights.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"insights.js","sourceRoot":"","sources":["../../src/tools/insights.ts"],"names":[],"mappings":"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"}