@attrkit/mcp 0.4.0 → 0.4.2
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/dist/cli.js +46 -7
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -14082,15 +14082,16 @@ function toToolResult(result) {
|
|
|
14082
14082
|
const expectedResponse = result.expectedResponse ?? "json";
|
|
14083
14083
|
const isEmptySuccess = result.status === 204 && (result.rawBody === undefined || result.rawBody === "");
|
|
14084
14084
|
const isJsonEnvelope = result.json !== null && typeof result.json === "object" && !Array.isArray(result.json) && Object.hasOwn(result.json, "data");
|
|
14085
|
-
const
|
|
14085
|
+
const contentType = (result.contentType ?? "").toLowerCase();
|
|
14086
|
+
const isExpectedText = expectedResponse === "text" && typeof result.json === "string" && (contentType.includes("text/csv") || contentType.includes("application/csv"));
|
|
14086
14087
|
if (!isEmptySuccess && !isJsonEnvelope && !isExpectedText) {
|
|
14087
|
-
const
|
|
14088
|
+
const reportedContentType = result.contentType ?? "unknown content type";
|
|
14088
14089
|
const received = result.json === null ? "an empty body" : Array.isArray(result.json) ? "a JSON array" : typeof result.json === "object" ? "a JSON object without a data field" : `a ${typeof result.json} body`;
|
|
14089
14090
|
const body = result.rawBody ?? (typeof result.json === "string" ? result.json : JSON.stringify(result.json, null, 2));
|
|
14090
14091
|
return {
|
|
14091
14092
|
content: [{
|
|
14092
14093
|
type: "text",
|
|
14093
|
-
text: `AttrKit API error (${result.status}): invalid_response: expected a JSON data envelope but received ${received} with Content-Type ${
|
|
14094
|
+
text: `AttrKit API error (${result.status}): invalid_response: expected a JSON data envelope but received ${received} with Content-Type ${reportedContentType}. Body:
|
|
14094
14095
|
${body}`
|
|
14095
14096
|
}],
|
|
14096
14097
|
isError: true
|
|
@@ -14102,7 +14103,7 @@ ${body}`
|
|
|
14102
14103
|
structuredContent: structured
|
|
14103
14104
|
};
|
|
14104
14105
|
}
|
|
14105
|
-
var SERVER_VERSION = "0.4.
|
|
14106
|
+
var SERVER_VERSION = "0.4.2";
|
|
14106
14107
|
var periodSchema = z4.enum(["7d", "30d", "90d", "all"]).describe("Reporting window. Defaults to 30d.").optional();
|
|
14107
14108
|
var appIdSchema = z4.string().describe("Optional app id to scope the result to one app.").optional();
|
|
14108
14109
|
var requiredAppIdSchema = z4.string().describe("The AttrKit app id.");
|
|
@@ -14157,16 +14158,19 @@ function createServer(config, fetchImpl) {
|
|
|
14157
14158
|
const server = new McpServer({ name: "attrkit", version: SERVER_VERSION });
|
|
14158
14159
|
const call = (path, options) => callApi(config, path, { fetchImpl, ...options });
|
|
14159
14160
|
server.registerTool("whoami", {
|
|
14161
|
+
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
|
14160
14162
|
title: "Inspect management-key scope",
|
|
14161
14163
|
description: "Return the authenticated workspace, plan, app restriction and read/write scopes.",
|
|
14162
14164
|
inputSchema: {}
|
|
14163
14165
|
}, async () => toToolResult(await call("/api/v1/whoami")));
|
|
14164
14166
|
server.registerTool("get_usage_cap", {
|
|
14167
|
+
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
|
14165
14168
|
title: "Get the workspace usage cap",
|
|
14166
14169
|
description: "Return the workspace's monthly qualified-install cap, alert email, current billing period and usage. Requires a workspace-scoped read key.",
|
|
14167
14170
|
inputSchema: {}
|
|
14168
14171
|
}, async () => toToolResult(await call("/api/v1/workspace/usage-cap")));
|
|
14169
14172
|
server.registerTool("set_usage_cap", {
|
|
14173
|
+
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
|
|
14170
14174
|
title: "Set the workspace usage cap",
|
|
14171
14175
|
description: "Set a monthly qualified-install cap of at least 10,000 and its alert email. Pass null for both values to clear the cap. Requires a workspace-scoped write key.",
|
|
14172
14176
|
inputSchema: {
|
|
@@ -14198,11 +14202,13 @@ function createServer(config, fetchImpl) {
|
|
|
14198
14202
|
}));
|
|
14199
14203
|
});
|
|
14200
14204
|
server.registerTool("list_apps", {
|
|
14205
|
+
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
|
14201
14206
|
title: "List apps",
|
|
14202
14207
|
description: "List the iOS and Android apps in your AttrKit workspace (id, name, platform, bundle id, store id, status).",
|
|
14203
14208
|
inputSchema: {}
|
|
14204
14209
|
}, async () => toToolResult(await call("/api/v1/apps")));
|
|
14205
14210
|
server.registerTool("create_app", {
|
|
14211
|
+
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
|
|
14206
14212
|
title: "Create an app",
|
|
14207
14213
|
description: "Create an iOS or Android app without the web UI. Returns the publishable key and a one-time app-scoped management key.",
|
|
14208
14214
|
inputSchema: {
|
|
@@ -14235,11 +14241,13 @@ function createServer(config, fetchImpl) {
|
|
|
14235
14241
|
}
|
|
14236
14242
|
})));
|
|
14237
14243
|
server.registerTool("get_app", {
|
|
14244
|
+
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
|
14238
14245
|
title: "Get an app",
|
|
14239
14246
|
description: "Return one app's configuration.",
|
|
14240
14247
|
inputSchema: { app_id: requiredAppIdSchema }
|
|
14241
14248
|
}, async ({ app_id }) => toToolResult(await call(`/api/v1/apps/${encodeURIComponent(app_id)}`)));
|
|
14242
14249
|
server.registerTool("update_app", {
|
|
14250
|
+
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
|
|
14243
14251
|
title: "Update an app",
|
|
14244
14252
|
description: "Update app metadata, store destination, timezone or device-matching mode.",
|
|
14245
14253
|
inputSchema: {
|
|
@@ -14274,6 +14282,7 @@ function createServer(config, fetchImpl) {
|
|
|
14274
14282
|
}
|
|
14275
14283
|
})));
|
|
14276
14284
|
server.registerTool("archive_app", {
|
|
14285
|
+
annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: false, openWorldHint: true },
|
|
14277
14286
|
title: "Archive an app",
|
|
14278
14287
|
description: "Archive an app and remove it from active customer operations.",
|
|
14279
14288
|
inputSchema: { app_id: requiredAppIdSchema }
|
|
@@ -14281,11 +14290,13 @@ function createServer(config, fetchImpl) {
|
|
|
14281
14290
|
method: "DELETE"
|
|
14282
14291
|
})));
|
|
14283
14292
|
server.registerTool("get_publishable_key", {
|
|
14293
|
+
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
|
14284
14294
|
title: "Get an app publishable key",
|
|
14285
14295
|
description: "Reveal the recoverable SDK publishable key for an app.",
|
|
14286
14296
|
inputSchema: { app_id: requiredAppIdSchema }
|
|
14287
14297
|
}, async ({ app_id }) => toToolResult(await call(`/api/v1/apps/${encodeURIComponent(app_id)}/publishable-key`)));
|
|
14288
14298
|
server.registerTool("rotate_publishable_key", {
|
|
14299
|
+
annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: false, openWorldHint: true },
|
|
14289
14300
|
title: "Rotate an app publishable key",
|
|
14290
14301
|
description: "Issue a new SDK publishable key and return the old-key grace deadline.",
|
|
14291
14302
|
inputSchema: {
|
|
@@ -14294,11 +14305,13 @@ function createServer(config, fetchImpl) {
|
|
|
14294
14305
|
}
|
|
14295
14306
|
}, async ({ app_id, idempotency_key }) => toToolResult(await call(`/api/v1/apps/${encodeURIComponent(app_id)}/publishable-key`, { method: "POST", idempotencyKey: idempotency_key })));
|
|
14296
14307
|
server.registerTool("list_api_keys", {
|
|
14308
|
+
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
|
14297
14309
|
title: "List management keys",
|
|
14298
14310
|
description: "List masked workspace and app management keys. Secret plaintext is never returned.",
|
|
14299
14311
|
inputSchema: {}
|
|
14300
14312
|
}, async () => toToolResult(await call("/api/v1/api-keys")));
|
|
14301
14313
|
server.registerTool("create_api_key", {
|
|
14314
|
+
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
|
|
14302
14315
|
title: "Create a management key",
|
|
14303
14316
|
description: "Create a read-only or read/write workspace or app key. The secret is returned once.",
|
|
14304
14317
|
inputSchema: {
|
|
@@ -14313,6 +14326,7 @@ function createServer(config, fetchImpl) {
|
|
|
14313
14326
|
body: { label, scopes, app_id: app_id ?? null }
|
|
14314
14327
|
})));
|
|
14315
14328
|
server.registerTool("revoke_api_key", {
|
|
14329
|
+
annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: false, openWorldHint: true },
|
|
14316
14330
|
title: "Revoke a management key",
|
|
14317
14331
|
description: "Immediately revoke a management key by id.",
|
|
14318
14332
|
inputSchema: { key_id: z4.string().uuid() }
|
|
@@ -14320,6 +14334,7 @@ function createServer(config, fetchImpl) {
|
|
|
14320
14334
|
method: "DELETE"
|
|
14321
14335
|
})));
|
|
14322
14336
|
server.registerTool("list_links", {
|
|
14337
|
+
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
|
14323
14338
|
title: "List campaign links",
|
|
14324
14339
|
description: "List tracking links, optionally for one app.",
|
|
14325
14340
|
inputSchema: {
|
|
@@ -14335,11 +14350,13 @@ function createServer(config, fetchImpl) {
|
|
|
14335
14350
|
}
|
|
14336
14351
|
})));
|
|
14337
14352
|
server.registerTool("list_campaigns", {
|
|
14353
|
+
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
|
14338
14354
|
title: "List campaigns",
|
|
14339
14355
|
description: "List ad campaigns with their honest profit surface: the scale/cut/hold call, profit p05/p50/p95, spend, retention, and payback. Use this to see how campaigns are performing.",
|
|
14340
14356
|
inputSchema: { app_id: appIdSchema, period: periodSchema }
|
|
14341
14357
|
}, async ({ app_id, period }) => toToolResult(await call("/api/v1/reports/campaigns", { query: { appId: app_id, period } })));
|
|
14342
14358
|
server.registerTool("list_ads", {
|
|
14359
|
+
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
|
14343
14360
|
title: "List creative-level ad performance",
|
|
14344
14361
|
description: "Return ad and ad-set performance, evidence tiers, ROAS, CPA, CPC and modeled remainders.",
|
|
14345
14362
|
inputSchema: {
|
|
@@ -14355,6 +14372,7 @@ function createServer(config, fetchImpl) {
|
|
|
14355
14372
|
}
|
|
14356
14373
|
})));
|
|
14357
14374
|
server.registerTool("list_recent_events", {
|
|
14375
|
+
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
|
14358
14376
|
title: "List recent events and installs",
|
|
14359
14377
|
description: "Return the same recent attribution events and installs visible on the Live dashboard.",
|
|
14360
14378
|
inputSchema: {
|
|
@@ -14368,11 +14386,13 @@ function createServer(config, fetchImpl) {
|
|
|
14368
14386
|
}
|
|
14369
14387
|
})));
|
|
14370
14388
|
server.registerTool("get_campaign_decision", {
|
|
14389
|
+
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
|
14371
14390
|
title: "Get campaign decisions (scale / cut / hold)",
|
|
14372
14391
|
description: "Return AttrKit's profit DECISIONS for your campaigns: the scale/cut/hold call and confidence, computed by the attribution engine. Report the `call` VERBATIM — do not recompute or override it; when it says not_enough_data, say so. This is the tool to drive budget automation.",
|
|
14373
14392
|
inputSchema: { app_id: appIdSchema }
|
|
14374
14393
|
}, async ({ app_id }) => toToolResult(await call("/api/v1/decisions", { query: { appId: app_id } })));
|
|
14375
14394
|
server.registerTool("record_campaign_decision", {
|
|
14395
|
+
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
|
|
14376
14396
|
title: "Record a campaign decision",
|
|
14377
14397
|
description: "Freeze a scale/cut/hold decision and its exact model inputs for later maturity evaluation.",
|
|
14378
14398
|
inputSchema: {
|
|
@@ -14438,11 +14458,13 @@ function createServer(config, fetchImpl) {
|
|
|
14438
14458
|
}
|
|
14439
14459
|
})));
|
|
14440
14460
|
server.registerTool("get_attribution_rollup", {
|
|
14461
|
+
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
|
14441
14462
|
title: "Get attribution rollup",
|
|
14442
14463
|
description: "Return the account-level attribution overview: installs accounted-for by evidence class (verified / device-matched / modeled / organic), MER, revenue and data freshness.",
|
|
14443
14464
|
inputSchema: { app_id: appIdSchema, period: periodSchema }
|
|
14444
14465
|
}, async ({ app_id, period }) => toToolResult(await call("/api/v1/reports/overview", { query: { appId: app_id, period } })));
|
|
14445
14466
|
server.registerTool("create_campaign_link", {
|
|
14467
|
+
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
|
|
14446
14468
|
title: "Create a campaign tracking link",
|
|
14447
14469
|
description: "Create a web-to-app tracking link for an ad campaign. Requires a write-scoped API key. Returns the link id and url.",
|
|
14448
14470
|
inputSchema: {
|
|
@@ -14450,10 +14472,11 @@ function createServer(config, fetchImpl) {
|
|
|
14450
14472
|
network: z4.enum(["meta", "google", "tiktok"]).describe("The ad network delivering the campaign."),
|
|
14451
14473
|
destination_url: z4.string().url().describe("The App Store URL to send users to."),
|
|
14452
14474
|
campaign_name: z4.string().max(120).optional().describe("Optional human-readable campaign name."),
|
|
14453
|
-
campaign_id: z4.string().optional().describe("Optional external campaign id."),
|
|
14475
|
+
campaign_id: z4.string().optional().describe("Optional external campaign id. This is the AD NETWORK's own campaign id, not an AttrKit uuid; it is the opposite of import_spend.campaign_id, which requires the AttrKit one."),
|
|
14476
|
+
serve_landing: z4.boolean().optional().describe("Serve the interstitial landing bridge on this link. Defaults to true at the API. The bridge is what captures browser-side context for device matching, so turning it off narrows what can be matched."),
|
|
14454
14477
|
idempotency_key: idempotencyKeySchema
|
|
14455
14478
|
}
|
|
14456
|
-
}, async ({ app_id, network, destination_url, campaign_name, campaign_id, idempotency_key }) => toToolResult(await call("/api/v1/links", {
|
|
14479
|
+
}, async ({ app_id, network, destination_url, campaign_name, campaign_id, serve_landing, idempotency_key }) => toToolResult(await call("/api/v1/links", {
|
|
14457
14480
|
method: "POST",
|
|
14458
14481
|
idempotencyKey: idempotency_key,
|
|
14459
14482
|
body: {
|
|
@@ -14461,10 +14484,12 @@ function createServer(config, fetchImpl) {
|
|
|
14461
14484
|
network,
|
|
14462
14485
|
destinationUrl: destination_url,
|
|
14463
14486
|
...campaign_name ? { campaignName: campaign_name } : {},
|
|
14464
|
-
...campaign_id ? { campaignId: campaign_id } : {}
|
|
14487
|
+
...campaign_id ? { campaignId: campaign_id } : {},
|
|
14488
|
+
...serve_landing === undefined ? {} : { serveLanding: serve_landing }
|
|
14465
14489
|
}
|
|
14466
14490
|
})));
|
|
14467
14491
|
server.registerTool("update_link_status", {
|
|
14492
|
+
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
|
|
14468
14493
|
title: "Enable or disable a campaign link",
|
|
14469
14494
|
description: "Change a tracking link between active and disabled.",
|
|
14470
14495
|
inputSchema: {
|
|
@@ -14474,6 +14499,7 @@ function createServer(config, fetchImpl) {
|
|
|
14474
14499
|
}
|
|
14475
14500
|
}, async ({ link_id, status, idempotency_key }) => toToolResult(await call(`/api/v1/links/${encodeURIComponent(link_id)}`, { method: "PATCH", idempotencyKey: idempotency_key, body: { status } })));
|
|
14476
14501
|
server.registerTool("get_spend", {
|
|
14502
|
+
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
|
14477
14503
|
title: "Get spend and cost models",
|
|
14478
14504
|
description: "Return imported ad spend, cost models, completeness and spend freshness.",
|
|
14479
14505
|
inputSchema: { app_id: appIdSchema }
|
|
@@ -14481,6 +14507,7 @@ function createServer(config, fetchImpl) {
|
|
|
14481
14507
|
query: { appId: app_id }
|
|
14482
14508
|
})));
|
|
14483
14509
|
server.registerTool("import_spend", {
|
|
14510
|
+
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
|
|
14484
14511
|
title: "Import ad spend",
|
|
14485
14512
|
description: "Import campaign or creative-level spend rows.",
|
|
14486
14513
|
inputSchema: {
|
|
@@ -14529,6 +14556,7 @@ function createServer(config, fetchImpl) {
|
|
|
14529
14556
|
}
|
|
14530
14557
|
})));
|
|
14531
14558
|
server.registerTool("set_cost_model", {
|
|
14559
|
+
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
|
|
14532
14560
|
title: "Set an app cost model",
|
|
14533
14561
|
description: "Version commission, payment fees and variable COGS used in profit decisions.",
|
|
14534
14562
|
inputSchema: {
|
|
@@ -14564,6 +14592,7 @@ function createServer(config, fetchImpl) {
|
|
|
14564
14592
|
}
|
|
14565
14593
|
})));
|
|
14566
14594
|
server.registerTool("pull_network_spend", {
|
|
14595
|
+
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
|
|
14567
14596
|
title: "Pull spend from an ad network",
|
|
14568
14597
|
description: "Fetch and import creative-level spend from a configured Meta, Google or TikTok connection.",
|
|
14569
14598
|
inputSchema: {
|
|
@@ -14587,11 +14616,13 @@ function createServer(config, fetchImpl) {
|
|
|
14587
14616
|
}
|
|
14588
14617
|
})));
|
|
14589
14618
|
server.registerTool("list_integrations", {
|
|
14619
|
+
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
|
14590
14620
|
title: "List ad-network integrations",
|
|
14591
14621
|
description: "List redacted ad-network connections and their readiness.",
|
|
14592
14622
|
inputSchema: {}
|
|
14593
14623
|
}, async () => toToolResult(await call("/api/v1/integrations")));
|
|
14594
14624
|
server.registerTool("create_integration", {
|
|
14625
|
+
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
|
|
14595
14626
|
title: "Create an ad-network integration",
|
|
14596
14627
|
description: "Store encrypted network credentials and configure event ownership.",
|
|
14597
14628
|
inputSchema: {
|
|
@@ -14608,6 +14639,7 @@ function createServer(config, fetchImpl) {
|
|
|
14608
14639
|
body: { network, account_ref, credential, owners, enable: enable ?? false }
|
|
14609
14640
|
})));
|
|
14610
14641
|
server.registerTool("update_integration", {
|
|
14642
|
+
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
|
|
14611
14643
|
title: "Update an ad-network integration",
|
|
14612
14644
|
description: "Rotate credentials or enable/disable an integration.",
|
|
14613
14645
|
inputSchema: {
|
|
@@ -14627,16 +14659,19 @@ function createServer(config, fetchImpl) {
|
|
|
14627
14659
|
}
|
|
14628
14660
|
})));
|
|
14629
14661
|
server.registerTool("delete_integration", {
|
|
14662
|
+
annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: false, openWorldHint: true },
|
|
14630
14663
|
title: "Delete an ad-network integration",
|
|
14631
14664
|
description: "Delete a disabled integration. Enabled integrations must be disabled first.",
|
|
14632
14665
|
inputSchema: { connection_id: z4.string() }
|
|
14633
14666
|
}, async ({ connection_id }) => toToolResult(await call(`/api/v1/integrations/${encodeURIComponent(connection_id)}`, { method: "DELETE" })));
|
|
14634
14667
|
server.registerTool("get_revenuecat", {
|
|
14668
|
+
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
|
14635
14669
|
title: "Get RevenueCat configuration",
|
|
14636
14670
|
description: "Return redacted RevenueCat status and the AttrKit webhook URL.",
|
|
14637
14671
|
inputSchema: { app_id: requiredAppIdSchema }
|
|
14638
14672
|
}, async ({ app_id }) => toToolResult(await call(`/api/v1/apps/${encodeURIComponent(app_id)}/revenuecat`)));
|
|
14639
14673
|
server.registerTool("configure_revenuecat", {
|
|
14674
|
+
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
|
|
14640
14675
|
title: "Configure RevenueCat",
|
|
14641
14676
|
description: "Store the RevenueCat provider app id and encrypted authorization secret for an app.",
|
|
14642
14677
|
inputSchema: {
|
|
@@ -14651,11 +14686,13 @@ function createServer(config, fetchImpl) {
|
|
|
14651
14686
|
body: { provider_app_id, authorization_secret }
|
|
14652
14687
|
})));
|
|
14653
14688
|
server.registerTool("list_webhooks", {
|
|
14689
|
+
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
|
14654
14690
|
title: "List outbound webhooks",
|
|
14655
14691
|
description: "List redacted outbound webhook subscriptions.",
|
|
14656
14692
|
inputSchema: {}
|
|
14657
14693
|
}, async () => toToolResult(await call("/api/v1/webhooks")));
|
|
14658
14694
|
server.registerTool("create_webhook", {
|
|
14695
|
+
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
|
|
14659
14696
|
title: "Create an outbound webhook",
|
|
14660
14697
|
description: "Create an SSRF-checked webhook subscription. Returns the signing secret once.",
|
|
14661
14698
|
inputSchema: {
|
|
@@ -14676,11 +14713,13 @@ function createServer(config, fetchImpl) {
|
|
|
14676
14713
|
}
|
|
14677
14714
|
})));
|
|
14678
14715
|
server.registerTool("delete_webhook", {
|
|
14716
|
+
annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: false, openWorldHint: true },
|
|
14679
14717
|
title: "Delete an outbound webhook",
|
|
14680
14718
|
description: "Delete a webhook subscription.",
|
|
14681
14719
|
inputSchema: { subscription_id: z4.string().uuid() }
|
|
14682
14720
|
}, async ({ subscription_id }) => toToolResult(await call(`/api/v1/webhooks/${encodeURIComponent(subscription_id)}`, { method: "DELETE" })));
|
|
14683
14721
|
server.registerTool("export_events", {
|
|
14722
|
+
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
|
14684
14723
|
title: "Export events and installs",
|
|
14685
14724
|
description: "Export one app's events and installs as CSV for an inclusive date range.",
|
|
14686
14725
|
inputSchema: {
|