@kaminari-ad/mcp 0.19.1 → 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 +96 -0
- package/README.md +3 -3
- package/dist/bin.js +3 -3
- package/dist/{chunk-MKBTS4IH.js → chunk-6INS6YMW.js} +3 -3
- package/dist/{chunk-MKBTS4IH.js.map → chunk-6INS6YMW.js.map} +1 -1
- package/dist/{chunk-NPSDASQE.js → chunk-XJZE6KTY.js} +93 -19
- package/dist/chunk-XJZE6KTY.js.map +1 -0
- package/dist/{http-bootstrap-FN4DOOJT.js → http-bootstrap-NSZVATPV.js} +4 -4
- package/dist/{http-bootstrap-FN4DOOJT.js.map → http-bootstrap-NSZVATPV.js.map} +1 -1
- package/dist/{stdio-bootstrap-4PXPX6BD.js → stdio-bootstrap-M7I2WD5F.js} +4 -4
- package/dist/{stdio-bootstrap-4PXPX6BD.js.map → stdio-bootstrap-M7I2WD5F.js.map} +1 -1
- package/package.json +2 -2
- package/dist/chunk-NPSDASQE.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,102 @@ 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
|
+
|
|
41
|
+
## [0.22.0] - 2026-09-15
|
|
42
|
+
|
|
43
|
+
### Changed
|
|
44
|
+
|
|
45
|
+
- **`regexp_request_url` and `regexp_request_body` accept the creative
|
|
46
|
+
surface.** Both were rejected locally with anything but `target='page'`,
|
|
47
|
+
which made the rule that catches an exploit kit embedded in a banner
|
|
48
|
+
unauthorable: that kit is a script inside the creative's own iframe and
|
|
49
|
+
appears on no landing page's request list. Both now take `'page'`,
|
|
50
|
+
`'creative'` or `'creative_and_page'` (evaluated on each surface, every
|
|
51
|
+
match reporting the one it came from), matching what the API validates.
|
|
52
|
+
Tool descriptions updated with it, since an agent picks the target from
|
|
53
|
+
them.
|
|
54
|
+
|
|
55
|
+
Requires the API-side deploy that widens the same validator. Until it
|
|
56
|
+
lands, production rejects the two new targets with HTTP 422.
|
|
57
|
+
|
|
58
|
+
## [0.21.0] - 2026-09-14
|
|
59
|
+
|
|
60
|
+
> Requires the API-side KAMIAD-177 deploy. Until it lands, production
|
|
61
|
+
> rejects `ignore_first_n_domains` as an unknown body field, so do not tag
|
|
62
|
+
> this release ahead of the API.
|
|
63
|
+
|
|
64
|
+
### Added
|
|
65
|
+
|
|
66
|
+
- **`ignore_first_n_domains` on `create_campaign`, `update_campaign`,
|
|
67
|
+
`create_scan` and `create_bulk_scans`.** A check that enters through the
|
|
68
|
+
caller's own click or tracking domains used to have those domains rated
|
|
69
|
+
by every domain checker, so a reputation hit on the caller's own
|
|
70
|
+
infrastructure tagged the material and raised an alert that said nothing
|
|
71
|
+
about the offer. The new field (0-5, default 0) drops the first N unique
|
|
72
|
+
domains of the redirect chain, counted from the entry point, from
|
|
73
|
+
detection and tagging. Domains fold to their registrable form, so
|
|
74
|
+
`www.example.com` and `example.com` consume one slot between them, and
|
|
75
|
+
sub-requests made from a skipped domain are excluded too.
|
|
76
|
+
|
|
77
|
+
Deliberately NOT nullable, unlike `referrer` and `max_discovered_ads`
|
|
78
|
+
next to it: `0` is both the default and the reset, so a nullable variant
|
|
79
|
+
would only offer an agent a second spelling the API answers with a 422.
|
|
80
|
+
The shared `.describe()` text warns that a skipped domain is checked by
|
|
81
|
+
nothing, because the failure mode of guessing high is a hidden finding
|
|
82
|
+
rather than an error.
|
|
83
|
+
|
|
84
|
+
`CampaignResponse` and `ScanResponse` both echo the field, so an agent can
|
|
85
|
+
read back what a campaign will do and how much of a finished scan's chain
|
|
86
|
+
was excluded — the latter is the only way to answer that once the campaign
|
|
87
|
+
behind the scan has been edited. Parsed as optional rather than defaulted
|
|
88
|
+
to 0: an api that predates the field says nothing, and inventing a 0 would
|
|
89
|
+
claim the scan skipped nothing when the truth is unknown.
|
|
90
|
+
|
|
91
|
+
The generated schemas were left alone: the field is declared through the
|
|
92
|
+
same port-side intersection `max_discovered_ads` uses, because
|
|
93
|
+
`gen:api-types` reads the DEPLOYED spec and cannot see an unshipped
|
|
94
|
+
field. The next regen absorbs it and the intersections can go.
|
|
95
|
+
|
|
96
|
+
## [0.20.0] - 2026-09-13
|
|
97
|
+
|
|
98
|
+
### Added
|
|
99
|
+
|
|
100
|
+
- **`set_default_policy_set`** — mark or clear an owned policy set as
|
|
101
|
+
the organization's default for new campaigns (`POST /api/v1/policy-sets/{id}/set-default`).
|
|
102
|
+
`list_policy_sets` / `get_policy_set` now surface `is_default`. Omit
|
|
103
|
+
`policy_set_id` on `create_campaign` to bind that default; pass
|
|
104
|
+
`null` to create an unbound campaign.
|
|
105
|
+
|
|
10
106
|
## [0.19.1] - 2026-09-10
|
|
11
107
|
|
|
12
108
|
> Requires the API-side KAMIAD-104 deploy. Until it lands, production
|
package/README.md
CHANGED
|
@@ -63,7 +63,7 @@ Add to your MCP client config (Cursor: `~/.cursor/mcp.json`; Claude Desktop: `~/
|
|
|
63
63
|
}
|
|
64
64
|
```
|
|
65
65
|
|
|
66
|
-
Restart your client. You should see `kaminari-ad` in the MCP servers list with
|
|
66
|
+
Restart your client. You should see `kaminari-ad` in the MCP servers list with 108 tools exposed.
|
|
67
67
|
|
|
68
68
|
### 2b. Hosted HTTP transport (no install)
|
|
69
69
|
|
|
@@ -113,7 +113,7 @@ which decides which credential type minted it.
|
|
|
113
113
|
|
|
114
114
|
## Tools
|
|
115
115
|
|
|
116
|
-
|
|
116
|
+
108 tools covering the public `/api/v1` surface of Kaminari Ad. Every tool carries MCP behaviour annotations (`title`, `readOnlyHint`, `destructiveHint`, `idempotentHint`, `openWorldHint`) so MCP clients can warn before destructive actions. The complete list, by domain:
|
|
117
117
|
|
|
118
118
|
- **Account** (14) — `get_account`, `update_org`, `list_org_users`, `invite_user`, `update_user_role`, `remove_user`, `transfer_ownership`, `list_org_roles`, `create_custom_role`, `list_account_labels`, `update_account_labels`, `list_api_keys`, `create_api_key`, `revoke_api_key`
|
|
119
119
|
- **Scans** (13) — `list_scans`, `get_scan`, `list_scan_children`, `create_scan`, `create_bulk_scans`, `recheck_scans`, `cancel_scan`, `get_scan_screenshot`, `get_scan_creative_screenshot`, `get_scan_landing_screenshot`, `get_scan_creative_html`, `get_scan_creative_video`, `get_scan_vast_xml`
|
|
@@ -123,7 +123,7 @@ which decides which credential type minted it.
|
|
|
123
123
|
- **Tags** (5) — `list_tags`, `get_tag_definition`, `update_tag_definition`, `delete_tag_definition`, `list_scan_tags`
|
|
124
124
|
- **Custom rules** (6) — `list_custom_rules`, `get_custom_rule`, `create_custom_rule`, `update_custom_rule`, `delete_custom_rule`, `test_custom_rule`
|
|
125
125
|
- **Custom taxonomies** (7) — `list_custom_taxonomies`, `get_custom_taxonomy`, `create_custom_taxonomy`, `update_custom_taxonomy`, `delete_custom_taxonomy`, `restore_custom_taxonomy`, `parse_custom_taxonomy_text`
|
|
126
|
-
- **Policy sets** (
|
|
126
|
+
- **Policy sets** (11) — `list_policy_sets`, `get_policy_set`, `create_policy_set`, `update_policy_set`, `delete_policy_set`, `request_policy_set_approval`, `unpublish_policy_set`, `set_default_policy_set`, `list_policy_set_campaigns`, `attach_policy_set_campaigns`, `detach_policy_set_campaigns`
|
|
127
127
|
- **Alerts** (4) — `list_alerts`, `update_alert_status`, `bulk_update_alert_status`, `get_alert_stats`
|
|
128
128
|
- **Webhooks** (11) — `list_webhooks`, `get_webhook`, `create_webhook`, `update_webhook`, `delete_webhook`, `list_webhook_event_types`, `list_webhook_deliveries`, `test_webhook`, `rotate_webhook_secret`, `replay_webhook_delivery`, `bulk_replay_webhook`
|
|
129
129
|
- **Billing** (4) — `get_billing_summary`, `list_usage`, `get_usage_summary`, `list_balance_history`
|
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';
|
|
@@ -832,6 +832,7 @@ var PolicySetResponse = z.object({
|
|
|
832
832
|
organization_id: z.string().uuid(),
|
|
833
833
|
visibility: z.string(),
|
|
834
834
|
is_approved: z.boolean(),
|
|
835
|
+
is_default: z.boolean(),
|
|
835
836
|
entries: z.array(PolicyEntryResponse),
|
|
836
837
|
campaigns: z.array(LinkedCampaignResponse).optional(),
|
|
837
838
|
campaigns_total: z.number().int().optional().default(0),
|
|
@@ -846,6 +847,7 @@ var PolicySetListItem = z.object({
|
|
|
846
847
|
organization_id: z.string().uuid(),
|
|
847
848
|
visibility: z.string(),
|
|
848
849
|
is_approved: z.boolean(),
|
|
850
|
+
is_default: z.boolean(),
|
|
849
851
|
created_at: z.string().datetime({ offset: true })
|
|
850
852
|
}).passthrough();
|
|
851
853
|
z.object({
|
|
@@ -873,6 +875,7 @@ z.object({
|
|
|
873
875
|
campaign_ids: z.array(z.string().uuid()).max(500),
|
|
874
876
|
detach_all: z.boolean().default(false)
|
|
875
877
|
}).partial().passthrough();
|
|
878
|
+
z.object({ is_default: z.boolean() }).passthrough();
|
|
876
879
|
var AlertStatus = z.enum(["open", "escalated", "resolved", "dismissed"]);
|
|
877
880
|
z.union([AlertStatus, z.null()]).optional();
|
|
878
881
|
var AlertResponse = z.object({
|
|
@@ -1377,7 +1380,7 @@ var CampaignSchema = schemas.CampaignResponse.pick({
|
|
|
1377
1380
|
is_archived: true,
|
|
1378
1381
|
created_at: true,
|
|
1379
1382
|
last_run_at: true
|
|
1380
|
-
}).extend({ repeat_mode: schemas.RepeatMode.default("isolated") }).extend({ max_discovered_ads: z.number().int().nullable().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();
|
|
1381
1384
|
var parseCampaign = (raw) => parseWithSchema(CampaignSchema, raw, "campaign");
|
|
1382
1385
|
var parseCampaignPage = (raw) => parsePagedWithItemSchema(CampaignSchema, raw, "campaigns");
|
|
1383
1386
|
|
|
@@ -1747,6 +1750,7 @@ var PolicySetSchema = schemas.PolicySetResponse.pick({
|
|
|
1747
1750
|
organization_id: true,
|
|
1748
1751
|
visibility: true,
|
|
1749
1752
|
is_approved: true,
|
|
1753
|
+
is_default: true,
|
|
1750
1754
|
entries: true,
|
|
1751
1755
|
created_at: true
|
|
1752
1756
|
}).strip();
|
|
@@ -1760,6 +1764,7 @@ var PolicySetListItemSchema = schemas.PolicySetListItem.pick({
|
|
|
1760
1764
|
organization_id: true,
|
|
1761
1765
|
visibility: true,
|
|
1762
1766
|
is_approved: true,
|
|
1767
|
+
is_default: true,
|
|
1763
1768
|
created_at: true
|
|
1764
1769
|
}).strip();
|
|
1765
1770
|
var parsePolicySetPage = (raw) => parsePagedWithItemSchema(PolicySetListItemSchema, raw, "policy-sets");
|
|
@@ -1839,7 +1844,7 @@ var ScanSchema = schemas.ScanResponse.pick({
|
|
|
1839
1844
|
repeat_scan_ids: true,
|
|
1840
1845
|
retry_attempt: true,
|
|
1841
1846
|
retry_max_attempts: true
|
|
1842
|
-
}).extend({ creative_kind: z.string().default("banner") }).extend({ max_discovered_ads: z.number().int().nullable().optional() }).extend({ network_host: z.string().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();
|
|
1843
1848
|
var ScanArraySchema = z.array(ScanSchema);
|
|
1844
1849
|
var parseScan = (raw) => parseWithSchema(ScanSchema, raw, "scan");
|
|
1845
1850
|
var parseScanArray = (raw) => parseWithSchema(ScanArraySchema, raw, "scans");
|
|
@@ -2562,6 +2567,14 @@ function createHttpApiGateway(config) {
|
|
|
2562
2567
|
parseEmpty
|
|
2563
2568
|
);
|
|
2564
2569
|
},
|
|
2570
|
+
async setDefaultPolicySet(id, isDefault) {
|
|
2571
|
+
return call(
|
|
2572
|
+
"POST",
|
|
2573
|
+
"/api/v1/policy-sets/{policy_set_id}/set-default",
|
|
2574
|
+
{ params: { path: { policy_set_id: id } }, body: { is_default: isDefault } },
|
|
2575
|
+
parseEmpty
|
|
2576
|
+
);
|
|
2577
|
+
},
|
|
2565
2578
|
// ── Custom taxonomies ─────────────────────────────────────────
|
|
2566
2579
|
async listCustomTaxonomies(filters) {
|
|
2567
2580
|
return call(
|
|
@@ -3890,6 +3903,22 @@ var cancelCampaignTool = {
|
|
|
3890
3903
|
return ok(result.value);
|
|
3891
3904
|
}
|
|
3892
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
|
+
);
|
|
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.";
|
|
3914
|
+
var ignoreFirstNDomains = z.number().int().min(0).max(5);
|
|
3915
|
+
var ignoreFirstNDomainsField = ignoreFirstNDomains.optional().describe(`${IGNORE_FIRST_N_DOMAINS_DESCRIPTION} Omit it to skip nothing (0).`);
|
|
3916
|
+
var ignoreFirstNDomainsScanField = ignoreFirstNDomains.optional().describe(
|
|
3917
|
+
`${IGNORE_FIRST_N_DOMAINS_DESCRIPTION} Omit it to skip nothing (0). A scan created directly does NOT inherit this from the campaign named in \`campaign_id\` \u2014 only scans queued by a campaign run do \u2014 so send it explicitly on every direct submission that needs it.`
|
|
3918
|
+
);
|
|
3919
|
+
var ignoreFirstNDomainsUpdateField = ignoreFirstNDomains.optional().describe(
|
|
3920
|
+
`${IGNORE_FIRST_N_DOMAINS_DESCRIPTION} Omitting the field leaves the campaign's current setting unchanged; pass 0 to go back to skipping nothing. Not nullable \u2014 null is rejected with 422.`
|
|
3921
|
+
);
|
|
3893
3922
|
var MAX_DISCOVERED_ADS_DESCRIPTION = 'How many ad blocks to look for on each publisher page before stopping (1-25). Every ad found becomes its own scan with its own report and is BILLED AS A SEPARATE CHECK, so this multiplies the cost: a page scanned at 25 can cost 26 checks \u2014 one parent plus its children. 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.';
|
|
3894
3923
|
var PLATFORM_DEFAULT_NOTE = "The platform default is 12 unless an operator retuned it.";
|
|
3895
3924
|
var maxDiscoveredAds = z.number().int().min(1).max(25);
|
|
@@ -3993,12 +4022,16 @@ var CreateCampaignInputShape = {
|
|
|
3993
4022
|
"VAST video ad tag: an http(s) URL of a VAST endpoint OR raw VAST XML (required if campaign_type=vast)."
|
|
3994
4023
|
),
|
|
3995
4024
|
referrer: campaignReferrerField,
|
|
4025
|
+
ignore_first_n_domains: ignoreFirstNDomainsField,
|
|
3996
4026
|
max_discovered_ads: maxDiscoveredAdsField,
|
|
4027
|
+
ad_formats: adFormatsField,
|
|
3997
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."),
|
|
3998
4029
|
group_id: z.string().uuid().optional().describe("Parent group UUID; defaults to the org's default group."),
|
|
3999
4030
|
...campaignConfigFields,
|
|
4000
4031
|
labels: z.record(z.string()).optional().describe("Arbitrary metadata applied to every queued scan."),
|
|
4001
|
-
policy_set_id: z.string().uuid().optional().describe(
|
|
4032
|
+
policy_set_id: z.union([z.string().uuid(), z.null()]).optional().describe(
|
|
4033
|
+
"Policy set to evaluate every scan against. Omit to bind the organization's default (if any). Pass null for no policy set and no policy alerts."
|
|
4034
|
+
),
|
|
4002
4035
|
schedule_enabled: z.boolean().optional().describe("If true, the scheduler runs immediately. Default: false (manual run).")
|
|
4003
4036
|
};
|
|
4004
4037
|
var createCampaignTool = {
|
|
@@ -4021,7 +4054,9 @@ var createCampaignTool = {
|
|
|
4021
4054
|
...input.ad_tag !== void 0 ? { ad_tag: input.ad_tag } : {},
|
|
4022
4055
|
...input.vast_tag !== void 0 ? { vast_tag: input.vast_tag } : {},
|
|
4023
4056
|
...input.referrer !== void 0 ? { referrer: input.referrer } : {},
|
|
4057
|
+
...input.ignore_first_n_domains !== void 0 ? { ignore_first_n_domains: input.ignore_first_n_domains } : {},
|
|
4024
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 } : {},
|
|
4025
4060
|
...input.group_id !== void 0 ? { group_id: input.group_id } : {},
|
|
4026
4061
|
...input.labels !== void 0 ? { labels: input.labels } : {},
|
|
4027
4062
|
...input.policy_set_id !== void 0 ? { policy_set_id: input.policy_set_id } : {},
|
|
@@ -4195,7 +4230,9 @@ var UpdateCampaignInputShape = {
|
|
|
4195
4230
|
"New VAST video ad tag: an http(s) URL of a VAST endpoint OR raw VAST XML (vast-type campaigns)."
|
|
4196
4231
|
),
|
|
4197
4232
|
referrer: campaignReferrerUpdateField,
|
|
4233
|
+
ignore_first_n_domains: ignoreFirstNDomainsUpdateField,
|
|
4198
4234
|
max_discovered_ads: maxDiscoveredAdsUpdateField,
|
|
4235
|
+
ad_formats: adFormatsUpdateField,
|
|
4199
4236
|
country_codes: z.array(z.string().length(2)).optional().describe("Replace the country list."),
|
|
4200
4237
|
group_id: z.string().uuid().optional().describe("Move the campaign to another group."),
|
|
4201
4238
|
...campaignConfigFields,
|
|
@@ -4205,7 +4242,7 @@ var UpdateCampaignInputShape = {
|
|
|
4205
4242
|
};
|
|
4206
4243
|
var updateCampaignTool = {
|
|
4207
4244
|
name: "update_campaign",
|
|
4208
|
-
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.",
|
|
4209
4246
|
annotations: {
|
|
4210
4247
|
title: "Update Campaign",
|
|
4211
4248
|
readOnlyHint: false,
|
|
@@ -4221,7 +4258,9 @@ var updateCampaignTool = {
|
|
|
4221
4258
|
...input.ad_tag !== void 0 ? { ad_tag: input.ad_tag } : {},
|
|
4222
4259
|
...input.vast_tag !== void 0 ? { vast_tag: input.vast_tag } : {},
|
|
4223
4260
|
...input.referrer !== void 0 ? { referrer: input.referrer } : {},
|
|
4261
|
+
...input.ignore_first_n_domains !== void 0 ? { ignore_first_n_domains: input.ignore_first_n_domains } : {},
|
|
4224
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 } : {},
|
|
4225
4264
|
...input.country_codes !== void 0 ? { country_codes: input.country_codes } : {},
|
|
4226
4265
|
...input.group_id !== void 0 ? { group_id: input.group_id } : {},
|
|
4227
4266
|
...input.labels !== void 0 ? { labels: input.labels } : {},
|
|
@@ -4235,21 +4274,26 @@ var updateCampaignTool = {
|
|
|
4235
4274
|
}
|
|
4236
4275
|
};
|
|
4237
4276
|
var PATTERN_RULE_TYPES = ["regexp_request_url", "regexp_request_body"];
|
|
4277
|
+
var PATTERN_RULE_TARGETS = ["page", "creative", "creative_and_page"];
|
|
4238
4278
|
var patternRuleConfigSchema = z.object({
|
|
4239
4279
|
pattern: z.string().min(1).max(4096).describe("Non-empty regular expression, at most 4,096 characters."),
|
|
4240
4280
|
flags: z.enum(["", "i"]).optional().describe("Omit or use '' for case-sensitive matching; use 'i' to ignore case.")
|
|
4241
4281
|
}).strict();
|
|
4242
|
-
var PATTERN_RULE_CONFIG_DOC = "For `rule_type='regexp_request_url'` and `rule_type='regexp_request_body'`, `config` must be exactly `{ pattern: string, flags?: '' | 'i' }`: pattern is non-empty and at most 4,096 characters; omit flags or use `''` for case-sensitive matching, or `'i'` for case-insensitive matching. `target`
|
|
4282
|
+
var PATTERN_RULE_CONFIG_DOC = "For `rule_type='regexp_request_url'` and `rule_type='regexp_request_body'`, `config` must be exactly `{ pattern: string, flags?: '' | 'i' }`: pattern is non-empty and at most 4,096 characters; omit flags or use `''` for case-sensitive matching, or `'i'` for case-insensitive matching. `target` may be `'page'` (the landing tab), `'creative'` (the ad-tag creative's own traffic) or `'creative_and_page'` (both, reported separately) \u2014 a script inside a banner's iframe is on no landing's request list, so a page-only rule cannot see it. Default `page`. `regexp_request_url` inspects up to 5,000 captured request URLs on a fresh scan; tests and rechecks of stored scans reconstruct main-frame hops plus up to 200 persisted subrequests with selected resource types omitted, so historical matching is best-effort. `regexp_request_body` inspects the CONTENTS of the page's scripts, fetch/XHR responses and iframe documents \u2014 never images, video, fonts or stylesheets \u2014 capped at 400 resources, 128 KB each and 8 MB per scan. Those contents are kept for ONE DAY, so a test or recheck against an older scan reports no match because there is nothing left to read.";
|
|
4243
4283
|
function isPatternRuleType(ruleType) {
|
|
4244
4284
|
return PATTERN_RULE_TYPES.some((known) => known === ruleType);
|
|
4245
4285
|
}
|
|
4286
|
+
function isPatternRuleTarget(target) {
|
|
4287
|
+
return PATTERN_RULE_TARGETS.some((known) => known === target);
|
|
4288
|
+
}
|
|
4246
4289
|
function patternRuleInputError(input) {
|
|
4247
4290
|
if (!isPatternRuleType(input.rule_type)) return null;
|
|
4248
|
-
if (input.target !== void 0 && input.target
|
|
4291
|
+
if (input.target !== void 0 && !isPatternRuleTarget(input.target)) {
|
|
4292
|
+
const allowed = PATTERN_RULE_TARGETS.join(", ");
|
|
4249
4293
|
return {
|
|
4250
4294
|
kind: "invalid-input",
|
|
4251
|
-
message: `${input.rule_type}
|
|
4252
|
-
fieldErrors: { target: [`Must be
|
|
4295
|
+
message: `${input.rule_type} accepts target: ${allowed}.`,
|
|
4296
|
+
fieldErrors: { target: [`Must be one of: ${allowed}.`] }
|
|
4253
4297
|
};
|
|
4254
4298
|
}
|
|
4255
4299
|
const parsed = patternRuleConfigSchema.safeParse(input.config);
|
|
@@ -4292,12 +4336,12 @@ var CreateCustomRuleInputShape = {
|
|
|
4292
4336
|
"Rule-type-specific configuration object. Shape depends on `rule_type`. " + PATTERN_RULE_CONFIG_DOC + " `regexp_url` remains redirect-chain-only. For `rule_type='llm'` the shape is `{ prompt: string, tags: { <tag_slug>: <description>, ... } }`; each key in `config.tags` is auto-registered as a custom tag definition AND must not collide with a system slug (same 422 contract as `tag_slug`). " + COMBO_MATCH_SCOPE_DOC
|
|
4293
4337
|
),
|
|
4294
4338
|
target: z.string().max(30).optional().describe(
|
|
4295
|
-
"Where to apply the rule (e.g. 'page' for landing HTML). `regexp_request_url` and `regexp_request_body`
|
|
4339
|
+
"Where to apply the rule (e.g. 'page' for landing HTML). `regexp_request_url` and `regexp_request_body` also accept `'creative'` (the ad-tag creative's own traffic) and `'creative_and_page'` (both, reported separately). Default: page. See API docs for the full set of valid values."
|
|
4296
4340
|
)
|
|
4297
4341
|
};
|
|
4298
4342
|
var createCustomRuleTool = {
|
|
4299
4343
|
name: "create_custom_rule",
|
|
4300
|
-
description: "Define a custom tag-detection rule. Use `rule_type='regexp_request_url'` to match captured network and subresource URLs
|
|
4344
|
+
description: "Define a custom tag-detection rule. Use `rule_type='regexp_request_url'` to match captured network and subresource URLs; fresh scans carry up to 5,000 URLs, while later tests/rechecks use a reduced persisted request tree and are best-effort. Use `rule_type='regexp_request_body'` to match the CONTENTS of those sub-resources instead \u2014 the right choice when the code you want to catch keeps changing its filename; those contents are kept for one day. `rule_type='regexp_url'` remains redirect-chain-only. The API auto-registers a tag definition for each emitted slug and rejects built-in system-slug collisions with HTTP 422 / `checking.system_slug_reserved`. Matches tag future scans; existing scans are untouched until `recheck_scans`.",
|
|
4301
4345
|
annotations: {
|
|
4302
4346
|
title: "Create Custom Rule",
|
|
4303
4347
|
readOnlyHint: false,
|
|
@@ -4388,7 +4432,7 @@ var TestCustomRuleInputShape = {
|
|
|
4388
4432
|
"Rule-type-specific config to test. Same shape as `create_custom_rule`'s `config`. " + PATTERN_RULE_CONFIG_DOC + " `regexp_url` remains redirect-chain-only. NOTE: `test_custom_rule` evaluates the rule against a scan WITHOUT persisting it, so slug-collision validation does NOT run here \u2014 verify slugs against `list_tags` (`scope=system`) before promoting to `create_custom_rule`. " + COMBO_MATCH_SCOPE_DOC
|
|
4389
4433
|
),
|
|
4390
4434
|
target: z.string().max(30).describe(
|
|
4391
|
-
"Where to apply the rule (e.g. 'page' for landing HTML). `regexp_request_url` and `regexp_request_body`
|
|
4435
|
+
"Where to apply the rule (e.g. 'page' for landing HTML). `regexp_request_url` and `regexp_request_body` also accept `'creative'` and `'creative_and_page'`. See API docs for the full set of valid values."
|
|
4392
4436
|
),
|
|
4393
4437
|
scan_id: z.string().uuid().describe("Existing scan UUID to evaluate the rule against.")
|
|
4394
4438
|
};
|
|
@@ -4428,13 +4472,13 @@ var UpdateCustomRuleInputShape = {
|
|
|
4428
4472
|
"New rule-type-specific config object. Replaces the stored config wholesale \u2014 resend every key you want to keep, including a combo rule's `match_scope`. For `rule_type='llm'` the keys of `config.tags` are auto-registered as tag definitions; any key that collides with a system slug returns the same 422 contract. " + PATTERN_RULE_CONFIG_DOC + " Read the rule first because `rule_type` is immutable and is not repeated in this update input. " + COMBO_MATCH_SCOPE_DOC
|
|
4429
4473
|
),
|
|
4430
4474
|
target: z.string().max(30).optional().describe(
|
|
4431
|
-
"Where to apply the rule. `regexp_request_url` and `regexp_request_body`
|
|
4475
|
+
"Where to apply the rule. `regexp_request_url` and `regexp_request_body` accept `'page'`, `'creative'` or `'creative_and_page'`. See API docs for the valid targets of other rule types."
|
|
4432
4476
|
),
|
|
4433
4477
|
is_active: z.boolean().optional().describe("Enable/disable the rule.")
|
|
4434
4478
|
};
|
|
4435
4479
|
var updateCustomRuleTool = {
|
|
4436
4480
|
name: "update_custom_rule",
|
|
4437
|
-
description: "Update a custom tag-detection rule. Only supplied fields are sent, but `config` replaces the stored object wholesale; read the rule first and resend every required key. `regexp_request_url` and `regexp_request_body` need a non-empty pattern (max 4,096), flags `''`/`'i'`, and
|
|
4481
|
+
description: "Update a custom tag-detection rule. Only supplied fields are sent, but `config` replaces the stored object wholesale; read the rule first and resend every required key. `regexp_request_url` and `regexp_request_body` need a non-empty pattern (max 4,096), flags `''`/`'i'`, and a target of `'page'`, `'creative'` or `'creative_and_page'`. Same-slug GLOBAL rule edits preserve separately managed tag metadata; use `update_tag_definition` to change it. Existing scans are not re-evaluated until `recheck_scans`.",
|
|
4438
4482
|
annotations: {
|
|
4439
4483
|
title: "Update Custom Rule",
|
|
4440
4484
|
readOnlyHint: false,
|
|
@@ -4989,7 +5033,7 @@ var GetPolicySetInputShape = {
|
|
|
4989
5033
|
};
|
|
4990
5034
|
var getPolicySetTool = {
|
|
4991
5035
|
name: "get_policy_set",
|
|
4992
|
-
description: "Get one policy set by UUID with its complete list of entries (each entry is one of five rule kinds \u2014 tag / iab_v3 / brand / ai_category / custom_taxonomy \u2014 plus applicable country codes).",
|
|
5036
|
+
description: "Get one policy set by UUID with its complete list of entries (each entry is one of five rule kinds \u2014 tag / iab_v3 / brand / ai_category / custom_taxonomy \u2014 plus applicable country codes). `is_default` is true when this owned set is the organization's default for new campaigns.",
|
|
4993
5037
|
annotations: {
|
|
4994
5038
|
title: "Get Policy Set",
|
|
4995
5039
|
readOnlyHint: true,
|
|
@@ -5040,7 +5084,7 @@ var ListPolicySetsInputShape = {
|
|
|
5040
5084
|
};
|
|
5041
5085
|
var listPolicySetsTool = {
|
|
5042
5086
|
name: "list_policy_sets",
|
|
5043
|
-
description: "Paginated list of policy sets: named collections of violation rules (tag / IAB V3 / brand / AI category / custom-taxonomy entries) that define what counts as a violation. Campaigns bind to one policy set. Returns `{items, total, page, limit}`. List items omit `entries` for payload size \u2014 fetch a single set via `get_policy_set` when you need them. Use `visibility=public` to discover Kaminari Ad-curated sets.",
|
|
5087
|
+
description: "Paginated list of policy sets: named collections of violation rules (tag / IAB V3 / brand / AI category / custom-taxonomy entries) that define what counts as a violation. Campaigns bind to one policy set. Returns `{items, total, page, limit}`. List items omit `entries` for payload size \u2014 fetch a single set via `get_policy_set` when you need them. `is_default` is true on the owned set that new campaigns bind when `policy_set_id` is omitted. Use `visibility=public` to discover Kaminari Ad-curated sets.",
|
|
5044
5088
|
annotations: {
|
|
5045
5089
|
title: "List Policy Sets",
|
|
5046
5090
|
readOnlyHint: true,
|
|
@@ -5079,6 +5123,29 @@ var requestPolicySetApprovalTool = {
|
|
|
5079
5123
|
return ok({ requested: true });
|
|
5080
5124
|
}
|
|
5081
5125
|
};
|
|
5126
|
+
var SetDefaultPolicySetInputShape = {
|
|
5127
|
+
policy_set_id: z.string().uuid().describe("Owned policy set UUID."),
|
|
5128
|
+
is_default: z.boolean().describe(
|
|
5129
|
+
"True makes this the organization's default for new campaigns (clearing any previous default). False clears the flag on this set and leaves the org without a default."
|
|
5130
|
+
)
|
|
5131
|
+
};
|
|
5132
|
+
var setDefaultPolicySetTool = {
|
|
5133
|
+
name: "set_default_policy_set",
|
|
5134
|
+
description: "Mark or clear one of your organization's policy sets as the default for new campaigns. At most one owned set may be default. Creating a campaign without `policy_set_id` then binds this set (or stays unbound if none is set). Pass `policy_set_id: null` on create_campaign to opt out of the default. Foreign public sets cannot be made default. The API returns 204; this tool echoes `is_default`.",
|
|
5135
|
+
annotations: {
|
|
5136
|
+
title: "Set Default Policy Set",
|
|
5137
|
+
readOnlyHint: false,
|
|
5138
|
+
destructiveHint: false,
|
|
5139
|
+
idempotentHint: true,
|
|
5140
|
+
openWorldHint: false
|
|
5141
|
+
},
|
|
5142
|
+
inputSchema: z.object(SetDefaultPolicySetInputShape),
|
|
5143
|
+
handler: async (input, ctx) => {
|
|
5144
|
+
const result = await ctx.api.setDefaultPolicySet(input.policy_set_id, input.is_default);
|
|
5145
|
+
if (result.isErr()) return err(mapApiError(result.error));
|
|
5146
|
+
return ok({ is_default: input.is_default });
|
|
5147
|
+
}
|
|
5148
|
+
};
|
|
5082
5149
|
var UnpublishPolicySetInputShape = {
|
|
5083
5150
|
policy_set_id: z.string().uuid().describe("Policy set UUID.")
|
|
5084
5151
|
};
|
|
@@ -5271,6 +5338,7 @@ var CreateBulkScansInputShape = {
|
|
|
5271
5338
|
"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`."
|
|
5272
5339
|
),
|
|
5273
5340
|
referrer: scanReferrerField,
|
|
5341
|
+
ignore_first_n_domains: ignoreFirstNDomainsScanField,
|
|
5274
5342
|
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."),
|
|
5275
5343
|
emulator_id: z.string().min(1).max(100).describe("Device/OS profile slug; same for every country in the batch."),
|
|
5276
5344
|
proxy: scanProxyField,
|
|
@@ -5296,6 +5364,7 @@ var createBulkScansTool = {
|
|
|
5296
5364
|
...input.ad_tag !== void 0 ? { ad_tag: input.ad_tag } : {},
|
|
5297
5365
|
...input.vast_tag !== void 0 ? { vast_tag: input.vast_tag } : {},
|
|
5298
5366
|
...input.referrer !== void 0 ? { referrer: input.referrer } : {},
|
|
5367
|
+
...input.ignore_first_n_domains !== void 0 ? { ignore_first_n_domains: input.ignore_first_n_domains } : {},
|
|
5299
5368
|
...input.proxy !== void 0 ? { proxy: input.proxy } : {},
|
|
5300
5369
|
...input.labels !== void 0 ? { labels: input.labels } : {},
|
|
5301
5370
|
...pickRepeatRetryBody(input)
|
|
@@ -5316,6 +5385,7 @@ var CreateScanInputShape = {
|
|
|
5316
5385
|
"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`."
|
|
5317
5386
|
),
|
|
5318
5387
|
referrer: scanReferrerField,
|
|
5388
|
+
ignore_first_n_domains: ignoreFirstNDomainsScanField,
|
|
5319
5389
|
country_code: z.string().length(2).describe("ISO 3166-1 alpha-2 country code, e.g. US, DE, JP. Determines proxy geo."),
|
|
5320
5390
|
emulator_id: z.string().min(1).max(100).describe("Device/OS profile slug; use `list_emulators` to discover valid values."),
|
|
5321
5391
|
proxy: scanProxyField,
|
|
@@ -5323,9 +5393,10 @@ var CreateScanInputShape = {
|
|
|
5323
5393
|
campaign_id: z.string().uuid().optional().describe("Optional campaign UUID to attribute the scan to."),
|
|
5324
5394
|
run_id: z.string().uuid().optional().describe("Optional run UUID inside the campaign."),
|
|
5325
5395
|
ad_discovery: z.boolean().optional().describe(
|
|
5326
|
-
"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`."
|
|
5327
5397
|
),
|
|
5328
5398
|
max_discovered_ads: maxDiscoveredAdsField,
|
|
5399
|
+
ad_formats: adFormatsField,
|
|
5329
5400
|
...repeatRetryFields
|
|
5330
5401
|
};
|
|
5331
5402
|
var createScanTool = {
|
|
@@ -5347,12 +5418,14 @@ var createScanTool = {
|
|
|
5347
5418
|
...input.ad_tag !== void 0 ? { ad_tag: input.ad_tag } : {},
|
|
5348
5419
|
...input.vast_tag !== void 0 ? { vast_tag: input.vast_tag } : {},
|
|
5349
5420
|
...input.referrer !== void 0 ? { referrer: input.referrer } : {},
|
|
5421
|
+
...input.ignore_first_n_domains !== void 0 ? { ignore_first_n_domains: input.ignore_first_n_domains } : {},
|
|
5350
5422
|
...input.proxy !== void 0 ? { proxy: input.proxy } : {},
|
|
5351
5423
|
...input.labels !== void 0 ? { labels: input.labels } : {},
|
|
5352
5424
|
...input.campaign_id !== void 0 ? { campaign_id: input.campaign_id } : {},
|
|
5353
5425
|
...input.run_id !== void 0 ? { run_id: input.run_id } : {},
|
|
5354
5426
|
...input.ad_discovery !== void 0 ? { ad_discovery: input.ad_discovery } : {},
|
|
5355
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 } : {},
|
|
5356
5429
|
...pickRepeatRetryBody(input)
|
|
5357
5430
|
};
|
|
5358
5431
|
const result = await ctx.api.createScan(body);
|
|
@@ -6131,6 +6204,7 @@ function registerAllTools(register) {
|
|
|
6131
6204
|
register(deletePolicySetTool);
|
|
6132
6205
|
register(requestPolicySetApprovalTool);
|
|
6133
6206
|
register(unpublishPolicySetTool);
|
|
6207
|
+
register(setDefaultPolicySetTool);
|
|
6134
6208
|
register(listPolicySetCampaignsTool);
|
|
6135
6209
|
register(attachPolicySetCampaignsTool);
|
|
6136
6210
|
register(detachPolicySetCampaignsTool);
|
|
@@ -6240,5 +6314,5 @@ function formatToolError(error) {
|
|
|
6240
6314
|
}
|
|
6241
6315
|
|
|
6242
6316
|
export { BearerToken, SERVER_INSTRUCTIONS, createHttpApiGateway, createPinoLogger, declareEmptyResourcesAndPrompts, newRequestId, wireToolsIntoMcpServer };
|
|
6243
|
-
//# sourceMappingURL=chunk-
|
|
6244
|
-
//# sourceMappingURL=chunk-
|
|
6317
|
+
//# sourceMappingURL=chunk-XJZE6KTY.js.map
|
|
6318
|
+
//# sourceMappingURL=chunk-XJZE6KTY.js.map
|