@kaminari-ad/mcp 0.22.0 → 0.23.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 +31 -0
- package/dist/bin.js +3 -3
- package/dist/{chunk-J6SALJR4.js → chunk-6INS6YMW.js} +3 -3
- package/dist/{chunk-J6SALJR4.js.map → chunk-6INS6YMW.js.map} +1 -1
- package/dist/{chunk-VEPJEI3S.js → chunk-XJZE6KTY.js} +20 -7
- package/dist/chunk-XJZE6KTY.js.map +1 -0
- package/dist/{http-bootstrap-JX5RQALF.js → http-bootstrap-NSZVATPV.js} +4 -4
- package/dist/{http-bootstrap-JX5RQALF.js.map → http-bootstrap-NSZVATPV.js.map} +1 -1
- package/dist/{stdio-bootstrap-6PXVYXHT.js → stdio-bootstrap-M7I2WD5F.js} +4 -4
- package/dist/{stdio-bootstrap-6PXVYXHT.js.map → stdio-bootstrap-M7I2WD5F.js.map} +1 -1
- package/package.json +2 -2
- package/dist/chunk-VEPJEI3S.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,37 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.23.0] - 2026-09-29
|
|
11
|
+
|
|
12
|
+
> Requires the API-side ad-format deploy. Until it lands, production
|
|
13
|
+
> silently ignores `ad_formats` as an unknown body field: a `['pop']` request
|
|
14
|
+
> checks and bills every format and reads back without the field. Do not tag
|
|
15
|
+
> this release ahead of the API.
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
|
|
19
|
+
- **`ad_formats` on `create_scan`, `create_campaign` and `update_campaign`.**
|
|
20
|
+
An ad-discovery run can now be narrowed to some formats: any of
|
|
21
|
+
`banner`, `video` and `pop` (pop-unders and tab-unders). A format left out
|
|
22
|
+
is neither captured nor billed, so `['pop']` checks a publisher's pops
|
|
23
|
+
without screenshotting or clicking every banner on the page. Omit the
|
|
24
|
+
field to check every format; on `update_campaign`, pass `null` to go back
|
|
25
|
+
to every format.
|
|
26
|
+
|
|
27
|
+
`ScanResponse` and `CampaignResponse` echo the selection (`null` for
|
|
28
|
+
every format). The read side is parsed as plain strings rather than the
|
|
29
|
+
request enum, so a format added on the API side cannot fail a whole
|
|
30
|
+
`get_scan` / `get_campaign` call. The generated schemas were left alone:
|
|
31
|
+
the field is declared through the port's escape hatch until the next
|
|
32
|
+
regen against the deployed API, like `max_discovered_ads` before it.
|
|
33
|
+
|
|
34
|
+
### Security
|
|
35
|
+
|
|
36
|
+
- `undici` 8.10.0 → 8.11.2 (GHSA-3wwx-pv8p-q78v, WebSocket
|
|
37
|
+
permessage-deflate DoS) and transitive `ip-address` 10.4.0 → 10.7.2
|
|
38
|
+
(link-local and NAT64 classification bypasses), which were failing
|
|
39
|
+
`audit:deps`.
|
|
40
|
+
|
|
10
41
|
## [0.22.0] - 2026-09-15
|
|
11
42
|
|
|
12
43
|
### Changed
|
package/dist/bin.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { NAME, VERSION, err, ok } from './chunk-
|
|
2
|
+
import { NAME, VERSION, err, ok } from './chunk-6INS6YMW.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-
|
|
163
|
+
const { bootstrapStdio } = await import('./stdio-bootstrap-M7I2WD5F.js');
|
|
164
164
|
return bootstrapStdio(config);
|
|
165
165
|
}
|
|
166
|
-
const { bootstrapHttp } = await import('./http-bootstrap-
|
|
166
|
+
const { bootstrapHttp } = await import('./http-bootstrap-NSZVATPV.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.
|
|
6
|
+
var VERSION = "0.23.0";
|
|
7
7
|
|
|
8
8
|
export { NAME, VERSION };
|
|
9
|
-
//# sourceMappingURL=chunk-
|
|
10
|
-
//# sourceMappingURL=chunk-
|
|
9
|
+
//# sourceMappingURL=chunk-6INS6YMW.js.map
|
|
10
|
+
//# sourceMappingURL=chunk-6INS6YMW.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/shared/version.ts"],"names":[],"mappings":";;;;AASO,IAAM,IAAA,GAAO;AACb,IAAM,OAAA,GAAU","file":"chunk-
|
|
1
|
+
{"version":3,"sources":["../src/shared/version.ts"],"names":[],"mappings":";;;;AASO,IAAM,IAAA,GAAO;AACb,IAAM,OAAA,GAAU","file":"chunk-6INS6YMW.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.23.0\";\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { err, ok } from './chunk-
|
|
2
|
+
import { err, ok } from './chunk-6INS6YMW.js';
|
|
3
3
|
import { createHash, randomUUID } from 'crypto';
|
|
4
4
|
import createClient from 'openapi-fetch';
|
|
5
5
|
import { fetch } from 'undici';
|
|
@@ -1380,7 +1380,7 @@ var CampaignSchema = schemas.CampaignResponse.pick({
|
|
|
1380
1380
|
is_archived: true,
|
|
1381
1381
|
created_at: true,
|
|
1382
1382
|
last_run_at: true
|
|
1383
|
-
}).extend({ repeat_mode: schemas.RepeatMode.default("isolated") }).extend({ max_discovered_ads: z.number().int().nullable().optional() }).extend({ ignore_first_n_domains: z.number().int().optional() }).strip();
|
|
1383
|
+
}).extend({ repeat_mode: schemas.RepeatMode.default("isolated") }).extend({ max_discovered_ads: z.number().int().nullable().optional() }).extend({ ad_formats: z.array(z.string()).nullable().optional() }).extend({ ignore_first_n_domains: z.number().int().optional() }).strip();
|
|
1384
1384
|
var parseCampaign = (raw) => parseWithSchema(CampaignSchema, raw, "campaign");
|
|
1385
1385
|
var parseCampaignPage = (raw) => parsePagedWithItemSchema(CampaignSchema, raw, "campaigns");
|
|
1386
1386
|
|
|
@@ -1844,7 +1844,7 @@ var ScanSchema = schemas.ScanResponse.pick({
|
|
|
1844
1844
|
repeat_scan_ids: true,
|
|
1845
1845
|
retry_attempt: true,
|
|
1846
1846
|
retry_max_attempts: true
|
|
1847
|
-
}).extend({ creative_kind: z.string().default("banner") }).extend({ max_discovered_ads: z.number().int().nullable().optional() }).extend({ network_host: z.string().optional() }).extend({ ignore_first_n_domains: z.number().int().optional() }).strip();
|
|
1847
|
+
}).extend({ creative_kind: z.string().default("banner") }).extend({ max_discovered_ads: z.number().int().nullable().optional() }).extend({ ad_formats: z.array(z.string()).nullable().optional() }).extend({ network_host: z.string().optional() }).extend({ ignore_first_n_domains: z.number().int().optional() }).strip();
|
|
1848
1848
|
var ScanArraySchema = z.array(ScanSchema);
|
|
1849
1849
|
var parseScan = (raw) => parseWithSchema(ScanSchema, raw, "scan");
|
|
1850
1850
|
var parseScanArray = (raw) => parseWithSchema(ScanArraySchema, raw, "scans");
|
|
@@ -3903,6 +3903,13 @@ var cancelCampaignTool = {
|
|
|
3903
3903
|
return ok(result.value);
|
|
3904
3904
|
}
|
|
3905
3905
|
};
|
|
3906
|
+
var AD_FORMATS_DESCRIPTION = "Which ad formats an ad-discovery run checks: any of `banner`, `video` and `pop` (`pop` covers pop-unders and tab-unders), each at most once. A format left out is neither captured nor billed \u2014 `['pop']` checks the page's pops without screenshotting or clicking a single banner. A tab-under the page forces on its own is still reported as a pop. Only valid on an ad-discovery target \u2014 `ad_discovery: true` on a scan, or `campaign_type: \"ad_discovery\"` on a campaign \u2014 and rejected with 422 anywhere else, as is an empty list.";
|
|
3907
|
+
var adFormat = z.enum(["banner", "video", "pop"]);
|
|
3908
|
+
var adFormats = z.array(adFormat).min(1).max(adFormat.options.length);
|
|
3909
|
+
var adFormatsField = adFormats.optional().describe(`${AD_FORMATS_DESCRIPTION} Omit it to check every format.`);
|
|
3910
|
+
var adFormatsUpdateField = adFormats.nullable().optional().describe(
|
|
3911
|
+
`${AD_FORMATS_DESCRIPTION} Omitting the field leaves the campaign's current selection unchanged; pass null to go back to checking every format.`
|
|
3912
|
+
);
|
|
3906
3913
|
var IGNORE_FIRST_N_DOMAINS_DESCRIPTION = "How many leading domains of the redirect chain to exclude from detection and tagging (0-5). Use it when the check enters through the caller's OWN click or tracking domains: without it a reputation hit on one of those tags the material and raises an alert about the caller's infrastructure rather than about the offer. Counting starts at the entry point and follows chain order; domains fold to their registrable form, so www.example.com and example.com consume one slot between them, and any other request to one of those domains is excluded too. A skipped domain is checked by NOTHING, so never set this higher than the number of domains the caller actually owns at the head of the chain \u2014 ask rather than guess. The full redirect chain is still captured and returned either way.";
|
|
3907
3914
|
var ignoreFirstNDomains = z.number().int().min(0).max(5);
|
|
3908
3915
|
var ignoreFirstNDomainsField = ignoreFirstNDomains.optional().describe(`${IGNORE_FIRST_N_DOMAINS_DESCRIPTION} Omit it to skip nothing (0).`);
|
|
@@ -4017,6 +4024,7 @@ var CreateCampaignInputShape = {
|
|
|
4017
4024
|
referrer: campaignReferrerField,
|
|
4018
4025
|
ignore_first_n_domains: ignoreFirstNDomainsField,
|
|
4019
4026
|
max_discovered_ads: maxDiscoveredAdsField,
|
|
4027
|
+
ad_formats: adFormatsField,
|
|
4020
4028
|
country_codes: z.array(z.string().length(2)).min(1).describe("ISO 3166-1 alpha-2 codes \u2014 one scan per country per run."),
|
|
4021
4029
|
group_id: z.string().uuid().optional().describe("Parent group UUID; defaults to the org's default group."),
|
|
4022
4030
|
...campaignConfigFields,
|
|
@@ -4048,6 +4056,7 @@ var createCampaignTool = {
|
|
|
4048
4056
|
...input.referrer !== void 0 ? { referrer: input.referrer } : {},
|
|
4049
4057
|
...input.ignore_first_n_domains !== void 0 ? { ignore_first_n_domains: input.ignore_first_n_domains } : {},
|
|
4050
4058
|
...input.max_discovered_ads !== void 0 ? { max_discovered_ads: input.max_discovered_ads } : {},
|
|
4059
|
+
...input.ad_formats !== void 0 ? { ad_formats: input.ad_formats } : {},
|
|
4051
4060
|
...input.group_id !== void 0 ? { group_id: input.group_id } : {},
|
|
4052
4061
|
...input.labels !== void 0 ? { labels: input.labels } : {},
|
|
4053
4062
|
...input.policy_set_id !== void 0 ? { policy_set_id: input.policy_set_id } : {},
|
|
@@ -4223,6 +4232,7 @@ var UpdateCampaignInputShape = {
|
|
|
4223
4232
|
referrer: campaignReferrerUpdateField,
|
|
4224
4233
|
ignore_first_n_domains: ignoreFirstNDomainsUpdateField,
|
|
4225
4234
|
max_discovered_ads: maxDiscoveredAdsUpdateField,
|
|
4235
|
+
ad_formats: adFormatsUpdateField,
|
|
4226
4236
|
country_codes: z.array(z.string().length(2)).optional().describe("Replace the country list."),
|
|
4227
4237
|
group_id: z.string().uuid().optional().describe("Move the campaign to another group."),
|
|
4228
4238
|
...campaignConfigFields,
|
|
@@ -4232,7 +4242,7 @@ var UpdateCampaignInputShape = {
|
|
|
4232
4242
|
};
|
|
4233
4243
|
var updateCampaignTool = {
|
|
4234
4244
|
name: "update_campaign",
|
|
4235
|
-
description: "Update one or more fields of a campaign. Fields not supplied are left unchanged. `policy_set_id` accepts null to clear the binding, `referrer` accepts null to clear the publisher page scans are checked from,
|
|
4245
|
+
description: "Update one or more fields of a campaign. Fields not supplied are left unchanged. `policy_set_id` accepts null to clear the binding, `referrer` accepts null to clear the publisher page scans are checked from, `max_discovered_ads` accepts null to go back to the platform ad cap, and `ad_formats` accepts null to go back to checking every ad format. `ignore_first_n_domains` is the exception: it is not nullable, so pass 0 to go back to skipping nothing.",
|
|
4236
4246
|
annotations: {
|
|
4237
4247
|
title: "Update Campaign",
|
|
4238
4248
|
readOnlyHint: false,
|
|
@@ -4250,6 +4260,7 @@ var updateCampaignTool = {
|
|
|
4250
4260
|
...input.referrer !== void 0 ? { referrer: input.referrer } : {},
|
|
4251
4261
|
...input.ignore_first_n_domains !== void 0 ? { ignore_first_n_domains: input.ignore_first_n_domains } : {},
|
|
4252
4262
|
...input.max_discovered_ads !== void 0 ? { max_discovered_ads: input.max_discovered_ads } : {},
|
|
4263
|
+
...input.ad_formats !== void 0 ? { ad_formats: input.ad_formats } : {},
|
|
4253
4264
|
...input.country_codes !== void 0 ? { country_codes: input.country_codes } : {},
|
|
4254
4265
|
...input.group_id !== void 0 ? { group_id: input.group_id } : {},
|
|
4255
4266
|
...input.labels !== void 0 ? { labels: input.labels } : {},
|
|
@@ -5382,9 +5393,10 @@ var CreateScanInputShape = {
|
|
|
5382
5393
|
campaign_id: z.string().uuid().optional().describe("Optional campaign UUID to attribute the scan to."),
|
|
5383
5394
|
run_id: z.string().uuid().optional().describe("Optional run UUID inside the campaign."),
|
|
5384
5395
|
ad_discovery: z.boolean().optional().describe(
|
|
5385
|
-
"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`."
|
|
5396
|
+
"Publisher ad discovery: detect ad blocks on the page and spawn one child scan per detected ad (banner/video/pop). Only valid with `url`. Each child is a separate billed scan; list them with `list_scan_children`."
|
|
5386
5397
|
),
|
|
5387
5398
|
max_discovered_ads: maxDiscoveredAdsField,
|
|
5399
|
+
ad_formats: adFormatsField,
|
|
5388
5400
|
...repeatRetryFields
|
|
5389
5401
|
};
|
|
5390
5402
|
var createScanTool = {
|
|
@@ -5413,6 +5425,7 @@ var createScanTool = {
|
|
|
5413
5425
|
...input.run_id !== void 0 ? { run_id: input.run_id } : {},
|
|
5414
5426
|
...input.ad_discovery !== void 0 ? { ad_discovery: input.ad_discovery } : {},
|
|
5415
5427
|
...input.max_discovered_ads !== void 0 ? { max_discovered_ads: input.max_discovered_ads } : {},
|
|
5428
|
+
...input.ad_formats !== void 0 ? { ad_formats: input.ad_formats } : {},
|
|
5416
5429
|
...pickRepeatRetryBody(input)
|
|
5417
5430
|
};
|
|
5418
5431
|
const result = await ctx.api.createScan(body);
|
|
@@ -6301,5 +6314,5 @@ function formatToolError(error) {
|
|
|
6301
6314
|
}
|
|
6302
6315
|
|
|
6303
6316
|
export { BearerToken, SERVER_INSTRUCTIONS, createHttpApiGateway, createPinoLogger, declareEmptyResourcesAndPrompts, newRequestId, wireToolsIntoMcpServer };
|
|
6304
|
-
//# sourceMappingURL=chunk-
|
|
6305
|
-
//# sourceMappingURL=chunk-
|
|
6317
|
+
//# sourceMappingURL=chunk-XJZE6KTY.js.map
|
|
6318
|
+
//# sourceMappingURL=chunk-XJZE6KTY.js.map
|