@kaminari-ad/mcp 0.8.0 → 0.9.1

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/bin.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { NAME, VERSION, err, ok } from './chunk-HZXVKCW3.js';
2
+ import { NAME, VERSION, err, ok } from './chunk-JEGBPX3R.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-KIBN4X7J.js');
163
+ const { bootstrapStdio } = await import('./stdio-bootstrap-YQFKQP2G.js');
164
164
  return bootstrapStdio(config);
165
165
  }
166
- const { bootstrapHttp } = await import('./http-bootstrap-5SJGGI5Y.js');
166
+ const { bootstrapHttp } = await import('./http-bootstrap-JS2O6I22.js');
167
167
  return bootstrapHttp(config);
168
168
  }
169
169
  main().then(
@@ -3,8 +3,8 @@ export { err, ok } from 'neverthrow';
3
3
 
4
4
  // src/shared/version.ts
5
5
  var NAME = "@kaminari-ad/mcp";
6
- var VERSION = "0.8.0";
6
+ var VERSION = "0.9.1";
7
7
 
8
8
  export { NAME, VERSION };
9
- //# sourceMappingURL=chunk-HZXVKCW3.js.map
10
- //# sourceMappingURL=chunk-HZXVKCW3.js.map
9
+ //# sourceMappingURL=chunk-JEGBPX3R.js.map
10
+ //# sourceMappingURL=chunk-JEGBPX3R.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/shared/version.ts"],"names":[],"mappings":";;;;AASO,IAAM,IAAA,GAAO;AACb,IAAM,OAAA,GAAU","file":"chunk-HZXVKCW3.js","sourcesContent":["/**\n * Package version and name. Hard-coded as constants here, asserted to\n * match `package.json` by a unit test.\n *\n * Why not import `package.json`: it would force JSON-module support at\n * runtime and tsup-bundling would inline the entire manifest. Two\n * constants + one assertion test is simpler and gives the same safety.\n */\n\nexport const NAME = \"@kaminari-ad/mcp\";\nexport const VERSION = \"0.8.0\";\n"]}
1
+ {"version":3,"sources":["../src/shared/version.ts"],"names":[],"mappings":";;;;AASO,IAAM,IAAA,GAAO;AACb,IAAM,OAAA,GAAU","file":"chunk-JEGBPX3R.js","sourcesContent":["/**\n * Package version and name. Hard-coded as constants here, asserted to\n * match `package.json` by a unit test.\n *\n * Why not import `package.json`: it would force JSON-module support at\n * runtime and tsup-bundling would inline the entire manifest. Two\n * constants + one assertion test is simpler and gives the same safety.\n */\n\nexport const NAME = \"@kaminari-ad/mcp\";\nexport const VERSION = \"0.9.1\";\n"]}
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { err, ok } from './chunk-HZXVKCW3.js';
2
+ import { err, ok } from './chunk-JEGBPX3R.js';
3
3
  import { createHash, randomUUID } from 'crypto';
4
4
  import createClient from 'openapi-fetch';
5
5
  import { fetch } from 'undici';
@@ -249,7 +249,8 @@ z.object({
249
249
  proxy: ProxyTargetRequest.optional(),
250
250
  labels: z.record(z.string()).optional(),
251
251
  campaign_id: z.union([z.string(), z.null()]).optional(),
252
- 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)
253
254
  }).passthrough();
