@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 CHANGED
@@ -1 +1,2 @@
1
+ #!/usr/bin/env node
1
2
  export {};
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 response = await fetch(url.toString(), {
45
+ const requestOptions = {
45
46
  method,
46
47
  headers,
47
- body: body ? JSON.stringify(body) : "",
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
- page: validatePage(page),
72
- max_results,
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.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"),
127
150
  }, async ({ page, max_results, type, exclude_src, exclude_revisions, is_disabled, label, }) => {
128
- const queryParams = {
129
- page: validatePage(page),
130
- max_results,
131
- type,
132
- exclude_src,
133
- exclude_revisions,
134
- is_disabled,
135
- label,
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.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"),
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 = revision ? { revision } : undefined;
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 = { max_results };
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 = { max_results };
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
- metric,
539
- from: from_time,
540
- until: until_time,
541
- spec_id,
542
- collection_id,
543
- endpoint_id,
544
- rollup,
545
- unlearned,
546
- max_results,
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
- page: validatePage(page),
595
- max_results,
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
- page: validatePage(page),
685
- max_results,
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.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"),
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 = revision ? { revision } : undefined;
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
- page: validatePage(page),
770
- max_results,
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.string().optional().describe("The list kind to query for"),
862
- 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"),
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
- kind,
874
- subkind,
875
- page: validatePage(page),
876
- max_results,
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", "Creates a new list for the organization", {
948
- name: zod_1.z.string().describe("Name of the list"),
949
- kind: zod_1.z.string().describe("The kind of list"),
950
- subkind: zod_1.z.string().optional().describe("Optional subkind of list"),
951
- description: zod_1.z.string().optional().describe("Optional description"),
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.record(zod_1.z.any()))
958
- .optional()
959
- .describe("Optional initial list items"),
960
- }, async ({ name, kind, subkind, description, functionality, items }) => {
961
- const payload = {
962
- 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 = {
963
1123
  kind,
964
1124
  subkind,
965
- description,
966
- functionality,
967
- items: items ?? [],
1125
+ name,
968
1126
  };
969
- 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);
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: [{ 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
+ ],
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
- page: validatePage(page),
1052
- max_results,
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.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.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",
@@ -41,7 +41,7 @@
41
41
  },
42
42
  "scripts": {
43
43
  "circular-check": "madge --circular ./src",
44
- "dep-check": "pnpm depcheck-custom",
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",