@kaminari-ad/mcp 0.7.2 → 0.9.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/CHANGELOG.md CHANGED
@@ -7,6 +7,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.8.0] - 2026-07-10
11
+
12
+ ### Added
13
+
14
+ - **VAST video-ad support.** `create_scan`, `create_bulk_scans`,
15
+ `create_campaign` (new `vast` campaign type), and `update_campaign` now
16
+ accept a `vast_tag` — an http(s) URL of a VAST endpoint or raw VAST XML —
17
+ mutually exclusive with `url` / `ad_tag`. Scan responses surface
18
+ `creative_kind` (`banner` | `video`) plus a `video` block (duration,
19
+ media-file URL, VAST version, ad system, VPAID flag, wrapper depth), and the
20
+ scan-list brief carries `is_vast`. Regenerated the OpenAPI type + zod-schema
21
+ snapshots against the updated `/api/v1` surface.
22
+
10
23
  ## [0.6.0] - 2026-06-30
11
24
 
12
25
  ### Changed
package/dist/bin.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { NAME, VERSION, err, ok } from './chunk-VTKVXW4G.js';
2
+ import { NAME, VERSION, err, ok } from './chunk-SWFPWJ74.js';
3
3
  import process from 'process';
4
4
  import { z } from 'zod';
5
5
 
@@ -160,10 +160,10 @@ async function main() {
160
160
  }
161
161
  const config = configResult.value;
162
162
  if (config.transport === "stdio") {
163
- const { bootstrapStdio } = await import('./stdio-bootstrap-CE2Y76DX.js');
163
+ const { bootstrapStdio } = await import('./stdio-bootstrap-6DXIUJTV.js');
164
164
  return bootstrapStdio(config);
165
165
  }
166
- const { bootstrapHttp } = await import('./http-bootstrap-7VZLKAM4.js');
166
+ const { bootstrapHttp } = await import('./http-bootstrap-ZXECSCYN.js');
167
167
  return bootstrapHttp(config);
168
168
  }