254
255
  var ScanStatus = z.enum([
255
256
  "pending",
@@ -344,6 +345,11 @@ var ScanResponse = z.object({
344
345
  country_code: z.string(),
345
346
  emulator_id: z.string(),
346
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(""),
347
353
  offer_url: z.string(),
348
354
  redirect_chain: z.array(RedirectHopResponse),
349
355
  screenshot_url: z.string().optional().default(""),
@@ -389,6 +395,11 @@ var ScanBriefResponse = z.object({
389
395
  campaign_name: z.union([z.string(), z.null()]).optional(),
390
396
  is_ad_tag: z.boolean().optional().default(false),
391
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(""),
392
403
  emulator_display_name: z.string().optional().default(""),
393
404
  emulator_category: z.string().optional().default("")
394
405
  }).passthrough();
@@ -1729,6 +1740,11 @@ var ScanSchema = schemas.ScanResponse.pick({
1729
1740
  labels: true,
1730
1741
  campaign_id: true,
1731
1742
  campaign_name: true,
1743
+ parent_scan_id: true,
1744
+ ad_discovery: true,
1745
+ slot_index: true,
1746
+ ad_kind: true,
1747
+ network: true,
1732
1748
  created_at: true,
1733
1749
  completed_at: true
1734
1750
  }).strip();
@@ -1752,6 +1768,11 @@ var ScanBriefSchema = schemas.ScanBriefResponse.pick({
1752
1768
  campaign_name: true,
1753
1769
  is_ad_tag: true,
1754
1770
  is_vast: true,
1771
+ parent_scan_id: true,
1772
+ ad_discovery: true,
1773
+ slot_index: true,
1774
+ ad_kind: true,
1775
+ network: true,
1755
1776
  created_at: true
1756
1777
  }).strip();
1757
1778
  var parseScanPage = (raw) => parsePagedWithItemSchema(ScanBriefSchema, raw, "scans");
@@ -2035,6 +2056,14 @@ function createHttpApiGateway(config) {
2035
2056
  parseScan
2036
2057
  );
2037
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
+ },
2038
2067
  async createScan(body) {
2039
2068
  return call("POST", "/api/v1/scans", { body }, parseScan);
2040
2069
  },
@@ -2625,8 +2654,10 @@ var SERVER_INSTRUCTIONS = [
2625
2654
  "- `report_url`: authenticated dashboard report (requires login).",
2626
2655
  "- `public_report_url`: shareable report (no login).",
2627
2656
  "- `screenshot_url` / `creative_screenshot_url`: absolute, directly followable.",
2628
- "These come from `get_scan`, `list_scans`, and `list_run_scans`. Do NOT assemble",
2629
- "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)."
2630
2661
  ].join("\n");
2631
2662
  function declareEmptyResourcesAndPrompts(server) {
2632
2663
  server.server.registerCapabilities({ resources: {}, prompts: {} });
@@ -3575,8 +3606,10 @@ function pickCampaignConfigBody(input) {
3575
3606
  // src/application/tools/campaigns/create-campaign.tool.ts
3576
3607
  var CreateCampaignInputShape = {
3577
3608
  name: z.string().min(1).max(200).describe("Display name (1-200 chars)."),
3578
- campaign_type: z.enum(["url", "ad_tag", "vast"]).describe("`url`, `ad_tag`, or `vast` \u2014 must match the target field below."),
3579
- url: z.string().url().optional().describe("Target URL (required if campaign_type=url)."),
3609
+ campaign_type: z.enum(["url", "ad_tag", "vast", "ad_discovery"]).describe(
3610
+ "`url`, `ad_tag`, `vast`, or `ad_discovery` \u2014 must match the target field below. `ad_discovery` is a publisher-page scan: set `url`; each run detects the page's ad blocks and opens a child scan per detected ad."
3611
+ ),
3612
+ url: z.string().url().optional().describe("Target URL (required if campaign_type=url or ad_discovery)."),
3580
3613
  ad_tag: z.string().optional().describe(
3581
3614
  "Ad-tag HTML/JS or an http(s) URL of a page with the rendered creative (required if campaign_type=ad_tag)."
3582
3615
  ),
@@ -3625,7 +3658,7 @@ var GetCampaignInputShape = {
3625
3658
  };
3626
3659
  var getCampaignTool = {
3627
3660
  name: "get_campaign",
3628
- 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.",
3661
+ description: "Get one campaign by UUID: name, type (url|ad_tag|vast|ad_discovery), target URL / ad-tag / VAST tag (vast_tag), countries, schedule status, archive status, parent group. `ad_discovery` campaigns store the publisher page in the URL field.",
3629
3662
  annotations: {
3630
3663
  title: "Get Campaign",
3631
3664
  readOnlyHint: true,
@@ -3772,7 +3805,7 @@ var unarchiveCampaignTool = {
3772
3805
  var UpdateCampaignInputShape = {
3773
3806
  campaign_id: z.string().uuid().describe("Campaign UUID to update."),
3774
3807
  name: z.string().min(1).max(200).optional().describe("New display name."),
3775
- url: z.string().url().optional().describe("New target URL (url-type campaigns)."),
3808
+ url: z.string().url().optional().describe("New target URL (url-type and ad_discovery campaigns)."),
3776
3809
  ad_tag: z.string().optional().describe(
3777
3810
  "New ad-tag HTML/JS or an http(s) URL of a page with the rendered creative (ad_tag-type campaigns)."
3778
3811
  ),
@@ -4686,7 +4719,10 @@ var CreateScanInputShape = {
4686
4719
  proxy: scanProxyField,
4687
4720
  labels: z.record(z.string()).optional().describe("Arbitrary string -> string metadata attached to the scan."),
4688
4721
  campaign_id: z.string().uuid().optional().describe("Optional campaign UUID to attribute the scan to."),
4689
- run_id: z.string().uuid().optional().describe("Optional run UUID inside the campaign.")
4722
+ run_id: z.string().uuid().optional().describe("Optional run UUID inside the campaign."),
4723
+ ad_discovery: z.boolean().optional().describe(
4724
+ "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`."
4725
+ )
4690
4726
  };
4691
4727
  var createScanTool = {
4692
4728
  name: "create_scan",
@@ -4709,7 +4745,8 @@ var createScanTool = {
4709
4745
  ...input.proxy !== void 0 ? { proxy: input.proxy } : {},
4710
4746
  ...input.labels !== void 0 ? { labels: input.labels } : {},
4711
4747
  ...input.campaign_id !== void 0 ? { campaign_id: input.campaign_id } : {},
4712
- ...input.run_id !== void 0 ? { run_id: input.run_id } : {}
4748
+ ...input.run_id !== void 0 ? { run_id: input.run_id } : {},
4749
+ ...input.ad_discovery !== void 0 ? { ad_discovery: input.ad_discovery } : {}
4713
4750
  };
4714
4751
  const result = await ctx.api.createScan(body);
4715
4752
  if (result.isErr()) return err(mapApiError(result.error));
@@ -4806,6 +4843,31 @@ var getScanScreenshotTool = {
4806
4843
  return ok(imageBlock(result.value.bytes, result.value.contentType));
4807
4844
  }
4808
4845
  };
4846
+ var ListScanChildrenInputShape = {
4847
+ scan_id: z.string().uuid().describe("The publisher scan's UUID (an ad-discovery scan created with ad_discovery=true)."),
4848
+ page: z.number().int().min(1).max(500).default(1).describe("1-indexed page number."),
4849
+ limit: z.number().int().min(1).max(200).default(50).describe("Page size (1-200). Default 50.")
4850
+ };
4851
+ var listScanChildrenTool = {
4852
+ name: "list_scan_children",
4853
+ 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.",
4854
+ annotations: {
4855
+ title: "List Scan Children",
4856
+ readOnlyHint: true,
4857
+ destructiveHint: false,
4858
+ idempotentHint: true,
4859
+ openWorldHint: false
4860
+ },
4861
+ inputSchema: z.object(ListScanChildrenInputShape),
4862
+ handler: async (input, ctx) => {
4863
+ const result = await ctx.api.listScanChildren(input.scan_id, {
4864
+ page: input.page,
4865
+ limit: input.limit
4866
+ });
4867
+ if (result.isErr()) return err(mapApiError(result.error));
4868
+ return ok(result.value);
4869
+ }
4870
+ };
4809
4871
  var ListScansInputShape = {
4810
4872
  status: z.string().optional().describe(
4811
4873
  "Comma-separated statuses to filter by. Lifecycle values: pending, running, crawled, checking, checking_async, completed, partial, failed, cancelled."
@@ -5312,6 +5374,7 @@ function registerAllTools(register) {
5312
5374
  register(listGeosTool);
5313
5375
  register(listEmulatorsTool);
5314
5376
  register(getScanTool);
5377
+ register(listScanChildrenTool);
5315
5378
  register(listScansTool);
5316
5379
  register(cancelScanTool);
5317
5380
  register(createBulkScansTool);
@@ -5472,5 +5535,5 @@ function formatToolError(error) {
5472
5535
  }
5473
5536
 
5474
5537
  export { BearerToken, SERVER_INSTRUCTIONS, createHttpApiGateway, createPinoLogger, declareEmptyResourcesAndPrompts, newRequestId, wireToolsIntoMcpServer };
5475
- //# sourceMappingURL=chunk-ZZIYFLWG.js.map
5476
- //# sourceMappingURL=chunk-ZZIYFLWG.js.map
5538
+ //# sourceMappingURL=chunk-R56UDCOA.js.map
5539
+ //# sourceMappingURL=chunk-R56UDCOA.js.map