@chkp/policy-insights-mcp 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js ADDED
@@ -0,0 +1,3192 @@
1
+ #!/usr/bin/env node
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __esm = (fn, res) => function __init() {
5
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
6
+ };
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+
12
+ // ../mcp-utils/dist/ui-dialog.js
13
+ var ui_dialog_exports = {};
14
+ __export(ui_dialog_exports, {
15
+ showDialog: () => showDialog,
16
+ showLoginDialog: () => showLoginDialog
17
+ });
18
+ import { createServer } from "http";
19
+ import { URL as URL2 } from "url";
20
+ import { exec } from "child_process";
21
+ import { promisify } from "util";
22
+ import * as fs2 from "fs";
23
+ import * as path from "path";
24
+ async function showDialog(config) {
25
+ const dialog = new UIDialog();
26
+ return dialog.showDialog(config);
27
+ }
28
+ async function showLoginDialog(title, message) {
29
+ return showDialog({
30
+ title: title || "Login Information",
31
+ message,
32
+ fields: [
33
+ {
34
+ name: "address",
35
+ label: "Address",
36
+ type: "text",
37
+ placeholder: "Enter server address...",
38
+ required: true
39
+ },
40
+ {
41
+ name: "user",
42
+ label: "Username",
43
+ type: "text",
44
+ placeholder: "Enter username...",
45
+ required: true
46
+ },
47
+ {
48
+ name: "password",
49
+ label: "Password",
50
+ type: "password",
51
+ placeholder: "Enter password...",
52
+ required: true
53
+ }
54
+ ]
55
+ });
56
+ }
57
+ var execAsync, UIDialog;
58
+ var init_ui_dialog = __esm({
59
+ "../mcp-utils/dist/ui-dialog.js"() {
60
+ "use strict";
61
+ execAsync = promisify(exec);
62
+ UIDialog = class {
63
+ constructor() {
64
+ this.server = null;
65
+ this.port = 0;
66
+ this.resolve = null;
67
+ }
68
+ async showDialog(config) {
69
+ return new Promise((resolve, reject) => {
70
+ this.resolve = resolve;
71
+ this.server = createServer((req, res) => {
72
+ this.handleRequest(req, res, config);
73
+ });
74
+ this.server.listen(0, "localhost", () => {
75
+ const address = this.server.address();
76
+ if (address && typeof address === "object") {
77
+ this.port = address.port;
78
+ this.openBrowser(`http://localhost:${this.port}`);
79
+ } else {
80
+ reject(new Error("Failed to start server"));
81
+ }
82
+ });
83
+ setTimeout(() => {
84
+ this.cleanup();
85
+ resolve({ cancelled: true, data: {} });
86
+ }, 5 * 60 * 1e3);
87
+ });
88
+ }
89
+ handleRequest(req, res, config) {
90
+ const url = new URL2(req.url, `http://localhost:${this.port}`);
91
+ if (req.method === "GET" && url.pathname === "/") {
92
+ res.writeHead(200, { "Content-Type": "text/html" });
93
+ res.end(this.generateHTML(config));
94
+ } else if (req.method === "POST" && url.pathname === "/submit") {
95
+ let body = "";
96
+ req.on("data", (chunk) => {
97
+ body += chunk.toString();
98
+ });
99
+ req.on("end", () => {
100
+ const formData = new URLSearchParams(body);
101
+ const result = {};
102
+ for (const field of config.fields) {
103
+ result[field.name] = formData.get(field.name) || "";
104
+ }
105
+ res.writeHead(200, { "Content-Type": "text/html" });
106
+ res.end(`
107
+ <html>
108
+ <head><title>Success</title></head>
109
+ <body style="font-family: Arial, sans-serif; text-align: center; padding: 50px;">
110
+ <h2>Form submitted successfully!</h2>
111
+ <p>You can close this window now.</p>
112
+ <script>setTimeout(() => window.close(), 2000);</script>
113
+ </body>
114
+ </html>
115
+ `);
116
+ this.cleanup();
117
+ if (this.resolve) {
118
+ this.resolve({ cancelled: false, data: result });
119
+ }
120
+ });
121
+ } else if (req.method === "POST" && url.pathname === "/cancel") {
122
+ res.writeHead(200, { "Content-Type": "text/html" });
123
+ res.end(`
124
+ <html>
125
+ <head><title>Cancelled</title></head>
126
+ <body style="font-family: Arial, sans-serif; text-align: center; padding: 50px;">
127
+ <h2>Form cancelled</h2>
128
+ <p>You can close this window now.</p>
129
+ <script>setTimeout(() => window.close(), 2000);</script>
130
+ </body>
131
+ </html>
132
+ `);
133
+ this.cleanup();
134
+ if (this.resolve) {
135
+ this.resolve({ cancelled: true, data: {} });
136
+ }
137
+ } else {
138
+ res.writeHead(404);
139
+ res.end("Not found");
140
+ }
141
+ }
142
+ generateHTML(config) {
143
+ const fieldsHTML = config.fields.map((field) => {
144
+ let fieldHTML = "";
145
+ const fieldType = field.type || "text";
146
+ switch (fieldType) {
147
+ case "textarea":
148
+ fieldHTML = `
149
+ <textarea
150
+ name="${field.name}"
151
+ placeholder="${field.placeholder || ""}"
152
+ ${field.required ? "required" : ""}
153
+ style="width: 100%; box-sizing: border-box; min-height: 80px; padding: 8px; border: 1px solid #ddd; border-radius: 4px; font-family: Arial, sans-serif; font-size: 14px; resize: vertical;"
154
+ >${field.defaultValue || ""}</textarea>
155
+ `;
156
+ break;
157
+ case "select":
158
+ fieldHTML = `
159
+ <select
160
+ name="${field.name}"
161
+ ${field.required ? "required" : ""}
162
+ style="width: 100%; box-sizing: border-box; padding: 8px; border: 1px solid #ddd; border-radius: 4px; font-family: Arial, sans-serif; font-size: 14px;"
163
+ >
164
+ <option value="">Select an option...</option>
165
+ ${(field.options || []).map((option) => `<option value="${option}" ${option === field.defaultValue ? "selected" : ""}>${option}</option>`).join("")}
166
+ </select>
167
+ `;
168
+ break;
169
+ default:
170
+ fieldHTML = `
171
+ <input
172
+ type="${fieldType}"
173
+ name="${field.name}"
174
+ placeholder="${field.placeholder || ""}"
175
+ value="${field.defaultValue || ""}"
176
+ ${field.required ? "required" : ""}
177
+ style="width: 100%; box-sizing: border-box; padding: 8px; border: 1px solid #ddd; border-radius: 4px; font-family: Arial, sans-serif; font-size: 14px;"
178
+ />
179
+ `;
180
+ }
181
+ return `
182
+ <div style="margin-bottom: 15px;">
183
+ <label style="display: block; margin-bottom: 5px; font-weight: bold; color: #333;">
184
+ ${field.label}${field.required ? " *" : ""}
185
+ </label>
186
+ ${fieldHTML}
187
+ </div>
188
+ `;
189
+ }).join("");
190
+ return `
191
+ <!DOCTYPE html>
192
+ <html>
193
+ <head>
194
+ <title>${config.title}</title>
195
+ <meta charset="UTF-8">
196
+ <meta name="viewport" content="width=device-width, initial-scale=1">
197
+ <style>
198
+ * {
199
+ box-sizing: border-box;
200
+ }
201
+ body {
202
+ font-family: Arial, sans-serif;
203
+ max-width: 500px;
204
+ margin: 50px auto;
205
+ padding: 20px;
206
+ background-color: #f5f5f5;
207
+ line-height: 1.4;
208
+ }
209
+ .dialog {
210
+ background: white;
211
+ padding: 30px;
212
+ border-radius: 8px;
213
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
214
+ }
215
+ .buttons {
216
+ margin-top: 20px;
217
+ text-align: right;
218
+ }
219
+ button {
220
+ padding: 10px 20px;
221
+ margin-left: 10px;
222
+ border: none;
223
+ border-radius: 4px;
224
+ cursor: pointer;
225
+ font-size: 14px;
226
+ font-family: Arial, sans-serif;
227
+ }
228
+ .submit-btn {
229
+ background-color: #007cba;
230
+ color: white;
231
+ }
232
+ .submit-btn:hover {
233
+ background-color: #005a87;
234
+ }
235
+ .cancel-btn {
236
+ background-color: #6c757d;
237
+ color: white;
238
+ }
239
+ .cancel-btn:hover {
240
+ background-color: #545b62;
241
+ }
242
+ input:focus, textarea:focus, select:focus {
243
+ outline: none;
244
+ border-color: #007cba;
245
+ box-shadow: 0 0 0 2px rgba(0, 124, 186, 0.2);
246
+ }
247
+ </style>
248
+ </head>
249
+ <body>
250
+ <div class="dialog">
251
+ <h2 style="margin-top: 0; color: #333;">${config.title}</h2>
252
+ ${config.message ? `<p style="color: #666; margin-bottom: 20px;">${config.message}</p>` : ""}
253
+
254
+ <form id="dialogForm" method="POST" action="/submit">
255
+ ${fieldsHTML}
256
+
257
+ <div class="buttons">
258
+ <button type="button" class="cancel-btn" onclick="cancel()">
259
+ ${config.cancelButtonText || "Cancel"}
260
+ </button>
261
+ <button type="submit" class="submit-btn">
262
+ ${config.submitButtonText || "Submit"}
263
+ </button>
264
+ </div>
265
+ </form>
266
+ </div>
267
+
268
+ <script>
269
+ function cancel() {
270
+ fetch('/cancel', { method: 'POST' })
271
+ .then(() => {
272
+ document.body.innerHTML = '<div style="text-align: center; padding: 50px; font-family: Arial, sans-serif;"><h2>Cancelled</h2><p>You can close this window now.</p></div>';
273
+ setTimeout(() => window.close(), 2000);
274
+ });
275
+ }
276
+
277
+ // Auto-focus first input
278
+ document.addEventListener('DOMContentLoaded', () => {
279
+ const firstInput = document.querySelector('input, textarea, select');
280
+ if (firstInput) {
281
+ firstInput.focus();
282
+ // If it's a text input, place cursor at end
283
+ if (firstInput.type === 'text' || firstInput.tagName === 'TEXTAREA') {
284
+ const val = firstInput.value;
285
+ firstInput.value = '';
286
+ firstInput.value = val;
287
+ }
288
+ }
289
+ });
290
+
291
+ // Prevent form submission if required fields are empty
292
+ document.getElementById('dialogForm').addEventListener('submit', function(e) {
293
+ const requiredFields = document.querySelectorAll('[required]');
294
+ for (let field of requiredFields) {
295
+ if (!field.value.trim()) {
296
+ e.preventDefault();
297
+ field.focus();
298
+ alert('Please fill in all required fields.');
299
+ return false;
300
+ }
301
+ }
302
+ });
303
+ </script>
304
+ </body>
305
+ </html>
306
+ `;
307
+ }
308
+ async openBrowser(urlString) {
309
+ try {
310
+ let url;
311
+ try {
312
+ url = new URL2(urlString);
313
+ if (!["http:", "https:"].includes(url.protocol) || url.hostname !== "localhost" && url.hostname !== "127.0.0.1") {
314
+ throw new Error("Invalid URL protocol or non-localhost hostname");
315
+ }
316
+ } catch (e) {
317
+ console.error("Invalid URL:", e);
318
+ return;
319
+ }
320
+ switch (process.platform) {
321
+ case "darwin": {
322
+ const scriptPath = path.join(process.env.TMPDIR || "/tmp", `open-browser-${Date.now()}.applescript`);
323
+ const script = `open location "${urlString}"`;
324
+ fs2.writeFileSync(scriptPath, script);
325
+ await execAsync(`osascript "${scriptPath}"`);
326
+ try {
327
+ fs2.unlinkSync(scriptPath);
328
+ } catch (e) {
329
+ }
330
+ break;
331
+ }
332
+ case "win32": {
333
+ await execAsync(`rundll32 url.dll,FileProtocolHandler "${urlString}"`);
334
+ break;
335
+ }
336
+ default: {
337
+ const browsers = ["xdg-open", "google-chrome", "firefox", "chromium-browser"];
338
+ for (const browser of browsers) {
339
+ try {
340
+ await execAsync(`which ${browser}`);
341
+ await execAsync(`${browser} "${urlString}"`);
342
+ break;
343
+ } catch {
344
+ continue;
345
+ }
346
+ }
347
+ }
348
+ }
349
+ } catch (error) {
350
+ console.error("Failed to open browser:", error);
351
+ }
352
+ }
353
+ cleanup() {
354
+ if (this.server) {
355
+ this.server.close();
356
+ this.server = null;
357
+ }
358
+ }
359
+ };
360
+ }
361
+ });
362
+
363
+ // src/index.ts
364
+ import { z as z2 } from "zod";
365
+
366
+ // src/toolDefinitionMap.ts
367
+ var toolDefinitionMap = [
368
+ {
369
+ "name": "ShowCardInfo",
370
+ "description": "Provide information for the Infinity Cloud Services display card",
371
+ "inputSchema": {
372
+ "type": "object",
373
+ "properties": {}
374
+ },
375
+ "method": "post",
376
+ "pathTemplate": "/insights/v3.0/show-card-info",
377
+ "parameters": [],
378
+ "executionParameters": [],
379
+ "securityRequirements": [],
380
+ "operationId": "ShowCardInfo",
381
+ "baseUrl": ""
382
+ },
383
+ {
384
+ "name": "ShowConfig",
385
+ "description": "Get user configuration and settings for Policy Insights product",
386
+ "inputSchema": {
387
+ "type": "object",
388
+ "properties": {}
389
+ },
390
+ "method": "post",
391
+ "pathTemplate": "/insights/v3.0/show-config",
392
+ "parameters": [],
393
+ "executionParameters": [],
394
+ "securityRequirements": [],
395
+ "operationId": "ShowConfig",
396
+ "baseUrl": ""
397
+ },
398
+ {
399
+ "name": "ShowRulesUidsWithSuggestions",
400
+ "description": "Retrieve rule UIDs that have suggestions for a specific suggestion type using the required layer UID\nEnhanced to show both direct suggestions and inline layer suggestions",
401
+ "inputSchema": {
402
+ "type": "object",
403
+ "properties": {
404
+ "requestBody": {
405
+ "properties": {
406
+ "layer": {
407
+ "type": "string",
408
+ "format": "uuid",
409
+ "description": "Access layer identifier in UUID format",
410
+ "pattern": "^[0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}$"
411
+ },
412
+ "filters": {
413
+ "properties": {
414
+ "states": {
415
+ "items": {
416
+ "description": "State of a suggestion - either ACCEPTED or REJECTED",
417
+ "enum": [
418
+ "ACCEPTED",
419
+ "REJECTED"
420
+ ],
421
+ "type": "string",
422
+ "x-enum-varnames": [
423
+ "ACCEPTED",
424
+ "REJECTED"
425
+ ]
426
+ },
427
+ "type": "array",
428
+ "description": "Array of insight state values"
429
+ },
430
+ "user-interaction": {
431
+ "properties": {
432
+ "operator": {
433
+ "description": "Operator for filtering by user-interaction-types",
434
+ "enum": [
435
+ "NOT-IN",
436
+ "IN"
437
+ ],
438
+ "type": "string",
439
+ "x-enum-varnames": [
440
+ "NOT_IN",
441
+ "IN"
442
+ ]
443
+ },
444
+ "types": {
445
+ "items": {
446
+ "description": "Type of user interaction with an insight",
447
+ "enum": [
448
+ "DECIDE_LATER"
449
+ ],
450
+ "type": "string",
451
+ "x-enum-varnames": [
452
+ "DECIDE_LATER"
453
+ ]
454
+ },
455
+ "type": "array",
456
+ "description": "Array of user interaction type values"
457
+ }
458
+ },
459
+ "required": [
460
+ "types"
461
+ ],
462
+ "type": "object"
463
+ },
464
+ "security-impact": {
465
+ "enum": [
466
+ "HIGH",
467
+ "MEDIUM_AND_ABOVE",
468
+ "LOW_AND_ABOVE"
469
+ ],
470
+ "type": "string",
471
+ "x-enum-varnames": [
472
+ "HIGH",
473
+ "MEDIUM_AND_ABOVE",
474
+ "LOW_AND_ABOVE"
475
+ ],
476
+ "description": "Minimum security impact threshold to include"
477
+ },
478
+ "confidence-level": {
479
+ "enum": [
480
+ "HIGH",
481
+ "MEDIUM_AND_ABOVE",
482
+ "LOW_AND_ABOVE"
483
+ ],
484
+ "type": "string",
485
+ "x-enum-varnames": [
486
+ "HIGH",
487
+ "MEDIUM_AND_ABOVE",
488
+ "LOW_AND_ABOVE"
489
+ ],
490
+ "description": "Minimum confidence threshold to include"
491
+ },
492
+ "default-filter": {
493
+ "enum": [
494
+ "NONE"
495
+ ],
496
+ "type": "string",
497
+ "x-enum-varnames": [
498
+ "NONE"
499
+ ],
500
+ "description": "Ignore default filtering of the system"
501
+ },
502
+ "suggestions-type": {
503
+ "description": "Type of insight",
504
+ "enum": [
505
+ "unused-objects",
506
+ "tighten-rule",
507
+ "delete-disabled-rule",
508
+ "zero-hits-rule"
509
+ ],
510
+ "type": "string",
511
+ "x-enum-varnames": [
512
+ "UnusedObjects",
513
+ "TightenRule",
514
+ "DeleteDisabledRule",
515
+ "ZeroHitsRule"
516
+ ]
517
+ }
518
+ },
519
+ "required": [
520
+ "suggestions-type"
521
+ ],
522
+ "type": "object"
523
+ }
524
+ },
525
+ "required": [
526
+ "layer",
527
+ "filters"
528
+ ],
529
+ "type": "object",
530
+ "description": "Parameters for showing rules UIDs with their suggestions"
531
+ }
532
+ },
533
+ "required": [
534
+ "requestBody"
535
+ ]
536
+ },
537
+ "method": "post",
538
+ "pathTemplate": "/insights/v3.0/show-rules-uids-with-suggestions",
539
+ "parameters": [],
540
+ "executionParameters": [],
541
+ "requestBodyContentType": "application/json",
542
+ "securityRequirements": [],
543
+ "operationId": "ShowRulesUidsWithSuggestions",
544
+ "baseUrl": ""
545
+ },
546
+ {
547
+ "name": "ShowState",
548
+ "description": "Shows Policy Insights enabled/disabled status\nAllows the Infinity Cloud Services page to determine current state",
549
+ "inputSchema": {
550
+ "type": "object",
551
+ "properties": {}
552
+ },
553
+ "method": "post",
554
+ "pathTemplate": "/insights/v3.0/show-state",
555
+ "parameters": [],
556
+ "executionParameters": [],
557
+ "securityRequirements": [],
558
+ "operationId": "ShowState",
559
+ "baseUrl": ""
560
+ },
561
+ {
562
+ "name": "ShowSuggestionEngineMetadata",
563
+ "description": "Retrieve next suggestions engine run schedule for each suggestion type",
564
+ "inputSchema": {
565
+ "type": "object",
566
+ "properties": {
567
+ "requestBody": {
568
+ "properties": {
569
+ "filters": {
570
+ "properties": {
571
+ "suggestion-type": {
572
+ "description": "Type of insight",
573
+ "enum": [
574
+ "unused-objects",
575
+ "tighten-rule",
576
+ "delete-disabled-rule",
577
+ "zero-hits-rule"
578
+ ],
579
+ "type": "string",
580
+ "x-enum-varnames": [
581
+ "UnusedObjects",
582
+ "TightenRule",
583
+ "DeleteDisabledRule",
584
+ "ZeroHitsRule"
585
+ ]
586
+ }
587
+ },
588
+ "type": "object"
589
+ }
590
+ },
591
+ "type": "object",
592
+ "description": "The JSON request body."
593
+ }
594
+ },
595
+ "required": [
596
+ "requestBody"
597
+ ]
598
+ },
599
+ "method": "post",
600
+ "pathTemplate": "/insights/v3.0/show-suggestion-engine-metadata",
601
+ "parameters": [],
602
+ "executionParameters": [],
603
+ "requestBodyContentType": "application/json",
604
+ "securityRequirements": [],
605
+ "operationId": "ShowSuggestionEngineMetadata",
606
+ "baseUrl": ""
607
+ },
608
+ {
609
+ "name": "ShowSuggestions",
610
+ "description": 'Retrieve all suggestions with advanced filtering capabilities.\nIncludes suggestions from all inline layers.\nExcludes rejected/accepted suggestions by default.\n\nRequired Parameters:\n- Must provide either "layer" OR "filters.rules-uids" OR "filters.uids"\n- Cannot retrieve suggestions without specifying at least one of these targeting parameters',
611
+ "inputSchema": {
612
+ "type": "object",
613
+ "properties": {
614
+ "requestBody": {
615
+ "properties": {
616
+ "layer": {
617
+ "type": "string",
618
+ "format": "uuid",
619
+ "description": "Access layer identifier in UUID format",
620
+ "pattern": "^[0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}$"
621
+ },
622
+ "options": {
623
+ "properties": {
624
+ "include-inline-layers": {
625
+ "type": "boolean",
626
+ "description": "Whether to include insights on inline layers"
627
+ }
628
+ },
629
+ "type": "object"
630
+ },
631
+ "limit": {
632
+ "type": "number",
633
+ "format": "int32",
634
+ "description": "Maximum number of items to return"
635
+ },
636
+ "offset": {
637
+ "type": "number",
638
+ "format": "int32",
639
+ "description": "Number of items to skip for pagination"
640
+ },
641
+ "filters": {
642
+ "properties": {
643
+ "states": {
644
+ "items": {
645
+ "description": "State of a suggestion - either ACCEPTED or REJECTED",
646
+ "enum": [
647
+ "ACCEPTED",
648
+ "REJECTED"
649
+ ],
650
+ "type": "string",
651
+ "x-enum-varnames": [
652
+ "ACCEPTED",
653
+ "REJECTED"
654
+ ]
655
+ },
656
+ "type": "array",
657
+ "description": "Array of insight state values"
658
+ },
659
+ "user-interaction": {
660
+ "properties": {
661
+ "operator": {
662
+ "description": "Operator for filtering by user-interaction-types",
663
+ "enum": [
664
+ "NOT-IN",
665
+ "IN"
666
+ ],
667
+ "type": "string",
668
+ "x-enum-varnames": [
669
+ "NOT_IN",
670
+ "IN"
671
+ ]
672
+ },
673
+ "types": {
674
+ "items": {
675
+ "description": "Type of user interaction with an insight",
676
+ "enum": [
677
+ "DECIDE_LATER"
678
+ ],
679
+ "type": "string",
680
+ "x-enum-varnames": [
681
+ "DECIDE_LATER"
682
+ ]
683
+ },
684
+ "type": "array",
685
+ "description": "Array of user interaction type values"
686
+ }
687
+ },
688
+ "required": [
689
+ "types"
690
+ ],
691
+ "type": "object"
692
+ },
693
+ "security-impact": {
694
+ "enum": [
695
+ "HIGH",
696
+ "MEDIUM_AND_ABOVE",
697
+ "LOW_AND_ABOVE"
698
+ ],
699
+ "type": "string",
700
+ "x-enum-varnames": [
701
+ "HIGH",
702
+ "MEDIUM_AND_ABOVE",
703
+ "LOW_AND_ABOVE"
704
+ ],
705
+ "description": "Minimum security impact threshold to include"
706
+ },
707
+ "confidence-level": {
708
+ "enum": [
709
+ "HIGH",
710
+ "MEDIUM_AND_ABOVE",
711
+ "LOW_AND_ABOVE"
712
+ ],
713
+ "type": "string",
714
+ "x-enum-varnames": [
715
+ "HIGH",
716
+ "MEDIUM_AND_ABOVE",
717
+ "LOW_AND_ABOVE"
718
+ ],
719
+ "description": "Minimum confidence threshold to include"
720
+ },
721
+ "default-filter": {
722
+ "enum": [
723
+ "NONE"
724
+ ],
725
+ "type": "string",
726
+ "x-enum-varnames": [
727
+ "NONE"
728
+ ],
729
+ "description": "Ignore default filtering of the system"
730
+ },
731
+ "uids": {
732
+ "items": {
733
+ "type": "string",
734
+ "format": "uuid",
735
+ "description": "Stringified UUID.",
736
+ "pattern": "^[0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}$"
737
+ },
738
+ "type": "array",
739
+ "description": "Array of insight unique identifiers"
740
+ },
741
+ "rules-uids": {
742
+ "items": {
743
+ "type": "string",
744
+ "format": "uuid",
745
+ "description": "Stringified UUID.",
746
+ "pattern": "^[0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}$"
747
+ },
748
+ "type": "array",
749
+ "description": "Array of rule unique identifiers"
750
+ },
751
+ "types": {
752
+ "items": {
753
+ "description": "Type of insight",
754
+ "enum": [
755
+ "unused-objects",
756
+ "tighten-rule",
757
+ "delete-disabled-rule",
758
+ "zero-hits-rule"
759
+ ],
760
+ "type": "string",
761
+ "x-enum-varnames": [
762
+ "UnusedObjects",
763
+ "TightenRule",
764
+ "DeleteDisabledRule",
765
+ "ZeroHitsRule"
766
+ ]
767
+ },
768
+ "type": "array",
769
+ "description": "Type of insight"
770
+ }
771
+ },
772
+ "type": "object"
773
+ }
774
+ },
775
+ "type": "object",
776
+ "description": "Parameters for showing suggestions with enhanced v3.0 capabilities"
777
+ }
778
+ },
779
+ "required": [
780
+ "requestBody"
781
+ ]
782
+ },
783
+ "method": "post",
784
+ "pathTemplate": "/insights/v3.0/show-suggestions",
785
+ "parameters": [],
786
+ "executionParameters": [],
787
+ "requestBodyContentType": "application/json",
788
+ "securityRequirements": [],
789
+ "operationId": "ShowSuggestions",
790
+ "baseUrl": ""
791
+ },
792
+ {
793
+ "name": "ShowSuggestionsInfo",
794
+ "description": "Retrieve detailed information such as last engine run, next run schedule and suggestions status, can be specified by suggestion type.\nProvides onboarding guidance for cases where the system has not yet completed its first analysis and generated its first set of insights,\nor if insights were generated but can't see the suggestions.",
795
+ "inputSchema": {
796
+ "type": "object",
797
+ "properties": {
798
+ "requestBody": {
799
+ "properties": {
800
+ "layer": {
801
+ "type": "string",
802
+ "format": "uuid",
803
+ "description": "Access layer identifier in UUID format",
804
+ "pattern": "^[0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}$"
805
+ }
806
+ },
807
+ "required": [
808
+ "layer"
809
+ ],
810
+ "type": "object",
811
+ "description": "The JSON request body."
812
+ }
813
+ },
814
+ "required": [
815
+ "requestBody"
816
+ ]
817
+ },
818
+ "method": "post",
819
+ "pathTemplate": "/insights/v3.0/show-suggestions-info",
820
+ "parameters": [],
821
+ "executionParameters": [],
822
+ "requestBodyContentType": "application/json",
823
+ "securityRequirements": [],
824
+ "operationId": "ShowSuggestionsInfo",
825
+ "baseUrl": ""
826
+ },
827
+ {
828
+ "name": "ShowSuggestionsSummary",
829
+ "description": "Retrieve number of rule suggestions grouped by their type.\nProvides generation batch metadata about the current suggestions we see: how many days of traffic logs were analyzed, on which publish timestamp the suggestions are based on.",
830
+ "inputSchema": {
831
+ "type": "object",
832
+ "properties": {
833
+ "requestBody": {
834
+ "properties": {
835
+ "layer": {
836
+ "type": "string",
837
+ "format": "uuid",
838
+ "description": "Access layer identifier in UUID format",
839
+ "pattern": "^[0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}$"
840
+ },
841
+ "filters": {
842
+ "properties": {
843
+ "states": {
844
+ "items": {
845
+ "description": "State of a suggestion - either ACCEPTED or REJECTED",
846
+ "enum": [
847
+ "ACCEPTED",
848
+ "REJECTED"
849
+ ],
850
+ "type": "string",
851
+ "x-enum-varnames": [
852
+ "ACCEPTED",
853
+ "REJECTED"
854
+ ]
855
+ },
856
+ "type": "array",
857
+ "description": "Array of insight state values"
858
+ },
859
+ "user-interaction": {
860
+ "properties": {
861
+ "operator": {
862
+ "description": "Operator for filtering by user-interaction-types",
863
+ "enum": [
864
+ "NOT-IN",
865
+ "IN"
866
+ ],
867
+ "type": "string",
868
+ "x-enum-varnames": [
869
+ "NOT_IN",
870
+ "IN"
871
+ ]
872
+ },
873
+ "types": {
874
+ "items": {
875
+ "description": "Type of user interaction with an insight",
876
+ "enum": [
877
+ "DECIDE_LATER"
878
+ ],
879
+ "type": "string",
880
+ "x-enum-varnames": [
881
+ "DECIDE_LATER"
882
+ ]
883
+ },
884
+ "type": "array",
885
+ "description": "Array of user interaction type values"
886
+ }
887
+ },
888
+ "required": [
889
+ "types"
890
+ ],
891
+ "type": "object"
892
+ },
893
+ "security-impact": {
894
+ "enum": [
895
+ "HIGH",
896
+ "MEDIUM_AND_ABOVE",
897
+ "LOW_AND_ABOVE"
898
+ ],
899
+ "type": "string",
900
+ "x-enum-varnames": [
901
+ "HIGH",
902
+ "MEDIUM_AND_ABOVE",
903
+ "LOW_AND_ABOVE"
904
+ ],
905
+ "description": "Minimum security impact threshold to include"
906
+ },
907
+ "confidence-level": {
908
+ "enum": [
909
+ "HIGH",
910
+ "MEDIUM_AND_ABOVE",
911
+ "LOW_AND_ABOVE"
912
+ ],
913
+ "type": "string",
914
+ "x-enum-varnames": [
915
+ "HIGH",
916
+ "MEDIUM_AND_ABOVE",
917
+ "LOW_AND_ABOVE"
918
+ ],
919
+ "description": "Minimum confidence threshold to include"
920
+ },
921
+ "default-filter": {
922
+ "enum": [
923
+ "NONE"
924
+ ],
925
+ "type": "string",
926
+ "x-enum-varnames": [
927
+ "NONE"
928
+ ],
929
+ "description": "Ignore default filtering of the system"
930
+ }
931
+ },
932
+ "type": "object"
933
+ }
934
+ },
935
+ "type": "object",
936
+ "description": "Parameters for showing suggestions summary"
937
+ }
938
+ },
939
+ "required": [
940
+ "requestBody"
941
+ ]
942
+ },
943
+ "method": "post",
944
+ "pathTemplate": "/insights/v3.0/show-suggestions-summary",
945
+ "parameters": [],
946
+ "executionParameters": [],
947
+ "requestBodyContentType": "application/json",
948
+ "securityRequirements": [],
949
+ "operationId": "ShowSuggestionsSummary",
950
+ "baseUrl": ""
951
+ },
952
+ {
953
+ "name": "ShowPolicyInsightsStatus",
954
+ "description": "Shows Policy Insights status, reflecting the overall status of the product including supported API versions.\nReturns both Insights API versions and Threat Prevention Insights API versions when Threat Prevention is enabled.\nMay also include license status information if available.\nA license is required to activate the product, and the status provides details about the validity and expiration of the product license.",
955
+ "inputSchema": {
956
+ "type": "object",
957
+ "properties": {}
958
+ },
959
+ "method": "post",
960
+ "pathTemplate": "/show-policy-insights-status",
961
+ "parameters": [],
962
+ "executionParameters": [],
963
+ "securityRequirements": [],
964
+ "operationId": "ShowPolicyInsightsStatus",
965
+ "baseUrl": ""
966
+ }
967
+ ];
968
+
969
+ // ../infra/dist/api-client.js
970
+ import axios from "axios";
971
+ import https from "https";
972
+ var TokenType;
973
+ (function(TokenType2) {
974
+ TokenType2["API_KEY"] = "API_KEY";
975
+ TokenType2["CI_TOKEN"] = "CI_TOKEN";
976
+ })(TokenType || (TokenType = {}));
977
+ function getMainPackageUserAgent() {
978
+ if (process.env.CP_MCP_MAIN_PKG) {
979
+ if (process.env.CP_MCP_MAIN_PKG.includes("quantum-management-mcp")) {
980
+ return "mgmt-mcp";
981
+ }
982
+ }
983
+ return "Check Point MCP API Client";
984
+ }
985
+ var ClientResponse = class {
986
+ constructor(status, response) {
987
+ this.status = status;
988
+ this.response = response;
989
+ }
990
+ };
991
+ var APIClientBase = class {
992
+ constructor(authToken = "", tokenType = TokenType.API_KEY) {
993
+ this.authToken = authToken;
994
+ this.tokenType = tokenType;
995
+ this.sid = null;
996
+ this.sessionTimeout = null;
997
+ this.sessionStart = null;
998
+ this.isMDS = false;
999
+ }
1000
+ /**
1001
+ * Create an API client instance - generic method for creating clients
1002
+ */
1003
+ static create(...args) {
1004
+ return new this(...args);
1005
+ }
1006
+ /**
1007
+ * Get headers for the API requests
1008
+ */
1009
+ getHeaders() {
1010
+ const headers = {
1011
+ "Content-Type": "application/json",
1012
+ "User-Agent": getMainPackageUserAgent()
1013
+ };
1014
+ if (this.sid) {
1015
+ headers["X-chkp-sid"] = this.sid;
1016
+ }
1017
+ return headers;
1018
+ }
1019
+ /**
1020
+ * Get debug mode
1021
+ */
1022
+ get debug() {
1023
+ return !!this._debug;
1024
+ }
1025
+ /**
1026
+ * Set debug mode
1027
+ */
1028
+ set debug(value) {
1029
+ this._debug = value;
1030
+ }
1031
+ /**
1032
+ * Check if this client needs to perform login before making API calls
1033
+ */
1034
+ needsLogin() {
1035
+ return true;
1036
+ }
1037
+ /**
1038
+ * Check if this client is in an MDS environment
1039
+ */
1040
+ async isMDSEnvironment() {
1041
+ if (!this.hasValidSession()) {
1042
+ await this.login();
1043
+ }
1044
+ return this.isMDS;
1045
+ }
1046
+ /**
1047
+ * Check if the client has a valid session
1048
+ */
1049
+ hasValidSession() {
1050
+ return !!this.sid && !this.isSessionExpired();
1051
+ }
1052
+ /**
1053
+ * Get the current session ID (for debugging/logging purposes)
1054
+ */
1055
+ getSessionId() {
1056
+ return this.sid;
1057
+ }
1058
+ /**
1059
+ * Create a new API client instance with a specific session ID
1060
+ * Used for domain-specific clients in MDS environments
1061
+ */
1062
+ static createWithSid(originalClient, sid) {
1063
+ const newClient = Object.create(Object.getPrototypeOf(originalClient));
1064
+ Object.assign(newClient, originalClient);
1065
+ newClient.sid = sid;
1066
+ newClient.sessionStart = Date.now();
1067
+ return newClient;
1068
+ }
1069
+ /**
1070
+ * Call an API endpoint
1071
+ */
1072
+ async callApi(method, uri, data, params) {
1073
+ if (this.needsLogin() && (!this.sid || this.isSessionExpired())) {
1074
+ try {
1075
+ await this.login();
1076
+ } catch (error) {
1077
+ if (error instanceof ClientResponse) {
1078
+ console.error(`Login failed with status ${error.status}:`, error.response);
1079
+ return error;
1080
+ }
1081
+ console.error("Login failed with unexpected error:", error);
1082
+ return new ClientResponse(500, { error: "Authentication failed", message: error.message });
1083
+ }
1084
+ }
1085
+ let httpsAgent;
1086
+ if (this instanceof OnPremAPIClient) {
1087
+ httpsAgent = new https.Agent({ rejectUnauthorized: false });
1088
+ }
1089
+ try {
1090
+ return await this.makeRequest(this.getHost(), method, uri, data, this.getHeaders(), params, httpsAgent);
1091
+ } catch (error) {
1092
+ if ((error.message?.includes("401") || error.response?.status === 401) && error.message?.toLowerCase().includes("session")) {
1093
+ console.error("Session expired (401), resetting session and retrying...");
1094
+ this.sid = null;
1095
+ this.sessionStart = null;
1096
+ try {
1097
+ await this.login();
1098
+ } catch (loginError) {
1099
+ if (loginError instanceof ClientResponse) {
1100
+ console.error(`Login retry failed with status ${loginError.status}:`, loginError.response);
1101
+ return loginError;
1102
+ }
1103
+ console.error("Login retry failed with unexpected error:", loginError);
1104
+ throw loginError;
1105
+ }
1106
+ return await this.makeRequest(this.getHost(), method, uri, data, this.getHeaders(), params, httpsAgent);
1107
+ }
1108
+ throw error;
1109
+ }
1110
+ }
1111
+ /**
1112
+ * Check if the session is expired based on sessionTimeout and sessionStart
1113
+ */
1114
+ isSessionExpired() {
1115
+ if (!this.sid || !this.sessionTimeout || !this.sessionStart)
1116
+ return true;
1117
+ const now = Date.now();
1118
+ return now > this.sessionStart + (this.sessionTimeout - 5) * 1e3;
1119
+ }
1120
+ /**
1121
+ * Login to the API using the API key
1122
+ */
1123
+ async login() {
1124
+ const apiTokenHeader = this.tokenType === TokenType.API_KEY ? "api-key" : "ci-token";
1125
+ const loginResp = await this.makeRequest(this.getHost(), "POST", "login", { [apiTokenHeader]: this.authToken }, { "Content-Type": "application/json" });
1126
+ if (loginResp.status !== 200 || !loginResp.response || !loginResp.response.sid) {
1127
+ throw loginResp;
1128
+ }
1129
+ this.sid = loginResp.response.sid;
1130
+ this.sessionTimeout = loginResp.response["session-timeout"] || null;
1131
+ this.sessionStart = Date.now();
1132
+ if (loginResp.response.uid) {
1133
+ await this.detectMDS(loginResp.response.uid);
1134
+ }
1135
+ return loginResp.response.sid;
1136
+ }
1137
+ /**
1138
+ * Detect if this is an MDS environment by checking the session details
1139
+ */
1140
+ async detectMDS(sessionUid, handleSelfSigned = false) {
1141
+ try {
1142
+ let httpsAgent;
1143
+ if (handleSelfSigned) {
1144
+ httpsAgent = new https.Agent({ rejectUnauthorized: false });
1145
+ }
1146
+ const sessionResp = await this.makeRequest(this.getHost(), "POST", "show-session", { uid: sessionUid }, this.getHeaders(), null, httpsAgent);
1147
+ if (sessionResp.status === 200 && sessionResp.response?.domain?.["domain-type"] === "mds") {
1148
+ this.isMDS = true;
1149
+ }
1150
+ } catch (error) {
1151
+ console.warn("Could not determine MDS status:", error);
1152
+ this.isMDS = false;
1153
+ }
1154
+ }
1155
+ /**
1156
+ * Make a request to a Check Point API
1157
+ */
1158
+ async makeRequest(host, method, uri, data, headers = {}, params = null, httpsAgent) {
1159
+ uri = uri.replace(/^\//, "");
1160
+ const url = `${host}/${uri}`;
1161
+ const config = {
1162
+ method: method.toUpperCase(),
1163
+ url,
1164
+ headers,
1165
+ params: params || void 0
1166
+ };
1167
+ if (httpsAgent) {
1168
+ config.httpsAgent = httpsAgent;
1169
+ }
1170
+ if (method.toUpperCase() !== "GET" && data !== void 0) {
1171
+ config.data = data;
1172
+ }
1173
+ console.error(`API Request: ${method} ${url}`);
1174
+ try {
1175
+ const response = await axios(config);
1176
+ return new ClientResponse(response.status, response.data);
1177
+ } catch (error) {
1178
+ if (error.response) {
1179
+ console.error(`\u274C API Error (${error.response.status}):`);
1180
+ console.error("Headers:", error.response.headers);
1181
+ console.error("Data:", error.response.data);
1182
+ if (this.debug) {
1183
+ console.error("Debug mode: Printing request details:");
1184
+ console.error("Request Method:", method);
1185
+ console.error("Request URL:", url);
1186
+ console.error("Request Headers:", config.headers);
1187
+ console.error("Request Data:", config.data);
1188
+ console.error("Request Params:", config.params);
1189
+ }
1190
+ }
1191
+ if (error.response) {
1192
+ throw new Error(`API request failed: ${error.response.status} - ${JSON.stringify(error.response.data)}`);
1193
+ }
1194
+ throw error;
1195
+ }
1196
+ }
1197
+ };
1198
+ var SmartOneCloudAPIClient = class extends APIClientBase {
1199
+ constructor(authToken, tokenType, s1cUrl) {
1200
+ super(authToken, tokenType);
1201
+ this.s1cUrl = s1cUrl;
1202
+ }
1203
+ getHost() {
1204
+ return this.s1cUrl;
1205
+ }
1206
+ };
1207
+ var OnPremAPIClient = class extends APIClientBase {
1208
+ constructor(apiKey, managementHost, managementPort = "443", username, password) {
1209
+ super(apiKey || "");
1210
+ this.managementHost = managementHost;
1211
+ this.managementPort = managementPort;
1212
+ this.username = username;
1213
+ this.password = password;
1214
+ }
1215
+ getHost() {
1216
+ const managementHost = this.managementHost;
1217
+ const port = this.managementPort;
1218
+ return `https://${managementHost}:${port}/web_api`;
1219
+ }
1220
+ /**
1221
+ * Override login() to support both api-key and username/password authentication
1222
+ * and allow self-signed certificates
1223
+ */
1224
+ async login() {
1225
+ const isUsingApiKey = !!this.authToken;
1226
+ const isUsingCredentials = !!(this.username && this.password);
1227
+ if (!isUsingApiKey && !isUsingCredentials) {
1228
+ throw new ClientResponse(401, { message: "Authentication failed: No API key or username/password provided" });
1229
+ }
1230
+ const httpsAgent = new https.Agent({ rejectUnauthorized: false });
1231
+ const loginPayload = isUsingApiKey ? { "api-key": this.authToken } : { "user": this.username, "password": this.password };
1232
+ const loginResp = await this.makeRequest(this.getHost(), "POST", "login", loginPayload, { "Content-Type": "application/json" }, null, httpsAgent);
1233
+ if (loginResp.status !== 200 || !loginResp.response || !loginResp.response.sid) {
1234
+ throw loginResp;
1235
+ }
1236
+ this.sid = loginResp.response.sid;
1237
+ this.sessionTimeout = loginResp.response["session-timeout"] || null;
1238
+ this.sessionStart = Date.now();
1239
+ if (loginResp.response.uid) {
1240
+ await this.detectMDS(loginResp.response.uid, true);
1241
+ }
1242
+ return loginResp.response.sid;
1243
+ }
1244
+ };
1245
+
1246
+ // ../infra/dist/string-utils.js
1247
+ function nullOrEmpty(val) {
1248
+ return val === void 0 || val === null || typeof val === "string" && (val.trim() === "" || val === "undefined" || val === "null");
1249
+ }
1250
+ function sanitizeData(kwargs) {
1251
+ const data = {};
1252
+ for (const [key, value] of Object.entries(kwargs)) {
1253
+ if (value === null || value === void 0 || value === "" || Array.isArray(value) && value.length === 0) {
1254
+ continue;
1255
+ }
1256
+ const safeKey = key.replace(/_/g, "-");
1257
+ data[safeKey] = value;
1258
+ }
1259
+ return data;
1260
+ }
1261
+
1262
+ // ../mcp-utils/dist/launcher.js
1263
+ import { Command } from "commander";
1264
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
1265
+ import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
1266
+ import fs from "fs";
1267
+ import http from "http";
1268
+ import { randomUUID } from "crypto";
1269
+
1270
+ // ../mcp-utils/dist/settings-manager.js
1271
+ var SettingsManager = class _SettingsManager {
1272
+ /**
1273
+ * Creates a new SettingsManager
1274
+ * @param settingsClass The Settings class to use for creating settings instances
1275
+ */
1276
+ constructor(settingsClass) {
1277
+ this.settingsMap = /* @__PURE__ */ new Map();
1278
+ this.defaultSessionId = "default";
1279
+ this.settingsClass = settingsClass;
1280
+ }
1281
+ /**
1282
+ * Get settings for a specific session
1283
+ * @param sessionId The session ID (defaults to 'default' for stdio mode)
1284
+ * @returns Settings instance for the session
1285
+ */
1286
+ getSettings(sessionId) {
1287
+ const sid = sessionId || this.defaultSessionId;
1288
+ if (!this.settingsMap.has(sid)) {
1289
+ this.settingsMap.set(sid, new this.settingsClass());
1290
+ }
1291
+ return this.settingsMap.get(sid);
1292
+ }
1293
+ /**
1294
+ * Set settings for a specific session
1295
+ * @param settings The settings object to set
1296
+ * @param sessionId The session ID (defaults to 'default' for stdio mode)
1297
+ */
1298
+ setSettings(settings, sessionId) {
1299
+ const sid = sessionId || this.defaultSessionId;
1300
+ this.settingsMap.set(sid, settings);
1301
+ }
1302
+ /**
1303
+ * Injects debug settings from source into settings object
1304
+ * @param settings The settings object to update
1305
+ * @param source Source object containing debug information
1306
+ * @private
1307
+ */
1308
+ injectDebug(settings, source) {
1309
+ const debug = source?.debug ?? _SettingsManager.globalDebugState ?? process.env.DEBUG;
1310
+ if (typeof debug !== "undefined") {
1311
+ if (source?.debug !== void 0) {
1312
+ _SettingsManager.globalDebugState = source.debug;
1313
+ }
1314
+ if (typeof settings.set === "function") {
1315
+ settings.set("debug", debug);
1316
+ } else {
1317
+ settings.debug = debug;
1318
+ }
1319
+ if (debug) {
1320
+ console.error("Debug enabled. Source object contents:");
1321
+ console.error(JSON.stringify(source, null, 2));
1322
+ }
1323
+ }
1324
+ }
1325
+ /**
1326
+ * Print settings object for debugging by dynamically discovering its properties
1327
+ * @param settings The settings object to print
1328
+ * @private
1329
+ */
1330
+ printSettingsDebug(settings) {
1331
+ if (typeof settings.get === "function") {
1332
+ console.error("Settings (using get method):");
1333
+ if (settings.data && typeof settings.data === "object") {
1334
+ Object.entries(settings.data).forEach(([key, value]) => {
1335
+ console.error(` ${key}: ${JSON.stringify(value)}`);
1336
+ });
1337
+ } else {
1338
+ console.error(" Unable to enumerate settings properties - no accessible data structure");
1339
+ }
1340
+ } else {
1341
+ console.error("Settings (plain object):");
1342
+ Object.entries(settings).forEach(([key, value]) => {
1343
+ console.error(` ${key}: ${JSON.stringify(value)}`);
1344
+ });
1345
+ }
1346
+ }
1347
+ /**
1348
+ * Create settings from command-line arguments
1349
+ * @param args Command line arguments
1350
+ * @param sessionId Optional session ID
1351
+ * @returns Settings instance
1352
+ */
1353
+ createFromArgs(args, sessionId) {
1354
+ const settings = this.settingsClass.fromArgs(args);
1355
+ this.injectDebug(settings, args);
1356
+ this.setSettings(settings, sessionId);
1357
+ return settings;
1358
+ }
1359
+ /**
1360
+ * Create settings from HTTP headers
1361
+ * @param headers HTTP headers
1362
+ * @param sessionId Optional session ID
1363
+ * @returns Settings instance
1364
+ */
1365
+ createFromHeaders(headers, sessionId) {
1366
+ const verbose = _SettingsManager.globalDebugState;
1367
+ if (verbose) {
1368
+ console.error("[SettingsManager.createFromHeaders] Verbose: Starting with sessionId:", sessionId || "(default)");
1369
+ console.error("[SettingsManager.createFromHeaders] Verbose: Incoming headers count:", Object.keys(headers).length);
1370
+ }
1371
+ if (_SettingsManager.globalDebugState) {
1372
+ console.error("=== createFromHeaders Debug Info ===");
1373
+ console.error("Incoming headers:");
1374
+ console.error(JSON.stringify(headers, null, 2));
1375
+ }
1376
+ if (verbose && (!headers || Object.keys(headers).length === 0)) {
1377
+ console.error("[SettingsManager.createFromHeaders] Verbose: WARNING - Headers object is empty or undefined");
1378
+ }
1379
+ const normalizedHeaders = {};
1380
+ for (const [key, value] of Object.entries(headers)) {
1381
+ const normalizedKey = key.includes("_") ? key.replace(/_/g, "-") : key;
1382
+ normalizedHeaders[normalizedKey] = value;
1383
+ if (verbose) {
1384
+ console.error(`[SettingsManager.createFromHeaders] Verbose: Header normalized: "${key}" -> "${normalizedKey}"`);
1385
+ }
1386
+ }
1387
+ if (verbose) {
1388
+ console.error("[SettingsManager.createFromHeaders] Verbose: Normalized headers count:", Object.keys(normalizedHeaders).length);
1389
+ }
1390
+ if (_SettingsManager.globalDebugState) {
1391
+ console.error("Normalized headers:");
1392
+ console.error(JSON.stringify(normalizedHeaders, null, 2));
1393
+ }
1394
+ const debugHeader = normalizedHeaders["debug"] || normalizedHeaders["Debug"] || normalizedHeaders["DEBUG"];
1395
+ const debugSource = { debug: debugHeader !== void 0 ? debugHeader : _SettingsManager.globalDebugState };
1396
+ if (verbose) {
1397
+ console.error("[SettingsManager.createFromHeaders] Verbose: Calling settingsClass.fromHeaders");
1398
+ }
1399
+ const settings = this.settingsClass.fromHeaders(normalizedHeaders);
1400
+ if (verbose) {
1401
+ console.error("[SettingsManager.createFromHeaders] Verbose: Settings object created");
1402
+ }
1403
+ this.injectDebug(settings, debugSource);
1404
+ if (_SettingsManager.globalDebugState) {
1405
+ console.error("Final settings object for session:", sessionId || "(default)");
1406
+ this.printSettingsDebug(settings);
1407
+ console.error("=== End createFromHeaders Debug Info ===");
1408
+ }
1409
+ if (verbose) {
1410
+ console.error("[SettingsManager.createFromHeaders] Verbose: Storing settings for session:", sessionId || "(default)");
1411
+ }
1412
+ this.setSettings(settings, sessionId);
1413
+ return settings;
1414
+ }
1415
+ /**
1416
+ * Clear settings for a session
1417
+ * @param sessionId The session ID to clear
1418
+ */
1419
+ clearSession(sessionId) {
1420
+ if (sessionId !== this.defaultSessionId) {
1421
+ this.settingsMap.delete(sessionId);
1422
+ }
1423
+ }
1424
+ };
1425
+ SettingsManager.globalDebugState = void 0;
1426
+
1427
+ // ../mcp-utils/dist/launcher.js
1428
+ async function launchMCPServer(configPath, serverModule2) {
1429
+ const config = JSON.parse(fs.readFileSync(configPath, "utf8"));
1430
+ const program = new Command();
1431
+ if (config.description) {
1432
+ program.description(config.description);
1433
+ }
1434
+ config.options.forEach((option) => {
1435
+ const envValue = option.env ? process.env[option.env] : void 0;
1436
+ const defaultValue = envValue || option.default;
1437
+ if (option.type === "boolean") {
1438
+ const boolDefault = envValue === "true" || option.default === "true";
1439
+ program.option(option.flag, option.description, boolDefault);
1440
+ } else {
1441
+ program.option(option.flag, option.description, defaultValue);
1442
+ }
1443
+ });
1444
+ const transportTypeDefault = process.env.MCP_TRANSPORT_TYPE || "stdio";
1445
+ program.option("--transport <type>", "Transport type (stdio or http)", transportTypeDefault);
1446
+ const transportPortDefault = process.env.MCP_TRANSPORT_PORT || "3000";
1447
+ program.option("--transport-port <number>", "Port for network transports (e.g., HTTP)", transportPortDefault);
1448
+ const debugDefault = process.env.DEBUG === "true" || false;
1449
+ program.option("--debug", "Enable debug mode", debugDefault);
1450
+ const telemetryEnabledDefault = process.env.TELEMETRY_DISABLED === "true" ? false : true;
1451
+ program.option("--no-telemetry", "Disable anonymous usage telemetry", telemetryEnabledDefault);
1452
+ const telemetryUrlDefault = process.env.TELEMETRY_URL || "https://metrics.security.ai.checkpoint.com/api/v1/metrics/collect";
1453
+ program.option("--telemetry-url <url>", "URL for telemetry server", telemetryUrlDefault);
1454
+ program.parse(process.argv);
1455
+ const options = program.opts();
1456
+ if (options.telemetry === false) {
1457
+ process.env.TELEMETRY_DISABLED = "true";
1458
+ }
1459
+ if (options.telemetryUrl) {
1460
+ process.env.TELEMETRY_URL = options.telemetryUrl;
1461
+ }
1462
+ if (!serverModule2.settingsManager) {
1463
+ throw new Error("ServerModule must have a settingsManager. Create it with createServerModule.");
1464
+ }
1465
+ const settings = serverModule2.settingsManager.createFromArgs(options);
1466
+ if (typeof serverModule2.server.applyToolPolicy === "function") {
1467
+ console.error("[launchMCPServer] Applying tool policy before connecting");
1468
+ serverModule2.server.applyToolPolicy();
1469
+ }
1470
+ const transportType = (options.transport || process.env.MCP_TRANSPORT_TYPE || "stdio").toLowerCase() === "http" ? "http" : "stdio";
1471
+ const transportPort = options.transportPort ? parseInt(options.transportPort, 10) : process.env.MCP_TRANSPORT_PORT ? parseInt(process.env.MCP_TRANSPORT_PORT, 10) : 3e3;
1472
+ if (transportType === "http") {
1473
+ await launchHTTPServer(config, serverModule2, transportPort);
1474
+ } else {
1475
+ const transport = new StdioServerTransport();
1476
+ const defaultSessionId = "default";
1477
+ const sessionMetadata = {
1478
+ type: "stdio",
1479
+ startedAt: /* @__PURE__ */ new Date()
1480
+ };
1481
+ serverModule2.sessionManager.createSession(defaultSessionId, sessionMetadata);
1482
+ transport.extraContext = () => {
1483
+ return {
1484
+ sessionId: defaultSessionId,
1485
+ transport
1486
+ };
1487
+ };
1488
+ await serverModule2.server.connect(transport);
1489
+ console.error(`${config.name} running on stdio transport. Version: ${serverModule2.pkg.version}`);
1490
+ console.error(`Transport type: stdio`);
1491
+ }
1492
+ }
1493
+ async function launchHTTPServer(config, serverModule2, port) {
1494
+ const transports = {};
1495
+ const serverInstances = {};
1496
+ const server2 = http.createServer(async (req, res) => {
1497
+ if (req.url === "/" || req.url === "/mcp") {
1498
+ const sessionId = req.headers["mcp-session-id"];
1499
+ if (req.method === "POST") {
1500
+ const chunks = [];
1501
+ try {
1502
+ for await (const chunk of req) {
1503
+ chunks.push(Buffer.from(chunk));
1504
+ }
1505
+ const bodyBuffer = Buffer.concat(chunks);
1506
+ let body;
1507
+ try {
1508
+ const bodyText = bodyBuffer.toString("utf8");
1509
+ if (bodyText) {
1510
+ body = JSON.parse(bodyText);
1511
+ }
1512
+ } catch (err) {
1513
+ console.error("Error parsing request body:", err);
1514
+ }
1515
+ let transport;
1516
+ if (sessionId && transports[sessionId]) {
1517
+ const verbose = SettingsManager.globalDebugState;
1518
+ if (verbose) {
1519
+ console.error("[launchHTTPServer] Verbose: Reusing existing transport for session:", sessionId);
1520
+ }
1521
+ transport = transports[sessionId];
1522
+ if (!serverModule2.settingsManager) {
1523
+ throw new Error("ServerModule must have a settingsManager. Create it with createServerModule.");
1524
+ }
1525
+ if (verbose) {
1526
+ console.error("[launchHTTPServer] Verbose: Converting headers for existing session");
1527
+ }
1528
+ const envHeaders = headersToEnvVars(req.headers, config);
1529
+ if (verbose) {
1530
+ console.error("[launchHTTPServer] Verbose: Creating settings from headers for existing session");
1531
+ }
1532
+ serverModule2.settingsManager.createFromHeaders(envHeaders, sessionId);
1533
+ } else if (!sessionId && body && body.method === "initialize") {
1534
+ transport = new StreamableHTTPServerTransport({
1535
+ sessionIdGenerator: () => randomUUID(),
1536
+ onsessioninitialized: (sid) => {
1537
+ const verbose = SettingsManager.globalDebugState;
1538
+ if (verbose) {
1539
+ console.error("[launchHTTPServer] Verbose: New session initialized:", sid);
1540
+ }
1541
+ transports[sid] = transport;
1542
+ if (verbose) {
1543
+ console.error("[launchHTTPServer] Verbose: Converting headers for new session");
1544
+ console.error("[launchHTTPServer] Verbose: Raw request headers:", Object.keys(req.headers));
1545
+ }
1546
+ const headers = headersToEnvVars(req.headers, config);
1547
+ if (verbose) {
1548
+ console.error("[launchHTTPServer] Verbose: Converted headers count:", Object.keys(headers).length);
1549
+ }
1550
+ const metadata = {
1551
+ userAgent: req.headers["user-agent"],
1552
+ origin: req.headers.origin || req.headers.referer,
1553
+ remoteAddress: req.socket.remoteAddress,
1554
+ initialPath: req.url
1555
+ };
1556
+ if (verbose) {
1557
+ console.error("[launchHTTPServer] Verbose: Creating session in session manager");
1558
+ }
1559
+ serverModule2.sessionManager.createSession(sid, metadata);
1560
+ if (verbose) {
1561
+ console.error("[launchHTTPServer] Verbose: Creating settings from headers for new session");
1562
+ }
1563
+ serverModule2.settingsManager.createFromHeaders(headers, sid);
1564
+ if (verbose) {
1565
+ console.error("[launchHTTPServer] Verbose: Session initialization complete");
1566
+ }
1567
+ }
1568
+ });
1569
+ transport.onclose = () => {
1570
+ const sid = transport.sessionId;
1571
+ if (sid) {
1572
+ delete transports[sid];
1573
+ if (serverInstances[sid]) {
1574
+ delete serverInstances[sid];
1575
+ }
1576
+ serverModule2.settingsManager.clearSession(sid);
1577
+ serverModule2.apiManagerFactory.clearSession(sid);
1578
+ serverModule2.sessionManager.removeSession(sid);
1579
+ }
1580
+ };
1581
+ if (!serverModule2.settingsManager) {
1582
+ throw new Error("ServerModule must have a settingsManager. Create it with createServerModule.");
1583
+ }
1584
+ transport.extraContext = (msg) => {
1585
+ const sessionId2 = transport.sessionId;
1586
+ return {
1587
+ sessionId: sessionId2,
1588
+ transport
1589
+ };
1590
+ };
1591
+ let serverToConnect;
1592
+ if (serverModule2.createServerInstance) {
1593
+ const sessionServer = serverModule2.createServerInstance();
1594
+ serverToConnect = sessionServer;
1595
+ const originalOnSessionInit = transport.onsessioninitialized;
1596
+ transport.onsessioninitialized = (sid) => {
1597
+ serverInstances[sid] = sessionServer;
1598
+ if (originalOnSessionInit) {
1599
+ originalOnSessionInit(sid);
1600
+ }
1601
+ };
1602
+ } else {
1603
+ serverToConnect = serverModule2.server;
1604
+ console.error("Warning: Using shared server instance. Consider providing createServerInstance for better multi-user support.");
1605
+ }
1606
+ await serverToConnect.connect(transport).catch((error) => {
1607
+ console.error("Error connecting to HTTP transport:", error);
1608
+ });
1609
+ } else {
1610
+ res.writeHead(400, { "Content-Type": "application/json" });
1611
+ res.end(JSON.stringify({
1612
+ jsonrpc: "2.0",
1613
+ error: {
1614
+ code: -32e3,
1615
+ message: "Bad Request: No valid session ID provided"
1616
+ },
1617
+ id: null
1618
+ }));
1619
+ return;
1620
+ }
1621
+ await transport.handleRequest(req, res, body);
1622
+ } catch (error) {
1623
+ console.error("Error handling POST request:", error);
1624
+ res.writeHead(500, { "Content-Type": "application/json" });
1625
+ res.end(JSON.stringify({
1626
+ jsonrpc: "2.0",
1627
+ error: {
1628
+ code: -32e3,
1629
+ message: "Internal server error: " + error.message
1630
+ },
1631
+ id: null
1632
+ }));
1633
+ }
1634
+ } else if (req.method === "GET") {
1635
+ if (!sessionId || !transports[sessionId]) {
1636
+ res.writeHead(400, { "Content-Type": "text/plain" });
1637
+ res.end("Invalid or missing session ID");
1638
+ return;
1639
+ }
1640
+ const transport = transports[sessionId];
1641
+ await transport.handleRequest(req, res);
1642
+ } else if (req.method === "DELETE") {
1643
+ if (!sessionId || !transports[sessionId]) {
1644
+ res.writeHead(400, { "Content-Type": "text/plain" });
1645
+ res.end("Invalid or missing session ID");
1646
+ return;
1647
+ }
1648
+ const transport = transports[sessionId];
1649
+ await transport.handleRequest(req, res);
1650
+ } else {
1651
+ res.writeHead(405, { "Content-Type": "text/plain", "Allow": "GET, POST, DELETE" });
1652
+ res.end("Method not allowed");
1653
+ }
1654
+ } else if (req.url === "/health" || req.url === "/status") {
1655
+ res.writeHead(200, { "Content-Type": "application/json" });
1656
+ const sessionCount = serverModule2.sessionManager.getSessionCount();
1657
+ const sessions = serverModule2.sessionManager.getAllSessions().map((session) => ({
1658
+ id: session.sessionId,
1659
+ createdAt: session.createdAt,
1660
+ lastActive: session.lastActive
1661
+ // Don't include potentially sensitive metadata
1662
+ }));
1663
+ res.end(JSON.stringify({
1664
+ status: "ok",
1665
+ server: config.name,
1666
+ version: serverModule2.pkg.version,
1667
+ activeSessions: sessionCount,
1668
+ sessions
1669
+ }));
1670
+ } else {
1671
+ res.writeHead(404, { "Content-Type": "text/plain" });
1672
+ res.end("Not found");
1673
+ }
1674
+ });
1675
+ server2.listen(port, () => {
1676
+ console.error(`${config.name} running on HTTP transport at http://localhost:${port}. Version: ${serverModule2.pkg.version}`);
1677
+ console.error(`Transport type: HTTP, Transport-port: ${port}`);
1678
+ });
1679
+ server2.on("error", (err) => {
1680
+ console.error(`Server error: ${err.message}`);
1681
+ });
1682
+ }
1683
+ function headersToEnvVars(headers, config) {
1684
+ const verbose = SettingsManager.globalDebugState;
1685
+ if (verbose) {
1686
+ console.error("[headersToEnvVars] Verbose: Converting headers to env vars");
1687
+ console.error("[headersToEnvVars] Verbose: Input headers count:", Object.keys(headers).length);
1688
+ console.error("[headersToEnvVars] Verbose: Input header keys:", Object.keys(headers));
1689
+ if (!headers || Object.keys(headers).length === 0) {
1690
+ console.error("[headersToEnvVars] Verbose: WARNING - Headers object is empty");
1691
+ }
1692
+ }
1693
+ if (!headers || Object.keys(headers).length === 0) {
1694
+ return {};
1695
+ }
1696
+ const result = {};
1697
+ for (const [name, value] of Object.entries(headers)) {
1698
+ if (value !== void 0) {
1699
+ const envName = name.toUpperCase().replace(/-/g, "_");
1700
+ result[envName] = value;
1701
+ if (verbose) {
1702
+ console.error(`[headersToEnvVars] Verbose: Basic mapping: "${name}" -> "${envName}"`);
1703
+ }
1704
+ }
1705
+ }
1706
+ if (verbose) {
1707
+ console.error("[headersToEnvVars] Verbose: After basic mapping, result keys:", Object.keys(result));
1708
+ }
1709
+ if (config && config.options) {
1710
+ if (verbose) {
1711
+ console.error("[headersToEnvVars] Verbose: Config provided, building header-to-env mapping");
1712
+ }
1713
+ const headerToEnvMap = {};
1714
+ for (const option of config.options) {
1715
+ if (option.env) {
1716
+ const flagName = option.flag.split(" ")[0].replace(/^--?/, "").replace(/-/g, "_");
1717
+ headerToEnvMap[flagName.toLowerCase()] = option.env;
1718
+ if (verbose) {
1719
+ console.error(`[headersToEnvVars] Verbose: Mapping: "${flagName.toLowerCase()}" -> "${option.env}"`);
1720
+ }
1721
+ headerToEnvMap[option.env.toLowerCase()] = option.env;
1722
+ }
1723
+ }
1724
+ if (verbose) {
1725
+ console.error("[headersToEnvVars] Verbose: headerToEnvMap:", headerToEnvMap);
1726
+ }
1727
+ let mappedCount = 0;
1728
+ for (const [headerName, headerValue] of Object.entries(headers)) {
1729
+ if (headerValue !== void 0) {
1730
+ const normalizedHeaderName = headerName.toLowerCase().replace(/-/g, "_");
1731
+ const envVarName = headerToEnvMap[normalizedHeaderName];
1732
+ if (envVarName) {
1733
+ result[envVarName] = headerValue;
1734
+ mappedCount++;
1735
+ if (verbose) {
1736
+ console.error(`[headersToEnvVars] Verbose: Config mapping: "${headerName}" -> "${envVarName}"`);
1737
+ }
1738
+ }
1739
+ }
1740
+ }
1741
+ if (verbose) {
1742
+ console.error(`[headersToEnvVars] Verbose: Mapped ${mappedCount} headers using config`);
1743
+ }
1744
+ } else if (verbose) {
1745
+ console.error("[headersToEnvVars] Verbose: No config provided, skipping config-based mapping");
1746
+ }
1747
+ if (verbose) {
1748
+ console.error("[headersToEnvVars] Verbose: Final result keys:", Object.keys(result));
1749
+ console.error("[headersToEnvVars] Verbose: Final result (sanitized):", Object.fromEntries(Object.entries(result).map(([k, v]) => [k, k.toLowerCase().includes("key") || k.toLowerCase().includes("token") || k.toLowerCase().includes("password") ? "***" : v])));
1750
+ }
1751
+ return result;
1752
+ }
1753
+
1754
+ // ../mcp-utils/dist/api-manager-factory.js
1755
+ var APIManagerFactory = class {
1756
+ /**
1757
+ * Creates a new APIManagerFactory
1758
+ * @param apiManagerClass The API Manager class to use for creating instances
1759
+ * @param settingsManager The settings manager to get settings from
1760
+ */
1761
+ constructor(apiManagerClass, settingsManager) {
1762
+ this.apiManagerMap = /* @__PURE__ */ new Map();
1763
+ this.defaultSessionId = "default";
1764
+ this.apiManagerClass = apiManagerClass;
1765
+ this.settingsManager = settingsManager;
1766
+ }
1767
+ /**
1768
+ * Get or create an API manager for a specific session
1769
+ * @param sessionId The session ID (defaults to 'default' for stdio mode)
1770
+ * @returns API Manager instance for the session
1771
+ */
1772
+ getAPIManager(sessionId) {
1773
+ const verbose = SettingsManager.globalDebugState;
1774
+ const sid = sessionId || this.defaultSessionId;
1775
+ if (verbose) {
1776
+ console.error("[APIManagerFactory.getAPIManager] Verbose: Getting API manager for session:", sid);
1777
+ }
1778
+ if (!this.apiManagerMap.has(sid)) {
1779
+ if (verbose) {
1780
+ console.error("[APIManagerFactory.getAPIManager] Verbose: API manager not in cache, creating new one");
1781
+ }
1782
+ const settings2 = this.settingsManager.getSettings(sid);
1783
+ if (verbose) {
1784
+ console.error("[APIManagerFactory.getAPIManager] Verbose: Retrieved settings from settings manager");
1785
+ console.error("[APIManagerFactory.getAPIManager] Verbose: Creating API manager from settings");
1786
+ }
1787
+ const apiManager2 = this.createAPIManagerFromSettings(settings2);
1788
+ if (verbose) {
1789
+ console.error("[APIManagerFactory.getAPIManager] Verbose: API manager created successfully");
1790
+ }
1791
+ this.apiManagerMap.set(sid, apiManager2);
1792
+ } else if (verbose) {
1793
+ console.error("[APIManagerFactory.getAPIManager] Verbose: Using cached API manager");
1794
+ }
1795
+ const apiManager = this.apiManagerMap.get(sid);
1796
+ const settings = this.settingsManager.getSettings(sid);
1797
+ if (settings && typeof settings.debug !== "undefined") {
1798
+ apiManager.debug = !!settings.debug;
1799
+ }
1800
+ return apiManager;
1801
+ }
1802
+ /**
1803
+ * Create an API manager from settings
1804
+ * @param settings Settings instance
1805
+ * @returns API Manager instance
1806
+ */
1807
+ createAPIManagerFromSettings(settings) {
1808
+ const verbose = SettingsManager.globalDebugState;
1809
+ if (verbose) {
1810
+ console.error("[APIManagerFactory.createAPIManagerFromSettings] Verbose: Creating API manager from settings");
1811
+ console.error("[APIManagerFactory.createAPIManagerFromSettings] Verbose: Settings type:", typeof settings);
1812
+ console.error("[APIManagerFactory.createAPIManagerFromSettings] Verbose: Settings keys:", settings ? Object.keys(settings) : "null");
1813
+ }
1814
+ const apiManager = this.apiManagerClass.create(settings);
1815
+ if (verbose) {
1816
+ console.error("[APIManagerFactory.createAPIManagerFromSettings] Verbose: API manager created");
1817
+ }
1818
+ return apiManager;
1819
+ }
1820
+ /**
1821
+ * Clear API manager for a session
1822
+ * @param sessionId The session ID to clear
1823
+ */
1824
+ clearSession(sessionId) {
1825
+ if (sessionId !== this.defaultSessionId) {
1826
+ this.apiManagerMap.delete(sessionId);
1827
+ }
1828
+ }
1829
+ };
1830
+
1831
+ // ../mcp-utils/dist/session-context.js
1832
+ var _a;
1833
+ var SessionContext = class {
1834
+ /**
1835
+ * Start automatic cleanup timer
1836
+ */
1837
+ static startCleanupTimer() {
1838
+ if (this.cleanupTimer)
1839
+ return;
1840
+ this.cleanupTimer = setInterval(() => {
1841
+ this.cleanupExpiredSessions();
1842
+ }, this.CLEANUP_INTERVAL_MS);
1843
+ if (this.cleanupTimer.unref) {
1844
+ this.cleanupTimer.unref();
1845
+ }
1846
+ }
1847
+ /**
1848
+ * Clean up expired sessions
1849
+ */
1850
+ static cleanupExpiredSessions() {
1851
+ const now = Date.now();
1852
+ const expiredSessions = [];
1853
+ for (const [sessionId, sessionInfo] of this.sessionData.entries()) {
1854
+ if (sessionId === this.DEFAULT_SESSION_ID)
1855
+ continue;
1856
+ if (now - sessionInfo.lastAccessed > this.SESSION_TIMEOUT_MS) {
1857
+ expiredSessions.push(sessionId);
1858
+ }
1859
+ }
1860
+ expiredSessions.forEach((sessionId) => {
1861
+ this.sessionData.delete(sessionId);
1862
+ });
1863
+ if (this.sessionData.size > this.MAX_SESSIONS) {
1864
+ const sessions = Array.from(this.sessionData.entries()).filter(([sessionId]) => sessionId !== this.DEFAULT_SESSION_ID).sort(([, a], [, b]) => a.lastAccessed - b.lastAccessed);
1865
+ const toRemove = sessions.slice(0, sessions.length - this.MAX_SESSIONS + 1);
1866
+ toRemove.forEach(([sessionId]) => {
1867
+ this.sessionData.delete(sessionId);
1868
+ });
1869
+ }
1870
+ }
1871
+ /**
1872
+ * Get the current session ID from the MCP extra context
1873
+ * @param extra Extra context passed to MCP tool callbacks
1874
+ * @returns The session ID or DEFAULT_SESSION_ID if not available
1875
+ */
1876
+ static getSessionId(extra) {
1877
+ if (!extra)
1878
+ return this.DEFAULT_SESSION_ID;
1879
+ if (extra.transport && extra.transport.sessionId) {
1880
+ return extra.transport.sessionId;
1881
+ }
1882
+ if (extra.sessionId) {
1883
+ return extra.sessionId;
1884
+ }
1885
+ return this.DEFAULT_SESSION_ID;
1886
+ }
1887
+ /**
1888
+ * Get settings for the current session
1889
+ * @param serverModule ServerModule with settingsManager
1890
+ * @param extra Extra context passed to MCP tool callbacks
1891
+ * @returns Settings for the current session
1892
+ */
1893
+ static getSettings(serverModule2, extra) {
1894
+ const sessionId = this.getSessionId(extra);
1895
+ if (!serverModule2.settingsManager) {
1896
+ throw new Error("ServerModule does not have a settingsManager. Create it with createServerModule.");
1897
+ }
1898
+ return serverModule2.settingsManager.getSettings(sessionId);
1899
+ }
1900
+ /**
1901
+ * Get API manager for the current session
1902
+ * @param serverModule ServerModule with apiManagerFactory
1903
+ * @param extra Extra context passed to MCP tool callbacks
1904
+ * @returns API manager for the current session
1905
+ */
1906
+ static getAPIManager(serverModule2, extra) {
1907
+ const sessionId = this.getSessionId(extra);
1908
+ if (!serverModule2.apiManagerFactory) {
1909
+ throw new Error("ServerModule does not have an apiManagerFactory. Create it with createServerModule.");
1910
+ }
1911
+ return serverModule2.apiManagerFactory.getAPIManager(sessionId);
1912
+ }
1913
+ /**
1914
+ * Set session data for the current session
1915
+ * @param key The key to store the data under
1916
+ * @param value The value to store
1917
+ * @param extra Extra context with session information
1918
+ */
1919
+ static setData(key, value, extra) {
1920
+ const sessionId = this.getSessionId(extra);
1921
+ const now = Date.now();
1922
+ if (!this.sessionData.has(sessionId)) {
1923
+ this.sessionData.set(sessionId, {
1924
+ data: /* @__PURE__ */ new Map(),
1925
+ lastAccessed: now,
1926
+ createdAt: now
1927
+ });
1928
+ }
1929
+ const sessionInfo = this.sessionData.get(sessionId);
1930
+ sessionInfo.lastAccessed = now;
1931
+ sessionInfo.data.set(key, value);
1932
+ }
1933
+ /**
1934
+ * Get session data for the current session
1935
+ * @param key The key to retrieve data for
1936
+ * @param extra Extra context with session information
1937
+ * @returns The stored data or undefined if not found
1938
+ */
1939
+ static getData(key, extra) {
1940
+ const sessionId = this.getSessionId(extra);
1941
+ if (!this.sessionData.has(sessionId)) {
1942
+ return void 0;
1943
+ }
1944
+ const sessionInfo = this.sessionData.get(sessionId);
1945
+ sessionInfo.lastAccessed = Date.now();
1946
+ return sessionInfo.data.get(key);
1947
+ }
1948
+ /**
1949
+ * Clear session data for a specific session
1950
+ * @param sessionId The session ID to clear
1951
+ */
1952
+ static clearSessionData(sessionId) {
1953
+ this.sessionData.delete(sessionId);
1954
+ }
1955
+ /**
1956
+ * Get session statistics (for monitoring)
1957
+ */
1958
+ static getSessionStats() {
1959
+ const now = Date.now();
1960
+ let oldestAccess = null;
1961
+ for (const [, sessionInfo] of this.sessionData.entries()) {
1962
+ if (oldestAccess === null || sessionInfo.lastAccessed < oldestAccess) {
1963
+ oldestAccess = sessionInfo.lastAccessed;
1964
+ }
1965
+ }
1966
+ return {
1967
+ totalSessions: this.sessionData.size,
1968
+ memoryUsage: this.sessionData.size * 1e3,
1969
+ // Rough estimate
1970
+ oldestSession: oldestAccess ? now - oldestAccess : null
1971
+ };
1972
+ }
1973
+ /**
1974
+ * Get or prompt for user interactive data with automatic caching and expiration
1975
+ * @param options Configuration for the interactive data request
1976
+ * @param extra Extra context with session information
1977
+ * @returns Promise that resolves to the user data (either from cache or fresh prompt)
1978
+ */
1979
+ static async getOrPromptUserData(options, extra) {
1980
+ const sessionId = this.getSessionId(extra);
1981
+ const now = Date.now();
1982
+ const expirationMs = (options.expirationMinutes || 30) * 60 * 1e3;
1983
+ const cachedData = this.getData(options.cacheKey, extra);
1984
+ if (cachedData && cachedData.expiresAt && now < cachedData.expiresAt) {
1985
+ const refreshedData = {
1986
+ ...cachedData,
1987
+ expiresAt: now + expirationMs,
1988
+ lastUsed: now
1989
+ };
1990
+ this.setData(options.cacheKey, refreshedData, extra);
1991
+ let dataToReturn2 = cachedData.data;
1992
+ if (options.fieldsToShow) {
1993
+ dataToReturn2 = {};
1994
+ for (const field of options.fieldsToShow) {
1995
+ if (cachedData.data[field] !== void 0) {
1996
+ dataToReturn2[field] = cachedData.data[field];
1997
+ }
1998
+ }
1999
+ }
2000
+ console.error(`Using cached user data for session: ${sessionId}, key: ${options.cacheKey}`);
2001
+ return { cancelled: false, data: dataToReturn2 };
2002
+ }
2003
+ console.error(`Prompting user for data for session: ${sessionId}, key: ${options.cacheKey}`);
2004
+ let result;
2005
+ if (options.showLoginDialog) {
2006
+ const { showLoginDialog: showLoginDialog2 } = await Promise.resolve().then(() => (init_ui_dialog(), ui_dialog_exports));
2007
+ result = await showLoginDialog2(options.dialogTitle, options.dialogMessage);
2008
+ } else {
2009
+ const { showDialog: showDialog2 } = await Promise.resolve().then(() => (init_ui_dialog(), ui_dialog_exports));
2010
+ const defaultFields = [
2011
+ {
2012
+ name: "message",
2013
+ label: "Message",
2014
+ type: "text",
2015
+ placeholder: "Enter your message here...",
2016
+ required: true
2017
+ }
2018
+ ];
2019
+ result = await showDialog2({
2020
+ title: options.dialogTitle || "Input Required",
2021
+ message: options.dialogMessage,
2022
+ fields: options.customFields || defaultFields
2023
+ });
2024
+ }
2025
+ if (result.cancelled) {
2026
+ return result;
2027
+ }
2028
+ const cachedEntry = {
2029
+ data: result.data,
2030
+ expiresAt: now + expirationMs,
2031
+ createdAt: now,
2032
+ lastUsed: now
2033
+ };
2034
+ this.setData(options.cacheKey, cachedEntry, extra);
2035
+ let dataToReturn = result.data;
2036
+ if (options.fieldsToShow) {
2037
+ dataToReturn = {};
2038
+ for (const field of options.fieldsToShow) {
2039
+ if (result.data[field] !== void 0) {
2040
+ dataToReturn[field] = result.data[field];
2041
+ }
2042
+ }
2043
+ }
2044
+ return { cancelled: false, data: dataToReturn };
2045
+ }
2046
+ /**
2047
+ * Clear cached user data for a specific key
2048
+ * @param cacheKey The cache key to clear
2049
+ * @param extra Extra context with session information
2050
+ */
2051
+ static clearUserData(cacheKey, extra) {
2052
+ const sessionId = this.getSessionId(extra);
2053
+ if (this.sessionData.has(sessionId)) {
2054
+ const sessionInfo = this.sessionData.get(sessionId);
2055
+ sessionInfo.data.delete(cacheKey);
2056
+ sessionInfo.lastAccessed = Date.now();
2057
+ }
2058
+ }
2059
+ /**
2060
+ * Check if user data exists and is not expired
2061
+ * @param cacheKey The cache key to check
2062
+ * @param extra Extra context with session information
2063
+ * @returns true if valid cached data exists, false otherwise
2064
+ */
2065
+ static hasValidUserData(cacheKey, extra) {
2066
+ const cachedData = this.getData(cacheKey, extra);
2067
+ if (!cachedData || !cachedData.expiresAt) {
2068
+ return false;
2069
+ }
2070
+ return Date.now() < cachedData.expiresAt;
2071
+ }
2072
+ };
2073
+ _a = SessionContext;
2074
+ SessionContext.DEFAULT_SESSION_ID = "default";
2075
+ SessionContext.sessionData = /* @__PURE__ */ new Map();
2076
+ SessionContext.SESSION_TIMEOUT_MS = 24 * 60 * 60 * 1e3;
2077
+ SessionContext.CLEANUP_INTERVAL_MS = 60 * 60 * 1e3;
2078
+ SessionContext.MAX_SESSIONS = 1e3;
2079
+ SessionContext.cleanupTimer = null;
2080
+ (() => {
2081
+ _a.startCleanupTimer();
2082
+ })();
2083
+
2084
+ // ../mcp-utils/dist/session-manager.js
2085
+ var DEFAULT_SESSION_TIMEOUT_MS = 15 * 60 * 1e3;
2086
+ var SessionManager = class {
2087
+ constructor() {
2088
+ this.sessions = /* @__PURE__ */ new Map();
2089
+ }
2090
+ /**
2091
+ * Create a new session
2092
+ * @param sessionId The session ID
2093
+ * @param metadata Optional metadata to store with the session
2094
+ * @returns Session info
2095
+ */
2096
+ createSession(sessionId, metadata = {}) {
2097
+ const now = /* @__PURE__ */ new Date();
2098
+ const sessionInfo = {
2099
+ sessionId,
2100
+ createdAt: now,
2101
+ lastActive: now,
2102
+ ...metadata
2103
+ };
2104
+ this.sessions.set(sessionId, sessionInfo);
2105
+ return sessionInfo;
2106
+ }
2107
+ /**
2108
+ * Get info for a session
2109
+ * @param sessionId The session ID
2110
+ * @returns Session info or undefined if not found
2111
+ */
2112
+ getSession(sessionId) {
2113
+ if (this.sessions.has(sessionId)) {
2114
+ this.touchSession(sessionId);
2115
+ }
2116
+ return this.sessions.get(sessionId);
2117
+ }
2118
+ /**
2119
+ * Update session activity timestamp
2120
+ * @param sessionId The session ID
2121
+ */
2122
+ touchSession(sessionId) {
2123
+ const session = this.sessions.get(sessionId);
2124
+ if (session) {
2125
+ session.lastActive = /* @__PURE__ */ new Date();
2126
+ }
2127
+ }
2128
+ /**
2129
+ * Remove a session
2130
+ * @param sessionId The session ID
2131
+ */
2132
+ removeSession(sessionId) {
2133
+ this.sessions.delete(sessionId);
2134
+ SessionContext.clearSessionData(sessionId);
2135
+ }
2136
+ /**
2137
+ * Get all active sessions
2138
+ * @returns Array of session info objects
2139
+ */
2140
+ getAllSessions() {
2141
+ return Array.from(this.sessions.values());
2142
+ }
2143
+ /**
2144
+ * Get count of active sessions
2145
+ * @returns Number of active sessions
2146
+ */
2147
+ getSessionCount() {
2148
+ return this.sessions.size;
2149
+ }
2150
+ /**
2151
+ * Clean up inactive sessions older than the specified timeout
2152
+ * @param timeoutMs Timeout in milliseconds (default: 30 minutes)
2153
+ * @returns Number of sessions removed
2154
+ */
2155
+ cleanupInactiveSessions(timeoutMs = DEFAULT_SESSION_TIMEOUT_MS) {
2156
+ const now = /* @__PURE__ */ new Date();
2157
+ let removedCount = 0;
2158
+ for (const [sessionId, session] of this.sessions.entries()) {
2159
+ const inactiveTime = now.getTime() - session.lastActive.getTime();
2160
+ if (inactiveTime > timeoutMs) {
2161
+ this.removeSession(sessionId);
2162
+ removedCount++;
2163
+ }
2164
+ }
2165
+ return removedCount;
2166
+ }
2167
+ };
2168
+
2169
+ // ../mcp-utils/dist/server-utils.js
2170
+ function getHeaderValue(headers, key) {
2171
+ const normalizedKey = key.replace(/_/g, "-");
2172
+ const value = headers[normalizedKey] || headers[normalizedKey.toUpperCase()] || headers[normalizedKey.toLowerCase()];
2173
+ return typeof value === "string" ? value : Array.isArray(value) ? value[0] : void 0;
2174
+ }
2175
+ function createApiRunner(serverModule2) {
2176
+ return async (method, uri, data, extra, domain) => {
2177
+ const apiManager = SessionContext.getAPIManager(serverModule2, extra);
2178
+ return await apiManager.callApi(method, uri, data, domain);
2179
+ };
2180
+ }
2181
+ function wrapServerWithTracking(server2, createServerFn) {
2182
+ const registrations = [];
2183
+ const originalTool = server2.tool?.bind(server2);
2184
+ const originalPrompt = server2.prompt?.bind(server2);
2185
+ const originalResource = server2.resource?.bind(server2);
2186
+ if (originalTool) {
2187
+ server2.tool = function(...args) {
2188
+ registrations.push({ type: "tool", method: "tool", args: [...args] });
2189
+ return originalTool(...args);
2190
+ };
2191
+ }
2192
+ if (originalPrompt) {
2193
+ server2.prompt = function(...args) {
2194
+ registrations.push({ type: "prompt", method: "prompt", args: [...args] });
2195
+ return originalPrompt(...args);
2196
+ };
2197
+ }
2198
+ if (originalResource) {
2199
+ server2.resource = function(...args) {
2200
+ registrations.push({ type: "resource", method: "resource", args: [...args] });
2201
+ return originalResource(...args);
2202
+ };
2203
+ }
2204
+ const createInstance = () => {
2205
+ const newServer = createServerFn();
2206
+ for (const reg of registrations) {
2207
+ if (newServer[reg.method]) {
2208
+ newServer[reg.method](...reg.args);
2209
+ }
2210
+ }
2211
+ if (typeof server2.setToolPolicy === "function" && typeof newServer.setToolPolicy === "function") {
2212
+ const toolPolicy = server2._toolPolicyCallback;
2213
+ if (toolPolicy) {
2214
+ newServer.setToolPolicy(toolPolicy);
2215
+ }
2216
+ }
2217
+ return newServer;
2218
+ };
2219
+ return { wrappedServer: server2, createInstance };
2220
+ }
2221
+ function createServerModule(server2, Settings2, pkg2, apiManagerClass, toolPolicyCallback, createServerFn) {
2222
+ const settingsManager = new SettingsManager(Settings2);
2223
+ const apiManagerFactory = new APIManagerFactory(apiManagerClass, settingsManager);
2224
+ const sessionManager = new SessionManager();
2225
+ if (toolPolicyCallback && typeof server2.setToolPolicy === "function") {
2226
+ console.error("[createServerModule] Setting tool policy callback on server");
2227
+ server2.setToolPolicy(toolPolicyCallback);
2228
+ }
2229
+ const serverFactory = createServerFn || server2._createServerFn;
2230
+ let createServerInstance;
2231
+ if (serverFactory) {
2232
+ const { wrappedServer, createInstance } = wrapServerWithTracking(server2, serverFactory);
2233
+ createServerInstance = createInstance;
2234
+ console.error("[createServerModule] Server factory enabled - HTTP multi-user support active");
2235
+ } else {
2236
+ console.error("[createServerModule] Warning: No server factory provided - HTTP multi-user may have issues");
2237
+ }
2238
+ return {
2239
+ server: server2,
2240
+ Settings: Settings2,
2241
+ settingsManager,
2242
+ apiManagerFactory,
2243
+ sessionManager,
2244
+ pkg: pkg2,
2245
+ toolPolicyCallback,
2246
+ createServerInstance
2247
+ };
2248
+ }
2249
+
2250
+ // ../mcp-utils/dist/index.js
2251
+ init_ui_dialog();
2252
+
2253
+ // ../mcp-utils/dist/telemetry.js
2254
+ import machineIdPkg from "node-machine-id";
2255
+ import { createHash } from "crypto";
2256
+ var { machineIdSync } = machineIdPkg;
2257
+ var machineId = null;
2258
+ var hashedMachineId = null;
2259
+ function isTelemetryDisabled() {
2260
+ return process.env.TELEMETRY_DISABLED === "true" || process.env.TELEMETRY_DISABLED === "1";
2261
+ }
2262
+ function getTelemetryUrl() {
2263
+ return process.env.TELEMETRY_URL || "https://metrics.security.ai.checkpoint.com/api/v1/metrics/collect";
2264
+ }
2265
+ function hashString(input) {
2266
+ return createHash("sha256").update(input).digest("hex");
2267
+ }
2268
+ function getMachineId() {
2269
+ if (!machineId) {
2270
+ try {
2271
+ machineId = machineIdSync();
2272
+ } catch (error) {
2273
+ console.warn("Failed to get machine ID for telemetry:", error);
2274
+ machineId = "unknown";
2275
+ }
2276
+ }
2277
+ return machineId;
2278
+ }
2279
+ function getHashedMachineId() {
2280
+ if (!hashedMachineId) {
2281
+ hashedMachineId = hashString(getMachineId());
2282
+ }
2283
+ return hashedMachineId;
2284
+ }
2285
+ function calculateChecksum(mcpName, toolName, machineId2, clientVersion) {
2286
+ const data = mcpName + machineId2.slice(0, 16) + toolName + clientVersion;
2287
+ return hashString(data);
2288
+ }
2289
+ async function trackToolCall(mcpName, toolName, clientVersion, extra) {
2290
+ if (isTelemetryDisabled()) {
2291
+ return;
2292
+ }
2293
+ try {
2294
+ const machineId2 = getHashedMachineId();
2295
+ const checksum = calculateChecksum(mcpName, toolName, machineId2, clientVersion);
2296
+ fetch(getTelemetryUrl(), {
2297
+ method: "POST",
2298
+ headers: { "Content-Type": "application/json" },
2299
+ body: JSON.stringify({
2300
+ mcp_name: mcpName,
2301
+ tool_name: toolName,
2302
+ machine_id: machineId2,
2303
+ client_version: clientVersion,
2304
+ checksum
2305
+ })
2306
+ }).catch(() => {
2307
+ });
2308
+ } catch (error) {
2309
+ }
2310
+ }
2311
+
2312
+ // ../mcp-utils/dist/mcp-server.js
2313
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2314
+ var CPMcpServer = class extends McpServer {
2315
+ constructor(serverInfo, options) {
2316
+ super(serverInfo, options);
2317
+ this.mcpName = serverInfo.name;
2318
+ this.mcpVersion = serverInfo.version || "0.0.0";
2319
+ }
2320
+ /**
2321
+ * Set a tool policy callback to filter which tools are available
2322
+ * This should be called after all tools are registered but before connecting
2323
+ * @param callback Function that returns true if a tool should be enabled
2324
+ */
2325
+ setToolPolicy(callback) {
2326
+ console.error("[CPMcpServer] Setting tool policy callback");
2327
+ this.toolPolicyCallback = callback;
2328
+ }
2329
+ /**
2330
+ * Apply the tool policy by checking all registered tools
2331
+ * This should be called after all tools are registered but before connecting
2332
+ */
2333
+ applyToolPolicy() {
2334
+ if (!this.toolPolicyCallback) {
2335
+ console.error("[CPMcpServer] No tool policy callback set, allowing all tools");
2336
+ return;
2337
+ }
2338
+ console.error("[CPMcpServer] Applying tool policy");
2339
+ const registeredTools = this._registeredTools;
2340
+ if (!registeredTools || typeof registeredTools !== "object") {
2341
+ console.error("[CPMcpServer] No tools registered yet");
2342
+ return;
2343
+ }
2344
+ const toolNames = Object.keys(registeredTools);
2345
+ console.error(`[CPMcpServer] Found ${toolNames.length} registered tools:`, toolNames);
2346
+ let enabledCount = 0;
2347
+ let disabledCount = 0;
2348
+ for (const [toolName, tool] of Object.entries(registeredTools)) {
2349
+ const isAllowed = this.toolPolicyCallback(toolName);
2350
+ if (!isAllowed) {
2351
+ console.error(`[CPMcpServer] Tool '${toolName}' is NOT allowed by policy - disabling`);
2352
+ if (typeof tool.disable === "function") {
2353
+ tool.disable();
2354
+ disabledCount++;
2355
+ }
2356
+ } else {
2357
+ console.error(`[CPMcpServer] Tool '${toolName}' is allowed by policy`);
2358
+ enabledCount++;
2359
+ }
2360
+ }
2361
+ console.error(`[CPMcpServer] Policy applied: ${enabledCount}/${toolNames.length} tools enabled, ${disabledCount} disabled`);
2362
+ }
2363
+ // Override the tool method to wrap callbacks with telemetry
2364
+ tool(...args) {
2365
+ const callback = args[args.length - 1];
2366
+ if (typeof callback === "function") {
2367
+ const toolName = args[0];
2368
+ const wrappedCallback = async (...callbackArgs) => {
2369
+ let extra = callbackArgs[1];
2370
+ if (!extra && callbackArgs[0]?.sessionId) {
2371
+ extra = callbackArgs[0];
2372
+ }
2373
+ trackToolCall(this.mcpName, toolName, this.mcpVersion, extra).catch(() => {
2374
+ });
2375
+ if (callbackArgs.length === 1 && callbackArgs[0]?.sessionId) {
2376
+ return callback({}, callbackArgs[0]);
2377
+ }
2378
+ return callback(...callbackArgs);
2379
+ };
2380
+ args[args.length - 1] = wrappedCallback;
2381
+ }
2382
+ return super.tool(...args);
2383
+ }
2384
+ };
2385
+
2386
+ // ../mcp-utils/dist/package-utils.js
2387
+ import { readFileSync } from "fs";
2388
+ import { join as join2, dirname } from "path";
2389
+ import { fileURLToPath } from "url";
2390
+ function readPackageJson(importMetaUrl) {
2391
+ const pkg2 = JSON.parse(readFileSync(join2(dirname(fileURLToPath(importMetaUrl)), "../package.json"), "utf-8"));
2392
+ process.env.CP_MCP_MAIN_PKG = `${pkg2.name} v${pkg2.version}`;
2393
+ return pkg2;
2394
+ }
2395
+ function createMcpServer(importMetaUrl, serverInfo, options) {
2396
+ const pkg2 = readPackageJson(importMetaUrl);
2397
+ const fullServerInfo = {
2398
+ ...serverInfo,
2399
+ name: serverInfo.name || pkg2.name,
2400
+ version: serverInfo.version || pkg2.version
2401
+ };
2402
+ const createServerFn = () => {
2403
+ return new CPMcpServer(fullServerInfo, options);
2404
+ };
2405
+ const server2 = new CPMcpServer(fullServerInfo, options);
2406
+ server2._createServerFn = createServerFn;
2407
+ return { server: server2, pkg: pkg2 };
2408
+ }
2409
+
2410
+ // ../infra/dist/api-manager.js
2411
+ var APIManagerBase = class {
2412
+ constructor(client) {
2413
+ this.client = client;
2414
+ this.requestInfo = null;
2415
+ this.detailsLevel = "full";
2416
+ this._debug = false;
2417
+ this.domainClients = /* @__PURE__ */ new Map();
2418
+ this.gatewayDomainMap = /* @__PURE__ */ new Map();
2419
+ this.domains = null;
2420
+ }
2421
+ /**
2422
+ * Set debug mode for the API client
2423
+ */
2424
+ set debug(value) {
2425
+ this._debug = value;
2426
+ if (this.client) {
2427
+ if ("debug" in this.client) {
2428
+ this.client.debug = value;
2429
+ }
2430
+ }
2431
+ }
2432
+ /**
2433
+ * Get debug mode
2434
+ */
2435
+ get debug() {
2436
+ return this._debug;
2437
+ }
2438
+ /**
2439
+ * Call an API endpoint
2440
+ */
2441
+ async callApi(method, uri, data, domain) {
2442
+ const sanitizedData = sanitizeData(data);
2443
+ const apiClient = domain ? await this.getDomainApiClientByDomain(domain) : this.client;
2444
+ const clientResponse = await apiClient.callApi(method, uri, sanitizedData, void 0);
2445
+ return clientResponse.response;
2446
+ }
2447
+ /**
2448
+ * Get the result of a management API task (similar to getTaskResult but for management tasks)
2449
+ */
2450
+ async getManagementTaskResult(taskId, domain, maxRetries = 5) {
2451
+ let retries = 0;
2452
+ const timeouts = [500, 500, 1e3, 2e3, 5e3];
2453
+ while (retries < maxRetries) {
2454
+ const taskParams2 = { "task-id": taskId };
2455
+ const taskResp2 = await this.callApi("POST", "show-task", taskParams2, domain);
2456
+ const tasks = taskResp2?.tasks || [];
2457
+ if (tasks.length > 0) {
2458
+ const taskStatus = tasks[0].status;
2459
+ if (taskStatus === "succeeded" || taskStatus === "failed") {
2460
+ return { response: taskResp2 };
2461
+ }
2462
+ }
2463
+ const timeout = timeouts[Math.min(retries, timeouts.length - 1)];
2464
+ await new Promise((resolve) => setTimeout(resolve, timeout));
2465
+ retries++;
2466
+ }
2467
+ const taskParams = { "task-id": taskId };
2468
+ const taskResp = await this.callApi("POST", "show-task", taskParams, domain);
2469
+ return { response: taskResp };
2470
+ }
2471
+ /**
2472
+ * Check if the current environment is MDS
2473
+ */
2474
+ async isMds() {
2475
+ return await this.client.isMDSEnvironment();
2476
+ }
2477
+ /**
2478
+ * Get domains from show-domains API with full details including server information
2479
+ */
2480
+ async getDomains() {
2481
+ if (this.domains !== null) {
2482
+ return this.domains;
2483
+ }
2484
+ const response = await this.callApi("post", "show-domains", {
2485
+ "details-level": "full"
2486
+ });
2487
+ const domains = [];
2488
+ if (response.objects) {
2489
+ for (const obj of response.objects) {
2490
+ if (obj.name && obj.type) {
2491
+ domains.push({
2492
+ name: obj.name,
2493
+ type: obj.type,
2494
+ servers: obj.servers || []
2495
+ });
2496
+ }
2497
+ }
2498
+ }
2499
+ this.domains = domains;
2500
+ return domains;
2501
+ }
2502
+ /**
2503
+ * Create an API manager instance
2504
+ */
2505
+ static create(args) {
2506
+ throw new Error("Method must be implemented by subclass");
2507
+ }
2508
+ /**
2509
+ * Get the appropriate API client for a specific gateway, handling MDS domain routing
2510
+ */
2511
+ async getDomainApiClient(gatewayName) {
2512
+ const isMDS = await this.client.isMDSEnvironment();
2513
+ if (!isMDS) {
2514
+ return this.client;
2515
+ }
2516
+ const existingDomain = this.gatewayDomainMap.get(gatewayName);
2517
+ if (existingDomain) {
2518
+ const existingClient = this.domainClients.get(existingDomain);
2519
+ if (existingClient && existingClient.hasValidSession()) {
2520
+ return existingClient;
2521
+ }
2522
+ }
2523
+ const gatewayInfo = await this.getGatewayInfo(gatewayName);
2524
+ if (!gatewayInfo) {
2525
+ throw new Error(`Gateway '${gatewayName}' not found`);
2526
+ }
2527
+ const gatewayDomain = gatewayInfo.domain;
2528
+ if (!gatewayDomain) {
2529
+ return this.client;
2530
+ }
2531
+ const gatewayDomainName = gatewayDomain.name;
2532
+ const existingDomainClient = this.domainClients.get(gatewayDomainName);
2533
+ if (existingDomainClient && existingDomainClient.hasValidSession()) {
2534
+ this.gatewayDomainMap.set(gatewayName, gatewayDomainName);
2535
+ return existingDomainClient;
2536
+ }
2537
+ const domainSid = await this.loginToDomain(gatewayDomainName);
2538
+ const domainClient = this.createClientWithSid(domainSid);
2539
+ this.domainClients.set(gatewayDomainName, domainClient);
2540
+ this.gatewayDomainMap.set(gatewayName, gatewayDomainName);
2541
+ return domainClient;
2542
+ }
2543
+ /**
2544
+ * Get the appropriate API client for a specific domain, handling MDS domain routing
2545
+ * This method handles multi-MDS environments where domains may be distributed across
2546
+ * different MDS servers with active/standby configurations.
2547
+ */
2548
+ async getDomainApiClientByDomain(domainName) {
2549
+ const isMDS = await this.client.isMDSEnvironment();
2550
+ if (!isMDS) {
2551
+ return this.client;
2552
+ }
2553
+ const existingDomainClient = this.domainClients.get(domainName);
2554
+ if (existingDomainClient && existingDomainClient.hasValidSession()) {
2555
+ return existingDomainClient;
2556
+ }
2557
+ const isOnCurrentMDS = await this.isDomainOnCurrentMDS(domainName);
2558
+ if (isOnCurrentMDS) {
2559
+ const domainSid2 = await this.loginToDomain(domainName);
2560
+ const domainClient2 = this.createClientWithSid(domainSid2);
2561
+ this.domainClients.set(domainName, domainClient2);
2562
+ return domainClient2;
2563
+ }
2564
+ const targetMDSIP = await this.getMDSServerForDomain(domainName);
2565
+ if (!targetMDSIP) {
2566
+ throw new Error(`Domain '${domainName}' not found or has no available MDS servers. Make sure the domain exists and you have access to it.`);
2567
+ }
2568
+ const currentHost = this.client.getHost();
2569
+ const portMatch = currentHost.match(/:(\d+)/);
2570
+ const port = portMatch ? portMatch[1] : "443";
2571
+ const newMDSClient = this.createClientForMDS(targetMDSIP, port);
2572
+ if ("debug" in newMDSClient) {
2573
+ newMDSClient.debug = this._debug;
2574
+ }
2575
+ await newMDSClient.login();
2576
+ const loginResponse = await newMDSClient.callApi("post", "login-to-domain", {
2577
+ "domain": domainName
2578
+ }, void 0);
2579
+ if (!loginResponse.response.sid) {
2580
+ throw new Error(`Failed to login to domain '${domainName}' on MDS server ${targetMDSIP}`);
2581
+ }
2582
+ const domainSid = loginResponse.response.sid;
2583
+ const domainClient = this.createClientWithSid(domainSid);
2584
+ this.domainClients.set(domainName, domainClient);
2585
+ return domainClient;
2586
+ }
2587
+ /**
2588
+ * Get gateway information from show-gateways-and-servers
2589
+ */
2590
+ async getGatewayInfo(gatewayName) {
2591
+ const response = await this.callApi("post", "show-gateways-and-servers", {
2592
+ "details-level": "full"
2593
+ });
2594
+ if (response.objects) {
2595
+ return response.objects.find((obj) => obj.name === gatewayName);
2596
+ }
2597
+ return null;
2598
+ }
2599
+ /**
2600
+ * Login to a specific domain using the main API client
2601
+ */
2602
+ async loginToDomain(domainName) {
2603
+ const response = await this.callApi("post", "login-to-domain", {
2604
+ "domain": domainName
2605
+ });
2606
+ if (!response.sid) {
2607
+ throw new Error(`Failed to login to domain '${domainName}'`);
2608
+ }
2609
+ return response.sid;
2610
+ }
2611
+ /**
2612
+ * Create a new API client instance with the given session ID
2613
+ */
2614
+ createClientWithSid(sid) {
2615
+ if (this.client instanceof OnPremAPIClient) {
2616
+ return APIClientBase.createWithSid.call(OnPremAPIClient, this.client, sid);
2617
+ } else if (this.client instanceof SmartOneCloudAPIClient) {
2618
+ return APIClientBase.createWithSid.call(SmartOneCloudAPIClient, this.client, sid);
2619
+ } else {
2620
+ throw new Error("Unknown client type");
2621
+ }
2622
+ }
2623
+ /**
2624
+ * Check if a domain exists on the current MDS server (either active or standby)
2625
+ */
2626
+ async isDomainOnCurrentMDS(domainName) {
2627
+ const domains = await this.getDomains();
2628
+ const domain = domains.find((d) => d.name === domainName);
2629
+ if (!domain?.servers || domain.servers.length === 0) {
2630
+ return false;
2631
+ }
2632
+ const currentHost = this.client.getHost();
2633
+ return domain.servers.some((server2) => {
2634
+ const ipv4 = server2["ipv4-address"];
2635
+ const ipv6 = server2["ipv6-address"];
2636
+ return ipv4 && currentHost.includes(ipv4) || ipv6 && currentHost.includes(ipv6);
2637
+ });
2638
+ }
2639
+ /**
2640
+ * Get the appropriate MDS server IP for a domain
2641
+ * Prefers the active server, but returns any available server
2642
+ * Returns IPv4 if available, otherwise IPv6
2643
+ */
2644
+ async getMDSServerForDomain(domainName) {
2645
+ const domains = await this.getDomains();
2646
+ const domain = domains.find((d) => d.name === domainName);
2647
+ if (!domain?.servers || domain.servers.length === 0) {
2648
+ return null;
2649
+ }
2650
+ const activeServer = domain.servers.find((s) => s.active === true);
2651
+ if (activeServer) {
2652
+ if (activeServer["ipv4-address"]) {
2653
+ return activeServer["ipv4-address"];
2654
+ }
2655
+ if (activeServer["ipv6-address"]) {
2656
+ return activeServer["ipv6-address"];
2657
+ }
2658
+ }
2659
+ const ipv4Server = domain.servers.find((s) => s["ipv4-address"]);
2660
+ if (ipv4Server?.["ipv4-address"]) {
2661
+ return ipv4Server["ipv4-address"];
2662
+ }
2663
+ const ipv6Server = domain.servers.find((s) => s["ipv6-address"]);
2664
+ return ipv6Server?.["ipv6-address"] || null;
2665
+ }
2666
+ /**
2667
+ * Create a new API client for a different MDS server
2668
+ * Handles both IPv4 and IPv6 addresses
2669
+ * Only supports OnPremAPIClient for multi-MDS scenarios
2670
+ */
2671
+ createClientForMDS(mdsIP, port = "443") {
2672
+ if (this.client instanceof OnPremAPIClient) {
2673
+ const currentClient = this.client;
2674
+ const formattedHost = mdsIP.includes(":") && !mdsIP.startsWith("[") ? `[${mdsIP}]` : mdsIP;
2675
+ return new OnPremAPIClient(currentClient.authToken || void 0, formattedHost, port, currentClient.username, currentClient.password);
2676
+ } else if (this.client instanceof SmartOneCloudAPIClient) {
2677
+ throw new Error("Multi-MDS routing is not supported for SmartOneCloud environments");
2678
+ } else {
2679
+ throw new Error("Unknown client type for MDS routing");
2680
+ }
2681
+ }
2682
+ /**
2683
+ * Run a script on a target gateway
2684
+ */
2685
+ async runScript(targetGateway, scriptName, script) {
2686
+ const apiClient = await this.getDomainApiClient(targetGateway);
2687
+ const payload = {
2688
+ "script-name": scriptName,
2689
+ "script": script,
2690
+ "targets": [targetGateway]
2691
+ };
2692
+ const clientResponse = await apiClient.callApi("post", "run-script", payload, void 0);
2693
+ const resp = clientResponse.response;
2694
+ if (!resp.tasks) {
2695
+ return [false, { message: "Failed to run the script" }];
2696
+ }
2697
+ return [true, { tasks: resp.tasks.map((task) => task["task-id"]) }];
2698
+ }
2699
+ /**
2700
+ * Get the result of a task
2701
+ */
2702
+ async getTaskResult(gatewayName, taskId, maxRetries = 5) {
2703
+ const client = await this.getDomainApiClient(gatewayName);
2704
+ let retries = 0;
2705
+ const timeouts = [1e3, 1e3, 2e3, 5e3, 5e3];
2706
+ while (retries < maxRetries) {
2707
+ const payload = {
2708
+ "task-id": taskId,
2709
+ "details-level": "full"
2710
+ };
2711
+ const response = await client.callApi("post", "show-task", payload);
2712
+ const taskDetails = response.response.tasks?.[0];
2713
+ if (taskDetails?.status === "succeeded" || taskDetails?.status === "failed") {
2714
+ if (taskDetails["task-details"]?.[0]?.responseMessage) {
2715
+ const responseMessageBase64 = taskDetails["task-details"][0].responseMessage;
2716
+ const decoded = Buffer.from(responseMessageBase64, "base64").toString("utf-8");
2717
+ return [taskDetails.status === "succeeded", decoded];
2718
+ }
2719
+ return [false, "failed to get task result"];
2720
+ } else {
2721
+ const timeout = timeouts[Math.min(retries, timeouts.length - 1)];
2722
+ console.error(`Try #${retries}: Task ${taskId} is still running, waiting for ${timeout}ms...`);
2723
+ retries++;
2724
+ await new Promise((resolve) => setTimeout(resolve, timeout));
2725
+ }
2726
+ }
2727
+ return [false, "Task did not complete in time"];
2728
+ }
2729
+ };
2730
+ var APIManagerForAPIKey = class extends APIManagerBase {
2731
+ static create(args) {
2732
+ const verbose = SettingsManager.globalDebugState;
2733
+ if (verbose) {
2734
+ console.error("[APIManagerForAPIKey.create] Verbose: Creating API manager");
2735
+ console.error("[APIManagerForAPIKey.create] Verbose: Args received:", {
2736
+ apiKey: args.apiKey ? "***" : void 0,
2737
+ username: args.username ? "***" : void 0,
2738
+ password: args.password ? "***" : void 0,
2739
+ managementHost: args.managementHost,
2740
+ managementPort: args.managementPort,
2741
+ s1cUrl: args.s1cUrl,
2742
+ cloudInfraToken: args.cloudInfraToken ? "***" : void 0
2743
+ });
2744
+ }
2745
+ const hasAnyValue = args.apiKey || args.username || args.password || args.s1cUrl || args.managementHost || args.cloudInfraToken;
2746
+ if (!hasAnyValue) {
2747
+ if (verbose) {
2748
+ console.error("[APIManagerForAPIKey.create] Verbose: ERROR - Args object is effectively empty, no values provided");
2749
+ console.error("[APIManagerForAPIKey.create] Verbose: All args keys:", Object.keys(args));
2750
+ }
2751
+ throw new Error("No authentication or connection parameters provided. Args object is empty or contains only undefined values.");
2752
+ }
2753
+ if (args.managementHost) {
2754
+ if (verbose) {
2755
+ console.error("[APIManagerForAPIKey.create] Verbose: Using on-prem management with host:", args.managementHost);
2756
+ }
2757
+ const onPremClient = new OnPremAPIClient(args.apiKey, args.managementHost, args.managementPort || "443", args.username, args.password);
2758
+ return new this(onPremClient);
2759
+ }
2760
+ if (verbose) {
2761
+ console.error("[APIManagerForAPIKey.create] Verbose: managementHost not provided, checking s1cUrl");
2762
+ }
2763
+ if (!args.s1cUrl) {
2764
+ if (verbose) {
2765
+ console.error("[APIManagerForAPIKey.create] Verbose: ERROR - Neither managementHost nor s1cUrl provided");
2766
+ }
2767
+ throw new Error("Either management host or S1C URL must be provided");
2768
+ }
2769
+ if (verbose) {
2770
+ console.error("[APIManagerForAPIKey.create] Verbose: Using S1C with URL:", args.s1cUrl);
2771
+ }
2772
+ let keyType;
2773
+ let key;
2774
+ if (args.cloudInfraToken) {
2775
+ if (verbose) {
2776
+ console.error("[APIManagerForAPIKey.create] Verbose: Using cloud infra token");
2777
+ }
2778
+ keyType = TokenType.CI_TOKEN;
2779
+ key = args.cloudInfraToken;
2780
+ } else if (args.apiKey) {
2781
+ if (verbose) {
2782
+ console.error("[APIManagerForAPIKey.create] Verbose: Using API key");
2783
+ }
2784
+ keyType = TokenType.API_KEY;
2785
+ key = args.apiKey;
2786
+ } else {
2787
+ if (verbose) {
2788
+ console.error("[APIManagerForAPIKey.create] Verbose: ERROR - No API key or cloud infra token provided");
2789
+ }
2790
+ throw new Error("API key or cloud infrastructure token is required");
2791
+ }
2792
+ return new this(SmartOneCloudAPIClient.create(key, keyType, args.s1cUrl));
2793
+ }
2794
+ };
2795
+
2796
+ // ../infra/dist/settings.js
2797
+ var Settings = class _Settings {
2798
+ normalizeRegion(region) {
2799
+ if (!region) {
2800
+ return void 0;
2801
+ }
2802
+ const normalized = region.trim().toUpperCase();
2803
+ return this.isValidRegion(normalized) ? normalized : void 0;
2804
+ }
2805
+ /**
2806
+ * Extract the base gateway URL (scheme + host) from a full URL.
2807
+ * Allows users to copy-paste any URL from the API key creation dialog
2808
+ * without having to strip the path manually.
2809
+ * Falls back to the original string if URL parsing fails.
2810
+ */
2811
+ static stripGatewayPath(url) {
2812
+ try {
2813
+ const parsed = new URL(url);
2814
+ return `${parsed.protocol}//${parsed.host}`;
2815
+ } catch {
2816
+ return url;
2817
+ }
2818
+ }
2819
+ /**
2820
+ * Detect the region from a gateway base URL
2821
+ */
2822
+ static detectRegionFromUrl(url) {
2823
+ if (url.includes("cloudinfra-gw-us.portal.checkpoint.com"))
2824
+ return "US";
2825
+ if (url.includes("cloudinfra-gw.portal.checkpoint.com"))
2826
+ return "EU";
2827
+ if (url.includes("dev-cloudinfra-gw"))
2828
+ return "STG";
2829
+ return void 0;
2830
+ }
2831
+ constructor({ apiKey = process.env.API_KEY, username = process.env.USERNAME, password = process.env.PASSWORD, s1cUrl = process.env.S1C_URL, managementHost = process.env.MANAGEMENT_HOST, managementPort = process.env.MANAGEMENT_PORT || "443", cloudInfraToken = process.env.CLOUD_INFRA_TOKEN, clientId = process.env.CLIENT_ID, secretKey = process.env.SECRET_KEY, region = process.env.REGION || "EU", devPort = process.env.DEV_PORT || "8006", gatewayUrl } = {}) {
2832
+ this.region = "EU";
2833
+ this.devPort = "8006";
2834
+ this.gatewayUrl = "";
2835
+ const verbose = SettingsManager.globalDebugState;
2836
+ if (verbose) {
2837
+ console.error("[Settings] Verbose: Constructor called with params:", {
2838
+ apiKey: apiKey ? "***" : void 0,
2839
+ username: username ? "***" : void 0,
2840
+ password: password ? "***" : void 0,
2841
+ s1cUrl,
2842
+ managementHost,
2843
+ managementPort,
2844
+ cloudInfraToken: cloudInfraToken ? "***" : void 0,
2845
+ clientId,
2846
+ secretKey: secretKey ? "***" : void 0,
2847
+ region,
2848
+ devPort
2849
+ });
2850
+ }
2851
+ this.apiKey = apiKey;
2852
+ this.username = username;
2853
+ this.password = password;
2854
+ this.s1cUrl = s1cUrl;
2855
+ this.managementHost = managementHost;
2856
+ this.managementPort = managementPort;
2857
+ this.cloudInfraToken = cloudInfraToken;
2858
+ this.clientId = clientId;
2859
+ this.secretKey = secretKey;
2860
+ this.region = this.normalizeRegion(region) || "EU";
2861
+ this.devPort = devPort;
2862
+ this.gatewayUrl = this.resolveGatewayUrl(this.region, gatewayUrl);
2863
+ if (verbose) {
2864
+ console.error("[Settings] Verbose: After assignment:", {
2865
+ apiKey: this.apiKey ? "***" : void 0,
2866
+ username: this.username ? "***" : void 0,
2867
+ password: this.password ? "***" : void 0,
2868
+ s1cUrl: this.s1cUrl,
2869
+ managementHost: this.managementHost,
2870
+ managementPort: this.managementPort,
2871
+ cloudInfraToken: this.cloudInfraToken ? "***" : void 0,
2872
+ region: this.region
2873
+ });
2874
+ }
2875
+ this.validate();
2876
+ }
2877
+ /**
2878
+ * Check if the provided string is a valid region
2879
+ */
2880
+ isValidRegion(region) {
2881
+ return ["EU", "US", "STG", "LOCAL"].includes(region.toUpperCase());
2882
+ }
2883
+ /**
2884
+ * Get the base gateway URL for a given region
2885
+ */
2886
+ getRegionGatewayUrl(region) {
2887
+ switch (region) {
2888
+ case "EU":
2889
+ return "https://cloudinfra-gw.portal.checkpoint.com";
2890
+ case "US":
2891
+ return "https://cloudinfra-gw-us.portal.checkpoint.com";
2892
+ case "STG":
2893
+ case "LOCAL":
2894
+ return "https://dev-cloudinfra-gw.kube1.iaas.checkpoint.com";
2895
+ default:
2896
+ return "";
2897
+ }
2898
+ }
2899
+ /**
2900
+ * Resolve the base gateway URL from either a provided URL or the configured region.
2901
+ * If a URL is provided, its path suffix is stripped so users can paste the full
2902
+ * auth URL from the API key creation dialog (e.g. ending in /auth/external).
2903
+ * When the URL implies a different region, this.region is updated to match.
2904
+ */
2905
+ resolveGatewayUrl(region, providedUrl) {
2906
+ if (!providedUrl) {
2907
+ return this.getRegionGatewayUrl(region);
2908
+ }
2909
+ const base = _Settings.stripGatewayPath(providedUrl);
2910
+ const detectedRegion = _Settings.detectRegionFromUrl(base);
2911
+ if (detectedRegion && detectedRegion !== this.region) {
2912
+ this.region = detectedRegion;
2913
+ }
2914
+ return base;
2915
+ }
2916
+ /**
2917
+ * Get the base Cloud Infra Gateway URL.
2918
+ * Returns the precomputed gatewayUrl (derived from region or a provided URL).
2919
+ */
2920
+ getCloudInfraGateway() {
2921
+ return this.gatewayUrl;
2922
+ }
2923
+ /**
2924
+ * Validate the settings
2925
+ */
2926
+ validate() {
2927
+ const verbose = SettingsManager.globalDebugState;
2928
+ if (verbose) {
2929
+ console.error("[Settings] Verbose: Validating settings...");
2930
+ console.error("[Settings] Verbose: s1cUrl:", this.s1cUrl || "(empty)");
2931
+ console.error("[Settings] Verbose: managementHost:", this.managementHost || "(empty)");
2932
+ console.error("[Settings] Verbose: apiKey:", this.apiKey ? "***" : "(empty)");
2933
+ console.error("[Settings] Verbose: cloudInfraToken:", this.cloudInfraToken ? "***" : "(empty)");
2934
+ console.error("[Settings] Verbose: username:", this.username ? "***" : "(empty)");
2935
+ console.error("[Settings] Verbose: password:", this.password ? "***" : "(empty)");
2936
+ }
2937
+ if (!nullOrEmpty(this.s1cUrl) && nullOrEmpty(this.apiKey) && nullOrEmpty(this.cloudInfraToken)) {
2938
+ if (verbose) {
2939
+ console.error("[Settings] Verbose: Validation FAILED - S1C URL provided but no API key or CI token");
2940
+ }
2941
+ throw new Error("API key or CI Token is required for S1C (via --api-key or API_KEY env var)");
2942
+ }
2943
+ if (!nullOrEmpty(this.managementHost) && nullOrEmpty(this.apiKey) && (nullOrEmpty(this.username) || nullOrEmpty(this.password))) {
2944
+ if (verbose) {
2945
+ console.error("[Settings] Verbose: Validation FAILED - Management host provided but no API key or credentials");
2946
+ }
2947
+ throw new Error("Either API key or username/password are required for on-prem management (via CLI args or env vars)");
2948
+ }
2949
+ if (nullOrEmpty(this.s1cUrl) && nullOrEmpty(this.managementHost)) {
2950
+ if (verbose) {
2951
+ console.error("[Settings] Verbose: WARNING - Neither s1cUrl nor managementHost provided");
2952
+ }
2953
+ }
2954
+ if (verbose) {
2955
+ console.error("[Settings] Verbose: Validation PASSED");
2956
+ }
2957
+ }
2958
+ /**
2959
+ * Create settings from command-line arguments
2960
+ */
2961
+ static fromArgs(args) {
2962
+ const verbose = SettingsManager.globalDebugState;
2963
+ if (verbose) {
2964
+ console.error("[Settings.fromArgs] Verbose: Creating settings from args");
2965
+ console.error("[Settings.fromArgs] Verbose: Raw args:", {
2966
+ apiKey: args.apiKey ? "***" : void 0,
2967
+ username: args.username ? "***" : void 0,
2968
+ password: args.password ? "***" : void 0,
2969
+ s1cUrl: args.s1cUrl,
2970
+ managementHost: args.managementHost,
2971
+ managementPort: args.managementPort,
2972
+ cloudInfraToken: args.cloudInfraToken ? "***" : void 0,
2973
+ region: args.region,
2974
+ hasOtherKeys: Object.keys(args).length > 10
2975
+ });
2976
+ const hasAnyValue = args.apiKey || args.username || args.password || args.s1cUrl || args.managementHost || args.cloudInfraToken;
2977
+ if (!hasAnyValue) {
2978
+ console.error("[Settings.fromArgs] Verbose: WARNING - Args object appears empty, no authentication values found");
2979
+ }
2980
+ }
2981
+ return new _Settings({
2982
+ apiKey: args.apiKey,
2983
+ username: args.username,
2984
+ password: args.password,
2985
+ s1cUrl: args.s1cUrl,
2986
+ managementHost: args.managementHost,
2987
+ managementPort: args.managementPort,
2988
+ cloudInfraToken: args.cloudInfraToken,
2989
+ clientId: args.clientId,
2990
+ secretKey: args.secretKey,
2991
+ region: typeof args.region === "string" ? args.region.trim().toUpperCase() : void 0,
2992
+ devPort: args.devPort,
2993
+ gatewayUrl: args.gatewayUrl
2994
+ });
2995
+ }
2996
+ /**
2997
+ * Create settings from HTTP headers
2998
+ * Maps headers to environment variable format based on server config
2999
+ */
3000
+ static fromHeaders(headers) {
3001
+ const verbose = SettingsManager.globalDebugState;
3002
+ if (verbose) {
3003
+ console.error("[Settings.fromHeaders] Verbose: Creating settings from headers");
3004
+ console.error("[Settings.fromHeaders] Verbose: Available header keys:", Object.keys(headers));
3005
+ }
3006
+ const extractedValues = {
3007
+ apiKey: getHeaderValue(headers, "API-KEY"),
3008
+ username: getHeaderValue(headers, "USERNAME"),
3009
+ password: getHeaderValue(headers, "PASSWORD"),
3010
+ s1cUrl: getHeaderValue(headers, "S1C-URL"),
3011
+ managementHost: getHeaderValue(headers, "MANAGEMENT-HOST"),
3012
+ managementPort: getHeaderValue(headers, "MANAGEMENT-PORT"),
3013
+ cloudInfraToken: getHeaderValue(headers, "CLOUD-INFRA-TOKEN"),
3014
+ clientId: getHeaderValue(headers, "CLIENT-ID"),
3015
+ secretKey: getHeaderValue(headers, "SECRET-KEY"),
3016
+ region: getHeaderValue(headers, "REGION"),
3017
+ devPort: getHeaderValue(headers, "DEV-PORT"),
3018
+ gatewayUrl: getHeaderValue(headers, "GATEWAY-URL")
3019
+ };
3020
+ if (verbose) {
3021
+ console.error("[Settings.fromHeaders] Verbose: Extracted values:", {
3022
+ apiKey: extractedValues.apiKey ? "***" : void 0,
3023
+ username: extractedValues.username ? "***" : void 0,
3024
+ password: extractedValues.password ? "***" : void 0,
3025
+ s1cUrl: extractedValues.s1cUrl,
3026
+ managementHost: extractedValues.managementHost,
3027
+ managementPort: extractedValues.managementPort,
3028
+ cloudInfraToken: extractedValues.cloudInfraToken ? "***" : void 0,
3029
+ region: extractedValues.region,
3030
+ devPort: extractedValues.devPort
3031
+ });
3032
+ const hasAnyValue = extractedValues.apiKey || extractedValues.username || extractedValues.password || extractedValues.s1cUrl || extractedValues.managementHost || extractedValues.cloudInfraToken;
3033
+ if (!hasAnyValue) {
3034
+ console.error("[Settings.fromHeaders] Verbose: WARNING - No authentication values found in headers");
3035
+ console.error("[Settings.fromHeaders] Verbose: Full headers object (sanitized):", Object.fromEntries(Object.entries(headers).map(([k, v]) => [k, k.toLowerCase().includes("key") || k.toLowerCase().includes("token") || k.toLowerCase().includes("password") ? "***" : v])));
3036
+ }
3037
+ }
3038
+ return new _Settings({
3039
+ apiKey: extractedValues.apiKey,
3040
+ username: extractedValues.username,
3041
+ password: extractedValues.password,
3042
+ s1cUrl: extractedValues.s1cUrl,
3043
+ managementHost: extractedValues.managementHost,
3044
+ managementPort: extractedValues.managementPort,
3045
+ cloudInfraToken: extractedValues.cloudInfraToken,
3046
+ clientId: extractedValues.clientId,
3047
+ secretKey: extractedValues.secretKey,
3048
+ region: extractedValues.region?.toUpperCase(),
3049
+ devPort: extractedValues.devPort,
3050
+ gatewayUrl: extractedValues.gatewayUrl
3051
+ });
3052
+ }
3053
+ };
3054
+
3055
+ // ../infra/dist/external-user-token-manager.js
3056
+ import axios2 from "axios";
3057
+
3058
+ // src/index.ts
3059
+ import { join as join3, dirname as dirname2 } from "path";
3060
+ import { fileURLToPath as fileURLToPath2 } from "url";
3061
+
3062
+ // src/zodSchemas.ts
3063
+ import { z } from "zod";
3064
+ var zodSchemas = {
3065
+ ShowCardInfo: { domain: z.string().optional(), domains_to_process: z.enum(["ALL_DOMAINS_ON_THIS_SERVER", "CURRENT_DOMAIN"]).optional() },
3066
+ ShowConfig: { domain: z.string().optional(), domains_to_process: z.enum(["ALL_DOMAINS_ON_THIS_SERVER", "CURRENT_DOMAIN"]).optional() },
3067
+ ShowRulesUidsWithSuggestions: { domain: z.string().optional(), domains_to_process: z.enum(["ALL_DOMAINS_ON_THIS_SERVER", "CURRENT_DOMAIN"]).optional(), "requestBody": z.object({ "layer": z.string().uuid().regex(new RegExp("^[0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}$")).describe("Access layer identifier in UUID format"), "filters": z.object({ "states": z.array(z.enum(["ACCEPTED", "REJECTED"]).describe("State of a suggestion - either ACCEPTED or REJECTED")).describe("Array of insight state values").optional(), "user-interaction": z.object({ "operator": z.enum(["NOT-IN", "IN"]).describe("Operator for filtering by user-interaction-types").optional(), "types": z.array(z.literal("DECIDE_LATER").describe("Type of user interaction with an insight")).describe("Array of user interaction type values") }).optional(), "security-impact": z.enum(["HIGH", "MEDIUM_AND_ABOVE", "LOW_AND_ABOVE"]).describe("Minimum security impact threshold to include").optional(), "confidence-level": z.enum(["HIGH", "MEDIUM_AND_ABOVE", "LOW_AND_ABOVE"]).describe("Minimum confidence threshold to include").optional(), "default-filter": z.literal("NONE").describe("Ignore default filtering of the system").optional(), "suggestions-type": z.enum(["unused-objects", "tighten-rule", "delete-disabled-rule", "zero-hits-rule"]).describe("Type of insight") }) }).describe("Parameters for showing rules UIDs with their suggestions") },
3068
+ ShowState: { domain: z.string().optional(), domains_to_process: z.enum(["ALL_DOMAINS_ON_THIS_SERVER", "CURRENT_DOMAIN"]).optional() },
3069
+ ShowSuggestionEngineMetadata: { domain: z.string().optional(), domains_to_process: z.enum(["ALL_DOMAINS_ON_THIS_SERVER", "CURRENT_DOMAIN"]).optional(), "requestBody": z.object({ "filters": z.object({ "suggestion-type": z.enum(["unused-objects", "tighten-rule", "delete-disabled-rule", "zero-hits-rule"]).describe("Type of insight").optional() }).optional() }).describe("The JSON request body.") },
3070
+ ShowSuggestions: { domain: z.string().optional(), domains_to_process: z.enum(["ALL_DOMAINS_ON_THIS_SERVER", "CURRENT_DOMAIN"]).optional(), "requestBody": z.object({ "layer": z.string().uuid().regex(new RegExp("^[0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}$")).describe("Access layer identifier in UUID format").optional(), "options": z.object({ "include-inline-layers": z.boolean().describe("Whether to include insights on inline layers").optional() }).optional(), "limit": z.number().describe("Maximum number of items to return").optional(), "offset": z.number().describe("Number of items to skip for pagination").optional(), "filters": z.object({ "states": z.array(z.enum(["ACCEPTED", "REJECTED"]).describe("State of a suggestion - either ACCEPTED or REJECTED")).describe("Array of insight state values").optional(), "user-interaction": z.object({ "operator": z.enum(["NOT-IN", "IN"]).describe("Operator for filtering by user-interaction-types").optional(), "types": z.array(z.literal("DECIDE_LATER").describe("Type of user interaction with an insight")).describe("Array of user interaction type values") }).optional(), "security-impact": z.enum(["HIGH", "MEDIUM_AND_ABOVE", "LOW_AND_ABOVE"]).describe("Minimum security impact threshold to include").optional(), "confidence-level": z.enum(["HIGH", "MEDIUM_AND_ABOVE", "LOW_AND_ABOVE"]).describe("Minimum confidence threshold to include").optional(), "default-filter": z.literal("NONE").describe("Ignore default filtering of the system").optional(), "uids": z.array(z.string().uuid().regex(new RegExp("^[0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}$")).describe("Stringified UUID.")).describe("Array of insight unique identifiers").optional(), "rules-uids": z.array(z.string().uuid().regex(new RegExp("^[0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}$")).describe("Stringified UUID.")).describe("Array of rule unique identifiers").optional(), "types": z.array(z.enum(["unused-objects", "tighten-rule", "delete-disabled-rule", "zero-hits-rule"]).describe("Type of insight")).describe("Type of insight").optional() }).optional() }).describe("Parameters for showing suggestions with enhanced v3.0 capabilities") },
3071
+ ShowSuggestionsInfo: { domain: z.string().optional(), domains_to_process: z.enum(["ALL_DOMAINS_ON_THIS_SERVER", "CURRENT_DOMAIN"]).optional(), "requestBody": z.object({ "layer": z.string().uuid().regex(new RegExp("^[0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}$")).describe("Access layer identifier in UUID format") }).describe("The JSON request body.") },
3072
+ ShowSuggestionsSummary: { domain: z.string().optional(), domains_to_process: z.enum(["ALL_DOMAINS_ON_THIS_SERVER", "CURRENT_DOMAIN"]).optional(), "requestBody": z.object({ "layer": z.string().uuid().regex(new RegExp("^[0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}$")).describe("Access layer identifier in UUID format").optional(), "filters": z.object({ "states": z.array(z.enum(["ACCEPTED", "REJECTED"]).describe("State of a suggestion - either ACCEPTED or REJECTED")).describe("Array of insight state values").optional(), "user-interaction": z.object({ "operator": z.enum(["NOT-IN", "IN"]).describe("Operator for filtering by user-interaction-types").optional(), "types": z.array(z.literal("DECIDE_LATER").describe("Type of user interaction with an insight")).describe("Array of user interaction type values") }).optional(), "security-impact": z.enum(["HIGH", "MEDIUM_AND_ABOVE", "LOW_AND_ABOVE"]).describe("Minimum security impact threshold to include").optional(), "confidence-level": z.enum(["HIGH", "MEDIUM_AND_ABOVE", "LOW_AND_ABOVE"]).describe("Minimum confidence threshold to include").optional(), "default-filter": z.literal("NONE").describe("Ignore default filtering of the system").optional() }).optional() }).describe("Parameters for showing suggestions summary") },
3073
+ ShowPolicyInsightsStatus: { domain: z.string().optional(), domains_to_process: z.enum(["ALL_DOMAINS_ON_THIS_SERVER", "CURRENT_DOMAIN"]).optional() }
3074
+ };
3075
+
3076
+ // src/serverInfo.ts
3077
+ function getServerInfo() {
3078
+ return {
3079
+ description: '"Policy Insights analyzes Access Control policies and network traffic to identify opportunities for optimization. It examines traffic patterns and policy configurations, and suggests modifications to improve your security posture.\\\\n\\\\n## Key Benefits\\\\n- Reduces attack surface by making rules more restrictive and eliminating unnecessary traffic permissions\\\\n- Simplifies access control policies for easier management and auditing. Policy Insights automatically generates intelligent insights to streamline network security. It helps narrow down allowed traffic, remove unused objects and rules, and reduce potential threats, simplifying policy management."',
3080
+ websiteUrl: "https://support.checkpoint.com/results/sk/sk183313"
3081
+ };
3082
+ }
3083
+
3084
+ // src/index.ts
3085
+ var { server, pkg } = createMcpServer(import.meta.url, getServerInfo());
3086
+ var SERVER_PACKAGE_NAME = pkg["name"];
3087
+ var serverModule = createServerModule(server, Settings, pkg, APIManagerForAPIKey);
3088
+ var runApi = createApiRunner(serverModule);
3089
+ server.tool(
3090
+ `${SERVER_PACKAGE_NAME.split("/").pop().replace(/-mcp$/, "")}__init`,
3091
+ "Verify, login and initialize management connection. Use this tool on your first interaction with the server.",
3092
+ z2.object({}).strict(),
3093
+ async (args, extra) => {
3094
+ try {
3095
+ const apiManager = SessionContext.getAPIManager(serverModule, extra);
3096
+ const isMds = await apiManager.isMds();
3097
+ if (!isMds) {
3098
+ return {
3099
+ content: [
3100
+ {
3101
+ type: "text",
3102
+ text: `${SERVER_PACKAGE_NAME} server is up and running. The environment is NOT part of Multi Domain system, there is no need to use domain parameters in tool calls.`
3103
+ }
3104
+ ]
3105
+ };
3106
+ } else {
3107
+ const domains = await apiManager.getDomains();
3108
+ const domainList = domains.map((domain) => `${domain.name} (${domain.type})`).join(", ");
3109
+ return {
3110
+ content: [
3111
+ {
3112
+ type: "text",
3113
+ text: `${SERVER_PACKAGE_NAME} server is up and running. The environment is part of Multi Domain system. You need to use the domain parameter for calling APIs, if you are not sure which to use, ask the user. The domains in the system are: ${domainList}`
3114
+ }
3115
+ ]
3116
+ };
3117
+ }
3118
+ } catch (error) {
3119
+ const errorMessage = error instanceof Error ? error.message : String(error);
3120
+ return {
3121
+ content: [
3122
+ {
3123
+ type: "text",
3124
+ text: `Error initializing ${SERVER_PACKAGE_NAME} connection: ${errorMessage}`
3125
+ }
3126
+ ]
3127
+ };
3128
+ }
3129
+ }
3130
+ );
3131
+ for (const toolDef of toolDefinitionMap) {
3132
+ const toolName = toolDef.name;
3133
+ if (!toolName) {
3134
+ console.error("\u274C Tool definition missing name:", toolDef);
3135
+ continue;
3136
+ }
3137
+ server.tool(
3138
+ toolName,
3139
+ toolDef.description,
3140
+ zodSchemas[toolName],
3141
+ async (args, extra) => {
3142
+ return await executeApiTool(toolName, toolDef, args, extra);
3143
+ }
3144
+ );
3145
+ }
3146
+ async function executeApiTool(toolName, definition, validatedArgs, extra) {
3147
+ try {
3148
+ const urlPath = definition.pathTemplate;
3149
+ console.error(`=== Executing tool "${toolName}" ===`);
3150
+ console.error(`URL Path: ${urlPath}`);
3151
+ console.error(`Method: ${definition.method}`);
3152
+ console.error(`Raw args:`, JSON.stringify(validatedArgs, null, 2));
3153
+ console.error(`RequestBody:`, JSON.stringify(validatedArgs?.["requestBody"], null, 2));
3154
+ console.error(`Extra context:`, JSON.stringify(extra, null, 2));
3155
+ console.error(`Definition:`, JSON.stringify(definition, null, 2));
3156
+ let domain = void 0;
3157
+ if (validatedArgs.domain) {
3158
+ domain = typeof validatedArgs.domain === "string" && validatedArgs.domain.trim() !== "" ? validatedArgs.domain : void 0;
3159
+ console.error(`Sending request to domain:`, JSON.stringify(domain, null, 2));
3160
+ }
3161
+ const requestBody = validatedArgs?.["requestBody"] || {};
3162
+ if (validatedArgs.domains_to_process) {
3163
+ requestBody["domains-to-process"] = typeof validatedArgs.domain === "string" && validatedArgs.domain.trim() !== "" ? validatedArgs.domain : void 0;
3164
+ }
3165
+ const resp = await runApi("POST", urlPath, requestBody, extra, domain);
3166
+ console.error(`=== DEBUG: Response received ===`);
3167
+ console.error(`Response:`, JSON.stringify(resp, null, 2));
3168
+ return { content: [{ type: "text", text: JSON.stringify(resp, null, 2) }] };
3169
+ } catch (error) {
3170
+ console.error(`=== DEBUG: Error in executeApiTool ===`);
3171
+ console.error(`Error type:`, typeof error);
3172
+ console.error(`Error:`, error);
3173
+ console.error(`Error stack:`, error instanceof Error ? error.stack : "No stack trace");
3174
+ const errorMessage = error instanceof Error ? error.message : String(error);
3175
+ return {
3176
+ content: [{ type: "text", text: `Error executing tool '${toolName}': ${errorMessage}` }]
3177
+ };
3178
+ }
3179
+ }
3180
+ async function main() {
3181
+ await launchMCPServer(
3182
+ join3(dirname2(fileURLToPath2(import.meta.url)), "server-config.json"),
3183
+ serverModule
3184
+ );
3185
+ }
3186
+ main().catch((error) => {
3187
+ console.error("Fatal error in main():", error);
3188
+ process.exit(1);
3189
+ });
3190
+ export {
3191
+ server
3192
+ };