@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.
Files changed (2) hide show
  1. package/dist/index.js +691 -125
  2. 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 response = await fetch(url.toString(), {
45
+ const requestOptions = {
46
46
  method,
47
47
  headers,
48
- body: body ? JSON.stringify(body) : "",
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
- page: validatePage(page),
73
- max_results,
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.array(zod_1.z.string()).optional().describe("Filter by label slugs"),
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
- page: validatePage(page),
131
- max_results,
132
- type,
133
- exclude_src,
134
- exclude_revisions,
135
- is_disabled,
136
- label,
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.number().optional().describe("The specific revision to fetch"),
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 = revision ? { revision } : undefined;
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 = { max_results };
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 = { max_results };
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
- metric,
540
- from: from_time,
541
- until: until_time,
542
- spec_id,
543
- collection_id,
544
- endpoint_id,
545
- rollup,
546
- unlearned,
547
- max_results,
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
- page: validatePage(page),
596
- max_results,
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
- page: validatePage(page),
686
- max_results,
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.number().optional().describe("The specific revision to fetch"),
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 = revision ? { revision } : undefined;
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
- page: validatePage(page),
771
- max_results,
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.string().optional().describe("The list kind to query for"),
863
- subkind: zod_1.z.string().optional().describe("The list subkind to query for"),
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
- kind,
875
- subkind,
876
- page: validatePage(page),
877
- max_results,
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", "Creates a new list for the organization", {
949
- name: zod_1.z.string().describe("Name of the list"),
950
- kind: zod_1.z.string().describe("The kind of list"),
951
- subkind: zod_1.z.string().optional().describe("Optional subkind of list"),
952
- description: zod_1.z.string().optional().describe("Optional description"),
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.record(zod_1.z.any()))
959
- .optional()
960
- .describe("Optional initial list items"),
961
- }, async ({ name, kind, subkind, description, functionality, items }) => {
962
- const payload = {
963
- name,
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
- description,
967
- functionality,
968
- items: items ?? [],
1125
+ name,
969
1126
  };
970
- const data = await makeImpartRequest("lists", undefined, "POST", payload);
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: [{ type: "text", text: formattedList }],
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
- page: validatePage(page),
1053
- max_results,
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.2",
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.9.0",
24
+ "@modelcontextprotocol/sdk": "1.10.2",
25
25
  "axios": "1.8.4",
26
- "zod": "3.24.2"
26
+ "zod": "3.24.3"
27
27
  },
28
28
  "devDependencies": {
29
29
  "@types/node": "22.14.1",