@impart-security/impart-mcp 0.1.1 → 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.d.ts +1 -0
- package/dist/index.js +692 -125
- package/package.json +4 -4
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
1
2
|
"use strict";
|
|
2
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
4
|
const mcp_js_1 = require("@modelcontextprotocol/sdk/server/mcp.js");
|
|
@@ -41,11 +42,14 @@ async function makeImpartRequest(endpoint, queryParams, method = "GET", body) {
|
|
|
41
42
|
});
|
|
42
43
|
}
|
|
43
44
|
try {
|
|
44
|
-
const
|
|
45
|
+
const requestOptions = {
|
|
45
46
|
method,
|
|
46
47
|
headers,
|
|
47
|
-
|
|
48
|
-
|
|
48
|
+
};
|
|
49
|
+
if (body && method !== "GET" && method !== "HEAD") {
|
|
50
|
+
requestOptions.body = JSON.stringify(body);
|
|
51
|
+
}
|
|
52
|
+
const response = await fetch(url.toString(), requestOptions);
|
|
49
53
|
if (!response.ok) {
|
|
50
54
|
throw new Error(`HTTP error! status: ${response.status}`);
|
|
51
55
|
}
|
|
@@ -56,21 +60,30 @@ async function makeImpartRequest(endpoint, queryParams, method = "GET", body) {
|
|
|
56
60
|
return null;
|
|
57
61
|
}
|
|
58
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
|
+
}
|
|
59
67
|
// Register tools with consistent naming patterns
|
|
60
|
-
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", {
|
|
61
69
|
page: zod_1.z
|
|
62
70
|
.number()
|
|
63
71
|
.default(1)
|
|
72
|
+
.optional()
|
|
64
73
|
.describe("The page of results to return (minimum value: 1)"),
|
|
65
74
|
max_results: zod_1.z
|
|
66
75
|
.number()
|
|
67
76
|
.default(100)
|
|
77
|
+
.optional()
|
|
68
78
|
.describe("The maximum number of results to return"),
|
|
69
79
|
}, async ({ page, max_results }) => {
|
|
70
|
-
const queryParams = {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
}
|
|
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
|
+
}
|
|
74
87
|
const data = await makeImpartRequest("inspectors", queryParams);
|
|
75
88
|
if (!data) {
|
|
76
89
|
return {
|
|
@@ -98,42 +111,65 @@ server.tool("list_inspectors", "Get a list of inspectors for the organization",
|
|
|
98
111
|
};
|
|
99
112
|
});
|
|
100
113
|
// Rules Script Tools
|
|
101
|
-
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", {
|
|
102
115
|
page: zod_1.z
|
|
103
116
|
.number()
|
|
104
117
|
.default(1)
|
|
118
|
+
.nullable()
|
|
105
119
|
.describe("The page of results to return (minimum value: 1)"),
|
|
106
120
|
max_results: zod_1.z
|
|
107
121
|
.number()
|
|
108
122
|
.default(100)
|
|
123
|
+
.nullable()
|
|
109
124
|
.describe("The maximum number of results to return"),
|
|
110
125
|
type: zod_1.z
|
|
111
126
|
.string()
|
|
112
127
|
.optional()
|
|
128
|
+
.nullable()
|
|
113
129
|
.describe("Filter by type of rule script ('custom' or 'core')"),
|
|
114
130
|
exclude_src: zod_1.z
|
|
115
131
|
.boolean()
|
|
116
132
|
.default(false)
|
|
133
|
+
.nullable()
|
|
117
134
|
.describe("Whether to exclude the rule script source"),
|
|
118
135
|
exclude_revisions: zod_1.z
|
|
119
136
|
.boolean()
|
|
120
137
|
.default(false)
|
|
138
|
+
.nullable()
|
|
121
139
|
.describe("Whether to exclude rule script revisions"),
|
|
122
140
|
is_disabled: zod_1.z
|
|
123
141
|
.string()
|
|
124
142
|
.optional()
|
|
143
|
+
.nullable()
|
|
125
144
|
.describe("Filter by disabled status ('true' or 'false')"),
|
|
126
|
-
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"),
|
|
127
150
|
}, async ({ page, max_results, type, exclude_src, exclude_revisions, is_disabled, label, }) => {
|
|
128
|
-
const queryParams = {
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
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
|
+
}
|
|
137
173
|
const data = await makeImpartRequest("rules_scripts", queryParams);
|
|
138
174
|
if (!data) {
|
|
139
175
|
return {
|
|
@@ -176,11 +212,15 @@ server.tool("list_rules_scripts", "Get a list of rules scripts for your Impart o
|
|
|
176
212
|
content: [{ type: "text", text: formattedScripts.join("\n") }],
|
|
177
213
|
};
|
|
178
214
|
});
|
|
179
|
-
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", {
|
|
180
216
|
rules_script_id: zod_1.z
|
|
181
217
|
.string()
|
|
182
218
|
.describe("The unique identifier of the rules script"),
|
|
183
|
-
revision: zod_1.z
|
|
219
|
+
revision: zod_1.z
|
|
220
|
+
.number()
|
|
221
|
+
.optional()
|
|
222
|
+
.nullable()
|
|
223
|
+
.describe("The specific revision to fetch"),
|
|
184
224
|
}, async ({ rules_script_id, revision }) => {
|
|
185
225
|
if (!rules_script_id) {
|
|
186
226
|
return {
|
|
@@ -189,7 +229,10 @@ server.tool("get_rules_script", "Get details of a specific rules script", {
|
|
|
189
229
|
],
|
|
190
230
|
};
|
|
191
231
|
}
|
|
192
|
-
const queryParams =
|
|
232
|
+
const queryParams = {};
|
|
233
|
+
if (revision !== null && revision !== undefined) {
|
|
234
|
+
queryParams["revision"] = revision;
|
|
235
|
+
}
|
|
193
236
|
const data = await makeImpartRequest(`rules_scripts/${rules_script_id}`, queryParams);
|
|
194
237
|
if (!data) {
|
|
195
238
|
return {
|
|
@@ -225,7 +268,7 @@ server.tool("get_rules_script", "Get details of a specific rules script", {
|
|
|
225
268
|
content: [{ type: "text", text: formattedScript.join("\n") }],
|
|
226
269
|
};
|
|
227
270
|
});
|
|
228
|
-
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", {
|
|
229
272
|
name: zod_1.z.string().describe("The name of the rules script"),
|
|
230
273
|
src: zod_1.z
|
|
231
274
|
.string()
|
|
@@ -233,33 +276,48 @@ server.tool("create_rules_script", "Creates a new rules script for the organizat
|
|
|
233
276
|
lang: zod_1.z
|
|
234
277
|
.string()
|
|
235
278
|
.default("assemblyscript")
|
|
279
|
+
.nullable()
|
|
236
280
|
.describe("The language of the script"),
|
|
237
281
|
description: zod_1.z
|
|
238
282
|
.string()
|
|
239
283
|
.optional()
|
|
284
|
+
.nullable()
|
|
240
285
|
.describe("Optional description of the script"),
|
|
241
286
|
blocking_effect: zod_1.z
|
|
242
287
|
.string()
|
|
243
288
|
.default("block")
|
|
289
|
+
.nullable()
|
|
244
290
|
.describe("Effect when rule blocks"),
|
|
245
291
|
disabled: zod_1.z
|
|
246
292
|
.boolean()
|
|
247
293
|
.default(false)
|
|
294
|
+
.nullable()
|
|
248
295
|
.describe("Whether the script is disabled"),
|
|
249
296
|
labels: zod_1.z
|
|
250
297
|
.array(zod_1.z.string())
|
|
251
298
|
.optional()
|
|
299
|
+
.nullable()
|
|
252
300
|
.describe("Optional list of label slugs"),
|
|
253
301
|
}, async ({ name, src, lang, description, blocking_effect, disabled, labels, }) => {
|
|
254
302
|
const payload = {
|
|
255
303
|
name,
|
|
256
304
|
src,
|
|
257
|
-
lang,
|
|
258
|
-
description,
|
|
259
|
-
blocking_effect,
|
|
260
|
-
disabled,
|
|
261
|
-
labels: labels ?? [],
|
|
262
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
|
+
}
|
|
263
321
|
const data = await makeImpartRequest("rules_scripts", undefined, "POST", payload);
|
|
264
322
|
if (!data) {
|
|
265
323
|
return {
|
|
@@ -282,7 +340,7 @@ server.tool("create_rules_script", "Creates a new rules script for the organizat
|
|
|
282
340
|
content: [{ type: "text", text: formattedScript }],
|
|
283
341
|
};
|
|
284
342
|
});
|
|
285
|
-
server.tool("update_rules_script", "Updates an existing rules script", {
|
|
343
|
+
server.tool(getToolName("update_rules_script"), "Updates an existing rules script", {
|
|
286
344
|
rules_script_id: zod_1.z
|
|
287
345
|
.string()
|
|
288
346
|
.describe("The ID of the rules script to update"),
|
|
@@ -291,22 +349,27 @@ server.tool("update_rules_script", "Updates an existing rules script", {
|
|
|
291
349
|
lang: zod_1.z
|
|
292
350
|
.string()
|
|
293
351
|
.default("assemblyscript")
|
|
352
|
+
.nullable()
|
|
294
353
|
.describe("The language of the script"),
|
|
295
354
|
description: zod_1.z
|
|
296
355
|
.string()
|
|
297
356
|
.optional()
|
|
357
|
+
.nullable()
|
|
298
358
|
.describe("Optional description of the script"),
|
|
299
359
|
blocking_effect: zod_1.z
|
|
300
360
|
.string()
|
|
301
361
|
.default("block")
|
|
362
|
+
.nullable()
|
|
302
363
|
.describe("Effect when rule blocks"),
|
|
303
364
|
disabled: zod_1.z
|
|
304
365
|
.boolean()
|
|
305
366
|
.default(false)
|
|
367
|
+
.nullable()
|
|
306
368
|
.describe("Whether the script is disabled"),
|
|
307
369
|
labels: zod_1.z
|
|
308
370
|
.array(zod_1.z.string())
|
|
309
371
|
.optional()
|
|
372
|
+
.nullable()
|
|
310
373
|
.describe("Optional list of label slugs"),
|
|
311
374
|
}, async ({ rules_script_id, name, src, lang, description, blocking_effect, disabled, labels, }) => {
|
|
312
375
|
if (!rules_script_id) {
|
|
@@ -319,12 +382,22 @@ server.tool("update_rules_script", "Updates an existing rules script", {
|
|
|
319
382
|
const payload = {
|
|
320
383
|
name,
|
|
321
384
|
src,
|
|
322
|
-
lang,
|
|
323
|
-
description,
|
|
324
|
-
blocking_effect,
|
|
325
|
-
disabled,
|
|
326
|
-
labels: labels ?? [],
|
|
327
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
|
+
}
|
|
328
401
|
const data = await makeImpartRequest(`rules_scripts/${rules_script_id}`, undefined, "PUT", payload);
|
|
329
402
|
if (!data) {
|
|
330
403
|
return {
|
|
@@ -347,7 +420,7 @@ server.tool("update_rules_script", "Updates an existing rules script", {
|
|
|
347
420
|
content: [{ type: "text", text: formattedScript }],
|
|
348
421
|
};
|
|
349
422
|
});
|
|
350
|
-
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", {
|
|
351
424
|
query: zod_1.z.string().describe("Description of the rule you want to generate"),
|
|
352
425
|
}, async ({ query }) => {
|
|
353
426
|
const payload = {
|
|
@@ -378,13 +451,14 @@ server.tool("write_rule_script", "Generate a rule script using Impart's LLM", {
|
|
|
378
451
|
],
|
|
379
452
|
};
|
|
380
453
|
});
|
|
381
|
-
server.tool("validate_rules_script", "Validate a rules script", {
|
|
454
|
+
server.tool(getToolName("validate_rules_script"), "Validate a rules script", {
|
|
382
455
|
src: zod_1.z
|
|
383
456
|
.string()
|
|
384
457
|
.describe("The base64-encoded source code of the rules script to validate"),
|
|
385
458
|
lang: zod_1.z
|
|
386
459
|
.string()
|
|
387
460
|
.default("assemblyscript")
|
|
461
|
+
.nullable()
|
|
388
462
|
.describe("The language of the rules script"),
|
|
389
463
|
}, async ({ src, lang }) => {
|
|
390
464
|
if (!src) {
|
|
@@ -399,8 +473,10 @@ server.tool("validate_rules_script", "Validate a rules script", {
|
|
|
399
473
|
}
|
|
400
474
|
const payload = {
|
|
401
475
|
src,
|
|
402
|
-
lang,
|
|
403
476
|
};
|
|
477
|
+
if (lang !== null && lang !== undefined) {
|
|
478
|
+
payload["lang"] = lang;
|
|
479
|
+
}
|
|
404
480
|
const data = await makeImpartRequest("rules_script_validate", undefined, "POST", payload);
|
|
405
481
|
if (!data) {
|
|
406
482
|
return {
|
|
@@ -429,13 +505,17 @@ server.tool("validate_rules_script", "Validate a rules script", {
|
|
|
429
505
|
],
|
|
430
506
|
};
|
|
431
507
|
});
|
|
432
|
-
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", {
|
|
433
509
|
max_results: zod_1.z
|
|
434
510
|
.number()
|
|
435
511
|
.default(100)
|
|
512
|
+
.nullable()
|
|
436
513
|
.describe("The maximum number of results to return"),
|
|
437
514
|
}, async ({ max_results }) => {
|
|
438
|
-
const queryParams = {
|
|
515
|
+
const queryParams = {};
|
|
516
|
+
if (max_results !== null && max_results !== undefined) {
|
|
517
|
+
queryParams["max_results"] = max_results;
|
|
518
|
+
}
|
|
439
519
|
const data = await makeImpartRequest("endpoints", queryParams);
|
|
440
520
|
if (!data) {
|
|
441
521
|
return {
|
|
@@ -465,13 +545,17 @@ server.tool("list_endpoints", "Get an inventory of endpoints for the organizatio
|
|
|
465
545
|
content: [{ type: "text", text: formattedEndpoints.join("\n") }],
|
|
466
546
|
};
|
|
467
547
|
});
|
|
468
|
-
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", {
|
|
469
549
|
max_results: zod_1.z
|
|
470
550
|
.number()
|
|
471
551
|
.default(100)
|
|
552
|
+
.nullable()
|
|
472
553
|
.describe("The maximum number of results to return"),
|
|
473
554
|
}, async ({ max_results }) => {
|
|
474
|
-
const queryParams = {
|
|
555
|
+
const queryParams = {};
|
|
556
|
+
if (max_results !== null && max_results !== undefined) {
|
|
557
|
+
queryParams["max_results"] = max_results;
|
|
558
|
+
}
|
|
475
559
|
const data = await makeImpartRequest("tags", queryParams);
|
|
476
560
|
if (!data) {
|
|
477
561
|
return {
|
|
@@ -502,49 +586,73 @@ server.tool("list_tags", "Get a list of tags for your Impart organization", {
|
|
|
502
586
|
content: [{ type: "text", text: formattedTags.join("\n") }],
|
|
503
587
|
};
|
|
504
588
|
});
|
|
505
|
-
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", {
|
|
506
590
|
metric: zod_1.z
|
|
507
591
|
.array(zod_1.z.string())
|
|
508
592
|
.default(["http-request.count"])
|
|
593
|
+
.nullable()
|
|
509
594
|
.describe("List of metric names"),
|
|
510
|
-
from_time: zod_1.z.string().default("-1d").describe("Start time"),
|
|
511
|
-
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"),
|
|
512
597
|
spec_id: zod_1.z
|
|
513
598
|
.array(zod_1.z.string())
|
|
514
599
|
.optional()
|
|
600
|
+
.nullable()
|
|
515
601
|
.describe("Optional list of spec IDs"),
|
|
516
602
|
collection_id: zod_1.z
|
|
517
603
|
.array(zod_1.z.string())
|
|
518
604
|
.optional()
|
|
605
|
+
.nullable()
|
|
519
606
|
.describe("Optional list of collection IDs"),
|
|
520
607
|
endpoint_id: zod_1.z
|
|
521
608
|
.array(zod_1.z.string())
|
|
522
609
|
.optional()
|
|
610
|
+
.nullable()
|
|
523
611
|
.describe("Optional list of endpoint IDs"),
|
|
524
612
|
rollup: zod_1.z
|
|
525
613
|
.string()
|
|
526
614
|
.optional()
|
|
615
|
+
.nullable()
|
|
527
616
|
.describe("Optional time window rollup resolution"),
|
|
528
617
|
unlearned: zod_1.z
|
|
529
618
|
.string()
|
|
530
619
|
.default("include")
|
|
620
|
+
.nullable()
|
|
531
621
|
.describe("How to handle unlearned endpoints"),
|
|
532
622
|
max_results: zod_1.z
|
|
533
623
|
.number()
|
|
534
624
|
.default(100)
|
|
625
|
+
.nullable()
|
|
535
626
|
.describe("The maximum number of results to return"),
|
|
536
627
|
}, async ({ metric, from_time, until_time, spec_id, collection_id, endpoint_id, rollup, unlearned, max_results, }) => {
|
|
537
|
-
const queryParams = {
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
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
|
+
}
|
|
548
656
|
const data = await makeImpartRequest("timeseries/tags", queryParams);
|
|
549
657
|
if (!data) {
|
|
550
658
|
return {
|
|
@@ -580,20 +688,25 @@ server.tool("get_tag_metrics", "Get timeseries metrics for one or more tags", {
|
|
|
580
688
|
content: [{ type: "text", text: formattedMetrics.join("\n") }],
|
|
581
689
|
};
|
|
582
690
|
});
|
|
583
|
-
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", {
|
|
584
692
|
page: zod_1.z
|
|
585
693
|
.number()
|
|
586
694
|
.default(1)
|
|
695
|
+
.nullable()
|
|
587
696
|
.describe("The page of results to return (minimum value: 1)"),
|
|
588
697
|
max_results: zod_1.z
|
|
589
698
|
.number()
|
|
590
699
|
.default(100)
|
|
700
|
+
.nullable()
|
|
591
701
|
.describe("The maximum number of results to return"),
|
|
592
702
|
}, async ({ page, max_results }) => {
|
|
593
|
-
const queryParams = {
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
}
|
|
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
|
+
}
|
|
597
710
|
const data = await makeImpartRequest("observed_hosts", queryParams);
|
|
598
711
|
if (!data) {
|
|
599
712
|
return {
|
|
@@ -627,7 +740,7 @@ server.tool("list_observed_hosts", "Get a list of observed hosts for your Impart
|
|
|
627
740
|
content: [{ type: "text", text: formattedHosts.join("\n") }],
|
|
628
741
|
};
|
|
629
742
|
});
|
|
630
|
-
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", {
|
|
631
744
|
observed_host_id: zod_1.z
|
|
632
745
|
.string()
|
|
633
746
|
.describe("The unique identifier of the observed host"),
|
|
@@ -670,20 +783,25 @@ server.tool("get_observed_host", "Get details of a specific observed host", {
|
|
|
670
783
|
content: [{ type: "text", text: formattedHost.join("\n") }],
|
|
671
784
|
};
|
|
672
785
|
});
|
|
673
|
-
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", {
|
|
674
787
|
page: zod_1.z
|
|
675
788
|
.number()
|
|
676
789
|
.default(1)
|
|
790
|
+
.nullable()
|
|
677
791
|
.describe("The page of results to return (minimum value: 1)"),
|
|
678
792
|
max_results: zod_1.z
|
|
679
793
|
.number()
|
|
680
794
|
.default(100)
|
|
795
|
+
.nullable()
|
|
681
796
|
.describe("The maximum number of results to return"),
|
|
682
797
|
}, async ({ page, max_results }) => {
|
|
683
|
-
const queryParams = {
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
}
|
|
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
|
+
}
|
|
687
805
|
const data = await makeImpartRequest("specs", queryParams);
|
|
688
806
|
if (!data) {
|
|
689
807
|
return {
|
|
@@ -715,16 +833,23 @@ server.tool("list_specs", "Get a list of specs for your Impart organization", {
|
|
|
715
833
|
content: [{ type: "text", text: formattedSpecs.join("\n") }],
|
|
716
834
|
};
|
|
717
835
|
});
|
|
718
|
-
server.tool("get_spec", "Get details of a specific spec", {
|
|
836
|
+
server.tool(getToolName("get_spec"), "Get details of a specific spec", {
|
|
719
837
|
spec_id: zod_1.z.string().describe("The unique identifier of the spec"),
|
|
720
|
-
revision: zod_1.z
|
|
838
|
+
revision: zod_1.z
|
|
839
|
+
.number()
|
|
840
|
+
.optional()
|
|
841
|
+
.nullable()
|
|
842
|
+
.describe("The specific revision to fetch"),
|
|
721
843
|
}, async ({ spec_id, revision }) => {
|
|
722
844
|
if (!spec_id) {
|
|
723
845
|
return {
|
|
724
846
|
content: [{ type: "text", text: "Error: spec_id is required." }],
|
|
725
847
|
};
|
|
726
848
|
}
|
|
727
|
-
const queryParams =
|
|
849
|
+
const queryParams = {};
|
|
850
|
+
if (revision !== null && revision !== undefined) {
|
|
851
|
+
queryParams["revision"] = revision;
|
|
852
|
+
}
|
|
728
853
|
const data = await makeImpartRequest(`specs/${spec_id}`, queryParams);
|
|
729
854
|
if (!data) {
|
|
730
855
|
return {
|
|
@@ -755,20 +880,25 @@ server.tool("get_spec", "Get details of a specific spec", {
|
|
|
755
880
|
content: [{ type: "text", text: formattedSpec.join("\n") }],
|
|
756
881
|
};
|
|
757
882
|
});
|
|
758
|
-
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", {
|
|
759
884
|
page: zod_1.z
|
|
760
885
|
.number()
|
|
761
886
|
.default(1)
|
|
887
|
+
.nullable()
|
|
762
888
|
.describe("The page of results to return (minimum value: 1)"),
|
|
763
889
|
max_results: zod_1.z
|
|
764
890
|
.number()
|
|
765
891
|
.default(100)
|
|
892
|
+
.nullable()
|
|
766
893
|
.describe("The maximum number of results to return"),
|
|
767
894
|
}, async ({ page, max_results }) => {
|
|
768
|
-
const queryParams = {
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
}
|
|
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
|
+
}
|
|
772
902
|
const data = await makeImpartRequest("api_bindings", queryParams);
|
|
773
903
|
if (!data) {
|
|
774
904
|
return {
|
|
@@ -801,7 +931,7 @@ server.tool("list_api_bindings", "Get a list of API bindings for the organizatio
|
|
|
801
931
|
content: [{ type: "text", text: formattedBindings.join("\n") }],
|
|
802
932
|
};
|
|
803
933
|
});
|
|
804
|
-
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", {
|
|
805
935
|
name: zod_1.z.string().describe("The name of the API binding"),
|
|
806
936
|
binding_type: zod_1.z
|
|
807
937
|
.string()
|
|
@@ -814,26 +944,36 @@ server.tool("create_api_binding", "Create a new API binding for the organization
|
|
|
814
944
|
description: zod_1.z
|
|
815
945
|
.string()
|
|
816
946
|
.optional()
|
|
947
|
+
.nullable()
|
|
817
948
|
.describe("Optional description of the binding"),
|
|
818
949
|
patch_operations: zod_1.z
|
|
819
950
|
.array(zod_1.z.record(zod_1.z.any()))
|
|
820
951
|
.optional()
|
|
952
|
+
.nullable()
|
|
821
953
|
.describe("Optional list of JSON patch operations"),
|
|
822
954
|
enable_learning: zod_1.z
|
|
823
955
|
.boolean()
|
|
824
956
|
.default(true)
|
|
957
|
+
.nullable()
|
|
825
958
|
.describe("Whether to enable learning for this binding"),
|
|
826
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
|
|
827
961
|
const payload = {
|
|
828
962
|
name,
|
|
829
963
|
type: binding_type,
|
|
830
964
|
host,
|
|
831
965
|
source: api_binding_source,
|
|
832
966
|
value: binding_value,
|
|
833
|
-
description,
|
|
834
|
-
patch_operations: patch_operations ?? [],
|
|
835
|
-
enable_learning,
|
|
836
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
|
+
}
|
|
837
977
|
const data = await makeImpartRequest("api_bindings", undefined, "POST", payload);
|
|
838
978
|
if (!data) {
|
|
839
979
|
return {
|
|
@@ -857,24 +997,41 @@ server.tool("create_api_binding", "Create a new API binding for the organization
|
|
|
857
997
|
content: [{ type: "text", text: formattedBinding }],
|
|
858
998
|
};
|
|
859
999
|
});
|
|
860
|
-
server.tool("list_lists", "Get a list of lists for the organization", {
|
|
861
|
-
kind: zod_1.z
|
|
862
|
-
|
|
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"),
|
|
863
1011
|
page: zod_1.z
|
|
864
1012
|
.number()
|
|
865
1013
|
.default(1)
|
|
1014
|
+
.nullable()
|
|
866
1015
|
.describe("The page of results to return (minimum: 1)"),
|
|
867
1016
|
max_results: zod_1.z
|
|
868
1017
|
.number()
|
|
869
1018
|
.default(100)
|
|
1019
|
+
.nullable()
|
|
870
1020
|
.describe("The maximum number of results to return"),
|
|
871
1021
|
}, async ({ kind, subkind, page, max_results }) => {
|
|
872
|
-
const queryParams = {
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
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
|
+
}
|
|
878
1035
|
const data = await makeImpartRequest("lists", queryParams);
|
|
879
1036
|
if (!data) {
|
|
880
1037
|
return {
|
|
@@ -905,7 +1062,7 @@ server.tool("list_lists", "Get a list of lists for the organization", {
|
|
|
905
1062
|
content: [{ type: "text", text: formattedLists.join("\n") }],
|
|
906
1063
|
};
|
|
907
1064
|
});
|
|
908
|
-
server.tool("get_list_items", "Get items from a specific list", {
|
|
1065
|
+
server.tool(getToolName("get_list_items"), "Get items from a specific list", {
|
|
909
1066
|
list_id: zod_1.z.string().describe("The ID of the list"),
|
|
910
1067
|
page: zod_1.z
|
|
911
1068
|
.number()
|
|
@@ -944,49 +1101,61 @@ server.tool("get_list_items", "Get items from a specific list", {
|
|
|
944
1101
|
content: [{ type: "text", text: formattedItems.join("\n") }],
|
|
945
1102
|
};
|
|
946
1103
|
});
|
|
947
|
-
server.tool("create_list", "
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
description: zod_1.z.string().
|
|
952
|
-
functionality: zod_1.z
|
|
953
|
-
.string()
|
|
954
|
-
.default("add/remove")
|
|
955
|
-
.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"),
|
|
956
1109
|
items: zod_1.z
|
|
957
|
-
.array(zod_1.z.
|
|
958
|
-
.
|
|
959
|
-
.describe("
|
|
960
|
-
}, async ({
|
|
961
|
-
|
|
962
|
-
|
|
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 = {
|
|
963
1123
|
kind,
|
|
964
1124
|
subkind,
|
|
965
|
-
|
|
966
|
-
functionality,
|
|
967
|
-
items: items ?? [],
|
|
1125
|
+
name,
|
|
968
1126
|
};
|
|
969
|
-
|
|
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);
|
|
970
1134
|
if (!data) {
|
|
971
1135
|
return {
|
|
972
1136
|
content: [{ type: "text", text: "Failed to create list" }],
|
|
1137
|
+
isError: true,
|
|
973
1138
|
};
|
|
974
1139
|
}
|
|
975
|
-
const formattedList = [
|
|
976
|
-
"List created successfully:",
|
|
977
|
-
`ID: ${data.id}`,
|
|
978
|
-
`Name: ${data.name}`,
|
|
979
|
-
`Kind: ${data.kind}`,
|
|
980
|
-
`Subkind: ${data.subkind ?? "N/A"}`,
|
|
981
|
-
`Description: ${data.description ?? "N/A"}`,
|
|
982
|
-
`Created At: ${data.created_at}`,
|
|
983
|
-
"---",
|
|
984
|
-
].join("\n");
|
|
985
1140
|
return {
|
|
986
|
-
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
|
+
],
|
|
987
1156
|
};
|
|
988
1157
|
});
|
|
989
|
-
server.tool("update_list_items", "Updates items in a list", {
|
|
1158
|
+
server.tool(getToolName("update_list_items"), "Updates items in a list", {
|
|
990
1159
|
list_id: zod_1.z.string().describe("The ID of the list to update"),
|
|
991
1160
|
items: zod_1.z
|
|
992
1161
|
.array(zod_1.z.record(zod_1.z.any()))
|
|
@@ -1008,7 +1177,7 @@ server.tool("update_list_items", "Updates items in a list", {
|
|
|
1008
1177
|
content: [{ type: "text", text: "List items updated successfully" }],
|
|
1009
1178
|
};
|
|
1010
1179
|
});
|
|
1011
|
-
server.tool("create_label", "Creates a new label for the organization", {
|
|
1180
|
+
server.tool(getToolName("create_label"), "Creates a new label for the organization", {
|
|
1012
1181
|
name: zod_1.z.string().describe("Name of the label"),
|
|
1013
1182
|
description: zod_1.z.string().optional().describe("Optional description"),
|
|
1014
1183
|
color: zod_1.z.string().default("gray").describe("Label color"),
|
|
@@ -1037,20 +1206,25 @@ server.tool("create_label", "Creates a new label for the organization", {
|
|
|
1037
1206
|
content: [{ type: "text", text: formattedLabel }],
|
|
1038
1207
|
};
|
|
1039
1208
|
});
|
|
1040
|
-
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", {
|
|
1041
1210
|
page: zod_1.z
|
|
1042
1211
|
.number()
|
|
1043
1212
|
.default(1)
|
|
1213
|
+
.nullable()
|
|
1044
1214
|
.describe("The page of results to return (minimum: 1)"),
|
|
1045
1215
|
max_results: zod_1.z
|
|
1046
1216
|
.number()
|
|
1047
1217
|
.default(100)
|
|
1218
|
+
.nullable()
|
|
1048
1219
|
.describe("The maximum number of results to return"),
|
|
1049
1220
|
}, async ({ page, max_results }) => {
|
|
1050
|
-
const queryParams = {
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
}
|
|
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
|
+
}
|
|
1054
1228
|
const data = await makeImpartRequest("labels", queryParams);
|
|
1055
1229
|
if (!data) {
|
|
1056
1230
|
return {
|
|
@@ -1079,6 +1253,399 @@ server.tool("list_labels", "Get a list of labels for the organization", {
|
|
|
1079
1253
|
content: [{ type: "text", text: formattedLabels.join("\n") }],
|
|
1080
1254
|
};
|
|
1081
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
|
+
});
|
|
1082
1649
|
async function main() {
|
|
1083
1650
|
const transport = new stdio_js_1.StdioServerTransport();
|
|
1084
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",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
},
|
|
42
42
|
"scripts": {
|
|
43
43
|
"circular-check": "madge --circular ./src",
|
|
44
|
-
"dep-check": "
|
|
44
|
+
"dep-check": "echo 'No dependencies to check'",
|
|
45
45
|
"dev": "shx rm -rf dist && tsc -b --watch",
|
|
46
46
|
"build": "shx rm -rf dist && tsc -b && shx rm -rf dist/test",
|
|
47
47
|
"format": "prettier ./src --write --cache",
|