@kaminari-ad/mcp 0.1.0 → 0.2.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 +198 -1
- package/MIGRATION_0_2.md +139 -0
- package/README.md +8 -6
- package/dist/bin.js +181 -43
- package/dist/bin.js.map +1 -1
- package/package.json +6 -3
package/dist/bin.js
CHANGED
|
@@ -6,6 +6,7 @@ import createClient from 'openapi-fetch';
|
|
|
6
6
|
import { fetch } from 'undici';
|
|
7
7
|
import { stdTimeFunctions, pino } from 'pino';
|
|
8
8
|
import pinoPretty from 'pino-pretty';
|
|
9
|
+
import { ListResourcesRequestSchema, ListPromptsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
|
|
9
10
|
import process4 from 'process';
|
|
10
11
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
11
12
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
@@ -31,7 +32,7 @@ var NAME, VERSION;
|
|
|
31
32
|
var init_version = __esm({
|
|
32
33
|
"src/shared/version.ts"() {
|
|
33
34
|
NAME = "@kaminari-ad/mcp";
|
|
34
|
-
VERSION = "0.
|
|
35
|
+
VERSION = "0.2.0";
|
|
35
36
|
}
|
|
36
37
|
});
|
|
37
38
|
var REDACTED, BEARER_HASH_PREFIX_LEN, MAX_HEADER_LEN, BearerToken;
|
|
@@ -172,7 +173,10 @@ function toApiError(status2, parsed, retryAfterHeader) {
|
|
|
172
173
|
return code === void 0 ? { kind: "forbidden", detail: message } : { kind: "forbidden", detail: message, code };
|
|
173
174
|
}
|
|
174
175
|
if (status2 === 404) return { kind: "not-found", detail: message };
|
|
175
|
-
if (status2 === 422 || status2 === 400)
|
|
176
|
+
if (status2 === 422 || status2 === 400) {
|
|
177
|
+
const code = errCode(parsed);
|
|
178
|
+
return code === void 0 ? { kind: "invalid-input", detail: message } : { kind: "invalid-input", detail: message, code };
|
|
179
|
+
}
|
|
176
180
|
if (status2 === 429) {
|
|
177
181
|
const ra = Array.isArray(retryAfterHeader) ? retryAfterHeader[0] : retryAfterHeader;
|
|
178
182
|
const retryMs = ra === void 0 ? void 0 : Number.parseInt(ra, 10) * 1e3;
|
|
@@ -1253,6 +1257,21 @@ var init_parse_campaign_group = __esm({
|
|
|
1253
1257
|
parseCampaignGroupArray = (raw) => parseArrayOrItemsWithSchema(CampaignGroupSchema, raw, "campaign-groups");
|
|
1254
1258
|
}
|
|
1255
1259
|
});
|
|
1260
|
+
var CampaignPickerSchema, CampaignPickerArraySchema, parseCampaignPickerArray;
|
|
1261
|
+
var init_parse_campaign_picker = __esm({
|
|
1262
|
+
"src/infrastructure/api/parsers/parse-campaign-picker.ts"() {
|
|
1263
|
+
init_zod_schemas();
|
|
1264
|
+
init_parse_with_schema();
|
|
1265
|
+
CampaignPickerSchema = schemas.CampaignPickerItem.pick({
|
|
1266
|
+
id: true,
|
|
1267
|
+
name: true,
|
|
1268
|
+
group_id: true,
|
|
1269
|
+
is_archived: true
|
|
1270
|
+
}).strip();
|
|
1271
|
+
CampaignPickerArraySchema = z.array(CampaignPickerSchema);
|
|
1272
|
+
parseCampaignPickerArray = (raw) => parseWithSchema(CampaignPickerArraySchema, raw, "campaigns-picker");
|
|
1273
|
+
}
|
|
1274
|
+
});
|
|
1256
1275
|
|
|
1257
1276
|
// src/infrastructure/api/parsers/shared.ts
|
|
1258
1277
|
function isStringRecord(v) {
|
|
@@ -1282,7 +1301,7 @@ var init_parse_count_envelope = __esm({
|
|
|
1282
1301
|
});
|
|
1283
1302
|
|
|
1284
1303
|
// src/infrastructure/api/parsers/parse-custom-rule.ts
|
|
1285
|
-
var CustomRuleSchema, parseCustomRule
|
|
1304
|
+
var CustomRuleSchema, parseCustomRule;
|
|
1286
1305
|
var init_parse_custom_rule = __esm({
|
|
1287
1306
|
"src/infrastructure/api/parsers/parse-custom-rule.ts"() {
|
|
1288
1307
|
init_zod_schemas();
|
|
@@ -1299,7 +1318,27 @@ var init_parse_custom_rule = __esm({
|
|
|
1299
1318
|
created_at: true
|
|
1300
1319
|
}).strip();
|
|
1301
1320
|
parseCustomRule = (raw) => parseWithSchema(CustomRuleSchema, raw, "custom-rule");
|
|
1302
|
-
|
|
1321
|
+
}
|
|
1322
|
+
});
|
|
1323
|
+
|
|
1324
|
+
// src/infrastructure/api/parsers/parse-custom-rule-page.ts
|
|
1325
|
+
var CustomRuleSchema2, parseCustomRulePage;
|
|
1326
|
+
var init_parse_custom_rule_page = __esm({
|
|
1327
|
+
"src/infrastructure/api/parsers/parse-custom-rule-page.ts"() {
|
|
1328
|
+
init_zod_schemas();
|
|
1329
|
+
init_parse_with_schema();
|
|
1330
|
+
CustomRuleSchema2 = schemas.CustomRuleResponse.pick({
|
|
1331
|
+
id: true,
|
|
1332
|
+
organization_id: true,
|
|
1333
|
+
name: true,
|
|
1334
|
+
tag_slug: true,
|
|
1335
|
+
rule_type: true,
|
|
1336
|
+
config: true,
|
|
1337
|
+
target: true,
|
|
1338
|
+
is_active: true,
|
|
1339
|
+
created_at: true
|
|
1340
|
+
}).strip();
|
|
1341
|
+
parseCustomRulePage = (raw) => parsePagedWithItemSchema(CustomRuleSchema2, raw, "custom-rules");
|
|
1303
1342
|
}
|
|
1304
1343
|
});
|
|
1305
1344
|
|
|
@@ -1359,7 +1398,7 @@ function parseArrayOf(parseItem) {
|
|
|
1359
1398
|
return ok(out);
|
|
1360
1399
|
};
|
|
1361
1400
|
}
|
|
1362
|
-
var OrgSchema, parseOrg, UserSchema, parseUser, RoleSchema, parseRole, ApiKeyCreatedSchema, parseApiKeyCreated, ScanTagSchema, parseScanTag,
|
|
1401
|
+
var OrgSchema, parseOrg, UserSchema, parseUser, RoleSchema, parseRole, ApiKeyCreatedSchema, parseApiKeyCreated, ScanTagSchema, parseScanTag, RuleTestSchema, parseRuleTest, AlertStatsSchema, parseAlertStats, UsageSchema, parseUsage, UsageSummarySchema, parseUsageSummary, BalanceTxSchema, parseBalanceTx, InvoiceSchema, parseInvoice, WebhookDeliverySchema, parseWebhookDelivery, EventCatalogSchema, parseEventCatalog, AlertDestinationSchema, parseAlertDestination, CampaignOverridesSchema, parseCampaignAlertOverrides, BulkReplaySchema, parseBulkReplay, GroupActionSchema, parseGroupAction;
|
|
1363
1402
|
var init_parse_generic = __esm({
|
|
1364
1403
|
"src/infrastructure/api/parsers/parse-generic.ts"() {
|
|
1365
1404
|
init_zod_schemas();
|
|
@@ -1411,20 +1450,6 @@ var init_parse_generic = __esm({
|
|
|
1411
1450
|
created_at: true
|
|
1412
1451
|
}).strip();
|
|
1413
1452
|
parseScanTag = (raw) => parseWithSchema(ScanTagSchema, raw, "scan-tag");
|
|
1414
|
-
TagDetailSchema = schemas.TagDefinitionWithStatsResponse.pick({
|
|
1415
|
-
slug: true,
|
|
1416
|
-
category: true,
|
|
1417
|
-
source: true,
|
|
1418
|
-
display_name: true,
|
|
1419
|
-
description: true,
|
|
1420
|
-
severity: true,
|
|
1421
|
-
is_system: true,
|
|
1422
|
-
organization_id: true,
|
|
1423
|
-
show_in_public_report: true,
|
|
1424
|
-
scans_count: true,
|
|
1425
|
-
rules_count: true
|
|
1426
|
-
}).strip();
|
|
1427
|
-
parseTagDetail = (raw) => parseWithSchema(TagDetailSchema, raw, "tag-definition");
|
|
1428
1453
|
RuleTestSchema = schemas.RuleTestResponse.pick({
|
|
1429
1454
|
matched: true,
|
|
1430
1455
|
elapsed_ms: true,
|
|
@@ -1567,7 +1592,7 @@ var init_parse_geo_list = __esm({
|
|
|
1567
1592
|
});
|
|
1568
1593
|
|
|
1569
1594
|
// src/infrastructure/api/parsers/parse-policy-set.ts
|
|
1570
|
-
var PolicySetSchema,
|
|
1595
|
+
var PolicySetSchema, parsePolicySet;
|
|
1571
1596
|
var init_parse_policy_set = __esm({
|
|
1572
1597
|
"src/infrastructure/api/parsers/parse-policy-set.ts"() {
|
|
1573
1598
|
init_zod_schemas();
|
|
@@ -1582,6 +1607,16 @@ var init_parse_policy_set = __esm({
|
|
|
1582
1607
|
entries: true,
|
|
1583
1608
|
created_at: true
|
|
1584
1609
|
}).strip();
|
|
1610
|
+
parsePolicySet = (raw) => parseWithSchema(PolicySetSchema, raw, "policy-set");
|
|
1611
|
+
}
|
|
1612
|
+
});
|
|
1613
|
+
|
|
1614
|
+
// src/infrastructure/api/parsers/parse-policy-set-page.ts
|
|
1615
|
+
var PolicySetListItemSchema, parsePolicySetPage;
|
|
1616
|
+
var init_parse_policy_set_page = __esm({
|
|
1617
|
+
"src/infrastructure/api/parsers/parse-policy-set-page.ts"() {
|
|
1618
|
+
init_zod_schemas();
|
|
1619
|
+
init_parse_with_schema();
|
|
1585
1620
|
PolicySetListItemSchema = schemas.PolicySetListItem.pick({
|
|
1586
1621
|
id: true,
|
|
1587
1622
|
name: true,
|
|
@@ -1591,8 +1626,7 @@ var init_parse_policy_set = __esm({
|
|
|
1591
1626
|
is_approved: true,
|
|
1592
1627
|
created_at: true
|
|
1593
1628
|
}).strip();
|
|
1594
|
-
|
|
1595
|
-
parsePolicySetList = (raw) => parseArrayOrItemsWithSchema(PolicySetListItemSchema, raw, "policy-sets");
|
|
1629
|
+
parsePolicySetPage = (raw) => parsePagedWithItemSchema(PolicySetListItemSchema, raw, "policy-sets");
|
|
1596
1630
|
}
|
|
1597
1631
|
});
|
|
1598
1632
|
|
|
@@ -1617,6 +1651,25 @@ var init_parse_run = __esm({
|
|
|
1617
1651
|
parseRun = (raw) => parseWithSchema(RunSchema, raw, "run");
|
|
1618
1652
|
}
|
|
1619
1653
|
});
|
|
1654
|
+
|
|
1655
|
+
// src/infrastructure/api/parsers/parse-run-scan-page.ts
|
|
1656
|
+
var ScanTileSchema, parseRunScanPage;
|
|
1657
|
+
var init_parse_run_scan_page = __esm({
|
|
1658
|
+
"src/infrastructure/api/parsers/parse-run-scan-page.ts"() {
|
|
1659
|
+
init_zod_schemas();
|
|
1660
|
+
init_parse_with_schema();
|
|
1661
|
+
ScanTileSchema = schemas.ScanTileResponse.pick({
|
|
1662
|
+
id: true,
|
|
1663
|
+
country_code: true,
|
|
1664
|
+
status: true,
|
|
1665
|
+
offer_url: true,
|
|
1666
|
+
screenshot_url: true,
|
|
1667
|
+
elapsed_ms: true,
|
|
1668
|
+
error: true
|
|
1669
|
+
}).strip();
|
|
1670
|
+
parseRunScanPage = (raw) => parsePagedWithItemSchema(ScanTileSchema, raw, "run-scans");
|
|
1671
|
+
}
|
|
1672
|
+
});
|
|
1620
1673
|
var ScanSchema, ScanArraySchema, parseScan, parseScanArray;
|
|
1621
1674
|
var init_parse_scan = __esm({
|
|
1622
1675
|
"src/infrastructure/api/parsers/parse-scan.ts"() {
|
|
@@ -1670,7 +1723,7 @@ var init_parse_scan_page = __esm({
|
|
|
1670
1723
|
parseScanPage = (raw) => parsePagedWithItemSchema(ScanBriefSchema, raw, "scans");
|
|
1671
1724
|
}
|
|
1672
1725
|
});
|
|
1673
|
-
var TagDefinitionSchema, TagDefinitionArraySchema, parseTagDefinitionArray;
|
|
1726
|
+
var TagDefinitionSchema, TagDefinitionArraySchema, LinkedRuleSchema, TagDetailSchema, parseTagDefinitionArray, parseTagDetail;
|
|
1674
1727
|
var init_parse_tag = __esm({
|
|
1675
1728
|
"src/infrastructure/api/parsers/parse-tag.ts"() {
|
|
1676
1729
|
init_zod_schemas();
|
|
@@ -1689,7 +1742,26 @@ var init_parse_tag = __esm({
|
|
|
1689
1742
|
rules_count: true
|
|
1690
1743
|
}).strip();
|
|
1691
1744
|
TagDefinitionArraySchema = z.array(TagDefinitionSchema);
|
|
1745
|
+
LinkedRuleSchema = schemas.LinkedRuleResponse.pick({
|
|
1746
|
+
id: true,
|
|
1747
|
+
name: true,
|
|
1748
|
+
is_active: true
|
|
1749
|
+
}).strip();
|
|
1750
|
+
TagDetailSchema = schemas.TagDefinitionDetailResponse.pick({
|
|
1751
|
+
slug: true,
|
|
1752
|
+
category: true,
|
|
1753
|
+
source: true,
|
|
1754
|
+
display_name: true,
|
|
1755
|
+
description: true,
|
|
1756
|
+
severity: true,
|
|
1757
|
+
is_system: true,
|
|
1758
|
+
organization_id: true,
|
|
1759
|
+
show_in_public_report: true,
|
|
1760
|
+
scans_count: true,
|
|
1761
|
+
rules_count: true
|
|
1762
|
+
}).extend({ linked_rules: z.array(LinkedRuleSchema).optional() }).strip();
|
|
1692
1763
|
parseTagDefinitionArray = (raw) => parseWithSchema(TagDefinitionArraySchema, raw, "tag-definitions");
|
|
1764
|
+
parseTagDetail = (raw) => parseWithSchema(TagDetailSchema, raw, "tag-definition");
|
|
1693
1765
|
}
|
|
1694
1766
|
});
|
|
1695
1767
|
var WebhookSchema, WebhookListSchema, WebhookCreatedSchema, TestWebhookResponseSchema, parseWebhook, parseWebhookList, parseWebhookCreated, parseTestWebhookResponse;
|
|
@@ -1966,6 +2038,9 @@ function createHttpApiGateway(config) {
|
|
|
1966
2038
|
parsePageOf(parseRun)
|
|
1967
2039
|
);
|
|
1968
2040
|
},
|
|
2041
|
+
async listCampaignsPicker() {
|
|
2042
|
+
return call("GET", "/api/v1/campaigns/picker", {}, parseCampaignPickerArray);
|
|
2043
|
+
},
|
|
1969
2044
|
// ── Runs ──────────────────────────────────────────────────────
|
|
1970
2045
|
async getRun(id) {
|
|
1971
2046
|
return call("GET", "/api/v1/runs/{run_id}", { params: { path: { run_id: id } } }, parseRun);
|
|
@@ -1983,7 +2058,7 @@ function createHttpApiGateway(config) {
|
|
|
1983
2058
|
"GET",
|
|
1984
2059
|
"/api/v1/runs/{run_id}/scans",
|
|
1985
2060
|
{ params: { path: { run_id: runId }, query: filters } },
|
|
1986
|
-
|
|
2061
|
+
parseRunScanPage
|
|
1987
2062
|
);
|
|
1988
2063
|
},
|
|
1989
2064
|
// ── Campaign groups ───────────────────────────────────────────
|
|
@@ -2096,7 +2171,7 @@ function createHttpApiGateway(config) {
|
|
|
2096
2171
|
"GET",
|
|
2097
2172
|
"/api/v1/custom-rules",
|
|
2098
2173
|
{ params: { query: filters } },
|
|
2099
|
-
|
|
2174
|
+
parseCustomRulePage
|
|
2100
2175
|
);
|
|
2101
2176
|
},
|
|
2102
2177
|
async getCustomRule(id) {
|
|
@@ -2130,8 +2205,8 @@ function createHttpApiGateway(config) {
|
|
|
2130
2205
|
return call("POST", "/api/v1/custom-rules/test", { body }, parseRuleTest);
|
|
2131
2206
|
},
|
|
2132
2207
|
// ── Policy sets ───────────────────────────────────────────────
|
|
2133
|
-
async listPolicySets() {
|
|
2134
|
-
return call("GET", "/api/v1/policy-sets", {},
|
|
2208
|
+
async listPolicySets(filters) {
|
|
2209
|
+
return call("GET", "/api/v1/policy-sets", { params: { query: filters } }, parsePolicySetPage);
|
|
2135
2210
|
},
|
|
2136
2211
|
async getPolicySet(id) {
|
|
2137
2212
|
return call(
|
|
@@ -2341,14 +2416,18 @@ var init_http_api_gateway = __esm({
|
|
|
2341
2416
|
init_parse_billing_summary();
|
|
2342
2417
|
init_parse_campaign();
|
|
2343
2418
|
init_parse_campaign_group();
|
|
2419
|
+
init_parse_campaign_picker();
|
|
2344
2420
|
init_parse_count_envelope();
|
|
2345
2421
|
init_parse_custom_rule();
|
|
2422
|
+
init_parse_custom_rule_page();
|
|
2346
2423
|
init_parse_empty();
|
|
2347
2424
|
init_parse_emulator();
|
|
2348
2425
|
init_parse_generic();
|
|
2349
2426
|
init_parse_geo_list();
|
|
2350
2427
|
init_parse_policy_set();
|
|
2428
|
+
init_parse_policy_set_page();
|
|
2351
2429
|
init_parse_run();
|
|
2430
|
+
init_parse_run_scan_page();
|
|
2352
2431
|
init_parse_scan();
|
|
2353
2432
|
init_parse_scan_page();
|
|
2354
2433
|
init_parse_tag();
|
|
@@ -2415,6 +2494,21 @@ var init_pino_logger = __esm({
|
|
|
2415
2494
|
];
|
|
2416
2495
|
}
|
|
2417
2496
|
});
|
|
2497
|
+
function declareEmptyResourcesAndPrompts(server) {
|
|
2498
|
+
server.server.registerCapabilities({ resources: {}, prompts: {} });
|
|
2499
|
+
server.server.setRequestHandler(ListResourcesRequestSchema, async () => {
|
|
2500
|
+
await Promise.resolve();
|
|
2501
|
+
return { resources: [] };
|
|
2502
|
+
});
|
|
2503
|
+
server.server.setRequestHandler(ListPromptsRequestSchema, async () => {
|
|
2504
|
+
await Promise.resolve();
|
|
2505
|
+
return { prompts: [] };
|
|
2506
|
+
});
|
|
2507
|
+
}
|
|
2508
|
+
var init_declare_empty_caps = __esm({
|
|
2509
|
+
"src/presentation/shared/declare-empty-caps.ts"() {
|
|
2510
|
+
}
|
|
2511
|
+
});
|
|
2418
2512
|
|
|
2419
2513
|
// src/application/services/api-error-mapper.ts
|
|
2420
2514
|
function mapApiError(apiError) {
|
|
@@ -2427,8 +2521,12 @@ function mapApiError(apiError) {
|
|
|
2427
2521
|
return { kind: "not-found", message: apiError.detail };
|
|
2428
2522
|
case "rate-limited":
|
|
2429
2523
|
return apiError.retryAfterMs === void 0 ? { kind: "rate-limited", message: apiError.detail } : { kind: "rate-limited", message: apiError.detail, retryAfterMs: apiError.retryAfterMs };
|
|
2430
|
-
case "invalid-input":
|
|
2431
|
-
|
|
2524
|
+
case "invalid-input": {
|
|
2525
|
+
const out = { kind: "invalid-input", message: apiError.detail };
|
|
2526
|
+
if (apiError.fieldErrors !== void 0) out.fieldErrors = apiError.fieldErrors;
|
|
2527
|
+
if (apiError.code !== void 0) out.code = apiError.code;
|
|
2528
|
+
return out;
|
|
2529
|
+
}
|
|
2432
2530
|
case "upstream":
|
|
2433
2531
|
return apiError.status === void 0 ? { kind: "upstream", message: apiError.detail } : { kind: "upstream", message: apiError.detail, status: apiError.status };
|
|
2434
2532
|
}
|
|
@@ -3587,6 +3685,31 @@ var init_list_campaigns_tool = __esm({
|
|
|
3587
3685
|
};
|
|
3588
3686
|
}
|
|
3589
3687
|
});
|
|
3688
|
+
var ListCampaignsPickerInputShape, listCampaignsPickerTool;
|
|
3689
|
+
var init_list_campaigns_picker_tool = __esm({
|
|
3690
|
+
"src/application/tools/campaigns/list-campaigns-picker.tool.ts"() {
|
|
3691
|
+
init_result();
|
|
3692
|
+
init_api_error_mapper();
|
|
3693
|
+
ListCampaignsPickerInputShape = {};
|
|
3694
|
+
listCampaignsPickerTool = {
|
|
3695
|
+
name: "list_campaigns_picker",
|
|
3696
|
+
description: "Slim per-row campaign list for selection UIs \u2014 id, name, group_id, is_archived. Cheaper than `list_campaigns` for orgs with thousands of campaigns. Use `get_campaign(id)` after a selection to fetch full details.",
|
|
3697
|
+
annotations: {
|
|
3698
|
+
title: "List Campaigns (Picker)",
|
|
3699
|
+
readOnlyHint: true,
|
|
3700
|
+
destructiveHint: false,
|
|
3701
|
+
idempotentHint: true,
|
|
3702
|
+
openWorldHint: false
|
|
3703
|
+
},
|
|
3704
|
+
inputSchema: z.object(ListCampaignsPickerInputShape),
|
|
3705
|
+
handler: async (_input, ctx) => {
|
|
3706
|
+
const result = await ctx.api.listCampaignsPicker();
|
|
3707
|
+
if (result.isErr()) return err(mapApiError(result.error));
|
|
3708
|
+
return ok(result.value);
|
|
3709
|
+
}
|
|
3710
|
+
};
|
|
3711
|
+
}
|
|
3712
|
+
});
|
|
3590
3713
|
var RunCampaignInputShape, runCampaignTool;
|
|
3591
3714
|
var init_run_campaign_tool = __esm({
|
|
3592
3715
|
"src/application/tools/campaigns/run-campaign.tool.ts"() {
|
|
@@ -3690,7 +3813,9 @@ var init_create_custom_rule_tool = __esm({
|
|
|
3690
3813
|
tag_slug: z.string().max(100).optional().describe("Tag slug to assign on match. Empty = create-only (advanced)."),
|
|
3691
3814
|
rule_type: z.string().max(50).describe("Rule engine: regex | substring | iab_category | etc. (API validates)."),
|
|
3692
3815
|
config: z.record(z.unknown()).describe("Rule-type-specific configuration object. Shape depends on rule_type."),
|
|
3693
|
-
target: z.string().max(30).optional().describe(
|
|
3816
|
+
target: z.string().max(30).optional().describe(
|
|
3817
|
+
"Where to apply the rule (e.g. 'page' for landing HTML). Default: page. See API docs for the full set of valid values."
|
|
3818
|
+
)
|
|
3694
3819
|
};
|
|
3695
3820
|
createCustomRuleTool = {
|
|
3696
3821
|
name: "create_custom_rule",
|
|
@@ -3781,7 +3906,7 @@ var init_list_custom_rules_tool = __esm({
|
|
|
3781
3906
|
};
|
|
3782
3907
|
listCustomRulesTool = {
|
|
3783
3908
|
name: "list_custom_rules",
|
|
3784
|
-
description: "
|
|
3909
|
+
description: "Paginated list of the organization's custom tag-detection rules (regex / heuristics) with their config, target, and active flag. Returns `{items, total, page, limit}`. To iterate: there is a next page iff `page * limit < total` (or equivalently `items.length === limit` until the last page). `page` is 1-indexed.",
|
|
3785
3910
|
annotations: {
|
|
3786
3911
|
title: "List Custom Rules",
|
|
3787
3912
|
readOnlyHint: true,
|
|
@@ -3793,7 +3918,7 @@ var init_list_custom_rules_tool = __esm({
|
|
|
3793
3918
|
handler: async (input, ctx) => {
|
|
3794
3919
|
const result = await ctx.api.listCustomRules({ page: input.page, limit: input.limit });
|
|
3795
3920
|
if (result.isErr()) return err(mapApiError(result.error));
|
|
3796
|
-
return ok(
|
|
3921
|
+
return ok(result.value);
|
|
3797
3922
|
}
|
|
3798
3923
|
};
|
|
3799
3924
|
}
|
|
@@ -3806,7 +3931,9 @@ var init_test_custom_rule_tool = __esm({
|
|
|
3806
3931
|
TestCustomRuleInputShape = {
|
|
3807
3932
|
rule_type: z.string().max(50).describe("Rule engine type (regex, substring, ...)."),
|
|
3808
3933
|
config: z.record(z.unknown()).describe("Rule-type-specific config to test."),
|
|
3809
|
-
target: z.string().max(30).describe(
|
|
3934
|
+
target: z.string().max(30).describe(
|
|
3935
|
+
"Where to apply the rule (e.g. 'page' for landing HTML). See API docs for the full set of valid values."
|
|
3936
|
+
),
|
|
3810
3937
|
scan_id: z.string().uuid().describe("Existing scan UUID to evaluate the rule against.")
|
|
3811
3938
|
};
|
|
3812
3939
|
testCustomRuleTool = {
|
|
@@ -3843,7 +3970,9 @@ var init_update_custom_rule_tool = __esm({
|
|
|
3843
3970
|
name: z.string().min(1).max(200).optional().describe("New display name."),
|
|
3844
3971
|
tag_slug: z.string().max(100).optional().describe("New tag slug to assign on match."),
|
|
3845
3972
|
config: z.record(z.unknown()).optional().describe("New rule-type-specific config object."),
|
|
3846
|
-
target: z.string().max(30).optional().describe(
|
|
3973
|
+
target: z.string().max(30).optional().describe(
|
|
3974
|
+
"Where to apply the rule (e.g. 'page' for landing HTML). See API docs for the full set of valid values."
|
|
3975
|
+
),
|
|
3847
3976
|
is_active: z.boolean().optional().describe("Enable/disable the rule.")
|
|
3848
3977
|
};
|
|
3849
3978
|
updateCustomRuleTool = {
|
|
@@ -3998,7 +4127,7 @@ var init_delete_policy_set_tool = __esm({
|
|
|
3998
4127
|
};
|
|
3999
4128
|
deletePolicySetTool = {
|
|
4000
4129
|
name: "delete_policy_set",
|
|
4001
|
-
description: "Permanently delete a policy set.
|
|
4130
|
+
description: "Permanently delete a policy set. IMPORTANT: API returns HTTP 400 if any active campaign is still bound to this set. To unbind first, call `list_campaigns` with a `policy_set_id` filter (when available) or scan your campaigns for matches, then `update_campaign` for each match setting `policy_set_id=null`, then retry delete. Alerts created under this set persist (their `policy_set_id` becomes `null`).",
|
|
4002
4131
|
annotations: {
|
|
4003
4132
|
title: "Delete Policy Set",
|
|
4004
4133
|
readOnlyHint: false,
|
|
@@ -4047,10 +4176,13 @@ var init_list_policy_sets_tool = __esm({
|
|
|
4047
4176
|
"src/application/tools/policy-sets/list-policy-sets.tool.ts"() {
|
|
4048
4177
|
init_result();
|
|
4049
4178
|
init_api_error_mapper();
|
|
4050
|
-
ListPolicySetsInputShape = {
|
|
4179
|
+
ListPolicySetsInputShape = {
|
|
4180
|
+
page: z.number().int().min(1).max(500).default(1).describe("1-indexed page number."),
|
|
4181
|
+
limit: z.number().int().min(1).max(200).default(50).describe("Page size.")
|
|
4182
|
+
};
|
|
4051
4183
|
listPolicySetsTool = {
|
|
4052
4184
|
name: "list_policy_sets",
|
|
4053
|
-
description: "
|
|
4185
|
+
description: "Paginated list of policy sets: named collections of (tag, country-list) 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.",
|
|
4054
4186
|
annotations: {
|
|
4055
4187
|
title: "List Policy Sets",
|
|
4056
4188
|
readOnlyHint: true,
|
|
@@ -4059,10 +4191,10 @@ var init_list_policy_sets_tool = __esm({
|
|
|
4059
4191
|
openWorldHint: false
|
|
4060
4192
|
},
|
|
4061
4193
|
inputSchema: z.object(ListPolicySetsInputShape),
|
|
4062
|
-
handler: async (
|
|
4063
|
-
const result = await ctx.api.listPolicySets();
|
|
4194
|
+
handler: async (input, ctx) => {
|
|
4195
|
+
const result = await ctx.api.listPolicySets({ page: input.page, limit: input.limit });
|
|
4064
4196
|
if (result.isErr()) return err(mapApiError(result.error));
|
|
4065
|
-
return ok(
|
|
4197
|
+
return ok(result.value);
|
|
4066
4198
|
}
|
|
4067
4199
|
};
|
|
4068
4200
|
}
|
|
@@ -4194,7 +4326,7 @@ var init_list_run_scans_tool = __esm({
|
|
|
4194
4326
|
};
|
|
4195
4327
|
listRunScansTool = {
|
|
4196
4328
|
name: "list_run_scans",
|
|
4197
|
-
description: "List the
|
|
4329
|
+
description: "List the tile-scan items produced by one run (status, country, offer URL, screenshot, elapsed ms, error). For full scan details (input URL, labels, classification, redirect chain) fetch a specific scan via `get_scan`.",
|
|
4198
4330
|
annotations: {
|
|
4199
4331
|
title: "List Run Scans",
|
|
4200
4332
|
readOnlyHint: true,
|
|
@@ -4470,7 +4602,7 @@ var init_get_tag_definition_tool = __esm({
|
|
|
4470
4602
|
};
|
|
4471
4603
|
getTagDefinitionTool = {
|
|
4472
4604
|
name: "get_tag_definition",
|
|
4473
|
-
description: "Get full definition of one tag: display name, description, severity, category, source (system vs custom), public-report visibility, usage counts.",
|
|
4605
|
+
description: "Get full definition of one tag: display name, description, severity, category, source (system vs custom), public-report visibility, usage counts, plus `linked_rules` \u2014 the custom rules currently producing this tag (id, name, active flag). Fetch a specific rule's full config via `get_custom_rule`.",
|
|
4474
4606
|
annotations: {
|
|
4475
4607
|
title: "Get Tag Definition",
|
|
4476
4608
|
readOnlyHint: true,
|
|
@@ -4932,6 +5064,7 @@ function registerAllTools(register) {
|
|
|
4932
5064
|
register(createCampaignTool);
|
|
4933
5065
|
register(updateCampaignTool);
|
|
4934
5066
|
register(listCampaignRunsTool);
|
|
5067
|
+
register(listCampaignsPickerTool);
|
|
4935
5068
|
register(getRunTool);
|
|
4936
5069
|
register(listRunScansTool);
|
|
4937
5070
|
register(cancelRunTool);
|
|
@@ -5028,6 +5161,7 @@ var init_tool_registry = __esm({
|
|
|
5028
5161
|
init_get_campaign_tool();
|
|
5029
5162
|
init_list_campaign_runs_tool();
|
|
5030
5163
|
init_list_campaigns_tool();
|
|
5164
|
+
init_list_campaigns_picker_tool();
|
|
5031
5165
|
init_run_campaign_tool();
|
|
5032
5166
|
init_unarchive_campaign_tool();
|
|
5033
5167
|
init_update_campaign_tool();
|
|
@@ -5127,7 +5261,7 @@ function formatToolError(error) {
|
|
|
5127
5261
|
case "rate-limited":
|
|
5128
5262
|
return `Rate limited: ${error.message}${error.retryAfterMs === void 0 ? "" : ` (retry after ${String(error.retryAfterMs)} ms)`}`;
|
|
5129
5263
|
case "invalid-input":
|
|
5130
|
-
return `Invalid input: ${error.message}`;
|
|
5264
|
+
return `Invalid input${error.code === void 0 ? "" : ` (${error.code})`}: ${error.message}`;
|
|
5131
5265
|
case "upstream":
|
|
5132
5266
|
return `Upstream error: ${error.message}`;
|
|
5133
5267
|
case "internal":
|
|
@@ -5170,6 +5304,7 @@ async function bootstrapStdio(config) {
|
|
|
5170
5304
|
const ctx = { api, logger: scopedLogger, requestId };
|
|
5171
5305
|
const server = new McpServer({ name: NAME, version: VERSION });
|
|
5172
5306
|
wireToolsIntoMcpServer(server, () => ctx);
|
|
5307
|
+
declareEmptyResourcesAndPrompts(server);
|
|
5173
5308
|
const transport = new StdioServerTransport();
|
|
5174
5309
|
await server.connect(transport);
|
|
5175
5310
|
scopedLogger.info({}, "stdio.ready");
|
|
@@ -5188,6 +5323,7 @@ var init_stdio_bootstrap = __esm({
|
|
|
5188
5323
|
init_http_api_gateway();
|
|
5189
5324
|
init_pino_logger();
|
|
5190
5325
|
init_version();
|
|
5326
|
+
init_declare_empty_caps();
|
|
5191
5327
|
init_wire_tools();
|
|
5192
5328
|
}
|
|
5193
5329
|
});
|
|
@@ -5330,6 +5466,7 @@ async function initNewSession(args) {
|
|
|
5330
5466
|
current: { api: seedApi, logger: reqLogger, requestId: args.requestId }
|
|
5331
5467
|
};
|
|
5332
5468
|
wireToolsIntoMcpServer(server, () => ctxRef.current);
|
|
5469
|
+
declareEmptyResourcesAndPrompts(server);
|
|
5333
5470
|
const transport = new StreamableHTTPServerTransport({
|
|
5334
5471
|
sessionIdGenerator: () => randomUUID(),
|
|
5335
5472
|
enableJsonResponse: true,
|
|
@@ -5358,6 +5495,7 @@ var init_mcp_session_factory = __esm({
|
|
|
5358
5495
|
"src/presentation/http/mcp-session-factory.ts"() {
|
|
5359
5496
|
init_session_id();
|
|
5360
5497
|
init_version();
|
|
5498
|
+
init_declare_empty_caps();
|
|
5361
5499
|
init_wire_tools();
|
|
5362
5500
|
}
|
|
5363
5501
|
});
|