@chkp/documentation-mcp 1.0.1 β†’ 1.3.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/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @chkp/documentation-mcp
2
2
 
3
+ ## 1.3.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 56cf1d2: Updated implementation and features, Modified 3 file(s) (synced from internal repository)
8
+
9
+ ## 1.1.0
10
+
11
+ ### Minor Changes
12
+
13
+ - 3870c17: Updated implementation and features, Updated configuration, Modified 3 file(s) (synced from internal repository)
14
+
3
15
  ## 1.0.1
4
16
 
5
17
  ### Patch Changes
package/README.md CHANGED
@@ -40,6 +40,8 @@ This server accesses Check Point documentation resources and may have rate limit
40
40
 
41
41
  ## Configuration Options
42
42
 
43
+ > **πŸ“Š Anonymous Usage Statistics:** Check Point collects anonymous usage statistics to help improve this MCP server. To opt out, set `TELEMETRY_DISABLED=true` or use `--no-telemetry` flag.
44
+
43
45
  This server supports configuration via command-line arguments or environment variables:
44
46
 
45
47
  ### API Configuration
@@ -61,7 +63,8 @@ Set the following environment variables:
61
63
 
62
64
  - `CLIENT_ID`: Client ID for authentication with Check Point Documentation Tool (required)
63
65
  - `SECRET_KEY`: Secret Key for authentication with Check Point Documentation Tool (required)
64
- - `REGION`: Documentation Tool region - EU, US, STG, or Local (default: EU)
66
+ - `AUTH_URL`: Authentication URL copied from the API key creation dialog (e.g. `https://cloudinfra-gw.portal.checkpoint.com/auth/external`). Recommended β€” the path suffix is stripped automatically so you can paste it directly. When set, `REGION` is inferred and does not need to be set separately.
67
+ - `REGION`: Short region code β€” `EU`, `US`, `STG`, or `LOCAL` (default: `EU`). Use this instead of `AUTH_URL` for backwards-compatible configurations.
65
68
 
66
69
  ---
67
70
 
@@ -73,7 +76,7 @@ Set the following environment variables:
73
76
 
74
77
  - `CLIENT_ID`: Your client ID for Documentation Tool authentication
75
78
  - `SECRET_KEY`: Your secret key for Documentation Tool authentication
76
- - `REGION`: Set to "Local" for on-premises deployment
79
+ - `REGION`: Set to `LOCAL` for on-premises deployment
77
80
 
78
81
  ---
79
82
 
@@ -105,13 +108,15 @@ It is expected to work with any MCP client that supports the Model Context Proto
105
108
  "env": {
106
109
  "CLIENT_ID": "YOUR_CLIENT_ID",
107
110
  "SECRET_KEY": "YOUR_SECRET_KEY",
108
- "REGION": "EU"
111
+ "AUTH_URL": "YOUR_AUTH_URL"
109
112
  }
110
113
  }
111
114
  }
112
115
  }
113
116
  ```
114
117
 
118
+ > **Tip:** Copy `AUTH_URL` directly from the Authentication URL shown in the API key creation dialog. The path suffix is stripped automatically β€” no manual editing needed.
119
+
115
120
  ### Configuring the Claude Desktop App
116
121
 
117
122
  #### For macOS:
@@ -141,7 +146,7 @@ Add the server configuration:
141
146
  "env": {
142
147
  "CLIENT_ID": "YOUR_CLIENT_ID",
143
148
  "SECRET_KEY": "YOUR_SECRET_KEY",
144
- "REGION": "EU"
149
+ "AUTH_URL": "YOUR_AUTH_URL"
145
150
  }
146
151
  }
147
152
  }
@@ -168,7 +173,7 @@ Add this configuration:
168
173
  "env": {
169
174
  "CLIENT_ID": "YOUR_CLIENT_ID",
170
175
  "SECRET_KEY": "YOUR_SECRET_KEY",
171
- "REGION": "EU"
176
+ "AUTH_URL": "YOUR_AUTH_URL"
172
177
  }
173
178
  }
174
179
  }
@@ -217,7 +222,17 @@ npm run build
217
222
  You can run the server locally for development using [MCP Inspector](https://modelcontextprotocol.io/docs/tools/inspector) or any compatible MCP client.
218
223
 
219
224
  ```bash
