@kaminari-ad/mcp 0.24.1 → 0.25.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 +36 -0
- package/README.md +15 -5
- package/dist/bin.js +3 -3
- package/dist/{chunk-3G2F3FOW.js → chunk-IG36AHO3.js} +3 -3
- package/dist/{chunk-3G2F3FOW.js.map → chunk-IG36AHO3.js.map} +1 -1
- package/dist/{chunk-LPABQWHJ.js → chunk-MIDK3IA2.js} +100 -3
- package/dist/chunk-MIDK3IA2.js.map +1 -0
- package/dist/{http-bootstrap-6PQSTYXB.js → http-bootstrap-6L4VQJRM.js} +4 -4
- package/dist/{http-bootstrap-6PQSTYXB.js.map → http-bootstrap-6L4VQJRM.js.map} +1 -1
- package/dist/{stdio-bootstrap-VGOUNXAK.js → stdio-bootstrap-3IOUWYG3.js} +4 -4
- package/dist/{stdio-bootstrap-VGOUNXAK.js.map → stdio-bootstrap-3IOUWYG3.js.map} +1 -1
- package/package.json +9 -2
- package/dist/chunk-LPABQWHJ.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,42 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.25.0] - 2026-10-04
|
|
11
|
+
|
|
12
|
+
> Requires the API-side batch rule test deploy. Until it lands, the tool
|
|
13
|
+
> gets 404 from `POST /api/v1/custom-rules/test-batch`. Do not tag this
|
|
14
|
+
> release ahead of the API.
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
|
|
18
|
+
- **`test_custom_rules_batch`.** Preview up to 20 unsaved rule definitions
|
|
19
|
+
against up to 50 stored scans in one call, instead of chaining
|
|
20
|
+
`test_custom_rule`. The reply is one cell per rule and scan plus counts.
|
|
21
|
+
A cell that could not run carries `error` and `error_code` without
|
|
22
|
+
failing the rest. `deadline_exceeded` means the call ran out of time
|
|
23
|
+
before that cell, and the agent re-sends just those cells. A
|
|
24
|
+
rate-limited error means the organization already has a batch running.
|
|
25
|
+
Request and response schemas are regenerated from the API. The scan cap
|
|
26
|
+
comes from the generated schema; the 20-rule cap is restated in the tool
|
|
27
|
+
because each rule carries its own agent-facing field descriptions.
|
|
28
|
+
|
|
29
|
+
## [0.24.2] - 2026-10-03
|
|
30
|
+
|
|
31
|
+
### Added
|
|
32
|
+
|
|
33
|
+
- **Listed in the official MCP Registry.** Every release tag now publishes
|
|
34
|
+
`server.json` to `registry.modelcontextprotocol.io` as
|
|
35
|
+
`io.github.kaminari-ad/mcp`, with both the npm package and the hosted
|
|
36
|
+
`https://mcp.kaminari.ad/mcp` endpoint. `package.json` carries the matching
|
|
37
|
+
`mcpName` the registry uses to verify package ownership.
|
|
38
|
+
|
|
39
|
+
### Fixed
|
|
40
|
+
|
|
41
|
+
- **README privacy link.** It pointed at `kaminari.ad/legal/privacy`, which
|
|
42
|
+
returns 404; it now points at `kaminari.ad/privacy`.
|
|
43
|
+
- **npm homepage** now points at `https://kaminari.ad/mcp` instead of the
|
|
44
|
+
GitHub repository.
|
|
45
|
+
|
|
10
46
|
## [0.24.1] - 2026-10-02
|
|
11
47
|
|
|
12
48
|
### Fixed
|
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@ Lets AI agents (Cursor, Claude Desktop, Cline, and any MCP-compatible client) la
|
|
|
10
10
|
[](https://nodejs.org)
|
|
11
11
|
[](https://github.com/kaminari-ad/mcp/actions/workflows/ci.yml)
|
|
12
12
|
[](https://www.npmjs.com/package/@kaminari-ad/mcp)
|
|
13
|
-
[](https://registry.modelcontextprotocol.io)
|
|
13
|
+
[](https://registry.modelcontextprotocol.io/v0/servers?search=io.github.kaminari-ad/mcp)
|
|
14
14
|
|
|
15
15
|
## Install (one click)
|
|
16
16
|
|
|
@@ -18,6 +18,8 @@ Lets AI agents (Cursor, Claude Desktop, Cline, and any MCP-compatible client) la
|
|
|
18
18
|
|
|
19
19
|
<a href="https://kaminari.ad/mcp/install"><img alt="Install in Cursor" src="https://cursor.com/deeplink/mcp-install-dark.png" height="32" /></a>
|
|
20
20
|
|
|
21
|
+
What the server can do and how to connect any client: [Kaminari Ad MCP overview](https://kaminari.ad/mcp).
|
|
22
|
+
|
|
21
23
|
### Claude Desktop
|
|
22
24
|
|
|
23
25
|
[**Download `kaminari-ad-mcp.mcpb`**](https://github.com/kaminari-ad/mcp/releases/latest/download/kaminari-ad-mcp.mcpb) → double-click to install. Claude Desktop shows a config form for your API key.
|
|
@@ -113,7 +115,7 @@ which decides which credential type minted it.
|
|
|
113
115
|
|
|
114
116
|
## Tools
|
|
115
117
|
|
|
116
|
-
|
|
118
|
+
109 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
119
|
|
|
118
120
|
- **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
121
|
- **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`
|
|
@@ -121,7 +123,7 @@ which decides which credential type minted it.
|
|
|
121
123
|
- **Campaign groups** (10) — list/get/create/update/run/cancel/archive/unarchive + `pause_campaign_group_schedule`, `resume_campaign_group_schedule`
|
|
122
124
|
- **Runs** (3) — `get_run`, `list_run_scans`, `cancel_run` (use `list_campaign_runs` to enumerate runs of a campaign — the API has no standalone `/runs` index)
|
|
123
125
|
- **Tags** (5) — `list_tags`, `get_tag_definition`, `update_tag_definition`, `delete_tag_definition`, `list_scan_tags`
|
|
124
|
-
- **Custom rules** (
|
|
126
|
+
- **Custom rules** (7) — `list_custom_rules`, `get_custom_rule`, `create_custom_rule`, `update_custom_rule`, `delete_custom_rule`, `test_custom_rule`, `test_custom_rules_batch`
|
|
125
127
|
- **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
128
|
- **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
129
|
- **Alerts** (4) — `list_alerts`, `update_alert_status`, `bulk_update_alert_status`, `get_alert_stats`
|
|
@@ -182,7 +184,7 @@ npm run lint && npm run typecheck && npm test
|
|
|
182
184
|
|
|
183
185
|
See [CONTRIBUTING.md](CONTRIBUTING.md) for the development workflow and how to add a tool.
|
|
184
186
|
|
|
185
|
-
> The maintainers run the full development gate (integration tests, deploy automation, prod smoke) on a private GitLab instance and mirror the repo to GitHub. The public CI on GitHub Actions ([`.github/workflows/ci.yml`](.github/workflows/ci.yml)) runs lint + typecheck + unit tests + build + bundle-size check on every community PR, so contributors get fast green/red feedback without needing access to the internal infra. Tag pushes (`v*.*.*`) trigger [`.github/workflows/release.yml`](.github/workflows/release.yml), which publishes the package to npm with OIDC provenance
|
|
187
|
+
> The maintainers run the full development gate (integration tests, deploy automation, prod smoke) on a private GitLab instance and mirror the repo to GitHub. The public CI on GitHub Actions ([`.github/workflows/ci.yml`](.github/workflows/ci.yml)) runs lint + typecheck + unit tests + build + bundle-size check on every community PR, so contributors get fast green/red feedback without needing access to the internal infra. Tag pushes (`v*.*.*`) trigger [`.github/workflows/release.yml`](.github/workflows/release.yml), which publishes the package to npm with OIDC provenance, creates the GitHub Release and publishes [`server.json`](server.json) to the official MCP Registry.
|
|
186
188
|
|
|
187
189
|
---
|
|
188
190
|
|
|
@@ -202,12 +204,20 @@ We follow [Semantic Versioning](https://semver.org/spec/v2.0.0.html) for the two
|
|
|
202
204
|
## Privacy
|
|
203
205
|
|
|
204
206
|
- **Data collected by the MCP server itself:** none beyond the `Authorization` header it forwards. The HTTP transport is stateless — no sessions are persisted; each request is authenticated independently by its own Bearer. The only in-memory state is the leaky-bucket rate limiter keyed by `sha256(bearer)`.
|
|
205
|
-
- **Data forwarded to Kaminari Ad:** every tool call is a thin pass-through to `/api/v1` over HTTPS. The Kaminari Ad privacy policy applies: [https://kaminari.ad/
|
|
207
|
+
- **Data forwarded to Kaminari Ad:** every tool call is a thin pass-through to `/api/v1` over HTTPS. The Kaminari Ad privacy policy applies: [https://kaminari.ad/privacy](https://kaminari.ad/privacy).
|
|
206
208
|
- **Logs:** structured pino output, JSON in HTTP mode. The full Bearer token is redacted; only `bearer_hash = sha256(token).slice(0,8)` makes it into a log line, alongside `request_id`, `tool_name`, `api_status`, `elapsed_ms`. Tool inputs (which may contain customer scan IDs / URLs) are NOT logged.
|
|
207
209
|
- **Telemetry:** none. The OSS build ships a `NoopErrorReporter`. We do not bundle Sentry, OpenTelemetry exporters, or PostHog.
|
|
208
210
|
|
|
209
211
|
To report a security or privacy issue, see [SECURITY.md](SECURITY.md).
|
|
210
212
|
|
|
213
|
+
## Learn more
|
|
214
|
+
|
|
215
|
+
- [Kaminari Ad MCP overview](https://kaminari.ad/mcp) — what agents can do with the server, with setup for every client.
|
|
216
|
+
- [MCP server developer docs](https://kaminari.ad/docs/developers/mcp-server) — transports, authentication and OAuth connected apps.
|
|
217
|
+
- [REST API quickstart](https://kaminari.ad/docs/developers/rest-quickstart) — the `/api/v1` surface every tool calls.
|
|
218
|
+
- [Malvertising, auto-redirect and cloaking detections](https://kaminari.ad/detections) — what a scan verdict can flag.
|
|
219
|
+
- [DarkSword in the ad stack: an iOS exploit chain](https://kaminari.ad/blog/darksword-ios-exploit-chain-in-ad-traffic) — research from the Kaminari Ad team.
|
|
220
|
+
|
|
211
221
|
## License
|
|
212
222
|
|
|
213
223
|
MIT — see [LICENSE](LICENSE).
|
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-IG36AHO3.js';
|
|
3
3
|
import process from 'process';
|
|
4
4
|
import { z } from 'zod';
|
|
5
5
|
|
|
@@ -162,10 +162,10 @@ async function main() {
|
|
|
162
162
|
}
|
|
163
163
|
const config = configResult.value;
|
|
164
164
|
if (config.transport === "stdio") {
|
|
165
|
-
const { bootstrapStdio } = await import('./stdio-bootstrap-
|
|
165
|
+
const { bootstrapStdio } = await import('./stdio-bootstrap-3IOUWYG3.js');
|
|
166
166
|
return bootstrapStdio(config);
|
|
167
167
|
}
|
|
168
|
-
const { bootstrapHttp } = await import('./http-bootstrap-
|
|
168
|
+
const { bootstrapHttp } = await import('./http-bootstrap-6L4VQJRM.js');
|
|
169
169
|
return bootstrapHttp(config);
|
|
170
170
|
}
|
|
171
171
|
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.25.0";
|
|
7
7
|
|
|
8
8
|
export { NAME, VERSION };
|
|
9
|
-
//# sourceMappingURL=chunk-
|
|
10
|
-
//# sourceMappingURL=chunk-
|
|
9
|
+
//# sourceMappingURL=chunk-IG36AHO3.js.map
|
|
10
|
+
//# sourceMappingURL=chunk-IG36AHO3.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-IG36AHO3.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.25.0\";\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { err, ok } from './chunk-
|
|
2
|
+
import { err, ok } from './chunk-IG36AHO3.js';
|
|
3
3
|
import { createHash, randomUUID } from 'crypto';
|
|
4
4
|
import createClient from 'openapi-fetch';
|
|
5
5
|
import { fetch } from 'undici';
|
|
@@ -789,6 +789,37 @@ var RuleTestResponse = z.object({
|
|
|
789
789
|
llm_prompt_url: z.string().optional().default(""),
|
|
790
790
|
llm_response_url: z.string().optional().default("")
|
|
791
791
|
}).passthrough();
|
|
792
|
+
var RuleTestBatchRule = z.object({
|
|
793
|
+
id: z.union([z.string(), z.null()]).optional(),
|
|
794
|
+
rule_type: z.string(),
|
|
795
|
+
config: z.object({}).partial().passthrough(),
|
|
796
|
+
target: z.string().optional().default("page"),
|
|
797
|
+
name: z.string().optional().default("Test Rule")
|
|
798
|
+
}).passthrough();
|
|
799
|
+
var RuleTestBatchRequest = z.object({
|
|
800
|
+
rules: z.array(RuleTestBatchRule).min(1).max(20),
|
|
801
|
+
scan_ids: z.array(z.string().uuid()).min(1).max(50)
|
|
802
|
+
}).passthrough();
|
|
803
|
+
var RuleTestBatchCell = z.object({
|
|
804
|
+
index: z.number().int(),
|
|
805
|
+
rule_id: z.union([z.string(), z.null()]).optional(),
|
|
806
|
+
scan_id: z.string().uuid(),
|
|
807
|
+
matched: z.boolean(),
|
|
808
|
+
tags: z.array(RuleTestTagResult),
|
|
809
|
+
elapsed_ms: z.number().int(),
|
|
810
|
+
error: z.union([z.string(), z.null()]).optional(),
|
|
811
|
+
error_code: z.union([z.string(), z.null()]).optional()
|
|
812
|
+
}).passthrough();
|
|
813
|
+
var RuleTestBatchSummary = z.object({
|
|
814
|
+
total: z.number().int(),
|
|
815
|
+
matched: z.number().int(),
|
|
816
|
+
failed: z.number().int(),
|
|
817
|
+
deadline_exceeded: z.number().int()
|
|
818
|
+
}).passthrough();
|
|
819
|
+
var RuleTestBatchResponse = z.object({
|
|
820
|
+
results: z.array(RuleTestBatchCell),
|
|
821
|
+
summary: RuleTestBatchSummary
|
|
822
|
+
}).passthrough();
|
|
792
823
|
var IabV3PolicyCategoryRequest = z.object({
|
|
793
824
|
tier1: z.string().min(1).max(200),
|
|
794
825
|
tier2: z.union([z.string(), z.null()]).optional(),
|
|
@@ -1265,6 +1296,8 @@ var schemas = {
|
|
|
1265
1296
|
TagDefinitionDetailResponse,
|
|
1266
1297
|
CustomRuleResponse,
|
|
1267
1298
|
RuleTestResponse,
|
|
1299
|
+
RuleTestBatchRequest,
|
|
1300
|
+
RuleTestBatchResponse,
|
|
1268
1301
|
PolicyEntryResponse,
|
|
1269
1302
|
LinkedCampaignResponse,
|
|
1270
1303
|
PolicySetResponse,
|
|
@@ -1628,6 +1661,7 @@ var RuleTestSchema = schemas.RuleTestResponse.pick({
|
|
|
1628
1661
|
tags: true
|
|
1629
1662
|
}).strip();
|
|
1630
1663
|
var parseRuleTest = (raw) => parseWithSchema(RuleTestSchema, raw, "rule-test");
|
|
1664
|
+
var parseRuleTestBatch = (raw) => parseWithSchema(schemas.RuleTestBatchResponse.strip(), raw, "rule-test-batch");
|
|
1631
1665
|
var AlertStatsSchema = schemas.AlertStatsResponse.pick({
|
|
1632
1666
|
open: true,
|
|
1633
1667
|
escalated: true,
|
|
@@ -2529,6 +2563,9 @@ function createHttpApiGateway(config) {
|
|
|
2529
2563
|
async testCustomRule(body) {
|
|
2530
2564
|
return call("POST", "/api/v1/custom-rules/test", { body }, parseRuleTest);
|
|
2531
2565
|
},
|
|
2566
|
+
async testCustomRulesBatch(body) {
|
|
2567
|
+
return call("POST", "/api/v1/custom-rules/test-batch", { body }, parseRuleTestBatch);
|
|
2568
|
+
},
|
|
2532
2569
|
// ── Policy sets ───────────────────────────────────────────────
|
|
2533
2570
|
async listPolicySets(filters) {
|
|
2534
2571
|
return call("GET", "/api/v1/policy-sets", { params: { query: filters } }, parsePolicySetPage);
|
|
@@ -4533,6 +4570,65 @@ var testCustomRuleTool = {
|
|
|
4533
4570
|
return ok(result.value);
|
|
4534
4571
|
}
|
|
4535
4572
|
};
|
|
4573
|
+
var TestCustomRulesBatchInputShape = {
|
|
4574
|
+
rules: z.array(
|
|
4575
|
+
z.object({
|
|
4576
|
+
id: z.string().uuid().optional().describe(
|
|
4577
|
+
"Optional UUID you choose to tell rules apart in the reply; echoed back as rule_id. The API accepts only a UUID here. It is not looked up and does not select a saved rule."
|
|
4578
|
+
),
|
|
4579
|
+
rule_type: z.string().max(50).describe(
|
|
4580
|
+
"Rule engine type. Same set as `test_custom_rule`: `stopword_content`, `stopword_url`, `regexp_content`, `regexp_url`, `regexp_request_url`, `regexp_request_body`, `blacklist_domain`, `combo`, `llm`."
|
|
4581
|
+
),
|
|
4582
|
+
config: patternAwareRuleConfigField.describe(
|
|
4583
|
+
"Rule-type-specific config. Same shape as `test_custom_rule`'s `config`. " + PATTERN_RULE_CONFIG_DOC + " " + COMBO_MATCH_SCOPE_DOC
|
|
4584
|
+
),
|
|
4585
|
+
target: z.string().max(30).default("page").describe(
|
|
4586
|
+
"Where to apply the rule. Defaults to 'page'. `regexp_request_url` and `regexp_request_body` also accept 'creative' and 'creative_and_page'."
|
|
4587
|
+
),
|
|
4588
|
+
name: z.string().min(1).max(200).default("Test Rule").describe(
|
|
4589
|
+
"Label the LLM prompt quotes as [USER RULE: \"<name>\"]. Same field as the single test. Defaults to 'Test Rule', which is what that test sends when name is omitted. Capped at 200 like `create_custom_rule`'s name, so a draft that tests well can be saved as is."
|
|
4590
|
+
)
|
|
4591
|
+
})
|
|
4592
|
+
).min(1).max(20).describe("Up to 20 rules. Every rule runs against every scan in `scan_ids`."),
|
|
4593
|
+
scan_ids: schemas.RuleTestBatchRequest.shape.scan_ids.describe(
|
|
4594
|
+
"Up to 50 stored scan UUIDs. Testing one rule against many scans is the usual case."
|
|
4595
|
+
)
|
|
4596
|
+
};
|
|
4597
|
+
var testCustomRulesBatchTool = {
|
|
4598
|
+
name: "test_custom_rules_batch",
|
|
4599
|
+
description: "Preview-test up to 20 rule definitions against up to 50 stored scans in one call, without saving them. Returns one cell per rule and scan; a cell's `index` is the rule's position in `rules`, so pair it with `scan_id` to identify the cell. A rule definition the API rejects fails the whole call as invalid input before anything runs. Otherwise a cell that could not run has `error` and `error_code` and never fails the rest: `deadline_exceeded` means the call ran out of time before that cell (about 110s per call) \u2014 call again with just those rules and scans; others are `timed_out`, `llm_failed`, `content_prohibited`, `scan_not_found`, `invalid_rule`, `failed`. `summary.failed` counts every cell with an error and `summary.deadline_exceeded` is the part of them the deadline cut off. A rate-limited error means this organization already has a batch running; wait for it. Many AI (`llm`) rules over many scans are better split across calls. Historical limits match `test_custom_rule`: `regexp_request_body` only has captured bodies for the last day, and `regexp_request_url` on a stored scan is best-effort.",
|
|
4600
|
+
annotations: {
|
|
4601
|
+
title: "Test Custom Rules Batch",
|
|
4602
|
+
readOnlyHint: true,
|
|
4603
|
+
destructiveHint: false,
|
|
4604
|
+
idempotentHint: true,
|
|
4605
|
+
openWorldHint: false
|
|
4606
|
+
},
|
|
4607
|
+
inputSchema: z.object(TestCustomRulesBatchInputShape),
|
|
4608
|
+
handler: async (input, ctx) => {
|
|
4609
|
+
for (const [index, rule] of input.rules.entries()) {
|
|
4610
|
+
const inputError = patternRuleInputError(rule);
|
|
4611
|
+
if (inputError?.kind === "invalid-input") {
|
|
4612
|
+
const message = "rules[" + String(index) + "]: " + inputError.message;
|
|
4613
|
+
return err(
|
|
4614
|
+
inputError.fieldErrors === void 0 ? { kind: "invalid-input", message } : { kind: "invalid-input", message, fieldErrors: inputError.fieldErrors }
|
|
4615
|
+
);
|
|
4616
|
+
}
|
|
4617
|
+
}
|
|
4618
|
+
const result = await ctx.api.testCustomRulesBatch({
|
|
4619
|
+
rules: input.rules.map((rule) => ({
|
|
4620
|
+
rule_type: rule.rule_type,
|
|
4621
|
+
config: rule.config,
|
|
4622
|
+
target: rule.target,
|
|
4623
|
+
name: rule.name,
|
|
4624
|
+
...rule.id === void 0 ? {} : { id: rule.id }
|
|
4625
|
+
})),
|
|
4626
|
+
scan_ids: input.scan_ids
|
|
4627
|
+
});
|
|
4628
|
+
if (result.isErr()) return err(mapApiError(result.error));
|
|
4629
|
+
return ok(result.value);
|
|
4630
|
+
}
|
|
4631
|
+
};
|
|
4536
4632
|
var UpdateCustomRuleInputShape = {
|
|
4537
4633
|
rule_id: z.string().uuid().describe("Rule UUID to update."),
|
|
4538
4634
|
name: z.string().min(1).max(200).optional().describe(
|
|
@@ -6263,6 +6359,7 @@ function registerAllTools(register) {
|
|
|
6263
6359
|
register(updateCustomRuleTool);
|
|
6264
6360
|
register(deleteCustomRuleTool);
|
|
6265
6361
|
register(testCustomRuleTool);
|
|
6362
|
+
register(testCustomRulesBatchTool);
|
|
6266
6363
|
register(listCustomTaxonomiesTool);
|
|
6267
6364
|
register(getCustomTaxonomyTool);
|
|
6268
6365
|
register(createCustomTaxonomyTool);
|
|
@@ -6387,5 +6484,5 @@ function formatToolError(error) {
|
|
|
6387
6484
|
}
|
|
6388
6485
|
|
|
6389
6486
|
export { BearerToken, SERVER_INSTRUCTIONS, createHttpApiGateway, createPinoLogger, declareEmptyResourcesAndPrompts, newRequestId, wireToolsIntoMcpServer };
|
|
6390
|
-
//# sourceMappingURL=chunk-
|
|
6391
|
-
//# sourceMappingURL=chunk-
|
|
6487
|
+
//# sourceMappingURL=chunk-MIDK3IA2.js.map
|
|
6488
|
+
//# sourceMappingURL=chunk-MIDK3IA2.js.map
|