169
169
  main().then(
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { err, ok } from './chunk-VTKVXW4G.js';
2
+ import { err, ok } from './chunk-SWFPWJ74.js';
3
3
  import { createHash, randomUUID } from 'crypto';
4
4
  import createClient from 'openapi-fetch';
5
5
  import { fetch } from 'undici';
@@ -243,12 +243,14 @@ var ProxyTargetRequest = z.object({
243
243
  z.object({
244
244
  url: z.union([z.string(), z.null()]).optional(),
245
245
  ad_tag: z.union([z.string(), z.null()]).optional(),
246
+ vast_tag: z.union([z.string(), z.null()]).optional(),
246
247
  country_code: z.string().min(2).max(2),
247
248
  emulator_id: z.string().min(1).max(100),
248
249
  proxy: ProxyTargetRequest.optional(),
249
250
  labels: z.record(z.string()).optional(),
250
251
  campaign_id: z.union([z.string(), z.null()]).optional(),
251
- run_id: z.union([z.string(), z.null()]).optional()
252
+ run_id: z.union([z.string(), z.null()]).optional(),
253
+ ad_discovery: z.boolean().optional().default(false)
252
254
  }).passthrough();
253
255
  var ScanStatus = z.enum([
254
256
  "pending",
@@ -282,6 +284,14 @@ var RedirectHopResponse = z.object({
282
284
  redirected_from: z.string(),
283
285
  sub_requests: z.array(SubRequestResponse)
284
286
  }).passthrough();
287
+ var VideoMetaResponse = z.object({
288
+ duration_ms: z.number().int().default(0),
289
+ mediafile_url: z.string().default(""),
290
+ vast_version: z.string().default(""),
291
+ ad_system: z.string().default(""),
292
+ is_vpaid: z.boolean().default(false),
293
+ wrapper_depth: z.number().int().default(0)
294
+ }).partial().passthrough();
285
295
  var ProxyTargetResponse = z.object({
286
296
  proxy_type: z.string(),
287
297
  region: z.string().optional().default(""),
@@ -335,15 +345,23 @@ var ScanResponse = z.object({
335
345
  country_code: z.string(),
336
346
  emulator_id: z.string(),
337
347
  status: ScanStatus,
348
+ parent_scan_id: z.union([z.string(), z.null()]).optional(),
349
+ ad_discovery: z.boolean().optional().default(false),
350
+ slot_index: z.union([z.number(), z.null()]).optional(),
351
+ ad_kind: z.union([z.string(), z.null()]).optional(),
352
+ network: z.string().optional().default(""),
338
353
  offer_url: z.string(),
339
354
  redirect_chain: z.array(RedirectHopResponse),
340
355
  screenshot_url: z.string().optional().default(""),
341
356
  report_url: z.string().optional().default(""),
342
357
  public_report_url: z.string().optional().default(""),
343
358
  ad_tag: z.union([z.string(), z.null()]).optional(),
359
+ vast_tag: z.union([z.string(), z.null()]).optional(),
360
+ creative_kind: z.string().optional().default("banner"),
344
361
  creative_screenshot_url: z.string().optional().default(""),
345
362
  creative_width: z.number().int().optional().default(0),
346
363
  creative_height: z.number().int().optional().default(0),
364
+ video: z.union([VideoMetaResponse, z.null()]).optional(),
347
365
  proxy: z.union([ProxyTargetResponse, z.null()]).optional(),
348
366
  page_title: z.string(),
349
367
  elapsed_ms: z.number().int(),
@@ -376,6 +394,12 @@ var ScanBriefResponse = z.object({
376
394
  campaign_id: z.union([z.string(), z.null()]).optional(),
377
395
  campaign_name: z.union([z.string(), z.null()]).optional(),
378
396
  is_ad_tag: z.boolean().optional().default(false),
397
+ is_vast: z.boolean().optional().default(false),
398
+ parent_scan_id: z.union([z.string(), z.null()]).optional(),
399
+ ad_discovery: z.boolean().optional().default(false),
400
+ slot_index: z.union([z.number(), z.null()]).optional(),
401
+ ad_kind: z.union([z.string(), z.null()]).optional(),
402
+ network: z.string().optional().default(""),
379
403
  emulator_display_name: z.string().optional().default(""),
380
404
  emulator_category: z.string().optional().default("")
381
405
  }).passthrough();
@@ -389,6 +413,7 @@ z.object({
389
413
  z.object({
390
414
  url: z.union([z.string(), z.null()]).optional(),
391
415
  ad_tag: z.union([z.string(), z.null()]).optional(),
416
+ vast_tag: z.union([z.string(), z.null()]).optional(),
392
417
  country_codes: z.array(z.string()).min(1),
393
418
  emulator_id: z.string().min(1).max(100),
394
419
  proxy: ProxyTargetRequest.optional(),
@@ -441,6 +466,7 @@ z.object({
441
466
  campaign_type: z.string().optional().default("url"),
442
467
  url: z.union([z.string(), z.null()]).optional(),
443
468
  ad_tag: z.union([z.string(), z.null()]).optional(),
469
+ vast_tag: z.union([z.string(), z.null()]).optional(),
444
470
  country_codes: z.array(z.string()).min(1),
445
471
  group_id: z.union([z.string(), z.null()]).optional(),
446
472
  emulator_categories: z.array(z.string()).optional(),
@@ -469,6 +495,7 @@ var CampaignResponse = z.object({
469
495
  campaign_type: z.string().optional().default("url"),
470
496
  url: z.string(),
471
497
  ad_tag: z.union([z.string(), z.null()]).optional(),
498
+ vast_tag: z.union([z.string(), z.null()]).optional(),
472
499
  country_codes: z.array(z.string()),
473
500
  group_id: z.string().uuid(),
474
501
  emulator_selection: EmulatorSelectionResponse,
@@ -505,6 +532,7 @@ z.object({
505
532
  name: z.union([z.string(), z.null()]),
506
533
  url: z.union([z.string(), z.null()]),
507
534
  ad_tag: z.union([z.string(), z.null()]),
535
+ vast_tag: z.union([z.string(), z.null()]),
508
536
  country_codes: z.union([z.array(z.string()), z.null()]),
509
537
  group_id: z.union([z.string(), z.null()]),
510
538
  emulator_categories: z.union([z.array(z.string()), z.null()]),
@@ -1272,6 +1300,7 @@ var CampaignSchema = schemas.CampaignResponse.pick({
1272
1300
  campaign_type: true,
1273
1301
  url: true,
1274
1302
  ad_tag: true,
1303
+ vast_tag: true,
1275
1304
  country_codes: true,
1276
1305
  group_id: true,
1277
1306
  emulator_selection: true,
@@ -1701,6 +1730,9 @@ var ScanSchema = schemas.ScanResponse.pick({
1701
1730
  report_url: true,
1702
1731
  public_report_url: true,
1703
1732
  ad_tag: true,
1733
+ vast_tag: true,
1734
+ creative_kind: true,
1735
+ video: true,
1704
1736
  creative_screenshot_url: true,
1705
1737
  page_title: true,
1706
1738
  elapsed_ms: true,
@@ -1708,6 +1740,11 @@ var ScanSchema = schemas.ScanResponse.pick({
1708
1740
  labels: true,
1709
1741
  campaign_id: true,
1710
1742
  campaign_name: true,
1743
+ parent_scan_id: true,
1744
+ ad_discovery: true,
1745
+ slot_index: true,
1746
+ ad_kind: true,
1747
+ network: true,
1711
1748
  created_at: true,
1712
1749
  completed_at: true
1713
1750
  }).strip();
@@ -1730,6 +1767,12 @@ var ScanBriefSchema = schemas.ScanBriefResponse.pick({
1730
1767
  campaign_id: true,
1731
1768
  campaign_name: true,
1732
1769
  is_ad_tag: true,
1770
+ is_vast: true,
1771
+ parent_scan_id: true,
1772
+ ad_discovery: true,
1773
+ slot_index: true,
1774
+ ad_kind: true,
1775
+ network: true,
1733
1776
  created_at: true
1734
1777
  }).strip();
1735
1778
  var parseScanPage = (raw) => parsePagedWithItemSchema(ScanBriefSchema, raw, "scans");
@@ -2013,6 +2056,14 @@ function createHttpApiGateway(config) {
2013
2056
  parseScan
2014
2057
  );
2015
2058
  },
2059
+ async listScanChildren(scanId, filters) {
2060
+ return call(
2061
+ "GET",
2062
+ "/api/v1/scans/{scan_id}/children",
2063
+ { params: { path: { scan_id: scanId }, query: filters } },
2064
+ parseScanPage
2065
+ );
2066
+ },
2016
2067
  async createScan(body) {
2017
2068
  return call("POST", "/api/v1/scans", { body }, parseScan);
2018
2069
  },
@@ -2603,8 +2654,10 @@ var SERVER_INSTRUCTIONS = [
2603
2654
  "- `report_url`: authenticated dashboard report (requires login).",
2604
2655
  "- `public_report_url`: shareable report (no login).",
2605
2656
  "- `screenshot_url` / `creative_screenshot_url`: absolute, directly followable.",
2606
- "These come from `get_scan`, `list_scans`, and `list_run_scans`. Do NOT assemble",
2607
- "scan/app URLs from a base host yourself \u2014 the apex domain does not serve scan pages."
2657
+ "These come from `get_scan`, `list_scans`, `list_run_scans`, and `list_scan_children`.",
2658
+ "Do NOT assemble scan/app URLs from a base host yourself \u2014 the apex domain does not serve scan pages.",
2659
+ "Publisher ad discovery: create a scan with `ad_discovery: true` (url scans only) to detect",
2660
+ "ad blocks on a page; `list_scan_children` returns one child scan per detected ad (banner/pop)."
2608
2661
  ].join("\n");
2609
2662
  function declareEmptyResourcesAndPrompts(server) {
2610
2663
  server.server.registerCapabilities({ resources: {}, prompts: {} });
@@ -3553,11 +3606,14 @@ function pickCampaignConfigBody(input) {
3553
3606
  // src/application/tools/campaigns/create-campaign.tool.ts
3554
3607
  var CreateCampaignInputShape = {
3555
3608
  name: z.string().min(1).max(200).describe("Display name (1-200 chars)."),
3556
- campaign_type: z.enum(["url", "ad_tag"]).describe("`url` or `ad_tag` \u2014 must match the target field below."),
3609
+ campaign_type: z.enum(["url", "ad_tag", "vast"]).describe("`url`, `ad_tag`, or `vast` \u2014 must match the target field below."),
3557
3610
  url: z.string().url().optional().describe("Target URL (required if campaign_type=url)."),
3558
3611
  ad_tag: z.string().optional().describe(
3559
3612
  "Ad-tag HTML/JS or an http(s) URL of a page with the rendered creative (required if campaign_type=ad_tag)."
3560
3613
  ),
3614
+ vast_tag: z.string().optional().describe(
3615
+ "VAST video ad tag: an http(s) URL of a VAST endpoint OR raw VAST XML (required if campaign_type=vast)."
3616
+ ),
3561
3617
  country_codes: z.array(z.string().length(2)).min(1).describe("ISO 3166-1 alpha-2 codes \u2014 one scan per country per run."),
3562
3618
  group_id: z.string().uuid().optional().describe("Parent group UUID; defaults to the org's default group."),
3563
3619
  ...campaignConfigFields,
@@ -3583,6 +3639,7 @@ var createCampaignTool = {
3583
3639
  country_codes: input.country_codes,
3584
3640
  ...input.url !== void 0 ? { url: input.url } : {},
3585
3641
  ...input.ad_tag !== void 0 ? { ad_tag: input.ad_tag } : {},
3642
+ ...input.vast_tag !== void 0 ? { vast_tag: input.vast_tag } : {},
3586
3643
  ...input.group_id !== void 0 ? { group_id: input.group_id } : {},
3587
3644
  ...input.labels !== void 0 ? { labels: input.labels } : {},
3588
3645
  ...input.policy_set_id !== void 0 ? { policy_set_id: input.policy_set_id } : {},
@@ -3599,7 +3656,7 @@ var GetCampaignInputShape = {
3599
3656
  };
3600
3657
  var getCampaignTool = {
3601
3658
  name: "get_campaign",
3602
- description: "Get one campaign by UUID: name, type, target URL/ad-tag, countries, schedule status, archive status, parent group.",
3659
+ description: "Get one campaign by UUID: name, type (url|ad_tag|vast), target URL / ad-tag / VAST tag (vast_tag), countries, schedule status, archive status, parent group.",
3603
3660
  annotations: {
3604
3661
  title: "Get Campaign",
3605
3662
  readOnlyHint: true,
@@ -3750,6 +3807,9 @@ var UpdateCampaignInputShape = {
3750
3807
  ad_tag: z.string().optional().describe(
3751
3808
  "New ad-tag HTML/JS or an http(s) URL of a page with the rendered creative (ad_tag-type campaigns)."
3752
3809
  ),
3810
+ vast_tag: z.string().optional().describe(
3811
+ "New VAST video ad tag: an http(s) URL of a VAST endpoint OR raw VAST XML (vast-type campaigns)."
3812
+ ),
3753
3813
  country_codes: z.array(z.string().length(2)).optional().describe("Replace the country list."),
3754
3814
  group_id: z.string().uuid().optional().describe("Move the campaign to another group."),
3755
3815
  ...campaignConfigFields,
@@ -3773,6 +3833,7 @@ var updateCampaignTool = {
3773
3833
  ...input.name !== void 0 ? { name: input.name } : {},
3774
3834
  ...input.url !== void 0 ? { url: input.url } : {},
3775
3835
  ...input.ad_tag !== void 0 ? { ad_tag: input.ad_tag } : {},
3836
+ ...input.vast_tag !== void 0 ? { vast_tag: input.vast_tag } : {},
3776
3837
  ...input.country_codes !== void 0 ? { country_codes: input.country_codes } : {},
3777
3838
  ...input.group_id !== void 0 ? { group_id: input.group_id } : {},
3778
3839
  ...input.labels !== void 0 ? { labels: input.labels } : {},
@@ -4603,9 +4664,12 @@ var scanProxyField = z.object({
4603
4664
 
4604
4665
  // src/application/tools/scans/create-bulk-scans.tool.ts
4605
4666
  var CreateBulkScansInputShape = {
4606
- url: z.string().url().optional().describe("Direct URL. EITHER `url` OR `ad_tag` is required."),
4667
+ url: z.string().url().optional().describe("Direct URL. Provide exactly one of `url`, `ad_tag`, or `vast_tag`."),
4607
4668
  ad_tag: z.string().optional().describe(
4608
- "Raw ad-tag HTML/JS OR an http(s) URL of a page with the creative already rendered. EITHER `url` OR `ad_tag` is required."
4669
+ "Raw ad-tag HTML/JS OR an http(s) URL of a page with the creative already rendered. Provide exactly one of `url`, `ad_tag`, or `vast_tag`."
4670
+ ),
4671
+ vast_tag: z.string().optional().describe(
4672
+ "VAST video ad tag: an http(s) URL of a VAST endpoint OR raw VAST XML. Provide exactly one of `url`, `ad_tag`, or `vast_tag`."
4609
4673
  ),
4610
4674
  country_codes: z.array(z.string().length(2)).min(1).max(50).describe("List of ISO 3166-1 alpha-2 country codes; one scan per country is created."),
4611
4675
  emulator_id: z.string().min(1).max(100).describe("Device/OS profile slug; same for every country in the batch."),
@@ -4614,7 +4678,7 @@ var CreateBulkScansInputShape = {
4614
4678
  };
4615
4679
  var createBulkScansTool = {
4616
4680
  name: "create_bulk_scans",
4617
- description: "Queue one new scan per country in a single call (e.g. test the same URL from US + DE + JP). COSTS N CREDITS where N = number of countries. Returns the list of created scans.",
4681
+ description: "Queue one new scan per country in a single call (e.g. test the same URL, ad-tag, or VAST video tag from US + DE + JP). COSTS N CREDITS where N = number of countries. Returns the list of created scans.",
4618
4682
  annotations: {
4619
4683
  title: "Create Bulk Scans",
4620
4684
  readOnlyHint: false,
@@ -4629,6 +4693,7 @@ var createBulkScansTool = {
4629
4693
  emulator_id: input.emulator_id,
4630
4694
  ...input.url !== void 0 ? { url: input.url } : {},
4631
4695
  ...input.ad_tag !== void 0 ? { ad_tag: input.ad_tag } : {},
4696
+ ...input.vast_tag !== void 0 ? { vast_tag: input.vast_tag } : {},
4632
4697
  ...input.proxy !== void 0 ? { proxy: input.proxy } : {},
4633
4698
  ...input.labels !== void 0 ? { labels: input.labels } : {}
4634
4699
  };
@@ -4638,20 +4703,28 @@ var createBulkScansTool = {
4638
4703
  }
4639
4704
  };
4640
4705
  var CreateScanInputShape = {
4641
- url: z.string().url().optional().describe("Direct URL of the ad / landing page. EITHER `url` OR `ad_tag` is required."),
4706
+ url: z.string().url().optional().describe(
4707
+ "Direct URL of the ad / landing page. Provide exactly one of `url`, `ad_tag`, or `vast_tag`."
4708
+ ),
4642
4709
  ad_tag: z.string().optional().describe(
4643
- "Raw HTML/JS ad tag (script, iframe, image) OR an http(s) URL of a page with the creative already rendered. EITHER `url` OR `ad_tag` is required."
4710
+ "Raw HTML/JS ad tag (script, iframe, image) OR an http(s) URL of a page with the creative already rendered. Provide exactly one of `url`, `ad_tag`, or `vast_tag`."
4711
+ ),
4712
+ vast_tag: z.string().optional().describe(
4713
+ "VAST video ad tag: an http(s) URL of a VAST endpoint OR raw VAST XML (a document containing a <VAST> element). Fetched and played in a real browser. Provide exactly one of `url`, `ad_tag`, or `vast_tag`."
4644
4714
  ),
4645
4715
  country_code: z.string().length(2).describe("ISO 3166-1 alpha-2 country code, e.g. US, DE, JP. Determines proxy geo."),
4646
4716
  emulator_id: z.string().min(1).max(100).describe("Device/OS profile slug; use `list_emulators` to discover valid values."),
4647
4717
  proxy: scanProxyField,
4648
4718
  labels: z.record(z.string()).optional().describe("Arbitrary string -> string metadata attached to the scan."),
4649
4719
  campaign_id: z.string().uuid().optional().describe("Optional campaign UUID to attribute the scan to."),
4650
- run_id: z.string().uuid().optional().describe("Optional run UUID inside the campaign.")
4720
+ run_id: z.string().uuid().optional().describe("Optional run UUID inside the campaign."),
4721
+ ad_discovery: z.boolean().optional().describe(
4722
+ "Publisher ad discovery: detect ad blocks on the page and spawn one child scan per detected ad (banner/pop). Only valid with `url`. Each child is a separate billed scan; list them with `list_scan_children`."
4723
+ )
4651
4724
  };
4652
4725
  var createScanTool = {
4653
4726
  name: "create_scan",
4654
- description: "Queue a single new scan for a URL or ad-tag against one country. COSTS CREDITS and bills the caller's organization. Returns the newly-created scan record.",
4727
+ description: "Queue a single new scan for a URL, ad-tag, or VAST video tag against one country. COSTS CREDITS and bills the caller's organization. Returns the newly-created scan record.",
4655
4728
  annotations: {
4656
4729
  title: "Create Scan",
4657
4730
  readOnlyHint: false,
@@ -4666,10 +4739,12 @@ var createScanTool = {
4666
4739
  emulator_id: input.emulator_id,
4667
4740
  ...input.url !== void 0 ? { url: input.url } : {},
4668
4741
  ...input.ad_tag !== void 0 ? { ad_tag: input.ad_tag } : {},
4742
+ ...input.vast_tag !== void 0 ? { vast_tag: input.vast_tag } : {},
4669
4743
  ...input.proxy !== void 0 ? { proxy: input.proxy } : {},
4670
4744
  ...input.labels !== void 0 ? { labels: input.labels } : {},
4671
4745
  ...input.campaign_id !== void 0 ? { campaign_id: input.campaign_id } : {},
4672
- ...input.run_id !== void 0 ? { run_id: input.run_id } : {}
4746
+ ...input.run_id !== void 0 ? { run_id: input.run_id } : {},
4747
+ ...input.ad_discovery !== void 0 ? { ad_discovery: input.ad_discovery } : {}
4673
4748
  };
4674
4749
  const result = await ctx.api.createScan(body);
4675
4750
  if (result.isErr()) return err(mapApiError(result.error));
@@ -4681,7 +4756,7 @@ var GetScanInputShape = {
4681
4756
  };
4682
4757
  var getScanTool = {
4683
4758
  name: "get_scan",
4684
- description: "Get full detail for one scan by UUID: status, offer URL, absolute screenshot URL, report_url + public_report_url deep-links, timing, labels, and the parent campaign if any. Link users with the returned `report_url` / `public_report_url` \u2014 never construct URLs yourself.",
4759
+ description: "Get full detail for one scan by UUID: status, offer URL, absolute screenshot URL, report_url + public_report_url deep-links, timing, labels, and the parent campaign if any. VAST video scans also carry `vast_tag`, `creative_kind` (banner|video), and a `video` block (duration, media-file URL, VAST version, ad system, VPAID flag, wrapper depth). Link users with the returned `report_url` / `public_report_url` \u2014 never construct URLs yourself.",
4685
4760
  annotations: {
4686
4761
  title: "Get Scan",
4687
4762
  readOnlyHint: true,
@@ -4766,6 +4841,31 @@ var getScanScreenshotTool = {
4766
4841
  return ok(imageBlock(result.value.bytes, result.value.contentType));
4767
4842
  }
4768
4843
  };
4844
+ var ListScanChildrenInputShape = {
4845
+ scan_id: z.string().uuid().describe("The publisher scan's UUID (an ad-discovery scan created with ad_discovery=true)."),
4846
+ page: z.number().int().min(1).max(500).default(1).describe("1-indexed page number."),
4847
+ limit: z.number().int().min(1).max(200).default(50).describe("Page size (1-200). Default 50.")
4848
+ };
4849
+ var listScanChildrenTool = {
4850
+ name: "list_scan_children",
4851
+ description: "List the discovered-ad child scans of a publisher ad-discovery scan \u2014 one per detected ad block on the page. Each child brief carries ad_kind (banner|pop), the attributed ad network, and slot_index. Returns a paginated envelope with screenshot + report deep-links; link users with those, never hand-build URLs.",
4852
+ annotations: {
4853
+ title: "List Scan Children",
4854
+ readOnlyHint: true,
4855
+ destructiveHint: false,
4856
+ idempotentHint: true,
4857
+ openWorldHint: false
4858
+ },
4859
+ inputSchema: z.object(ListScanChildrenInputShape),
4860
+ handler: async (input, ctx) => {
4861
+ const result = await ctx.api.listScanChildren(input.scan_id, {
4862
+ page: input.page,
4863
+ limit: input.limit
4864
+ });
4865
+ if (result.isErr()) return err(mapApiError(result.error));
4866
+ return ok(result.value);
4867
+ }
4868
+ };
4769
4869
  var ListScansInputShape = {
4770
4870
  status: z.string().optional().describe(
4771
4871
  "Comma-separated statuses to filter by. Lifecycle values: pending, running, crawled, checking, checking_async, completed, partial, failed, cancelled."
@@ -4799,7 +4899,7 @@ var ListScansInputShape = {
4799
4899
  };
4800
4900
  var listScansTool = {
4801
4901
  name: "list_scans",
4802
- description: "List scans for the caller's organization with optional filters (status, country, URL substring, date range, run/campaign/group, tag, AI/IAB/brand category, dynamic labels). Returns a paginated envelope; each scan carries an absolute screenshot URL plus report_url (auth dashboard) and public_report_url (shareable) deep-links \u2014 link users with those, never hand-build URLs.",
4902
+ description: "List scans for the caller's organization with optional filters (status, country, URL substring, date range, run/campaign/group, tag, AI/IAB/brand category, dynamic labels). Returns a paginated envelope; each brief carries `is_ad_tag` and `is_vast` flags, an absolute screenshot URL plus report_url (auth dashboard) and public_report_url (shareable) deep-links \u2014 link users with those, never hand-build URLs.",
4803
4903
  annotations: {
4804
4904
  title: "List Scans",
4805
4905
  readOnlyHint: true,
@@ -5272,6 +5372,7 @@ function registerAllTools(register) {
5272
5372
  register(listGeosTool);
5273
5373
  register(listEmulatorsTool);
5274
5374
  register(getScanTool);
5375
+ register(listScanChildrenTool);
5275
5376
  register(listScansTool);
5276
5377
  register(cancelScanTool);
5277
5378
  register(createBulkScansTool);
@@ -5432,5 +5533,5 @@ function formatToolError(error) {
5432
5533
  }
5433
5534
 
5434
5535
  export { BearerToken, SERVER_INSTRUCTIONS, createHttpApiGateway, createPinoLogger, declareEmptyResourcesAndPrompts, newRequestId, wireToolsIntoMcpServer };
5435
- //# sourceMappingURL=chunk-NRDA7DQQ.js.map
5436
- //# sourceMappingURL=chunk-NRDA7DQQ.js.map
5536
+ //# sourceMappingURL=chunk-E66U4JXR.js.map
5537
+ //# sourceMappingURL=chunk-E66U4JXR.js.map