220
- node FULL_PATH_TO_SERVER/packages/copilot/dist/index.js --client-id "YOUR_CLIENT_ID" --secret-key "YOUR_SECRET_KEY" --region "EU"
225
+ # Option A: use the Authentication URL from the API key creation dialog
226
+ node FULL_PATH_TO_SERVER/packages/documentation-tool/dist/index.js \
227
+ --client-id "YOUR_CLIENT_ID" \
228
+ --secret-key "YOUR_SECRET_KEY" \
229
+ --auth-url "YOUR_AUTH_URL"
230
+
231
+ # Option B: use a region code (EU / US / STG / LOCAL)
232
+ node FULL_PATH_TO_SERVER/packages/documentation-tool/dist/index.js \
233
+ --client-id "YOUR_CLIENT_ID" \
234
+ --secret-key "YOUR_SECRET_KEY" \
235
+ --region "EU"
221
236
  ```
222
237
 
223
238
  ---
@@ -226,4 +241,10 @@ node FULL_PATH_TO_SERVER/packages/copilot/dist/index.js --client-id "YOUR_CLIENT
226
241
 
227
242
  1. **Authentication keys and credentials are never shared with the model.** They are used only by the MCP server to authenticate with your Check Point management system.
228
243
  2. **Only use client implementations you trust.** Malicious or untrusted clients could misuse your credentials or access data improperly.
229
- 3. **Management data is exposed to the model.** Ensure that you only use models and providers that comply with your organization’s policies for handling sensitive data and PII.
244
+ 3. **Management data is exposed to the model.** Ensure that you only use models and providers that comply with your organization's policies for handling sensitive data and PII.
245
+
246
+ ## πŸ“Š Telemetry and Privacy
247
+
248
+ **Anonymous Usage Statistics:** Check Point collects anonymous usage statistics to improve this MCP server. Only tool usage patterns and anonymous identifiers are collectedβ€”no credentials, policies, or sensitive data.
249
+
250
+ **Opt-Out:** Set `TELEMETRY_DISABLED=true` environment variable or use the `--no-telemetry` flag to disable telemetry collection.
package/dist/index.js CHANGED
@@ -16,7 +16,7 @@ __export(ui_dialog_exports, {
16
16
  showLoginDialog: () => showLoginDialog
17
17
  });
18
18
  import { createServer } from "http";
19
- import { URL } from "url";
19
+ import { URL as URL2 } from "url";
20
20
  import { exec } from "child_process";
21
21
  import { promisify } from "util";
22
22
  import * as fs2 from "fs";
@@ -87,7 +87,7 @@ var init_ui_dialog = __esm({
87
87
  });
88
88
  }
89
89
  handleRequest(req, res, config) {
90
- const url = new URL(req.url, `http://localhost:${this.port}`);
90
+ const url = new URL2(req.url, `http://localhost:${this.port}`);
91
91
  if (req.method === "GET" && url.pathname === "/") {
92
92
  res.writeHead(200, { "Content-Type": "text/html" });
93
93
  res.end(this.generateHTML(config));
@@ -309,7 +309,7 @@ var init_ui_dialog = __esm({
309
309
  try {
310
310
  let url;
311
311
  try {
312
- url = new URL(urlString);
312
+ url = new URL2(urlString);
313
313
  if (!["http:", "https:"].includes(url.protocol) || url.hostname !== "localhost" && url.hostname !== "127.0.0.1") {
314
314
  throw new Error("Invalid URL protocol or non-localhost hostname");
315
315
  }
@@ -362,7 +362,6 @@ var init_ui_dialog = __esm({
362
362
 
363
363
  // src/index.ts
364
364
  import { z } from "zod";
365
- import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
366
365
 
367
366
  // ../mcp-utils/dist/launcher.js
368
367
  import { Command } from "commander";
@@ -371,6 +370,165 @@ import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/
371
370
  import fs from "fs";
372
371
  import http from "http";
373
372
  import { randomUUID } from "crypto";
373
+
374
+ // ../mcp-utils/dist/settings-manager.js
375
+ var SettingsManager = class _SettingsManager {
376
+ /**
377
+ * Creates a new SettingsManager
378
+ * @param settingsClass The Settings class to use for creating settings instances
379
+ */
380
+ constructor(settingsClass) {
381
+ this.settingsMap = /* @__PURE__ */ new Map();
382
+ this.defaultSessionId = "default";
383
+ this.settingsClass = settingsClass;
384
+ }
385
+ /**
386
+ * Get settings for a specific session
387
+ * @param sessionId The session ID (defaults to 'default' for stdio mode)
388
+ * @returns Settings instance for the session
389
+ */
390
+ getSettings(sessionId) {
391
+ const sid = sessionId || this.defaultSessionId;
392
+ if (!this.settingsMap.has(sid)) {
393
+ this.settingsMap.set(sid, new this.settingsClass());
394
+ }
395
+ return this.settingsMap.get(sid);
396
+ }
397
+ /**
398
+ * Set settings for a specific session
399
+ * @param settings The settings object to set
400
+ * @param sessionId The session ID (defaults to 'default' for stdio mode)
401
+ */
402
+ setSettings(settings, sessionId) {
403
+ const sid = sessionId || this.defaultSessionId;
404
+ this.settingsMap.set(sid, settings);
405
+ }
406
+ /**
407
+ * Injects debug settings from source into settings object
408
+ * @param settings The settings object to update
409
+ * @param source Source object containing debug information
410
+ * @private
411
+ */
412
+ injectDebug(settings, source) {
413
+ const debug = source?.debug ?? _SettingsManager.globalDebugState ?? process.env.DEBUG;
414
+ if (typeof debug !== "undefined") {
415
+ if (source?.debug !== void 0) {
416
+ _SettingsManager.globalDebugState = source.debug;
417
+ }
418
+ if (typeof settings.set === "function") {
419
+ settings.set("debug", debug);
420
+ } else {
421
+ settings.debug = debug;
422
+ }
423
+ if (debug) {
424
+ console.error("Debug enabled. Source object contents:");
425
+ console.error(JSON.stringify(source, null, 2));
426
+ }
427
+ }
428
+ }
429
+ /**
430
+ * Print settings object for debugging by dynamically discovering its properties
431
+ * @param settings The settings object to print
432
+ * @private
433
+ */
434
+ printSettingsDebug(settings) {
435
+ if (typeof settings.get === "function") {
436
+ console.error("Settings (using get method):");
437
+ if (settings.data && typeof settings.data === "object") {
438
+ Object.entries(settings.data).forEach(([key, value]) => {
439
+ console.error(` ${key}: ${JSON.stringify(value)}`);
440
+ });
441
+ } else {
442
+ console.error(" Unable to enumerate settings properties - no accessible data structure");
443
+ }
444
+ } else {
445
+ console.error("Settings (plain object):");
446
+ Object.entries(settings).forEach(([key, value]) => {
447
+ console.error(` ${key}: ${JSON.stringify(value)}`);
448
+ });
449
+ }
450
+ }
451
+ /**
452
+ * Create settings from command-line arguments
453
+ * @param args Command line arguments
454
+ * @param sessionId Optional session ID
455
+ * @returns Settings instance
456
+ */
457
+ createFromArgs(args, sessionId) {
458
+ const settings = this.settingsClass.fromArgs(args);
459
+ this.injectDebug(settings, args);
460
+ this.setSettings(settings, sessionId);
461
+ return settings;
462
+ }
463
+ /**
464
+ * Create settings from HTTP headers
465
+ * @param headers HTTP headers
466
+ * @param sessionId Optional session ID
467
+ * @returns Settings instance
468
+ */
469
+ createFromHeaders(headers, sessionId) {
470
+ const verbose = _SettingsManager.globalDebugState;
471
+ if (verbose) {
472
+ console.error("[SettingsManager.createFromHeaders] Verbose: Starting with sessionId:", sessionId || "(default)");
473
+ console.error("[SettingsManager.createFromHeaders] Verbose: Incoming headers count:", Object.keys(headers).length);
474
+ }
475
+ if (_SettingsManager.globalDebugState) {
476
+ console.error("=== createFromHeaders Debug Info ===");
477
+ console.error("Incoming headers:");
478
+ console.error(JSON.stringify(headers, null, 2));
479
+ }
480
+ if (verbose && (!headers || Object.keys(headers).length === 0)) {
481
+ console.error("[SettingsManager.createFromHeaders] Verbose: WARNING - Headers object is empty or undefined");
482
+ }
483
+ const normalizedHeaders = {};
484
+ for (const [key, value] of Object.entries(headers)) {
485
+ const normalizedKey = key.includes("_") ? key.replace(/_/g, "-") : key;
486
+ normalizedHeaders[normalizedKey] = value;
487
+ if (verbose) {
488
+ console.error(`[SettingsManager.createFromHeaders] Verbose: Header normalized: "${key}" -> "${normalizedKey}"`);
489
+ }
490
+ }
491
+ if (verbose) {
492
+ console.error("[SettingsManager.createFromHeaders] Verbose: Normalized headers count:", Object.keys(normalizedHeaders).length);
493
+ }
494
+ if (_SettingsManager.globalDebugState) {
495
+ console.error("Normalized headers:");
496
+ console.error(JSON.stringify(normalizedHeaders, null, 2));
497
+ }
498
+ const debugHeader = normalizedHeaders["debug"] || normalizedHeaders["Debug"] || normalizedHeaders["DEBUG"];
499
+ const debugSource = { debug: debugHeader !== void 0 ? debugHeader : _SettingsManager.globalDebugState };
500
+ if (verbose) {
501
+ console.error("[SettingsManager.createFromHeaders] Verbose: Calling settingsClass.fromHeaders");
502
+ }
503
+ const settings = this.settingsClass.fromHeaders(normalizedHeaders);
504
+ if (verbose) {
505
+ console.error("[SettingsManager.createFromHeaders] Verbose: Settings object created");
506
+ }
507
+ this.injectDebug(settings, debugSource);
508
+ if (_SettingsManager.globalDebugState) {
509
+ console.error("Final settings object for session:", sessionId || "(default)");
510
+ this.printSettingsDebug(settings);
511
+ console.error("=== End createFromHeaders Debug Info ===");
512
+ }
513
+ if (verbose) {
514
+ console.error("[SettingsManager.createFromHeaders] Verbose: Storing settings for session:", sessionId || "(default)");
515
+ }
516
+ this.setSettings(settings, sessionId);
517
+ return settings;
518
+ }
519
+ /**
520
+ * Clear settings for a session
521
+ * @param sessionId The session ID to clear
522
+ */
523
+ clearSession(sessionId) {
524
+ if (sessionId !== this.defaultSessionId) {
525
+ this.settingsMap.delete(sessionId);
526
+ }
527
+ }
528
+ };
529
+ SettingsManager.globalDebugState = void 0;
530
+
531
+ // ../mcp-utils/dist/launcher.js
374
532
  async function launchMCPServer(configPath, serverModule2) {
375
533
  const config = JSON.parse(fs.readFileSync(configPath, "utf8"));
376
534
  const program = new Command();
@@ -379,7 +537,7 @@ async function launchMCPServer(configPath, serverModule2) {
379
537
  }
380
538
  config.options.forEach((option) => {
381
539
  const envValue = option.env ? process.env[option.env] : void 0;
382
- const defaultValue = option.default || envValue;
540
+ const defaultValue = envValue || option.default;
383
541
  if (option.type === "boolean") {
384
542
  const boolDefault = envValue === "true" || option.default === "true";
385
543
  program.option(option.flag, option.description, boolDefault);
@@ -393,12 +551,26 @@ async function launchMCPServer(configPath, serverModule2) {
393
551
  program.option("--transport-port <number>", "Port for network transports (e.g., HTTP)", transportPortDefault);
394
552
  const debugDefault = process.env.DEBUG === "true" || false;
395
553
  program.option("--debug", "Enable debug mode", debugDefault);
554
+ const telemetryEnabledDefault = process.env.TELEMETRY_DISABLED === "true" ? false : true;
555
+ program.option("--no-telemetry", "Disable anonymous usage telemetry", telemetryEnabledDefault);
556
+ const telemetryUrlDefault = process.env.TELEMETRY_URL || "https://metrics.security.ai.checkpoint.com/api/v1/metrics/collect";
557
+ program.option("--telemetry-url <url>", "URL for telemetry server", telemetryUrlDefault);
396
558
  program.parse(process.argv);
397
559
  const options = program.opts();
560
+ if (options.telemetry === false) {
561
+ process.env.TELEMETRY_DISABLED = "true";
562
+ }
563
+ if (options.telemetryUrl) {
564
+ process.env.TELEMETRY_URL = options.telemetryUrl;
565
+ }
398
566
  if (!serverModule2.settingsManager) {
399
567
  throw new Error("ServerModule must have a settingsManager. Create it with createServerModule.");
400
568
  }
401
569
  const settings = serverModule2.settingsManager.createFromArgs(options);
570
+ if (typeof serverModule2.server.applyToolPolicy === "function") {
571
+ console.error("[launchMCPServer] Applying tool policy before connecting");
572
+ serverModule2.server.applyToolPolicy();
573
+ }
402
574
  const transportType = (options.transport || process.env.MCP_TRANSPORT_TYPE || "stdio").toLowerCase() === "http" ? "http" : "stdio";
403
575
  const transportPort = options.transportPort ? parseInt(options.transportPort, 10) : process.env.MCP_TRANSPORT_PORT ? parseInt(process.env.MCP_TRANSPORT_PORT, 10) : 3e3;
404
576
  if (transportType === "http") {
@@ -424,6 +596,7 @@ async function launchMCPServer(configPath, serverModule2) {
424
596
  }
425
597
  async function launchHTTPServer(config, serverModule2, port) {
426
598
  const transports = {};
599
+ const serverInstances = {};
427
600
  const server2 = http.createServer(async (req, res) => {
428
601
  if (req.url === "/" || req.url === "/mcp") {
429
602
  const sessionId = req.headers["mcp-session-id"];
@@ -445,31 +618,65 @@ async function launchHTTPServer(config, serverModule2, port) {
445
618
  }
446
619
  let transport;
447
620
  if (sessionId && transports[sessionId]) {
621
+ const verbose = SettingsManager.globalDebugState;
622
+ if (verbose) {
623
+ console.error("[launchHTTPServer] Verbose: Reusing existing transport for session:", sessionId);
624
+ }
448
625
  transport = transports[sessionId];
449
626
  if (!serverModule2.settingsManager) {
450
627
  throw new Error("ServerModule must have a settingsManager. Create it with createServerModule.");
451
628
  }
452
- serverModule2.settingsManager.createFromHeaders(headersToEnvVars(req.headers, config), sessionId);
629
+ if (verbose) {
630
+ console.error("[launchHTTPServer] Verbose: Converting headers for existing session");
631
+ }
632
+ const envHeaders = headersToEnvVars(req.headers, config);
633
+ if (verbose) {
634
+ console.error("[launchHTTPServer] Verbose: Creating settings from headers for existing session");
635
+ }
636
+ serverModule2.settingsManager.createFromHeaders(envHeaders, sessionId);
453
637
  } else if (!sessionId && body && body.method === "initialize") {
454
638
  transport = new StreamableHTTPServerTransport({
455
639
  sessionIdGenerator: () => randomUUID(),
456
640
  onsessioninitialized: (sid) => {
641
+ const verbose = SettingsManager.globalDebugState;
642
+ if (verbose) {
643
+ console.error("[launchHTTPServer] Verbose: New session initialized:", sid);
644
+ }
457
645
  transports[sid] = transport;
646
+ if (verbose) {
647
+ console.error("[launchHTTPServer] Verbose: Converting headers for new session");
648
+ console.error("[launchHTTPServer] Verbose: Raw request headers:", Object.keys(req.headers));
649
+ }
458
650
  const headers = headersToEnvVars(req.headers, config);
651
+ if (verbose) {
652
+ console.error("[launchHTTPServer] Verbose: Converted headers count:", Object.keys(headers).length);
653
+ }
459
654
  const metadata = {
460
655
  userAgent: req.headers["user-agent"],
461
656
  origin: req.headers.origin || req.headers.referer,
462
657
  remoteAddress: req.socket.remoteAddress,
463
658
  initialPath: req.url
464
659
  };
660
+ if (verbose) {
661
+ console.error("[launchHTTPServer] Verbose: Creating session in session manager");
662
+ }
465
663
  serverModule2.sessionManager.createSession(sid, metadata);
664
+ if (verbose) {
665
+ console.error("[launchHTTPServer] Verbose: Creating settings from headers for new session");
666
+ }
466
667
  serverModule2.settingsManager.createFromHeaders(headers, sid);
668
+ if (verbose) {
669
+ console.error("[launchHTTPServer] Verbose: Session initialization complete");
670
+ }
467
671
  }
468
672
  });
469
673
  transport.onclose = () => {
470
674
  const sid = transport.sessionId;
471
675
  if (sid) {
472
676
  delete transports[sid];
677
+ if (serverInstances[sid]) {
678
+ delete serverInstances[sid];
679
+ }
473
680
  serverModule2.settingsManager.clearSession(sid);
474
681
  serverModule2.apiManagerFactory.clearSession(sid);
475
682
  serverModule2.sessionManager.removeSession(sid);
@@ -485,7 +692,22 @@ async function launchHTTPServer(config, serverModule2, port) {
485
692
  transport
486
693
  };
487
694
  };
488
- await serverModule2.server.connect(transport).catch((error) => {
695
+ let serverToConnect;
696
+ if (serverModule2.createServerInstance) {
697
+ const sessionServer = serverModule2.createServerInstance();
698
+ serverToConnect = sessionServer;
699
+ const originalOnSessionInit = transport.onsessioninitialized;
700
+ transport.onsessioninitialized = (sid) => {
701
+ serverInstances[sid] = sessionServer;
702
+ if (originalOnSessionInit) {
703
+ originalOnSessionInit(sid);
704
+ }
705
+ };
706
+ } else {
707
+ serverToConnect = serverModule2.server;
708
+ console.error("Warning: Using shared server instance. Consider providing createServerInstance for better multi-user support.");
709
+ }
710
+ await serverToConnect.connect(transport).catch((error) => {
489
711
  console.error("Error connecting to HTTP transport:", error);
490
712
  });
491
713
  } else {
@@ -563,168 +785,75 @@ async function launchHTTPServer(config, serverModule2, port) {
563
785
  });
564
786
  }
565
787
  function headersToEnvVars(headers, config) {
788
+ const verbose = SettingsManager.globalDebugState;
789
+ if (verbose) {
790
+ console.error("[headersToEnvVars] Verbose: Converting headers to env vars");
791
+ console.error("[headersToEnvVars] Verbose: Input headers count:", Object.keys(headers).length);
792
+ console.error("[headersToEnvVars] Verbose: Input header keys:", Object.keys(headers));
793
+ if (!headers || Object.keys(headers).length === 0) {
794
+ console.error("[headersToEnvVars] Verbose: WARNING - Headers object is empty");
795
+ }
796
+ }
797
+ if (!headers || Object.keys(headers).length === 0) {
798
+ return {};
799
+ }
566
800
  const result = {};
567
801
  for (const [name, value] of Object.entries(headers)) {
568
802
  if (value !== void 0) {
569
803
  const envName = name.toUpperCase().replace(/-/g, "_");
570
804
  result[envName] = value;
805
+ if (verbose) {
806
+ console.error(`[headersToEnvVars] Verbose: Basic mapping: "${name}" -> "${envName}"`);
807
+ }
571
808
  }
572
809
  }
810
+ if (verbose) {
811
+ console.error("[headersToEnvVars] Verbose: After basic mapping, result keys:", Object.keys(result));
812
+ }
573
813
  if (config && config.options) {
814
+ if (verbose) {
815
+ console.error("[headersToEnvVars] Verbose: Config provided, building header-to-env mapping");
816
+ }
574
817
  const headerToEnvMap = {};
575
818
  for (const option of config.options) {
576
819
  if (option.env) {
577
820
  const flagName = option.flag.split(" ")[0].replace(/^--?/, "").replace(/-/g, "_");
578
821
  headerToEnvMap[flagName.toLowerCase()] = option.env;
822
+ if (verbose) {
823
+ console.error(`[headersToEnvVars] Verbose: Mapping: "${flagName.toLowerCase()}" -> "${option.env}"`);
824
+ }
579
825
  headerToEnvMap[option.env.toLowerCase()] = option.env;
580
826
  }
581
827
  }
828
+ if (verbose) {
829
+ console.error("[headersToEnvVars] Verbose: headerToEnvMap:", headerToEnvMap);
830
+ }
831
+ let mappedCount = 0;
582
832
  for (const [headerName, headerValue] of Object.entries(headers)) {
583
833
  if (headerValue !== void 0) {
584
834
  const normalizedHeaderName = headerName.toLowerCase().replace(/-/g, "_");
585
835
  const envVarName = headerToEnvMap[normalizedHeaderName];
586
836
  if (envVarName) {
587
837
  result[envVarName] = headerValue;
838
+ mappedCount++;
839
+ if (verbose) {
840
+ console.error(`[headersToEnvVars] Verbose: Config mapping: "${headerName}" -> "${envVarName}"`);
841
+ }
588
842
  }
589
843
  }
590
844
  }
591
- }
592
- return result;
593
- }
594
-
595
- // ../mcp-utils/dist/settings-manager.js
596
- var SettingsManager = class _SettingsManager {
597
- /**
598
- * Creates a new SettingsManager
599
- * @param settingsClass The Settings class to use for creating settings instances
600
- */
601
- constructor(settingsClass) {
602
- this.settingsMap = /* @__PURE__ */ new Map();
603
- this.defaultSessionId = "default";
604
- this.settingsClass = settingsClass;
605
- }
606
- /**
607
- * Get settings for a specific session
608
- * @param sessionId The session ID (defaults to 'default' for stdio mode)
609
- * @returns Settings instance for the session
610
- */
611
- getSettings(sessionId) {
612
- const sid = sessionId || this.defaultSessionId;
613
- if (!this.settingsMap.has(sid)) {
614
- this.settingsMap.set(sid, new this.settingsClass());
845
+ if (verbose) {
846
+ console.error(`[headersToEnvVars] Verbose: Mapped ${mappedCount} headers using config`);
615
847
  }
616
- return this.settingsMap.get(sid);
848
+ } else if (verbose) {
849
+ console.error("[headersToEnvVars] Verbose: No config provided, skipping config-based mapping");
617
850
  }
618
- /**
619
- * Set settings for a specific session
620
- * @param settings The settings object to set
621
- * @param sessionId The session ID (defaults to 'default' for stdio mode)
622
- */
623
- setSettings(settings, sessionId) {
624
- const sid = sessionId || this.defaultSessionId;
625
- this.settingsMap.set(sid, settings);
851
+ if (verbose) {
852
+ console.error("[headersToEnvVars] Verbose: Final result keys:", Object.keys(result));
853
+ 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])));
626
854
  }
627
- /**
628
- * Injects debug settings from source into settings object
629
- * @param settings The settings object to update
630
- * @param source Source object containing debug information
631
- * @private
632
- */
633
- injectDebug(settings, source) {
634
- const debug = source?.debug ?? _SettingsManager.globalDebugState ?? process.env.DEBUG;
635
- if (typeof debug !== "undefined") {
636
- if (source?.debug !== void 0) {
637
- _SettingsManager.globalDebugState = source.debug;
638
- }
639
- if (typeof settings.set === "function") {
640
- settings.set("debug", debug);
641
- } else {
642
- settings.debug = debug;
643
- }
644
- if (debug) {
645
- console.error("Debug enabled. Source object contents:");
646
- console.error(JSON.stringify(source, null, 2));
647
- }
648
- }
649
- }
650
- /**
651
- * Print settings object for debugging by dynamically discovering its properties
652
- * @param settings The settings object to print
653
- * @private
654
- */
655
- printSettingsDebug(settings) {
656
- if (typeof settings.get === "function") {
657
- console.error("Settings (using get method):");
658
- if (settings.data && typeof settings.data === "object") {
659
- Object.entries(settings.data).forEach(([key, value]) => {
660
- console.error(` ${key}: ${JSON.stringify(value)}`);
661
- });
662
- } else {
663
- console.error(" Unable to enumerate settings properties - no accessible data structure");
664
- }
665
- } else {
666
- console.error("Settings (plain object):");
667
- Object.entries(settings).forEach(([key, value]) => {
668
- console.error(` ${key}: ${JSON.stringify(value)}`);
669
- });
670
- }
671
- }
672
- /**
673
- * Create settings from command-line arguments
674
- * @param args Command line arguments
675
- * @param sessionId Optional session ID
676
- * @returns Settings instance
677
- */
678
- createFromArgs(args, sessionId) {
679
- const settings = this.settingsClass.fromArgs(args);
680
- this.injectDebug(settings, args);
681
- this.setSettings(settings, sessionId);
682
- return settings;
683
- }
684
- /**
685
- * Create settings from HTTP headers
686
- * @param headers HTTP headers
687
- * @param sessionId Optional session ID
688
- * @returns Settings instance
689
- */
690
- createFromHeaders(headers, sessionId) {
691
- if (_SettingsManager.globalDebugState) {
692
- console.error("=== createFromHeaders Debug Info ===");
693
- console.error("Incoming headers:");
694
- console.error(JSON.stringify(headers, null, 2));
695
- }
696
- const normalizedHeaders = {};
697
- for (const [key, value] of Object.entries(headers)) {
698
- const normalizedKey = key.includes("_") ? key.replace(/_/g, "-") : key;
699
- normalizedHeaders[normalizedKey] = value;
700
- }
701
- if (_SettingsManager.globalDebugState) {
702
- console.error("Normalized headers:");
703
- console.error(JSON.stringify(normalizedHeaders, null, 2));
704
- }
705
- const debugHeader = normalizedHeaders["debug"] || normalizedHeaders["Debug"] || normalizedHeaders["DEBUG"];
706
- const debugSource = { debug: debugHeader !== void 0 ? debugHeader : _SettingsManager.globalDebugState };
707
- const settings = this.settingsClass.fromHeaders(normalizedHeaders);
708
- this.injectDebug(settings, debugSource);
709
- if (_SettingsManager.globalDebugState) {
710
- console.error("Final settings object:");
711
- this.printSettingsDebug(settings);
712
- console.error("=== End createFromHeaders Debug Info ===");
713
- }
714
- this.setSettings(settings, sessionId);
715
- return settings;
716
- }
717
- /**
718
- * Clear settings for a session
719
- * @param sessionId The session ID to clear
720
- */
721
- clearSession(sessionId) {
722
- if (sessionId !== this.defaultSessionId) {
723
- this.settingsMap.delete(sessionId);
724
- }
725
- }
726
- };
727
- SettingsManager.globalDebugState = void 0;
855
+ return result;
856
+ }
728
857
 
729
858
  // ../mcp-utils/dist/api-manager-factory.js
730
859
  var APIManagerFactory = class {
@@ -745,11 +874,27 @@ var APIManagerFactory = class {
745
874
  * @returns API Manager instance for the session
746
875
  */
747
876
  getAPIManager(sessionId) {
877
+ const verbose = SettingsManager.globalDebugState;
748
878
  const sid = sessionId || this.defaultSessionId;
879
+ if (verbose) {
880
+ console.error("[APIManagerFactory.getAPIManager] Verbose: Getting API manager for session:", sid);
881
+ }
749
882
  if (!this.apiManagerMap.has(sid)) {
883
+ if (verbose) {
884
+ console.error("[APIManagerFactory.getAPIManager] Verbose: API manager not in cache, creating new one");
885
+ }
750
886
  const settings2 = this.settingsManager.getSettings(sid);
887
+ if (verbose) {
888
+ console.error("[APIManagerFactory.getAPIManager] Verbose: Retrieved settings from settings manager");
889
+ console.error("[APIManagerFactory.getAPIManager] Verbose: Creating API manager from settings");
890
+ }
751
891
  const apiManager2 = this.createAPIManagerFromSettings(settings2);
892
+ if (verbose) {
893
+ console.error("[APIManagerFactory.getAPIManager] Verbose: API manager created successfully");
894
+ }
752
895
  this.apiManagerMap.set(sid, apiManager2);
896
+ } else if (verbose) {
897
+ console.error("[APIManagerFactory.getAPIManager] Verbose: Using cached API manager");
753
898
  }
754
899
  const apiManager = this.apiManagerMap.get(sid);
755
900
  const settings = this.settingsManager.getSettings(sid);
@@ -764,7 +909,17 @@ var APIManagerFactory = class {
764
909
  * @returns API Manager instance
765
910
  */
766
911
  createAPIManagerFromSettings(settings) {
767
- return this.apiManagerClass.create(settings);
912
+ const verbose = SettingsManager.globalDebugState;
913
+ if (verbose) {
914
+ console.error("[APIManagerFactory.createAPIManagerFromSettings] Verbose: Creating API manager from settings");
915
+ console.error("[APIManagerFactory.createAPIManagerFromSettings] Verbose: Settings type:", typeof settings);
916
+ console.error("[APIManagerFactory.createAPIManagerFromSettings] Verbose: Settings keys:", settings ? Object.keys(settings) : "null");
917
+ }
918
+ const apiManager = this.apiManagerClass.create(settings);
919
+ if (verbose) {
920
+ console.error("[APIManagerFactory.createAPIManagerFromSettings] Verbose: API manager created");
921
+ }
922
+ return apiManager;
768
923
  }
769
924
  /**
770
925
  * Clear API manager for a session
@@ -1117,7 +1272,8 @@ var SessionManager = class {
1117
1272
 
1118
1273
  // ../mcp-utils/dist/server-utils.js
1119
1274
  function getHeaderValue(headers, key) {
1120
- const value = headers[key] || headers[key.toUpperCase()] || headers[key.toLowerCase()];
1275
+ const normalizedKey = key.replace(/_/g, "-");
1276
+ const value = headers[normalizedKey] || headers[normalizedKey.toUpperCase()] || headers[normalizedKey.toLowerCase()];
1121
1277
  return typeof value === "string" ? value : Array.isArray(value) ? value[0] : void 0;
1122
1278
  }
1123
1279
  function createApiRunner(serverModule2) {
@@ -1126,27 +1282,238 @@ function createApiRunner(serverModule2) {
1126
1282
  return await apiManager.callApi(method, uri, data, domain);
1127
1283
  };
1128
1284
  }
1129
- function createServerModule(server2, Settings2, pkg2, apiManagerClass) {
1285
+ function wrapServerWithTracking(server2, createServerFn) {
1286
+ const registrations = [];
1287
+ const originalTool = server2.tool?.bind(server2);
1288
+ const originalPrompt = server2.prompt?.bind(server2);
1289
+ const originalResource = server2.resource?.bind(server2);
1290
+ if (originalTool) {
1291
+ server2.tool = function(...args) {
1292
+ registrations.push({ type: "tool", method: "tool", args: [...args] });
1293
+ return originalTool(...args);
1294
+ };
1295
+ }
1296
+ if (originalPrompt) {
1297
+ server2.prompt = function(...args) {
1298
+ registrations.push({ type: "prompt", method: "prompt", args: [...args] });
1299
+ return originalPrompt(...args);
1300
+ };
1301
+ }
1302
+ if (originalResource) {
1303
+ server2.resource = function(...args) {
1304
+ registrations.push({ type: "resource", method: "resource", args: [...args] });
1305
+ return originalResource(...args);
1306
+ };
1307
+ }
1308
+ const createInstance = () => {
1309
+ const newServer = createServerFn();
1310
+ for (const reg of registrations) {
1311
+ if (newServer[reg.method]) {
1312
+ newServer[reg.method](...reg.args);
1313
+ }
1314
+ }
1315
+ if (typeof server2.setToolPolicy === "function" && typeof newServer.setToolPolicy === "function") {
1316
+ const toolPolicy = server2._toolPolicyCallback;
1317
+ if (toolPolicy) {
1318
+ newServer.setToolPolicy(toolPolicy);
1319
+ }
1320
+ }
1321
+ return newServer;
1322
+ };
1323
+ return { wrappedServer: server2, createInstance };
1324
+ }
1325
+ function createServerModule(server2, Settings2, pkg2, apiManagerClass, toolPolicyCallback, createServerFn) {
1130
1326
  const settingsManager = new SettingsManager(Settings2);
1131
1327
  const apiManagerFactory = new APIManagerFactory(apiManagerClass, settingsManager);
1132
1328
  const sessionManager = new SessionManager();
1329
+ if (toolPolicyCallback && typeof server2.setToolPolicy === "function") {
1330
+ console.error("[createServerModule] Setting tool policy callback on server");
1331
+ server2.setToolPolicy(toolPolicyCallback);
1332
+ }
1333
+ const serverFactory = createServerFn || server2._createServerFn;
1334
+ let createServerInstance;
1335
+ if (serverFactory) {
1336
+ const { wrappedServer, createInstance } = wrapServerWithTracking(server2, serverFactory);
1337
+ createServerInstance = createInstance;
1338
+ console.error("[createServerModule] Server factory enabled - HTTP multi-user support active");
1339
+ } else {
1340
+ console.error("[createServerModule] Warning: No server factory provided - HTTP multi-user may have issues");
1341
+ }
1133
1342
  return {
1134
1343
  server: server2,
1135
1344
  Settings: Settings2,
1136
1345
  settingsManager,
1137
1346
  apiManagerFactory,
1138
1347
  sessionManager,
1139
- pkg: pkg2
1348
+ pkg: pkg2,
1349
+ toolPolicyCallback,
1350
+ createServerInstance
1140
1351
  };
1141
1352
  }
1142
1353
 
1143
1354
  // ../mcp-utils/dist/index.js
1144
1355
  init_ui_dialog();
1145
1356
 
1146
- // src/index.ts
1357
+ // ../mcp-utils/dist/telemetry.js
1358
+ import machineIdPkg from "node-machine-id";
1359
+ import { createHash } from "crypto";
1360
+ var { machineIdSync } = machineIdPkg;
1361
+ var machineId = null;
1362
+ var hashedMachineId = null;
1363
+ function isTelemetryDisabled() {
1364
+ return process.env.TELEMETRY_DISABLED === "true" || process.env.TELEMETRY_DISABLED === "1";
1365
+ }
1366
+ function getTelemetryUrl() {
1367
+ return process.env.TELEMETRY_URL || "https://metrics.security.ai.checkpoint.com/api/v1/metrics/collect";
1368
+ }
1369
+ function hashString(input) {
1370
+ return createHash("sha256").update(input).digest("hex");
1371
+ }
1372
+ function getMachineId() {
1373
+ if (!machineId) {
1374
+ try {
1375
+ machineId = machineIdSync();
1376
+ } catch (error) {
1377
+ console.warn("Failed to get machine ID for telemetry:", error);
1378
+ machineId = "unknown";
1379
+ }
1380
+ }
1381
+ return machineId;
1382
+ }
1383
+ function getHashedMachineId() {
1384
+ if (!hashedMachineId) {
1385
+ hashedMachineId = hashString(getMachineId());
1386
+ }
1387
+ return hashedMachineId;
1388
+ }
1389
+ function calculateChecksum(mcpName, toolName, machineId2, clientVersion) {
1390
+ const data = mcpName + machineId2.slice(0, 16) + toolName + clientVersion;
1391
+ return hashString(data);
1392
+ }
1393
+ async function trackToolCall(mcpName, toolName, clientVersion, extra) {
1394
+ if (isTelemetryDisabled()) {
1395
+ return;
1396
+ }
1397
+ try {
1398
+ const machineId2 = getHashedMachineId();
1399
+ const checksum = calculateChecksum(mcpName, toolName, machineId2, clientVersion);
1400
+ fetch(getTelemetryUrl(), {
1401
+ method: "POST",
1402
+ headers: { "Content-Type": "application/json" },
1403
+ body: JSON.stringify({
1404
+ mcp_name: mcpName,
1405
+ tool_name: toolName,
1406
+ machine_id: machineId2,
1407
+ client_version: clientVersion,
1408
+ checksum
1409
+ })
1410
+ }).catch(() => {
1411
+ });
1412
+ } catch (error) {
1413
+ }
1414
+ }
1415
+
1416
+ // ../mcp-utils/dist/mcp-server.js
1417
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
1418
+ var CPMcpServer = class extends McpServer {
1419
+ constructor(serverInfo, options) {
1420
+ super(serverInfo, options);
1421
+ this.mcpName = serverInfo.name;
1422
+ this.mcpVersion = serverInfo.version || "0.0.0";
1423
+ }
1424
+ /**
1425
+ * Set a tool policy callback to filter which tools are available
1426
+ * This should be called after all tools are registered but before connecting
1427
+ * @param callback Function that returns true if a tool should be enabled
1428
+ */
1429
+ setToolPolicy(callback) {
1430
+ console.error("[CPMcpServer] Setting tool policy callback");
1431
+ this.toolPolicyCallback = callback;
1432
+ }
1433
+ /**
1434
+ * Apply the tool policy by checking all registered tools
1435
+ * This should be called after all tools are registered but before connecting
1436
+ */
1437
+ applyToolPolicy() {
1438
+ if (!this.toolPolicyCallback) {
1439
+ console.error("[CPMcpServer] No tool policy callback set, allowing all tools");
1440
+ return;
1441
+ }
1442
+ console.error("[CPMcpServer] Applying tool policy");
1443
+ const registeredTools = this._registeredTools;
1444
+ if (!registeredTools || typeof registeredTools !== "object") {
1445
+ console.error("[CPMcpServer] No tools registered yet");
1446
+ return;
1447
+ }
1448
+ const toolNames = Object.keys(registeredTools);
1449
+ console.error(`[CPMcpServer] Found ${toolNames.length} registered tools:`, toolNames);
1450
+ let enabledCount = 0;
1451
+ let disabledCount = 0;
1452
+ for (const [toolName, tool] of Object.entries(registeredTools)) {
1453
+ const isAllowed = this.toolPolicyCallback(toolName);
1454
+ if (!isAllowed) {
1455
+ console.error(`[CPMcpServer] Tool '${toolName}' is NOT allowed by policy - disabling`);
1456
+ if (typeof tool.disable === "function") {
1457
+ tool.disable();
1458
+ disabledCount++;
1459
+ }
1460
+ } else {
1461
+ console.error(`[CPMcpServer] Tool '${toolName}' is allowed by policy`);
1462
+ enabledCount++;
1463
+ }
1464
+ }
1465
+ console.error(`[CPMcpServer] Policy applied: ${enabledCount}/${toolNames.length} tools enabled, ${disabledCount} disabled`);
1466
+ }
1467
+ // Override the tool method to wrap callbacks with telemetry
1468
+ tool(...args) {
1469
+ const callback = args[args.length - 1];
1470
+ if (typeof callback === "function") {
1471
+ const toolName = args[0];
1472
+ const wrappedCallback = async (...callbackArgs) => {
1473
+ let extra = callbackArgs[1];
1474
+ if (!extra && callbackArgs[0]?.sessionId) {
1475
+ extra = callbackArgs[0];
1476
+ }
1477
+ trackToolCall(this.mcpName, toolName, this.mcpVersion, extra).catch(() => {
1478
+ });
1479
+ if (callbackArgs.length === 1 && callbackArgs[0]?.sessionId) {
1480
+ return callback({}, callbackArgs[0]);
1481
+ }
1482
+ return callback(...callbackArgs);
1483
+ };
1484
+ args[args.length - 1] = wrappedCallback;
1485
+ }
1486
+ return super.tool(...args);
1487
+ }
1488
+ };
1489
+
1490
+ // ../mcp-utils/dist/package-utils.js
1147
1491
  import { readFileSync } from "fs";
1148
1492
  import { join as join2, dirname } from "path";
1149
1493
  import { fileURLToPath } from "url";
1494
+ function readPackageJson(importMetaUrl) {
1495
+ const pkg2 = JSON.parse(readFileSync(join2(dirname(fileURLToPath(importMetaUrl)), "../package.json"), "utf-8"));
1496
+ process.env.CP_MCP_MAIN_PKG = `${pkg2.name} v${pkg2.version}`;
1497
+ return pkg2;
1498
+ }
1499
+ function createMcpServer(importMetaUrl, serverInfo, options) {
1500
+ const pkg2 = readPackageJson(importMetaUrl);
1501
+ const fullServerInfo = {
1502
+ ...serverInfo,
1503
+ name: serverInfo.name || pkg2.name,
1504
+ version: serverInfo.version || pkg2.version
1505
+ };
1506
+ const createServerFn = () => {
1507
+ return new CPMcpServer(fullServerInfo, options);
1508
+ };
1509
+ const server2 = new CPMcpServer(fullServerInfo, options);
1510
+ server2._createServerFn = createServerFn;
1511
+ return { server: server2, pkg: pkg2 };
1512
+ }
1513
+
1514
+ // src/index.ts
1515
+ import { join as join3, dirname as dirname2 } from "path";
1516
+ import { fileURLToPath as fileURLToPath2 } from "url";
1150
1517
 
1151
1518
  // src/documentation-api-manager.ts
1152
1519
  import axios3 from "axios";
@@ -1167,9 +1534,59 @@ function nullOrEmpty(val) {
1167
1534
 
1168
1535
  // ../infra/dist/settings.js
1169
1536
  var Settings = class _Settings {
1170
- 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" } = {}) {
1537
+ normalizeRegion(region) {
1538
+ if (!region) {
1539
+ return void 0;
1540
+ }
1541
+ const normalized = region.trim().toUpperCase();
1542
+ return this.isValidRegion(normalized) ? normalized : void 0;
1543
+ }
1544
+ /**
1545
+ * Extract the base gateway URL (scheme + host) from a full URL.
1546
+ * Allows users to copy-paste any URL from the API key creation dialog
1547
+ * without having to strip the path manually.
1548
+ * Falls back to the original string if URL parsing fails.
1549
+ */
1550
+ static stripGatewayPath(url) {
1551
+ try {
1552
+ const parsed = new URL(url);
1553
+ return `${parsed.protocol}//${parsed.host}`;
1554
+ } catch {
1555
+ return url;
1556
+ }
1557
+ }
1558
+ /**
1559
+ * Detect the region from a gateway base URL
1560
+ */
1561
+ static detectRegionFromUrl(url) {
1562
+ if (url.includes("cloudinfra-gw-us.portal.checkpoint.com"))
1563
+ return "US";
1564
+ if (url.includes("cloudinfra-gw.portal.checkpoint.com"))
1565
+ return "EU";
1566
+ if (url.includes("dev-cloudinfra-gw"))
1567
+ return "STG";
1568
+ return void 0;
1569
+ }
1570
+ 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 } = {}) {
1171
1571
  this.region = "EU";
1172
1572
  this.devPort = "8006";
1573
+ this.gatewayUrl = "";
1574
+ const verbose = SettingsManager.globalDebugState;
1575
+ if (verbose) {
1576
+ console.error("[Settings] Verbose: Constructor called with params:", {
1577
+ apiKey: apiKey ? "***" : void 0,
1578
+ username: username ? "***" : void 0,
1579
+ password: password ? "***" : void 0,
1580
+ s1cUrl,
1581
+ managementHost,
1582
+ managementPort,
1583
+ cloudInfraToken: cloudInfraToken ? "***" : void 0,
1584
+ clientId,
1585
+ secretKey: secretKey ? "***" : void 0,
1586
+ region,
1587
+ devPort
1588
+ });
1589
+ }
1173
1590
  this.apiKey = apiKey;
1174
1591
  this.username = username;
1175
1592
  this.password = password;
@@ -1179,8 +1596,21 @@ var Settings = class _Settings {
1179
1596
  this.cloudInfraToken = cloudInfraToken;
1180
1597
  this.clientId = clientId;
1181
1598
  this.secretKey = secretKey;
1182
- this.region = this.isValidRegion(region) ? region : "EU";
1599
+ this.region = this.normalizeRegion(region) || "EU";
1183
1600
  this.devPort = devPort;
1601
+ this.gatewayUrl = this.resolveGatewayUrl(this.region, gatewayUrl);
1602
+ if (verbose) {
1603
+ console.error("[Settings] Verbose: After assignment:", {
1604
+ apiKey: this.apiKey ? "***" : void 0,
1605
+ username: this.username ? "***" : void 0,
1606
+ password: this.password ? "***" : void 0,
1607
+ s1cUrl: this.s1cUrl,
1608
+ managementHost: this.managementHost,
1609
+ managementPort: this.managementPort,
1610
+ cloudInfraToken: this.cloudInfraToken ? "***" : void 0,
1611
+ region: this.region
1612
+ });
1613
+ }
1184
1614
  this.validate();
1185
1615
  }
1186
1616
  /**
@@ -1190,10 +1620,10 @@ var Settings = class _Settings {
1190
1620
  return ["EU", "US", "STG", "LOCAL"].includes(region.toUpperCase());
1191
1621
  }
1192
1622
  /**
1193
- * Get Cloud Infra Gateway based on region
1623
+ * Get the base gateway URL for a given region
1194
1624
  */
1195
- getCloudInfraGateway() {
1196
- switch (this.region) {
1625
+ getRegionGatewayUrl(region) {
1626
+ switch (region) {
1197
1627
  case "EU":
1198
1628
  return "https://cloudinfra-gw.portal.checkpoint.com";
1199
1629
  case "US":
@@ -1205,23 +1635,88 @@ var Settings = class _Settings {
1205
1635
  return "";
1206
1636
  }
1207
1637
  }
1638
+ /**
1639
+ * Resolve the base gateway URL from either a provided URL or the configured region.
1640
+ * If a URL is provided, its path suffix is stripped so users can paste the full
1641
+ * auth URL from the API key creation dialog (e.g. ending in /auth/external).
1642
+ * When the URL implies a different region, this.region is updated to match.
1643
+ */
1644
+ resolveGatewayUrl(region, providedUrl) {
1645
+ if (!providedUrl) {
1646
+ return this.getRegionGatewayUrl(region);
1647
+ }
1648
+ const base = _Settings.stripGatewayPath(providedUrl);
1649
+ const detectedRegion = _Settings.detectRegionFromUrl(base);
1650
+ if (detectedRegion && detectedRegion !== this.region) {
1651
+ this.region = detectedRegion;
1652
+ }
1653
+ return base;
1654
+ }
1655
+ /**
1656
+ * Get the base Cloud Infra Gateway URL.
1657
+ * Returns the precomputed gatewayUrl (derived from region or a provided URL).
1658
+ */
1659
+ getCloudInfraGateway() {
1660
+ return this.gatewayUrl;
1661
+ }
1208
1662
  /**
1209
1663
  * Validate the settings
1210
1664
  */
1211
1665
  validate() {
1666
+ const verbose = SettingsManager.globalDebugState;
1667
+ if (verbose) {
1668
+ console.error("[Settings] Verbose: Validating settings...");
1669
+ console.error("[Settings] Verbose: s1cUrl:", this.s1cUrl || "(empty)");
1670
+ console.error("[Settings] Verbose: managementHost:", this.managementHost || "(empty)");
1671
+ console.error("[Settings] Verbose: apiKey:", this.apiKey ? "***" : "(empty)");
1672
+ console.error("[Settings] Verbose: cloudInfraToken:", this.cloudInfraToken ? "***" : "(empty)");
1673
+ console.error("[Settings] Verbose: username:", this.username ? "***" : "(empty)");
1674
+ console.error("[Settings] Verbose: password:", this.password ? "***" : "(empty)");
1675
+ }
1212
1676
  if (!nullOrEmpty(this.s1cUrl) && nullOrEmpty(this.apiKey) && nullOrEmpty(this.cloudInfraToken)) {
1677
+ if (verbose) {
1678
+ console.error("[Settings] Verbose: Validation FAILED - S1C URL provided but no API key or CI token");
1679
+ }
1213
1680
  throw new Error("API key or CI Token is required for S1C (via --api-key or API_KEY env var)");
1214
1681
  }
1215
1682
  if (!nullOrEmpty(this.managementHost) && nullOrEmpty(this.apiKey) && (nullOrEmpty(this.username) || nullOrEmpty(this.password))) {
1683
+ if (verbose) {
1684
+ console.error("[Settings] Verbose: Validation FAILED - Management host provided but no API key or credentials");
1685
+ }
1216
1686
  throw new Error("Either API key or username/password are required for on-prem management (via CLI args or env vars)");
1217
1687
  }
1218
1688
  if (nullOrEmpty(this.s1cUrl) && nullOrEmpty(this.managementHost)) {
1689
+ if (verbose) {
1690
+ console.error("[Settings] Verbose: WARNING - Neither s1cUrl nor managementHost provided");
1691
+ }
1692
+ }
1693
+ if (verbose) {
1694
+ console.error("[Settings] Verbose: Validation PASSED");
1219
1695
  }
1220
1696
  }
1221
1697
  /**
1222
1698
  * Create settings from command-line arguments
1223
1699
  */
1224
1700
  static fromArgs(args) {
1701
+ const verbose = SettingsManager.globalDebugState;
1702
+ if (verbose) {
1703
+ console.error("[Settings.fromArgs] Verbose: Creating settings from args");
1704
+ console.error("[Settings.fromArgs] Verbose: Raw args:", {
1705
+ apiKey: args.apiKey ? "***" : void 0,
1706
+ username: args.username ? "***" : void 0,
1707
+ password: args.password ? "***" : void 0,
1708
+ s1cUrl: args.s1cUrl,
1709
+ managementHost: args.managementHost,
1710
+ managementPort: args.managementPort,
1711
+ cloudInfraToken: args.cloudInfraToken ? "***" : void 0,
1712
+ region: args.region,
1713
+ hasOtherKeys: Object.keys(args).length > 10
1714
+ });
1715
+ const hasAnyValue = args.apiKey || args.username || args.password || args.s1cUrl || args.managementHost || args.cloudInfraToken;
1716
+ if (!hasAnyValue) {
1717
+ console.error("[Settings.fromArgs] Verbose: WARNING - Args object appears empty, no authentication values found");
1718
+ }
1719
+ }
1225
1720
  return new _Settings({
1226
1721
  apiKey: args.apiKey,
1227
1722
  username: args.username,
@@ -1232,8 +1727,9 @@ var Settings = class _Settings {
1232
1727
  cloudInfraToken: args.cloudInfraToken,
1233
1728
  clientId: args.clientId,
1234
1729
  secretKey: args.secretKey,
1235
- region: typeof args.region === "string" ? args.region.toUpperCase() : void 0,
1236
- devPort: args.devPort
1730
+ region: typeof args.region === "string" ? args.region.trim().toUpperCase() : void 0,
1731
+ devPort: args.devPort,
1732
+ gatewayUrl: args.gatewayUrl
1237
1733
  });
1238
1734
  }
1239
1735
  /**
@@ -1241,7 +1737,12 @@ var Settings = class _Settings {
1241
1737
  * Maps headers to environment variable format based on server config
1242
1738
  */
1243
1739
  static fromHeaders(headers) {
1244
- return new _Settings({
1740
+ const verbose = SettingsManager.globalDebugState;
1741
+ if (verbose) {
1742
+ console.error("[Settings.fromHeaders] Verbose: Creating settings from headers");
1743
+ console.error("[Settings.fromHeaders] Verbose: Available header keys:", Object.keys(headers));
1744
+ }
1745
+ const extractedValues = {
1245
1746
  apiKey: getHeaderValue(headers, "API-KEY"),
1246
1747
  username: getHeaderValue(headers, "USERNAME"),
1247
1748
  password: getHeaderValue(headers, "PASSWORD"),
@@ -1251,8 +1752,41 @@ var Settings = class _Settings {
1251
1752
  cloudInfraToken: getHeaderValue(headers, "CLOUD-INFRA-TOKEN"),
1252
1753
  clientId: getHeaderValue(headers, "CLIENT-ID"),
1253
1754
  secretKey: getHeaderValue(headers, "SECRET-KEY"),
1254
- region: getHeaderValue(headers, "REGION")?.toUpperCase(),
1255
- devPort: getHeaderValue(headers, "DEV-PORT")
1755
+ region: getHeaderValue(headers, "REGION"),
1756
+ devPort: getHeaderValue(headers, "DEV-PORT"),
1757
+ gatewayUrl: getHeaderValue(headers, "GATEWAY-URL")
1758
+ };
1759
+ if (verbose) {
1760
+ console.error("[Settings.fromHeaders] Verbose: Extracted values:", {
1761
+ apiKey: extractedValues.apiKey ? "***" : void 0,
1762
+ username: extractedValues.username ? "***" : void 0,
1763
+ password: extractedValues.password ? "***" : void 0,
1764
+ s1cUrl: extractedValues.s1cUrl,
1765
+ managementHost: extractedValues.managementHost,
1766
+ managementPort: extractedValues.managementPort,
1767
+ cloudInfraToken: extractedValues.cloudInfraToken ? "***" : void 0,
1768
+ region: extractedValues.region,
1769
+ devPort: extractedValues.devPort
1770
+ });
1771
+ const hasAnyValue = extractedValues.apiKey || extractedValues.username || extractedValues.password || extractedValues.s1cUrl || extractedValues.managementHost || extractedValues.cloudInfraToken;
1772
+ if (!hasAnyValue) {
1773
+ console.error("[Settings.fromHeaders] Verbose: WARNING - No authentication values found in headers");
1774
+ 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])));
1775
+ }
1776
+ }
1777
+ return new _Settings({
1778
+ apiKey: extractedValues.apiKey,
1779
+ username: extractedValues.username,
1780
+ password: extractedValues.password,
1781
+ s1cUrl: extractedValues.s1cUrl,
1782
+ managementHost: extractedValues.managementHost,
1783
+ managementPort: extractedValues.managementPort,
1784
+ cloudInfraToken: extractedValues.cloudInfraToken,
1785
+ clientId: extractedValues.clientId,
1786
+ secretKey: extractedValues.secretKey,
1787
+ region: extractedValues.region?.toUpperCase(),
1788
+ devPort: extractedValues.devPort,
1789
+ gatewayUrl: extractedValues.gatewayUrl
1256
1790
  });
1257
1791
  }
1258
1792
  };
@@ -1415,30 +1949,38 @@ var DocumentationToolAPIManager = class _DocumentationToolAPIManager {
1415
1949
  // src/settings.ts
1416
1950
  var DocumentationToolSettings = class _DocumentationToolSettings extends Settings {
1417
1951
  constructor(args = {}) {
1418
- super(args);
1952
+ super({
1953
+ ...args,
1954
+ gatewayUrl: args.authUrl || args.gatewayUrl
1955
+ });
1419
1956
  }
1420
1957
  /**
1421
1958
  * Create DocumentationToolSettings from command-line arguments for Documentation Tool
1422
1959
  */
1423
1960
  static fromArgs(args) {
1961
+ if (!args.authUrl && !args.region) {
1962
+ throw new Error(
1963
+ "Provide either --auth-url (Authentication URL from the API key creation dialog) or --region (EU, US, STG, or LOCAL)"
1964
+ );
1965
+ }
1424
1966
  return new _DocumentationToolSettings({
1425
1967
  ...args
1426
1968
  });
1427
1969
  }
1970
+ static fromHeaders(headers) {
1971
+ return new _DocumentationToolSettings({
1972
+ clientId: getHeaderValue(headers, "CLIENT-ID"),
1973
+ secretKey: getHeaderValue(headers, "SECRET-KEY"),
1974
+ region: getHeaderValue(headers, "REGION"),
1975
+ authUrl: getHeaderValue(headers, "AUTH-URL")
1976
+ });
1977
+ }
1428
1978
  };
1429
1979
 
1430
1980
  // src/index.ts
1431
- var pkg = JSON.parse(
1432
- readFileSync(
1433
- join2(dirname(fileURLToPath(import.meta.url)), "../package.json"),
1434
- "utf-8"
1435
- )
1436
- );
1437
- process.env.CP_MCP_MAIN_PKG = `${pkg.name} v${pkg.version}`;
1438
- var server = new McpServer({
1981
+ var { server, pkg } = createMcpServer(import.meta.url, {
1439
1982
  name: "checkpoint-documentation",
1440
- description: "Comprehensive Check Point documentation assistant providing instant access to product information, technical specifications, configuration guidance, and feature documentation across the entire Check Point security portfolio.",
1441
- version: "1.0.0"
1983
+ description: "Comprehensive Check Point documentation assistant providing instant access to product information, technical specifications, configuration guidance, and feature documentation across the entire Check Point security portfolio."
1442
1984
  });
1443
1985
  var serverModule = createServerModule(
1444
1986
  server,
@@ -1544,7 +2086,7 @@ server.tool(
1544
2086
  );
1545
2087
  var main = async () => {
1546
2088
  await launchMCPServer(
1547
- join2(dirname(fileURLToPath(import.meta.url)), "server-config.json"),
2089
+ join3(dirname2(fileURLToPath2(import.meta.url)), "server-config.json"),
1548
2090
  serverModule
1549
2091
  );
1550
2092
  };
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chkp/documentation-mcp",
3
- "version": "1.0.1",
3
+ "version": "1.3.0",
4
4
  "description": "Check Point Documentation Tool Service - API integration with Check Point Documentation Tool",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -26,9 +26,10 @@
26
26
  "start": "node dist/index.js"
27
27
  },
28
28
  "dependencies": {
29
- "@modelcontextprotocol/sdk": "^1.11.1",
30
- "axios": "^1.12.1",
29
+ "@modelcontextprotocol/sdk": "^1.26.0",
30
+ "axios": "^1.13.5",
31
31
  "commander": "^13.1.0",
32
+ "node-machine-id": "^1.1.12",
32
33
  "zod": "^3.22.4"
33
34
  },
34
35
  "devDependencies": {
@@ -7,20 +7,33 @@
7
7
  "description": "Client ID for authentication with Documentation Tool",
8
8
  "env": "CLIENT_ID",
9
9
  "required": true,
10
- "type": "string"
10
+ "type": "string",
11
+ "help": "Client ID for Check Point Documentation Tool authentication. To obtain: log in to the Infinity Portal β†’ API Keys β†’ New β†’ New User API Key β†’ copy the generated Client ID"
11
12
  },
12
13
  {
13
14
  "flag": "--secret-key <secret-key>",
14
15
  "description": "Secret Key for authentication with Documentation Tool",
15
16
  "env": "SECRET_KEY",
16
17
  "required": true,
17
- "type": "string"
18
+ "type": "string",
19
+ "help": "Secret Key for Check Point Documentation Tool authentication. Generated alongside the Client ID β€” copy and store it securely at creation time as it will not be shown again"
20
+ },
21
+ {
22
+ "flag": "--auth-url <url>",
23
+ "description": "Authentication URL from the API key creation dialog",
24
+ "env": "AUTH_URL",
25
+ "required": true,
26
+ "type": "string",
27
+ "help": "Paste the Authentication URL shown when creating your API key (e.g. https://cloudinfra-gw.portal.checkpoint.com/auth/external). The path suffix is stripped automatically so you can copy it directly from the portal"
18
28
  },
19
29
  {
20
30
  "flag": "--region <region>",
21
- "description": "Documentation Tool region: EU, US, STG, or Local",
31
+ "description": "Documentation Tool region: EU, US, STG, or LOCAL",
22
32
  "env": "REGION",
23
- "type": "string"
33
+ "required": false,
34
+ "hidden": true,
35
+ "type": "string",
36
+ "help": "Alternative to --auth-url. Region code for your deployment: EU, US, STG, or LOCAL. Use this if you know your region and prefer not to copy the full authentication URL"
24
37
  }
25
38
  ]
26
- }
39
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chkp/documentation-mcp",
3
- "version": "1.0.1",
3
+ "version": "1.3.0",
4
4
  "description": "Check Point Documentation Tool Service - API integration with Check Point Documentation Tool",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -26,9 +26,10 @@
26
26
  "start": "node dist/index.js"
27
27
  },
28
28
  "dependencies": {
29
- "@modelcontextprotocol/sdk": "^1.0.4",
29
+ "@modelcontextprotocol/sdk": "^1.26.0",
30
30
  "commander": "^13.1.0",
31
- "axios": "^1.12.1",
31
+ "axios": "^1.13.5",
32
+ "node-machine-id": "^1.1.12",
32
33
  "zod": "^3.24.4"
33
34
  },
34
35
  "devDependencies": {