@impart-security/impart-mcp 0.1.2 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +691 -125
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -42,11 +42,14 @@ async function makeImpartRequest(endpoint, queryParams, method = "GET", body) {
|
|
|
42
42
|
});
|
|
43
43
|
}
|
|
44
44
|
try {
|
|
45
|
-
const
|
|
45
|
+
const requestOptions = {
|
|
46
46
|
method,
|
|
47
47
|
headers,
|
|
48
|
-
|
|
49
|
-
|
|
48
|
+
};
|
|
49
|
+
if (body && method !== "GET" && method !== "HEAD") {
|
|
50
|
+
requestOptions.body = JSON.stringify(body);
|
|
51
|
+
}
|
|
52
|
+
const response = await fetch(url.toString(), requestOptions);
|
|
50
53
|
if (!response.ok) {
|
|
51
54
|
throw new Error(`HTTP error! status: ${response.status}`);
|
|
52
55
|
}
|
|
@@ -57,21 +60,30 @@ async function makeImpartRequest(endpoint, queryParams, method = "GET", body) {
|
|
|
57
60
|
return null;
|
|
58
61
|
}
|
|
59
62
|
}
|
|
63
|
+
// Helper function to generate tool names with orgId
|
|
64
|
+
function getToolName(baseName) {
|
|
65
|
+
return `${baseName}_${config_js_1.config.orgId.slice(-4)}`;
|
|
66
|
+
}
|
|
60
67
|
// Register tools with consistent naming patterns
|
|
61
|
-
server.tool("list_inspectors", "Get a list of inspectors for the organization", {
|
|
68
|
+
server.tool(getToolName("list_inspectors"), "Get a list of inspectors for the organization", {
|
|
62
69
|
page: zod_1.z
|
|
63
70
|
.number()
|
|
64
71
|
.default(1)
|
|
72
|
+
.optional()
|
|
65
73
|
.describe("The page of results to return (minimum value: 1)"),
|
|
66
74
|
max_results: zod_1.z
|
|
67
75
|
.number()
|
|
68
76
|
.default(100)
|
|
77
|
+
.optional()
|
|
69
78
|
.describe("The maximum number of results to return"),
|
|
70
79
|
}, async ({ page, max_results }) => {
|
|
71
|
-
const queryParams = {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
}
|
|
80
|
+
const queryParams = {};
|
|
81
|
+
if (page !== null && page !== undefined) {
|
|
82
|
+
queryParams["page"] = validatePage(page);
|
|
83
|
+
}
|
|
84
|
+
if (max_results !== null && max_results !== undefined) {
|
|
85
|
+
queryParams["max_results"] = max_results;
|
|
86
|
+
}
|
|
75
87
|
const data = await makeImpartRequest("inspectors", queryParams);
|
|
76
88
|
if (!data) {
|
|
77
89
|
return {
|
|
@@ -99,42 +111,65 @@ server.tool("list_inspectors", "Get a list of inspectors for the organization",
|
|
|
99
111
|
};
|
|
100
112
|
});
|
|
101
113
|
// Rules Script Tools
|
|
102
|
-
server.tool("list_rules_scripts", "Get a list of rules scripts for your Impart organization", {
|
|
114
|
+
server.tool(getToolName("list_rules_scripts"), "Get a list of rules scripts for your Impart organization", {
|
|
103
115
|
page: zod_1.z
|
|
104
116
|
.number()
|
|
105
117
|
.default(1)
|
|
118
|
+
.nullable()
|
|
106
119
|
.describe("The page of results to return (minimum value: 1)"),
|
|
107
120
|
max_results: zod_1.z
|
|
108
121
|
.number()
|
|
109
122
|
.default(100)
|
|
123
|
+
.nullable()
|
|
110
124
|
.describe("The maximum number of results to return"),
|
|
111
125
|
type: zod_1.z
|
|
112
126
|
.string()
|
|
113
127
|
.optional()
|
|
128
|
+
.nullable()
|
|
114
129
|
.describe("Filter by type of rule script ('custom' or 'core')"),
|
|
115
130
|
exclude_src: zod_1.z
|
|
116
131
|
.boolean()
|
|
117
132
|
.default(false)
|
|
133
|
+
.nullable()
|
|
118
134
|
.describe("Whether to exclude the rule script source"),
|
|
119
135
|
exclude_revisions: zod_1.z
|
|
120
136
|
.boolean()
|
|
121
137
|
.default(false)
|
|
138
|
+
.nullable()
|
|
122
139
|
.describe("Whether to exclude rule script revisions"),
|
|
123
140
|
is_disabled: zod_1.z
|
|
124
141
|
.string()
|
|
125
142
|
.optional()
|
|
143
|
+
.nullable()
|
|
126
144
|
.describe("Filter by disabled status ('true' or 'false')"),
|
|
127
|
-
label: zod_1.z
|
|
145
|
+
label: zod_1.z
|
|
146
|
+
.array(zod_1.z.string())
|
|
147
|
+
.optional()
|
|
148
|
+
.nullable()
|
|
149
|
+
.describe("Filter by label slugs"),
|
|
128
150
|
}, async ({ page, max_results, type, exclude_src, exclude_revisions, is_disabled, label, }) => {
|
|
129
|
-
const queryParams = {
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
151
|
+
const queryParams = {};
|
|
152
|
+
if (page !== null && page !== undefined) {
|
|
153
|
+
queryParams["page"] = validatePage(page);
|
|
154
|
+
}
|
|
155
|
+
if (max_results !== null && max_results !== undefined) {
|
|
156
|
+
queryParams["max_results"] = max_results;
|
|
157
|
+
}
|
|
158
|
+
if (type !== null && type !== undefined) {
|
|
159
|
+
queryParams["type"] = type;
|
|
160
|
+
}
|
|
161
|
+
if (exclude_src !== null && exclude_src !== undefined) {
|
|
162
|
+
queryParams["exclude_src"] = exclude_src;
|
|
163
|
+
}
|
|
164
|
+
if (exclude_revisions !== null && exclude_revisions !== undefined) {
|
|
165
|
+
queryParams["exclude_revisions"] = exclude_revisions;
|
|
166
|
+
}
|
|
167
|
+
if (is_disabled !== null && is_disabled !== undefined) {
|
|
168
|
+
queryParams["is_disabled"] = is_disabled;
|
|
169
|
+
}
|
|
170
|
+
if (label !== null && label !== undefined) {
|
|
171
|
+
queryParams["label"] = label;
|
|
172
|
+
}
|
|
138
173
|
const data = await makeImpartRequest("rules_scripts", queryParams);
|
|
139
174
|
if (!data) {
|
|
140
175
|
return {
|
|
@@ -177,11 +212,15 @@ server.tool("list_rules_scripts", "Get a list of rules scripts for your Impart o
|
|
|
177
212
|
content: [{ type: "text", text: formattedScripts.join("\n") }],
|
|
178
213
|
};
|
|
179
214
|
});
|
|
180
|
-
server.tool("get_rules_script", "Get details of a specific rules script", {
|
|
215
|
+
server.tool(getToolName("get_rules_script"), "Get details of a specific rules script", {
|
|
181
216
|
rules_script_id: zod_1.z
|
|
182
217
|
.string()
|
|
183
218
|
.describe("The unique identifier of the rules script"),
|
|
184
|
-
revision: zod_1.z
|
|
219
|
+
revision: zod_1.z
|
|
220
|
+
.number()
|
|
221
|
+
.optional()
|
|
222
|
+
.nullable()
|
|
223
|
+
.describe("The specific revision to fetch"),
|
|
185
224
|
}, async ({ rules_script_id, revision }) => {
|
|
186
225
|
if (!rules_script_id) {
|
|
187
226
|
return {
|
|
@@ -190,7 +229,10 @@ server.tool("get_rules_script", "Get details of a specific rules script", {
|
|
|
190
229
|
],
|
|
191
230
|
};
|
|
192
231
|
}
|
|
193
|
-
const queryParams =
|
|
232
|
+
const queryParams = {};
|
|
233
|
+
if (revision !== null && revision !== undefined) {
|
|
234
|
+
queryParams["revision"] = revision;
|
|
235
|
+
}
|
|
194
236
|
const data = await makeImpartRequest(`rules_scripts/${rules_script_id}`, queryParams);
|
|
195
237
|
if (!data) {
|
|
196
238
|
return {
|
|
@@ -226,7 +268,7 @@ server.tool("get_rules_script", "Get details of a specific rules script", {
|
|
|
226
268
|
content: [{ type: "text", text: formattedScript.join("\n") }],
|
|
227
269
|
};
|
|
228
270
|
});
|
|
229
|
-
server.tool("create_rules_script", "Creates a new rules script for the organization", {
|
|
271
|
+
server.tool(getToolName("create_rules_script"), "Creates a new rules script for the organization", {
|
|
230
272
|
name: zod_1.z.string().describe("The name of the rules script"),
|
|
231
273
|
src: zod_1.z
|
|
232
274
|
.string()
|
|
@@ -234,33 +276,48 @@ server.tool("create_rules_script", "Creates a new rules script for the organizat
|
|
|
234
276
|
lang: zod_1.z
|
|
235
277
|
.string()
|
|
236
278
|
.default("assemblyscript")
|
|
279
|
+
.nullable()
|
|
237
280
|
.describe("The language of the script"),
|
|
238
281
|
description: zod_1.z
|
|
239
282
|
.string()
|
|
240
283
|
.optional()
|
|
284
|
+
.nullable()
|
|
241
285
|
.describe("Optional description of the script"),
|
|
242
286
|
blocking_effect: zod_1.z
|
|
243
287
|
.string()
|
|
244
288
|
.default("block")
|
|
289
|
+
.nullable()
|
|
245
290
|
.describe("Effect when rule blocks"),
|
|
246
291
|
disabled: zod_1.z
|
|
247
292
|
.boolean()
|
|
248
293
|
.default(false)
|
|
294
|
+
.nullable()
|
|
249
295
|
.describe("Whether the script is disabled"),
|
|
250
296
|
labels: zod_1.z
|
|
251
297
|
.array(zod_1.z.string())
|
|
252
298
|
.optional()
|
|
299
|
+
.nullable()
|
|
253
300
|
.describe("Optional list of label slugs"),
|
|
254
301
|
}, async ({ name, src, lang, description, blocking_effect, disabled, labels, }) => {
|
|
255
302
|
const payload = {
|
|
256
303
|
name,
|
|
257
304
|
src,
|
|
258
|
-
lang,
|
|
259
|
-
description,
|
|
260
|
-
blocking_effect,
|
|
261
|
-
disabled,
|
|
262
|
-
labels: labels ?? [],
|
|
263
305
|
};
|
|
306
|
+
if (lang !== null && lang !== undefined) {
|
|
307
|
+
payload["lang"] = lang;
|
|
308
|
+
}
|
|
309
|
+
if (description !== null && description !== undefined) {
|
|
310
|
+
payload["description"] = description;
|
|
311
|
+
}
|
|
312
|
+
if (blocking_effect !== null && blocking_effect !== undefined) {
|
|
313
|
+
payload["blocking_effect"] = blocking_effect;
|
|
314
|
+
}
|
|
315
|
+
if (disabled !== null && disabled !== undefined) {
|
|
316
|
+
payload["disabled"] = disabled;
|
|
317
|
+
}
|
|
318
|
+
if (labels !== null && labels !== undefined) {
|
|
319
|
+
payload["labels"] = labels;
|
|
320
|
+
}
|
|
264
321
|
const data = await makeImpartRequest("rules_scripts", undefined, "POST", payload);
|
|
265
322
|
if (!data) {
|
|
266
323
|
return {
|
|
@@ -283,7 +340,7 @@ server.tool("create_rules_script", "Creates a new rules script for the organizat
|
|
|
283
340
|
content: [{ type: "text", text: formattedScript }],
|
|
284
341
|
};
|
|
285
342
|
});
|
|
286
|
-
server.tool("update_rules_script", "Updates an existing rules script", {
|
|
343
|
+
server.tool(getToolName("update_rules_script"), "Updates an existing rules script", {
|
|
287
344
|
rules_script_id: zod_1.z
|
|
288
345
|
.string()
|
|
289
346
|
.describe("The ID of the rules script to update"),
|
|
@@ -292,22 +349,27 @@ server.tool("update_rules_script", "Updates an existing rules script", {
|
|
|
292
349
|
lang: zod_1.z
|
|
293
350
|
.string()
|
|
294
351
|
.default("assemblyscript")
|
|
352
|
+
.nullable()
|
|
295
353
|
.describe("The language of the script"),
|
|
296
354
|
description: zod_1.z
|
|
297
355
|
.string()
|
|
298
356
|
.optional()
|
|
357
|
+
.nullable()
|
|
299
358
|
.describe("Optional description of the script"),
|
|
300
359
|
blocking_effect: zod_1.z
|
|
301
360
|
.string()
|
|
302
361
|
.default("block")
|
|
362
|
+
.nullable()
|
|
303
363
|
.describe("Effect when rule blocks"),
|
|
304
364
|
disabled: zod_1.z
|
|
305
365
|
.boolean()
|
|
306
366
|
.default(false)
|
|
367
|
+
.nullable()
|
|
307
368
|
.describe("Whether the script is disabled"),
|
|
308
369
|
labels: zod_1.z
|
|
309
370
|
.array(zod_1.z.string())
|
|
310
371
|
.optional()
|
|
372
|
+
.nullable()
|
|
311
373
|
.describe("Optional list of label slugs"),
|
|
312
374
|
}, async ({ rules_script_id, name, src, lang, description, blocking_effect, disabled, labels, }) => {
|
|
313
375
|
if (!rules_script_id) {
|
|
@@ -320,12 +382,22 @@ server.tool("update_rules_script", "Updates an existing rules script", {
|
|
|
320
382
|
const payload = {
|
|
321
383
|
name,
|
|
322
384
|
src,
|
|
323
|
-
lang,
|
|
324
|
-
description,
|
|
325
|
-
blocking_effect,
|
|
326
|
-
disabled,
|
|
327
|
-
labels: labels ?? [],
|
|
328
385
|
};
|
|
386
|
+
if (lang !== null && lang !== undefined) {
|
|
387
|
+
payload["lang"] = lang;
|
|
388
|
+
}
|
|
389
|
+
if (description !== null && description !== undefined) {
|
|
390
|
+
payload["description"] = description;
|
|
391
|
+
}
|
|
392
|
+
if (blocking_effect !== null && blocking_effect !== undefined) {
|
|
393
|
+
payload["blocking_effect"] = blocking_effect;
|
|
394
|
+
}
|
|
395
|
+
if (disabled !== null && disabled !== undefined) {
|
|
396
|
+
payload["disabled"] = disabled;
|
|
397
|
+
}
|
|
398
|
+
if (labels !== null && labels !== undefined) {
|
|
399
|
+
payload["labels"] = labels;
|
|
400
|
+
}
|
|
329
401
|
const data = await makeImpartRequest(`rules_scripts/${rules_script_id}`, undefined, "PUT", payload);
|
|
330
402
|
if (!data) {
|
|
331
403
|
return {
|
|
@@ -348,7 +420,7 @@ server.tool("update_rules_script", "Updates an existing rules script", {
|
|
|
348
420
|
content: [{ type: "text", text: formattedScript }],
|
|
349
421
|
};
|
|
350
422
|
});
|
|
351
|
-
server.tool("write_rule_script", "Generate a rule script using Impart's LLM", {
|
|
423
|
+
server.tool(getToolName("write_rule_script"), "Generate a rule script using Impart's LLM", {
|
|
352
424
|
query: zod_1.z.string().describe("Description of the rule you want to generate"),
|
|
353
425
|
}, async ({ query }) => {
|
|
354
426
|
const payload = {
|
|
@@ -379,13 +451,14 @@ server.tool("write_rule_script", "Generate a rule script using Impart's LLM", {
|
|
|
379
451
|
],
|
|
380
452
|
};
|
|
381
453
|
});
|
|
382
|
-
server.tool("validate_rules_script", "Validate a rules script", {
|
|
454
|
+
server.tool(getToolName("validate_rules_script"), "Validate a rules script", {
|
|
383
455
|
src: zod_1.z
|
|
384
456
|
.string()
|
|
385
457
|
.describe("The base64-encoded source code of the rules script to validate"),
|
|
386
458
|
lang: zod_1.z
|
|
387
459
|
.string()
|
|
388
460
|
.default("assemblyscript")
|
|
461
|
+
.nullable()
|
|
389
462
|
.describe("The language of the rules script"),
|
|
390
463
|
}, async ({ src, lang }) => {
|
|
391
464
|
if (!src) {
|
|
@@ -400,8 +473,10 @@ server.tool("validate_rules_script", "Validate a rules script", {
|
|
|
400
473
|
}
|
|
401
474
|
const payload = {
|
|
402
475
|
src,
|
|
403
|
-
lang,
|
|
404
476
|
};
|
|
477
|
+
if (lang !== null && lang !== undefined) {
|
|
478
|
+
payload["lang"] = lang;
|
|
479
|
+
}
|
|
405
480
|
const data = await makeImpartRequest("rules_script_validate", undefined, "POST", payload);
|
|
406
481
|
if (!data) {
|
|
407
482
|
return {
|
|
@@ -430,13 +505,17 @@ server.tool("validate_rules_script", "Validate a rules script", {
|
|
|
430
505
|
],
|
|
431
506
|
};
|
|
432
507
|
});
|
|
433
|
-
server.tool("list_endpoints", "Get an inventory of endpoints for the organization", {
|
|
508
|
+
server.tool(getToolName("list_endpoints"), "Get an inventory of endpoints for the organization", {
|
|
434
509
|
max_results: zod_1.z
|
|
435
510
|
.number()
|
|
436
511
|
.default(100)
|
|
512
|
+
.nullable()
|
|
437
513
|
.describe("The maximum number of results to return"),
|
|
438
514
|
}, async ({ max_results }) => {
|
|
439
|
-
const queryParams = {
|
|
515
|
+
const queryParams = {};
|
|
516
|
+
if (max_results !== null && max_results !== undefined) {
|
|
517
|
+
queryParams["max_results"] = max_results;
|
|
518
|
+
}
|
|
440
519
|
const data = await makeImpartRequest("endpoints", queryParams);
|
|
441
520
|
if (!data) {
|
|
442
521
|
return {
|
|
@@ -466,13 +545,17 @@ server.tool("list_endpoints", "Get an inventory of endpoints for the organizatio
|
|
|
466
545
|
content: [{ type: "text", text: formattedEndpoints.join("\n") }],
|
|
467
546
|
};
|
|
468
547
|
});
|
|
469
|
-
server.tool("list_tags", "Get a list of tags for your Impart organization", {
|
|
548
|
+
server.tool(getToolName("list_tags"), "Get a list of tags for your Impart organization", {
|
|
470
549
|
max_results: zod_1.z
|
|
471
550
|
.number()
|
|
472
551
|
.default(100)
|
|
552
|
+
.nullable()
|
|
473
553
|
.describe("The maximum number of results to return"),
|
|
474
554
|
}, async ({ max_results }) => {
|
|
475
|
-
const queryParams = {
|
|
555
|
+
const queryParams = {};
|
|
556
|
+
if (max_results !== null && max_results !== undefined) {
|
|
557
|
+
queryParams["max_results"] = max_results;
|
|
558
|
+
}
|
|
476
559
|
const data = await makeImpartRequest("tags", queryParams);
|
|
477
560
|
if (!data) {
|
|
478
561
|
return {
|
|
@@ -503,49 +586,73 @@ server.tool("list_tags", "Get a list of tags for your Impart organization", {
|
|
|
503
586
|
content: [{ type: "text", text: formattedTags.join("\n") }],
|
|
504
587
|
};
|
|
505
588
|
});
|
|
506
|
-
server.tool("get_tag_metrics", "Get timeseries metrics for one or more tags", {
|
|
589
|
+
server.tool(getToolName("get_tag_metrics"), "Get timeseries metrics for one or more tags", {
|
|
507
590
|
metric: zod_1.z
|
|
508
591
|
.array(zod_1.z.string())
|
|
509
592
|
.default(["http-request.count"])
|
|
593
|
+
.nullable()
|
|
510
594
|
.describe("List of metric names"),
|
|
511
|
-
from_time: zod_1.z.string().default("-1d").describe("Start time"),
|
|
512
|
-
until_time: zod_1.z.string().default("-0h").describe("End time"),
|
|
595
|
+
from_time: zod_1.z.string().default("-1d").nullable().describe("Start time"),
|
|
596
|
+
until_time: zod_1.z.string().default("-0h").nullable().describe("End time"),
|
|
513
597
|
spec_id: zod_1.z
|
|
514
598
|
.array(zod_1.z.string())
|
|
515
599
|
.optional()
|
|
600
|
+
.nullable()
|
|
516
601
|
.describe("Optional list of spec IDs"),
|
|
517
602
|
collection_id: zod_1.z
|
|
518
603
|
.array(zod_1.z.string())
|
|
519
604
|
.optional()
|
|
605
|
+
.nullable()
|
|
520
606
|
.describe("Optional list of collection IDs"),
|
|
521
607
|
endpoint_id: zod_1.z
|
|
522
608
|
.array(zod_1.z.string())
|
|
523
609
|
.optional()
|
|
610
|
+
.nullable()
|
|
524
611
|
.describe("Optional list of endpoint IDs"),
|
|
525
612
|
rollup: zod_1.z
|
|
526
613
|
.string()
|
|
527
614
|
.optional()
|
|
615
|
+
.nullable()
|
|
528
616
|
.describe("Optional time window rollup resolution"),
|
|
529
617
|
unlearned: zod_1.z
|
|
530
618
|
.string()
|
|
531
619
|
.default("include")
|
|
620
|
+
.nullable()
|
|
532
621
|
.describe("How to handle unlearned endpoints"),
|
|
533
622
|
max_results: zod_1.z
|
|
534
623
|
.number()
|
|
535
624
|
.default(100)
|
|
625
|
+
.nullable()
|
|
536
626
|
.describe("The maximum number of results to return"),
|
|
537
627
|
}, async ({ metric, from_time, until_time, spec_id, collection_id, endpoint_id, rollup, unlearned, max_results, }) => {
|
|
538
|
-
const queryParams = {
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
628
|
+
const queryParams = {};
|
|
629
|
+
if (metric !== null && metric !== undefined) {
|
|
630
|
+
queryParams["metric"] = metric;
|
|
631
|
+
}
|
|
632
|
+
if (from_time !== null && from_time !== undefined) {
|
|
633
|
+
queryParams["from"] = from_time;
|
|
634
|
+
}
|
|
635
|
+
if (until_time !== null && until_time !== undefined) {
|
|
636
|
+
queryParams["until"] = until_time;
|
|
637
|
+
}
|
|
638
|
+
if (spec_id !== null && spec_id !== undefined) {
|
|
639
|
+
queryParams["spec_id"] = spec_id;
|
|
640
|
+
}
|
|
641
|
+
if (collection_id !== null && collection_id !== undefined) {
|
|
642
|
+
queryParams["collection_id"] = collection_id;
|
|
643
|
+
}
|
|
644
|
+
if (endpoint_id !== null && endpoint_id !== undefined) {
|
|
645
|
+
queryParams["endpoint_id"] = endpoint_id;
|
|
646
|
+
}
|
|
647
|
+
if (rollup !== null && rollup !== undefined) {
|
|
648
|
+
queryParams["rollup"] = rollup;
|
|
649
|
+
}
|
|
650
|
+
if (unlearned !== null && unlearned !== undefined) {
|
|
651
|
+
queryParams["unlearned"] = unlearned;
|
|
652
|
+
}
|
|
653
|
+
if (max_results !== null && max_results !== undefined) {
|
|
654
|
+
queryParams["max_results"] = max_results;
|
|
655
|
+
}
|
|
549
656
|
const data = await makeImpartRequest("timeseries/tags", queryParams);
|
|
550
657
|
if (!data) {
|
|
551
658
|
return {
|
|
@@ -581,20 +688,25 @@ server.tool("get_tag_metrics", "Get timeseries metrics for one or more tags", {
|
|
|
581
688
|
content: [{ type: "text", text: formattedMetrics.join("\n") }],
|
|
582
689
|
};
|
|
583
690
|
});
|
|
584
|
-
server.tool("list_observed_hosts", "Get a list of observed hosts for your Impart organization", {
|
|
691
|
+
server.tool(getToolName("list_observed_hosts"), "Get a list of observed hosts for your Impart organization", {
|
|
585
692
|
page: zod_1.z
|
|
586
693
|
.number()
|
|
587
694
|
.default(1)
|
|
695
|
+
.nullable()
|
|
588
696
|
.describe("The page of results to return (minimum value: 1)"),
|
|
589
697
|
max_results: zod_1.z
|
|
590
698
|
.number()
|
|
591
699
|
.default(100)
|
|
700
|
+
.nullable()
|
|
592
701
|
.describe("The maximum number of results to return"),
|
|
593
702
|
}, async ({ page, max_results }) => {
|
|
594
|
-
const queryParams = {
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
}
|
|
703
|
+
const queryParams = {};
|
|
704
|
+
if (page !== null && page !== undefined) {
|
|
705
|
+
queryParams["page"] = validatePage(page);
|
|
706
|
+
}
|
|
707
|
+
if (max_results !== null && max_results !== undefined) {
|
|
708
|
+
queryParams["max_results"] = max_results;
|
|
709
|
+
}
|
|
598
710
|
const data = await makeImpartRequest("observed_hosts", queryParams);
|
|
599
711
|
if (!data) {
|
|
600
712
|
return {
|
|
@@ -628,7 +740,7 @@ server.tool("list_observed_hosts", "Get a list of observed hosts for your Impart
|
|
|
628
740
|
content: [{ type: "text", text: formattedHosts.join("\n") }],
|
|
629
741
|
};
|
|
630
742
|
});
|
|
631
|
-
server.tool("get_observed_host", "Get details of a specific observed host", {
|
|
743
|
+
server.tool(getToolName("get_observed_host"), "Get details of a specific observed host", {
|
|
632
744
|
observed_host_id: zod_1.z
|
|
633
745
|
.string()
|
|
634
746
|
.describe("The unique identifier of the observed host"),
|
|
@@ -671,20 +783,25 @@ server.tool("get_observed_host", "Get details of a specific observed host", {
|
|
|
671
783
|
content: [{ type: "text", text: formattedHost.join("\n") }],
|
|
672
784
|
};
|
|
673
785
|
});
|
|
674
|
-
server.tool("list_specs", "Get a list of specs for your Impart organization", {
|
|
786
|
+
server.tool(getToolName("list_specs"), "Get a list of specs for your Impart organization", {
|
|
675
787
|
page: zod_1.z
|
|
676
788
|
.number()
|
|
677
789
|
.default(1)
|
|
790
|
+
.nullable()
|
|
678
791
|
.describe("The page of results to return (minimum value: 1)"),
|
|
679
792
|
max_results: zod_1.z
|
|
680
793
|
.number()
|
|
681
794
|
.default(100)
|
|
795
|
+
.nullable()
|
|
682
796
|
.describe("The maximum number of results to return"),
|
|
683
797
|
}, async ({ page, max_results }) => {
|
|
684
|
-
const queryParams = {
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
}
|
|
798
|
+
const queryParams = {};
|
|
799
|
+
if (page !== null && page !== undefined) {
|
|
800
|
+
queryParams["page"] = validatePage(page);
|
|
801
|
+
}
|
|
802
|
+
if (max_results !== null && max_results !== undefined) {
|
|
803
|
+
queryParams["max_results"] = max_results;
|
|
804
|
+
}
|
|
688
805
|
const data = await makeImpartRequest("specs", queryParams);
|
|
689
806
|
if (!data) {
|
|
690
807
|
return {
|
|
@@ -716,16 +833,23 @@ server.tool("list_specs", "Get a list of specs for your Impart organization", {
|
|
|
716
833
|
content: [{ type: "text", text: formattedSpecs.join("\n") }],
|
|
717
834
|
};
|
|
718
835
|
});
|
|
719
|
-
server.tool("get_spec", "Get details of a specific spec", {
|
|
836
|
+
server.tool(getToolName("get_spec"), "Get details of a specific spec", {
|
|
720
837
|
spec_id: zod_1.z.string().describe("The unique identifier of the spec"),
|
|
721
|
-
revision: zod_1.z
|
|
838
|
+
revision: zod_1.z
|
|
839
|
+
.number()
|
|
840
|
+
.optional()
|
|
841
|
+
.nullable()
|
|
842
|
+
.describe("The specific revision to fetch"),
|
|
722
843
|
}, async ({ spec_id, revision }) => {
|
|
723
844
|
if (!spec_id) {
|
|
724
845
|
return {
|
|
725
846
|
content: [{ type: "text", text: "Error: spec_id is required." }],
|
|
726
847
|
};
|
|
727
848
|
}
|
|
728
|
-
const queryParams =
|
|
849
|
+
const queryParams = {};
|
|
850
|
+
if (revision !== null && revision !== undefined) {
|
|
851
|
+
queryParams["revision"] = revision;
|
|
852
|
+
}
|
|
729
853
|
const data = await makeImpartRequest(`specs/${spec_id}`, queryParams);
|
|
730
854
|
if (!data) {
|
|
731
855
|
return {
|
|
@@ -756,20 +880,25 @@ server.tool("get_spec", "Get details of a specific spec", {
|
|
|
756
880
|
content: [{ type: "text", text: formattedSpec.join("\n") }],
|
|
757
881
|
};
|
|
758
882
|
});
|
|
759
|
-
server.tool("list_api_bindings", "Get a list of API bindings for the organization", {
|
|
883
|
+
server.tool(getToolName("list_api_bindings"), "Get a list of API bindings for the organization", {
|
|
760
884
|
page: zod_1.z
|
|
761
885
|
.number()
|
|
762
886
|
.default(1)
|
|
887
|
+
.nullable()
|
|
763
888
|
.describe("The page of results to return (minimum value: 1)"),
|
|
764
889
|
max_results: zod_1.z
|
|
765
890
|
.number()
|
|
766
891
|
.default(100)
|
|
892
|
+
.nullable()
|
|
767
893
|
.describe("The maximum number of results to return"),
|
|
768
894
|
}, async ({ page, max_results }) => {
|
|
769
|
-
const queryParams = {
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
}
|
|
895
|
+
const queryParams = {};
|
|
896
|
+
if (page !== null && page !== undefined) {
|
|
897
|
+
queryParams["page"] = validatePage(page);
|
|
898
|
+
}
|
|
899
|
+
if (max_results !== null && max_results !== undefined) {
|
|
900
|
+
queryParams["max_results"] = max_results;
|
|
901
|
+
}
|
|
773
902
|
const data = await makeImpartRequest("api_bindings", queryParams);
|
|
774
903
|
if (!data) {
|
|
775
904
|
return {
|
|
@@ -802,7 +931,7 @@ server.tool("list_api_bindings", "Get a list of API bindings for the organizatio
|
|
|
802
931
|
content: [{ type: "text", text: formattedBindings.join("\n") }],
|
|
803
932
|
};
|
|
804
933
|
});
|
|
805
|
-
server.tool("create_api_binding", "Create a new API binding for the organization", {
|
|
934
|
+
server.tool(getToolName("create_api_binding"), "Create a new API binding for the organization", {
|
|
806
935
|
name: zod_1.z.string().describe("The name of the API binding"),
|
|
807
936
|
binding_type: zod_1.z
|
|
808
937
|
.string()
|
|
@@ -815,26 +944,36 @@ server.tool("create_api_binding", "Create a new API binding for the organization
|
|
|
815
944
|
description: zod_1.z
|
|
816
945
|
.string()
|
|
817
946
|
.optional()
|
|
947
|
+
.nullable()
|
|
818
948
|
.describe("Optional description of the binding"),
|
|
819
949
|
patch_operations: zod_1.z
|
|
820
950
|
.array(zod_1.z.record(zod_1.z.any()))
|
|
821
951
|
.optional()
|
|
952
|
+
.nullable()
|
|
822
953
|
.describe("Optional list of JSON patch operations"),
|
|
823
954
|
enable_learning: zod_1.z
|
|
824
955
|
.boolean()
|
|
825
956
|
.default(true)
|
|
957
|
+
.nullable()
|
|
826
958
|
.describe("Whether to enable learning for this binding"),
|
|
827
959
|
}, async ({ name, binding_type, host, api_binding_source, binding_value, description, patch_operations, enable_learning, }) => {
|
|
960
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
828
961
|
const payload = {
|
|
829
962
|
name,
|
|
830
963
|
type: binding_type,
|
|
831
964
|
host,
|
|
832
965
|
source: api_binding_source,
|
|
833
966
|
value: binding_value,
|
|
834
|
-
description,
|
|
835
|
-
patch_operations: patch_operations ?? [],
|
|
836
|
-
enable_learning,
|
|
837
967
|
};
|
|
968
|
+
if (description !== null && description !== undefined) {
|
|
969
|
+
payload["description"] = description;
|
|
970
|
+
}
|
|
971
|
+
if (patch_operations !== null && patch_operations !== undefined) {
|
|
972
|
+
payload["patch_operations"] = patch_operations;
|
|
973
|
+
}
|
|
974
|
+
if (enable_learning !== null && enable_learning !== undefined) {
|
|
975
|
+
payload["enable_learning"] = enable_learning;
|
|
976
|
+
}
|
|
838
977
|
const data = await makeImpartRequest("api_bindings", undefined, "POST", payload);
|
|
839
978
|
if (!data) {
|
|
840
979
|
return {
|
|
@@ -858,24 +997,41 @@ server.tool("create_api_binding", "Create a new API binding for the organization
|
|
|
858
997
|
content: [{ type: "text", text: formattedBinding }],
|
|
859
998
|
};
|
|
860
999
|
});
|
|
861
|
-
server.tool("list_lists", "Get a list of lists for the organization", {
|
|
862
|
-
kind: zod_1.z
|
|
863
|
-
|
|
1000
|
+
server.tool(getToolName("list_lists"), "Get a list of lists for the organization", {
|
|
1001
|
+
kind: zod_1.z
|
|
1002
|
+
.string()
|
|
1003
|
+
.optional()
|
|
1004
|
+
.nullable()
|
|
1005
|
+
.describe("The list kind to query for"),
|
|
1006
|
+
subkind: zod_1.z
|
|
1007
|
+
.string()
|
|
1008
|
+
.optional()
|
|
1009
|
+
.nullable()
|
|
1010
|
+
.describe("The list subkind to query for"),
|
|
864
1011
|
page: zod_1.z
|
|
865
1012
|
.number()
|
|
866
1013
|
.default(1)
|
|
1014
|
+
.nullable()
|
|
867
1015
|
.describe("The page of results to return (minimum: 1)"),
|
|
868
1016
|
max_results: zod_1.z
|
|
869
1017
|
.number()
|
|
870
1018
|
.default(100)
|
|
1019
|
+
.nullable()
|
|
871
1020
|
.describe("The maximum number of results to return"),
|
|
872
1021
|
}, async ({ kind, subkind, page, max_results }) => {
|
|
873
|
-
const queryParams = {
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
1022
|
+
const queryParams = {};
|
|
1023
|
+
if (kind !== null && kind !== undefined) {
|
|
1024
|
+
queryParams["kind"] = kind;
|
|
1025
|
+
}
|
|
1026
|
+
if (subkind !== null && subkind !== undefined) {
|
|
1027
|
+
queryParams["subkind"] = subkind;
|
|
1028
|
+
}
|
|
1029
|
+
if (page !== null && page !== undefined) {
|
|
1030
|
+
queryParams["page"] = validatePage(page);
|
|
1031
|
+
}
|
|
1032
|
+
if (max_results !== null && max_results !== undefined) {
|
|
1033
|
+
queryParams["max_results"] = max_results;
|
|
1034
|
+
}
|
|
879
1035
|
const data = await makeImpartRequest("lists", queryParams);
|
|
880
1036
|
if (!data) {
|
|
881
1037
|
return {
|
|
@@ -906,7 +1062,7 @@ server.tool("list_lists", "Get a list of lists for the organization", {
|
|
|
906
1062
|
content: [{ type: "text", text: formattedLists.join("\n") }],
|
|
907
1063
|
};
|
|
908
1064
|
});
|
|
909
|
-
server.tool("get_list_items", "Get items from a specific list", {
|
|
1065
|
+
server.tool(getToolName("get_list_items"), "Get items from a specific list", {
|
|
910
1066
|
list_id: zod_1.z.string().describe("The ID of the list"),
|
|
911
1067
|
page: zod_1.z
|
|
912
1068
|
.number()
|
|
@@ -945,49 +1101,61 @@ server.tool("get_list_items", "Get items from a specific list", {
|
|
|
945
1101
|
content: [{ type: "text", text: formattedItems.join("\n") }],
|
|
946
1102
|
};
|
|
947
1103
|
});
|
|
948
|
-
server.tool("create_list", "
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
description: zod_1.z.string().
|
|
953
|
-
functionality: zod_1.z
|
|
954
|
-
.string()
|
|
955
|
-
.default("add/remove")
|
|
956
|
-
.describe("List functionality"),
|
|
1104
|
+
server.tool(getToolName("create_list"), "Create a new list", {
|
|
1105
|
+
kind: zod_1.z.string().describe("The kind of list to create"),
|
|
1106
|
+
subkind: zod_1.z.string().describe("The subkind of list to create"),
|
|
1107
|
+
name: zod_1.z.string().describe("The name of the list"),
|
|
1108
|
+
description: zod_1.z.string().nullable().describe("The description of the list"),
|
|
957
1109
|
items: zod_1.z
|
|
958
|
-
.array(zod_1.z.
|
|
959
|
-
.
|
|
960
|
-
.describe("
|
|
961
|
-
}, async ({
|
|
962
|
-
|
|
963
|
-
|
|
1110
|
+
.array(zod_1.z.string())
|
|
1111
|
+
.nullable()
|
|
1112
|
+
.describe("The items to add to the list"),
|
|
1113
|
+
}, async ({ kind, subkind, name, description, items }) => {
|
|
1114
|
+
if (!kind || !subkind || !name) {
|
|
1115
|
+
return {
|
|
1116
|
+
content: [
|
|
1117
|
+
{ type: "text", text: "Error: kind, subkind, and name are required" },
|
|
1118
|
+
],
|
|
1119
|
+
isError: true,
|
|
1120
|
+
};
|
|
1121
|
+
}
|
|
1122
|
+
const body = {
|
|
964
1123
|
kind,
|
|
965
1124
|
subkind,
|
|
966
|
-
|
|
967
|
-
functionality,
|
|
968
|
-
items: items ?? [],
|
|
1125
|
+
name,
|
|
969
1126
|
};
|
|
970
|
-
|
|
1127
|
+
if (description !== null && description !== undefined) {
|
|
1128
|
+
body["description"] = description;
|
|
1129
|
+
}
|
|
1130
|
+
if (items !== null && items !== undefined) {
|
|
1131
|
+
body["items"] = items;
|
|
1132
|
+
}
|
|
1133
|
+
const data = await makeImpartRequest("lists", {}, "POST", body);
|
|
971
1134
|
if (!data) {
|
|
972
1135
|
return {
|
|
973
1136
|
content: [{ type: "text", text: "Failed to create list" }],
|
|
1137
|
+
isError: true,
|
|
974
1138
|
};
|
|
975
1139
|
}
|
|
976
|
-
const formattedList = [
|
|
977
|
-
"List created successfully:",
|
|
978
|
-
`ID: ${data.id}`,
|
|
979
|
-
`Name: ${data.name}`,
|
|
980
|
-
`Kind: ${data.kind}`,
|
|
981
|
-
`Subkind: ${data.subkind ?? "N/A"}`,
|
|
982
|
-
`Description: ${data.description ?? "N/A"}`,
|
|
983
|
-
`Created At: ${data.created_at}`,
|
|
984
|
-
"---",
|
|
985
|
-
].join("\n");
|
|
986
1140
|
return {
|
|
987
|
-
content: [
|
|
1141
|
+
content: [
|
|
1142
|
+
{
|
|
1143
|
+
type: "text",
|
|
1144
|
+
text: [
|
|
1145
|
+
"List created successfully:",
|
|
1146
|
+
`ID: ${data.id}`,
|
|
1147
|
+
`Name: ${name}`,
|
|
1148
|
+
`Kind: ${kind}`,
|
|
1149
|
+
`Subkind: ${subkind}`,
|
|
1150
|
+
`Description: ${description ?? "N/A"}`,
|
|
1151
|
+
`Created At: ${data.created_at}`,
|
|
1152
|
+
"---",
|
|
1153
|
+
].join("\n"),
|
|
1154
|
+
},
|
|
1155
|
+
],
|
|
988
1156
|
};
|
|
989
1157
|
});
|
|
990
|
-
server.tool("update_list_items", "Updates items in a list", {
|
|
1158
|
+
server.tool(getToolName("update_list_items"), "Updates items in a list", {
|
|
991
1159
|
list_id: zod_1.z.string().describe("The ID of the list to update"),
|
|
992
1160
|
items: zod_1.z
|
|
993
1161
|
.array(zod_1.z.record(zod_1.z.any()))
|
|
@@ -1009,7 +1177,7 @@ server.tool("update_list_items", "Updates items in a list", {
|
|
|
1009
1177
|
content: [{ type: "text", text: "List items updated successfully" }],
|
|
1010
1178
|
};
|
|
1011
1179
|
});
|
|
1012
|
-
server.tool("create_label", "Creates a new label for the organization", {
|
|
1180
|
+
server.tool(getToolName("create_label"), "Creates a new label for the organization", {
|
|
1013
1181
|
name: zod_1.z.string().describe("Name of the label"),
|
|
1014
1182
|
description: zod_1.z.string().optional().describe("Optional description"),
|
|
1015
1183
|
color: zod_1.z.string().default("gray").describe("Label color"),
|
|
@@ -1038,20 +1206,25 @@ server.tool("create_label", "Creates a new label for the organization", {
|
|
|
1038
1206
|
content: [{ type: "text", text: formattedLabel }],
|
|
1039
1207
|
};
|
|
1040
1208
|
});
|
|
1041
|
-
server.tool("list_labels", "Get a list of labels for the organization", {
|
|
1209
|
+
server.tool(getToolName("list_labels"), "Get a list of labels for the organization", {
|
|
1042
1210
|
page: zod_1.z
|
|
1043
1211
|
.number()
|
|
1044
1212
|
.default(1)
|
|
1213
|
+
.nullable()
|
|
1045
1214
|
.describe("The page of results to return (minimum: 1)"),
|
|
1046
1215
|
max_results: zod_1.z
|
|
1047
1216
|
.number()
|
|
1048
1217
|
.default(100)
|
|
1218
|
+
.nullable()
|
|
1049
1219
|
.describe("The maximum number of results to return"),
|
|
1050
1220
|
}, async ({ page, max_results }) => {
|
|
1051
|
-
const queryParams = {
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
}
|
|
1221
|
+
const queryParams = {};
|
|
1222
|
+
if (page !== null && page !== undefined) {
|
|
1223
|
+
queryParams["page"] = validatePage(page);
|
|
1224
|
+
}
|
|
1225
|
+
if (max_results !== null && max_results !== undefined) {
|
|
1226
|
+
queryParams["max_results"] = max_results;
|
|
1227
|
+
}
|
|
1055
1228
|
const data = await makeImpartRequest("labels", queryParams);
|
|
1056
1229
|
if (!data) {
|
|
1057
1230
|
return {
|
|
@@ -1080,6 +1253,399 @@ server.tool("list_labels", "Get a list of labels for the organization", {
|
|
|
1080
1253
|
content: [{ type: "text", text: formattedLabels.join("\n") }],
|
|
1081
1254
|
};
|
|
1082
1255
|
});
|
|
1256
|
+
server.tool(getToolName("list_rules_test_cases"), "Get a list of rules test cases for your Impart organization", {
|
|
1257
|
+
page: zod_1.z
|
|
1258
|
+
.number()
|
|
1259
|
+
.default(1)
|
|
1260
|
+
.nullable()
|
|
1261
|
+
.describe("The page of results to return (minimum value: 1)"),
|
|
1262
|
+
max_results: zod_1.z
|
|
1263
|
+
.number()
|
|
1264
|
+
.default(100)
|
|
1265
|
+
.nullable()
|
|
1266
|
+
.describe("The maximum number of results to return"),
|
|
1267
|
+
label: zod_1.z
|
|
1268
|
+
.array(zod_1.z.string())
|
|
1269
|
+
.optional()
|
|
1270
|
+
.nullable()
|
|
1271
|
+
.describe("Optional list of label slugs to filter by"),
|
|
1272
|
+
search: zod_1.z
|
|
1273
|
+
.string()
|
|
1274
|
+
.optional()
|
|
1275
|
+
.nullable()
|
|
1276
|
+
.describe("Optional search string to filter test cases"),
|
|
1277
|
+
}, async ({ page, max_results, label, search }) => {
|
|
1278
|
+
const queryParams = {};
|
|
1279
|
+
if (page !== null && page !== undefined) {
|
|
1280
|
+
queryParams["page"] = validatePage(page);
|
|
1281
|
+
}
|
|
1282
|
+
if (max_results !== null && max_results !== undefined) {
|
|
1283
|
+
queryParams["max_results"] = max_results;
|
|
1284
|
+
}
|
|
1285
|
+
if (label !== null && label !== undefined) {
|
|
1286
|
+
queryParams["label"] = label;
|
|
1287
|
+
}
|
|
1288
|
+
if (search !== null && search !== undefined) {
|
|
1289
|
+
queryParams["search"] = search;
|
|
1290
|
+
}
|
|
1291
|
+
const data = await makeImpartRequest("rules_test_cases", queryParams);
|
|
1292
|
+
if (!data) {
|
|
1293
|
+
return {
|
|
1294
|
+
content: [
|
|
1295
|
+
{
|
|
1296
|
+
type: "text",
|
|
1297
|
+
text: "Unable to fetch rules test cases: Unknown error",
|
|
1298
|
+
},
|
|
1299
|
+
],
|
|
1300
|
+
};
|
|
1301
|
+
}
|
|
1302
|
+
const testCases = data.items || [];
|
|
1303
|
+
if (testCases.length === 0) {
|
|
1304
|
+
return {
|
|
1305
|
+
content: [
|
|
1306
|
+
{
|
|
1307
|
+
type: "text",
|
|
1308
|
+
text: "No rules test cases found for this organization.",
|
|
1309
|
+
},
|
|
1310
|
+
],
|
|
1311
|
+
};
|
|
1312
|
+
}
|
|
1313
|
+
const formattedTestCases = testCases.map((testCase) => [
|
|
1314
|
+
`ID: ${testCase.id}`,
|
|
1315
|
+
`Name: ${testCase.name}`,
|
|
1316
|
+
`Description: ${testCase.description ?? "N/A"}`,
|
|
1317
|
+
`Required: ${testCase.required}`,
|
|
1318
|
+
`Labels: ${testCase.labels.join(", ")}`,
|
|
1319
|
+
`Messages Count: ${testCase.messages.length}`,
|
|
1320
|
+
`Assertions Count: ${testCase.assertions.length}`,
|
|
1321
|
+
`Created By: ${testCase.created_by}`,
|
|
1322
|
+
`Created At: ${testCase.created_at}`,
|
|
1323
|
+
`Updated By: ${testCase.updated_by}`,
|
|
1324
|
+
`Updated At: ${testCase.updated_at}`,
|
|
1325
|
+
"---",
|
|
1326
|
+
].join("\n"));
|
|
1327
|
+
return {
|
|
1328
|
+
content: [{ type: "text", text: formattedTestCases.join("\n") }],
|
|
1329
|
+
};
|
|
1330
|
+
});
|
|
1331
|
+
server.tool(getToolName("create_rules_test_case"), "Create a new rules test case", {
|
|
1332
|
+
name: zod_1.z.string().describe("The name of the test case"),
|
|
1333
|
+
description: zod_1.z
|
|
1334
|
+
.string()
|
|
1335
|
+
.optional()
|
|
1336
|
+
.nullable()
|
|
1337
|
+
.describe("Optional description of the test case"),
|
|
1338
|
+
required: zod_1.z
|
|
1339
|
+
.boolean()
|
|
1340
|
+
.default(false)
|
|
1341
|
+
.nullable()
|
|
1342
|
+
.describe("Whether the test case is required to pass"),
|
|
1343
|
+
messages: zod_1.z
|
|
1344
|
+
.array(zod_1.z.object({
|
|
1345
|
+
request: zod_1.z
|
|
1346
|
+
.object({
|
|
1347
|
+
method: zod_1.z.string().optional(),
|
|
1348
|
+
url: zod_1.z.string().optional(),
|
|
1349
|
+
headers: zod_1.z.record(zod_1.z.array(zod_1.z.string())).optional(),
|
|
1350
|
+
body: zod_1.z.string().optional(),
|
|
1351
|
+
})
|
|
1352
|
+
.optional(),
|
|
1353
|
+
response: zod_1.z
|
|
1354
|
+
.object({
|
|
1355
|
+
status_code: zod_1.z.number().optional(),
|
|
1356
|
+
headers: zod_1.z.record(zod_1.z.array(zod_1.z.string())).optional(),
|
|
1357
|
+
body: zod_1.z.string().optional(),
|
|
1358
|
+
})
|
|
1359
|
+
.optional(),
|
|
1360
|
+
}))
|
|
1361
|
+
.describe("The test case messages"),
|
|
1362
|
+
assertions: zod_1.z
|
|
1363
|
+
.array(zod_1.z.object({
|
|
1364
|
+
message_index: zod_1.z.number(),
|
|
1365
|
+
message_definition: zod_1.z.object({
|
|
1366
|
+
line: zod_1.z.number(),
|
|
1367
|
+
column: zod_1.z.number(),
|
|
1368
|
+
}),
|
|
1369
|
+
passed: zod_1.z.boolean(),
|
|
1370
|
+
}))
|
|
1371
|
+
.optional()
|
|
1372
|
+
.nullable()
|
|
1373
|
+
.describe("Optional test case assertions"),
|
|
1374
|
+
labels: zod_1.z
|
|
1375
|
+
.array(zod_1.z.string())
|
|
1376
|
+
.optional()
|
|
1377
|
+
.nullable()
|
|
1378
|
+
.describe("Optional list of label slugs"),
|
|
1379
|
+
}, async ({ name, description, required, messages, assertions, labels }) => {
|
|
1380
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1381
|
+
const payload = {
|
|
1382
|
+
name,
|
|
1383
|
+
messages,
|
|
1384
|
+
};
|
|
1385
|
+
if (description !== null && description !== undefined) {
|
|
1386
|
+
payload["description"] = description;
|
|
1387
|
+
}
|
|
1388
|
+
if (required !== null && required !== undefined) {
|
|
1389
|
+
payload["required"] = required;
|
|
1390
|
+
}
|
|
1391
|
+
if (assertions !== null && assertions !== undefined) {
|
|
1392
|
+
payload["assertions"] = assertions;
|
|
1393
|
+
}
|
|
1394
|
+
if (labels !== null && labels !== undefined) {
|
|
1395
|
+
payload["labels"] = labels;
|
|
1396
|
+
}
|
|
1397
|
+
const data = await makeImpartRequest("rules_test_cases", undefined, "POST", payload);
|
|
1398
|
+
if (!data) {
|
|
1399
|
+
return {
|
|
1400
|
+
content: [{ type: "text", text: "Failed to create rules test case" }],
|
|
1401
|
+
};
|
|
1402
|
+
}
|
|
1403
|
+
const formattedTestCase = [
|
|
1404
|
+
"Rules test case created successfully:",
|
|
1405
|
+
`ID: ${data.id}`,
|
|
1406
|
+
`Name: ${data.name}`,
|
|
1407
|
+
`Description: ${data.description ?? "N/A"}`,
|
|
1408
|
+
`Required: ${data.required}`,
|
|
1409
|
+
`Labels: ${data.labels.join(", ")}`,
|
|
1410
|
+
`Messages Count: ${data.messages.length}`,
|
|
1411
|
+
`Assertions Count: ${data.assertions.length}`,
|
|
1412
|
+
`Created By: ${data.created_by}`,
|
|
1413
|
+
`Created At: ${data.created_at}`,
|
|
1414
|
+
"---",
|
|
1415
|
+
].join("\n");
|
|
1416
|
+
return {
|
|
1417
|
+
content: [{ type: "text", text: formattedTestCase }],
|
|
1418
|
+
};
|
|
1419
|
+
});
|
|
1420
|
+
server.tool(getToolName("get_rules_test_case"), "Get details of a specific rules test case", {
|
|
1421
|
+
rules_test_case_id: zod_1.z
|
|
1422
|
+
.string()
|
|
1423
|
+
.describe("The unique identifier of the rules test case"),
|
|
1424
|
+
}, async ({ rules_test_case_id }) => {
|
|
1425
|
+
if (!rules_test_case_id) {
|
|
1426
|
+
return {
|
|
1427
|
+
content: [
|
|
1428
|
+
{ type: "text", text: "Error: rules_test_case_id is required." },
|
|
1429
|
+
],
|
|
1430
|
+
};
|
|
1431
|
+
}
|
|
1432
|
+
const data = await makeImpartRequest(`rules_test_cases/${rules_test_case_id}`);
|
|
1433
|
+
if (!data) {
|
|
1434
|
+
return {
|
|
1435
|
+
content: [
|
|
1436
|
+
{
|
|
1437
|
+
type: "text",
|
|
1438
|
+
text: "Unable to fetch rules test case: Unknown error",
|
|
1439
|
+
},
|
|
1440
|
+
],
|
|
1441
|
+
};
|
|
1442
|
+
}
|
|
1443
|
+
const formattedTestCase = [
|
|
1444
|
+
`ID: ${data.id}`,
|
|
1445
|
+
`Name: ${data.name}`,
|
|
1446
|
+
`Description: ${data.description ?? "N/A"}`,
|
|
1447
|
+
`Required: ${data.required}`,
|
|
1448
|
+
`Labels: ${data.labels.join(", ")}`,
|
|
1449
|
+
"Messages:",
|
|
1450
|
+
];
|
|
1451
|
+
data.messages.forEach((message, index) => {
|
|
1452
|
+
formattedTestCase.push(`Message ${index + 1}:`);
|
|
1453
|
+
if (message.request) {
|
|
1454
|
+
formattedTestCase.push(" Request:", ` Method: ${message.request.method ?? "N/A"}`, ` URL: ${message.request.url ?? "N/A"}`, " Headers:");
|
|
1455
|
+
if (message.request.headers) {
|
|
1456
|
+
Object.entries(message.request.headers).forEach(([key, values]) => {
|
|
1457
|
+
formattedTestCase.push(` ${key}: ${values.join(", ")}`);
|
|
1458
|
+
});
|
|
1459
|
+
}
|
|
1460
|
+
if (message.request.body) {
|
|
1461
|
+
formattedTestCase.push(` Body: ${message.request.body}`);
|
|
1462
|
+
}
|
|
1463
|
+
}
|
|
1464
|
+
if (message.response) {
|
|
1465
|
+
formattedTestCase.push(" Response:", ` Status Code: ${message.response.status_code ?? "N/A"}`, " Headers:");
|
|
1466
|
+
if (message.response.headers) {
|
|
1467
|
+
Object.entries(message.response.headers).forEach(([key, values]) => {
|
|
1468
|
+
formattedTestCase.push(` ${key}: ${values.join(", ")}`);
|
|
1469
|
+
});
|
|
1470
|
+
}
|
|
1471
|
+
if (message.response.body) {
|
|
1472
|
+
formattedTestCase.push(` Body: ${message.response.body}`);
|
|
1473
|
+
}
|
|
1474
|
+
}
|
|
1475
|
+
});
|
|
1476
|
+
formattedTestCase.push("Assertions:", ...data.assertions.map((assertion) => ` Message ${assertion.message_index + 1} at line ${assertion.message_definition.line}, column ${assertion.message_definition.column}: ${assertion.passed ? "Passed" : "Failed"}`), "---");
|
|
1477
|
+
return {
|
|
1478
|
+
content: [{ type: "text", text: formattedTestCase.join("\n") }],
|
|
1479
|
+
};
|
|
1480
|
+
});
|
|
1481
|
+
server.tool(getToolName("update_rules_test_case"), "Update an existing rules test case", {
|
|
1482
|
+
rules_test_case_id: zod_1.z
|
|
1483
|
+
.string()
|
|
1484
|
+
.describe("The unique identifier of the rules test case"),
|
|
1485
|
+
name: zod_1.z.string().describe("The name of the test case"),
|
|
1486
|
+
description: zod_1.z
|
|
1487
|
+
.string()
|
|
1488
|
+
.optional()
|
|
1489
|
+
.nullable()
|
|
1490
|
+
.describe("Optional description of the test case"),
|
|
1491
|
+
required: zod_1.z
|
|
1492
|
+
.boolean()
|
|
1493
|
+
.default(false)
|
|
1494
|
+
.nullable()
|
|
1495
|
+
.describe("Whether the test case is required to pass"),
|
|
1496
|
+
messages: zod_1.z
|
|
1497
|
+
.array(zod_1.z.object({
|
|
1498
|
+
request: zod_1.z
|
|
1499
|
+
.object({
|
|
1500
|
+
method: zod_1.z.string().optional(),
|
|
1501
|
+
url: zod_1.z.string().optional(),
|
|
1502
|
+
headers: zod_1.z.record(zod_1.z.array(zod_1.z.string())).optional(),
|
|
1503
|
+
body: zod_1.z.string().optional(),
|
|
1504
|
+
})
|
|
1505
|
+
.optional(),
|
|
1506
|
+
response: zod_1.z
|
|
1507
|
+
.object({
|
|
1508
|
+
status_code: zod_1.z.number().optional(),
|
|
1509
|
+
headers: zod_1.z.record(zod_1.z.array(zod_1.z.string())).optional(),
|
|
1510
|
+
body: zod_1.z.string().optional(),
|
|
1511
|
+
})
|
|
1512
|
+
.optional(),
|
|
1513
|
+
}))
|
|
1514
|
+
.describe("The test case messages"),
|
|
1515
|
+
assertions: zod_1.z
|
|
1516
|
+
.array(zod_1.z.object({
|
|
1517
|
+
message_index: zod_1.z.number(),
|
|
1518
|
+
message_definition: zod_1.z.object({
|
|
1519
|
+
line: zod_1.z.number(),
|
|
1520
|
+
column: zod_1.z.number(),
|
|
1521
|
+
}),
|
|
1522
|
+
passed: zod_1.z.boolean(),
|
|
1523
|
+
}))
|
|
1524
|
+
.optional()
|
|
1525
|
+
.nullable()
|
|
1526
|
+
.describe("Optional test case assertions"),
|
|
1527
|
+
labels: zod_1.z
|
|
1528
|
+
.array(zod_1.z.string())
|
|
1529
|
+
.optional()
|
|
1530
|
+
.nullable()
|
|
1531
|
+
.describe("Optional list of label slugs"),
|
|
1532
|
+
}, async ({ rules_test_case_id, name, description, required, messages, assertions, labels, }) => {
|
|
1533
|
+
if (!rules_test_case_id) {
|
|
1534
|
+
return {
|
|
1535
|
+
content: [
|
|
1536
|
+
{ type: "text", text: "Error: rules_test_case_id is required." },
|
|
1537
|
+
],
|
|
1538
|
+
};
|
|
1539
|
+
}
|
|
1540
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1541
|
+
const payload = {
|
|
1542
|
+
name,
|
|
1543
|
+
messages,
|
|
1544
|
+
};
|
|
1545
|
+
if (description !== null && description !== undefined) {
|
|
1546
|
+
payload["description"] = description;
|
|
1547
|
+
}
|
|
1548
|
+
if (required !== null && required !== undefined) {
|
|
1549
|
+
payload["required"] = required;
|
|
1550
|
+
}
|
|
1551
|
+
if (assertions !== null && assertions !== undefined) {
|
|
1552
|
+
payload["assertions"] = assertions;
|
|
1553
|
+
}
|
|
1554
|
+
if (labels !== null && labels !== undefined) {
|
|
1555
|
+
payload["labels"] = labels;
|
|
1556
|
+
}
|
|
1557
|
+
const data = await makeImpartRequest(`rules_test_cases/${rules_test_case_id}`, undefined, "PUT", payload);
|
|
1558
|
+
if (!data) {
|
|
1559
|
+
return {
|
|
1560
|
+
content: [{ type: "text", text: "Failed to update rules test case" }],
|
|
1561
|
+
};
|
|
1562
|
+
}
|
|
1563
|
+
const formattedTestCase = [
|
|
1564
|
+
"Rules test case updated successfully:",
|
|
1565
|
+
`ID: ${data.id}`,
|
|
1566
|
+
`Name: ${data.name}`,
|
|
1567
|
+
`Description: ${data.description ?? "N/A"}`,
|
|
1568
|
+
`Required: ${data.required}`,
|
|
1569
|
+
`Labels: ${data.labels.join(", ")}`,
|
|
1570
|
+
`Messages Count: ${data.messages.length}`,
|
|
1571
|
+
`Assertions Count: ${data.assertions.length}`,
|
|
1572
|
+
`Updated By: ${data.updated_by}`,
|
|
1573
|
+
`Updated At: ${data.updated_at}`,
|
|
1574
|
+
"---",
|
|
1575
|
+
].join("\n");
|
|
1576
|
+
return {
|
|
1577
|
+
content: [{ type: "text", text: formattedTestCase }],
|
|
1578
|
+
};
|
|
1579
|
+
});
|
|
1580
|
+
server.tool(getToolName("delete_rules_test_case"), "Delete a rules test case", {
|
|
1581
|
+
rules_test_case_id: zod_1.z
|
|
1582
|
+
.string()
|
|
1583
|
+
.describe("The unique identifier of the rules test case"),
|
|
1584
|
+
}, async ({ rules_test_case_id }) => {
|
|
1585
|
+
if (!rules_test_case_id) {
|
|
1586
|
+
return {
|
|
1587
|
+
content: [
|
|
1588
|
+
{ type: "text", text: "Error: rules_test_case_id is required." },
|
|
1589
|
+
],
|
|
1590
|
+
};
|
|
1591
|
+
}
|
|
1592
|
+
const data = await makeImpartRequest(`rules_test_cases/${rules_test_case_id}`, undefined, "DELETE");
|
|
1593
|
+
if (data === null) {
|
|
1594
|
+
return {
|
|
1595
|
+
content: [{ type: "text", text: "Failed to delete rules test case" }],
|
|
1596
|
+
};
|
|
1597
|
+
}
|
|
1598
|
+
return {
|
|
1599
|
+
content: [{ type: "text", text: "Rules test case deleted successfully" }],
|
|
1600
|
+
};
|
|
1601
|
+
});
|
|
1602
|
+
server.tool(getToolName("run_rules_test_case"), "Run a rules test case", {
|
|
1603
|
+
messages: zod_1.z
|
|
1604
|
+
.array(zod_1.z.object({
|
|
1605
|
+
request: zod_1.z
|
|
1606
|
+
.object({
|
|
1607
|
+
method: zod_1.z.string().optional(),
|
|
1608
|
+
url: zod_1.z.string().optional(),
|
|
1609
|
+
headers: zod_1.z.record(zod_1.z.array(zod_1.z.string())).optional(),
|
|
1610
|
+
body: zod_1.z.string().optional(),
|
|
1611
|
+
})
|
|
1612
|
+
.optional(),
|
|
1613
|
+
response: zod_1.z
|
|
1614
|
+
.object({
|
|
1615
|
+
status_code: zod_1.z.number().optional(),
|
|
1616
|
+
headers: zod_1.z.record(zod_1.z.array(zod_1.z.string())).optional(),
|
|
1617
|
+
body: zod_1.z.string().optional(),
|
|
1618
|
+
})
|
|
1619
|
+
.optional(),
|
|
1620
|
+
}))
|
|
1621
|
+
.nullable()
|
|
1622
|
+
.describe("The test case messages to run"),
|
|
1623
|
+
}, async ({ messages }) => {
|
|
1624
|
+
if (!messages) {
|
|
1625
|
+
return {
|
|
1626
|
+
content: [{ type: "text", text: "Error: messages is required." }],
|
|
1627
|
+
};
|
|
1628
|
+
}
|
|
1629
|
+
const payload = { messages };
|
|
1630
|
+
const data = await makeImpartRequest("rules_test_case_run", undefined, "POST", payload);
|
|
1631
|
+
if (!data) {
|
|
1632
|
+
return {
|
|
1633
|
+
content: [{ type: "text", text: "Failed to run rules test case" }],
|
|
1634
|
+
};
|
|
1635
|
+
}
|
|
1636
|
+
const formattedResult = [
|
|
1637
|
+
"Rules test case run completed:",
|
|
1638
|
+
`Duration: ${data.duration} microseconds`,
|
|
1639
|
+
"Output:",
|
|
1640
|
+
...data.output.map((out) => ` ${out.severity.toUpperCase()} at line ${out.line}, column ${out.column}: ${out.message}`),
|
|
1641
|
+
"Assertions:",
|
|
1642
|
+
...data.assertions.flatMap((assertion) => assertion.results.map((result) => ` Message ${result.message_index + 1} at line ${result.message_definition.line}, column ${result.message_definition.column}: ${result.passed ? "Passed" : "Failed"}`)),
|
|
1643
|
+
"---",
|
|
1644
|
+
].join("\n");
|
|
1645
|
+
return {
|
|
1646
|
+
content: [{ type: "text", text: formattedResult }],
|
|
1647
|
+
};
|
|
1648
|
+
});
|
|
1083
1649
|
async function main() {
|
|
1084
1650
|
const transport = new stdio_js_1.StdioServerTransport();
|
|
1085
1651
|
await server.connect(transport);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@impart-security/impart-mcp",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "Model Context Protocol (MCP) implementation for interacting with Impart's API",
|
|
5
5
|
"author": "Impart Security",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -21,9 +21,9 @@
|
|
|
21
21
|
"node": ">=18.0.0"
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@modelcontextprotocol/sdk": "1.
|
|
24
|
+
"@modelcontextprotocol/sdk": "1.10.2",
|
|
25
25
|
"axios": "1.8.4",
|
|
26
|
-
"zod": "3.24.
|
|
26
|
+
"zod": "3.24.3"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
29
|
"@types/node": "22.14.1",
|