@chkp/policy-insights-mcp 0.2.0 → 0.3.4

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/README.md CHANGED
@@ -29,6 +29,9 @@ Together they give you the full picture: combine actual rule content with insigh
29
29
  - Get when new insights are planned to be generated
30
30
  - Retrieve detailed information when you can't see insights
31
31
 
32
+ ## Management API Version
33
+
34
+ This server supports **Management API v2.1 (R82.10+)**. It is generally compatible with earlier versions; some parameters may not be available on older management servers.
32
35
 
33
36
  ## Example Use Cases
34
37
 
@@ -248,6 +251,40 @@ Add the configuration as Claude Desktop App.
248
251
 
249
252
  ---
250
253
 
254
+ ## HTTP Transport
255
+
256
+ By default, this server uses **stdio** transport, which is the standard mode for MCP clients like Claude Desktop and Cursor. For hosted or multi-user deployments, an **HTTP transport** (MCP Streamable HTTP) is also available.
257
+
258
+ > **Security notice before you continue:** The HTTP server has no built-in authentication and no TLS. Any client that can reach the port can establish a session, and credentials travel in cleartext. Only use HTTP transport behind an authenticated reverse proxy (nginx, Caddy, a cloud load balancer) that terminates TLS and enforces authentication. If you are running the server on the same machine as your MCP client, use the default stdio transport — it has none of these concerns.
259
+
260
+ ### Starting the server in HTTP mode
261
+
262
+ ```bash
263
+ MCP_TRANSPORT_TYPE=http MCP_TRANSPORT_PORT=3000 npx @chkp/policy-insights-mcp
264
+ # or
265
+ npx @chkp/policy-insights-mcp --transport http --transport-port 3000
266
+ ```
267
+
268
+ The server exposes:
269
+ - `POST/GET/DELETE /mcp` — MCP protocol endpoint
270
+ - `GET /health` — server status (active session count, version)
271
+
272
+ ### Connecting an MCP client
273
+
274
+ Point your MCP client at `http://<host>:3000/mcp`. Example for Claude Desktop (`claude_desktop_config.json`):
275
+
276
+ ```json
277
+ {
278
+ "mcpServers": {
279
+ "policy-insights": {
280
+ "url": "http://localhost:3000/mcp"
281
+ }
282
+ }
283
+ }
284
+ ```
285
+
286
+ ---
287
+
251
288
  ## Development
252
289
 
253
290
  ### Prerequisites
package/dist/index.js CHANGED
@@ -986,13 +986,15 @@ var ClientResponse = class {
986
986
  }
987
987
  };
988
988
  var APIClientBase = class {
989
- constructor(authToken = "", tokenType = TokenType.API_KEY) {
989
+ constructor(authToken = "", tokenType = TokenType.API_KEY, cloudConnected = false) {
990
990
  this.authToken = authToken;
991
991
  this.tokenType = tokenType;
992
+ this.cloudConnected = cloudConnected;
992
993
  this.sid = null;
993
994
  this.sessionTimeout = null;
994
995
  this.sessionStart = null;
995
996
  this.isMDS = false;
997
+ this._externalSid = false;
996
998
  }
997
999
  /**
998
1000
  * Create an API client instance - generic method for creating clients
@@ -1011,6 +1013,10 @@ var APIClientBase = class {
1011
1013
  if (this.sid) {
1012
1014
  headers["X-chkp-sid"] = this.sid;
1013
1015
  }
1016
+ if (this.cloudConnected && this.tokenType === TokenType.CI_TOKEN) {
1017
+ headers["Authorization"] = `Bearer ${this.authToken}`;
1018
+ headers["CLOUD-INFRA-TOKEN"] = this.authToken;
1019
+ }
1014
1020
  return headers;
1015
1021
  }
1016
1022
  /**
@@ -1026,9 +1032,22 @@ var APIClientBase = class {
1026
1032
  this._debug = value;
1027
1033
  }
1028
1034
  /**
1029
- * Check if this client needs to perform login before making API calls
1035
+ * Set a pre-authenticated session ID provided externally (e.g. via X-chkp-sid header).
1036
+ * When set, the client will skip login and use this SID directly for all requests.
1030
1037
  */
1038
+ setExternalSid(sid) {
1039
+ this.sid = sid;
1040
+ this._externalSid = true;
1041
+ this.sessionStart = Date.now();
1042
+ this.sessionTimeout = Number.MAX_SAFE_INTEGER / 1e3;
1043
+ }
1044
+ /**
1045
+ * Check if this client needs to perform login before making API calls
1046
+ */
1031
1047
  needsLogin() {
1048
+ if (this._externalSid) {
1049
+ return false;
1050
+ }
1032
1051
  return true;
1033
1052
  }
1034
1053
  /**
@@ -1087,6 +1106,9 @@ var APIClientBase = class {
1087
1106
  return await this.makeRequest(this.getHost(), method, uri, data, this.getHeaders(), params, httpsAgent);
1088
1107
  } catch (error) {
1089
1108
  if ((error.message?.includes("401") || error.response?.status === 401) && error.message?.toLowerCase().includes("session")) {
1109
+ if (this._externalSid) {
1110
+ throw new Error("Pre-authenticated session (X-chkp-sid) has expired. Provide a new session ID.");
1111
+ }
1090
1112
  console.error("Session expired (401), resetting session and retrying...");
1091
1113
  this.sid = null;
1092
1114
  this.sessionStart = null;
@@ -1114,12 +1136,20 @@ var APIClientBase = class {
1114
1136
  const now = Date.now();
1115
1137
  return now > this.sessionStart + (this.sessionTimeout - 5) * 1e3;
1116
1138
  }
1139
+ getHeadersForLogin() {
1140
+ return { "Content-Type": "application/json" };
1141
+ }
1117
1142
  /**
1118
1143
  * Login to the API using the API key
1119
1144
  */
1120
1145
  async login() {
1146
+ if (this._externalSid) {
1147
+ if (!this.sid)
1148
+ throw new Error("External SID has expired");
1149
+ return this.sid;
1150
+ }
1121
1151
  const apiTokenHeader = this.tokenType === TokenType.API_KEY ? "api-key" : "ci-token";
1122
- const loginResp = await this.makeRequest(this.getHost(), "POST", "login", { [apiTokenHeader]: this.authToken }, { "Content-Type": "application/json" });
1152
+ const loginResp = await this.makeRequest(this.getHost(), "POST", "login", { [apiTokenHeader]: this.authToken }, this.getHeadersForLogin());
1123
1153
  if (loginResp.status !== 200 || !loginResp.response || !loginResp.response.sid) {
1124
1154
  throw loginResp;
1125
1155
  }
@@ -1193,19 +1223,27 @@ var APIClientBase = class {
1193
1223
  }
1194
1224
  };
1195
1225
  var SmartOneCloudAPIClient = class extends APIClientBase {
1196
- constructor(authToken, tokenType, s1cUrl) {
1197
- super(authToken, tokenType);
1226
+ constructor(authToken, tokenType, s1cUrl, cloudConnected = false) {
1227
+ super(authToken, tokenType, cloudConnected);
1198
1228
  this.s1cUrl = s1cUrl;
1199
1229
  }
1200
1230
  getHost() {
1201
1231
  return this.s1cUrl;
1202
1232
  }
1233
+ getHeadersForLogin() {
1234
+ const headers = { "Content-Type": "application/json" };
1235
+ if (this.cloudConnected && this.tokenType === TokenType.CI_TOKEN) {
1236
+ headers["Authorization"] = `Bearer ${this.authToken}`;
1237
+ }
1238
+ return headers;
1239
+ }
1203
1240
  };
1204
1241
  var OnPremAPIClient = class extends APIClientBase {
1205
- constructor(apiKey, managementHost, managementPort = "443", username, password) {
1242
+ constructor(apiKey, managementHost, managementPort = "443", username, password, domain) {
1206
1243
  super(apiKey || "");
1207
1244
  this.managementHost = managementHost;
1208
1245
  this.managementPort = managementPort;
1246
+ this.domain = domain;
1209
1247
  this.username = username;
1210
1248
  this.password = password;
1211
1249
  }
@@ -1219,6 +1257,11 @@ var OnPremAPIClient = class extends APIClientBase {
1219
1257
  * and allow self-signed certificates
1220
1258
  */
1221
1259
  async login() {
1260
+ if (this._externalSid) {
1261
+ if (!this.sid)
1262
+ throw new Error("External SID has expired");
1263
+ return this.sid;
1264
+ }
1222
1265
  const isUsingApiKey = !!this.authToken;
1223
1266
  const isUsingCredentials = !!(this.username && this.password);
1224
1267
  if (!isUsingApiKey && !isUsingCredentials) {
@@ -1226,6 +1269,9 @@ var OnPremAPIClient = class extends APIClientBase {
1226
1269
  }
1227
1270
  const httpsAgent = new https.Agent({ rejectUnauthorized: false });
1228
1271
  const loginPayload = isUsingApiKey ? { "api-key": this.authToken } : { "user": this.username, "password": this.password };
1272
+ if (this.domain) {
1273
+ loginPayload["domain"] = this.domain;
1274
+ }
1229
1275
  const loginResp = await this.makeRequest(this.getHost(), "POST", "login", loginPayload, { "Content-Type": "application/json" }, null, httpsAgent);
1230
1276
  if (loginResp.status !== 200 || !loginResp.response || !loginResp.response.sid) {
1231
1277
  throw loginResp;
@@ -2407,6 +2453,7 @@ var APIManagerBase = class {
2407
2453
  this.domainClients = /* @__PURE__ */ new Map();
2408
2454
  this.gatewayDomainMap = /* @__PURE__ */ new Map();
2409
2455
  this.domains = null;
2456
+ this.mdsServers = null;
2410
2457
  }
2411
2458
  /**
2412
2459
  * Set debug mode for the API client
@@ -2430,7 +2477,7 @@ var APIManagerBase = class {
2430
2477
  */
2431
2478
  async callApi(method, uri, data, domain) {
2432
2479
  const sanitizedData = sanitizeData(data);
2433
- const apiClient = domain ? await this.getDomainApiClientByDomain(domain) : this.client;
2480
+ const apiClient = domain && !data["domains-to-process"] ? await this.getDomainApiClientByDomain(domain) : this.client;
2434
2481
  const clientResponse = await apiClient.callApi(method, uri, sanitizedData, void 0);
2435
2482
  return clientResponse.response;
2436
2483
  }
@@ -2471,23 +2518,35 @@ var APIManagerBase = class {
2471
2518
  if (this.domains !== null) {
2472
2519
  return this.domains;
2473
2520
  }
2474
- const response = await this.callApi("post", "show-domains", {
2475
- "details-level": "full"
2476
- });
2477
- const domains = [];
2478
- if (response.objects) {
2479
- for (const obj of response.objects) {
2480
- if (obj.name && obj.type) {
2481
- domains.push({
2482
- name: obj.name,
2483
- type: obj.type,
2484
- servers: obj.servers || []
2485
- });
2521
+ const allDomains = [];
2522
+ const limit = 50;
2523
+ let offset = 0;
2524
+ let total = Infinity;
2525
+ while (offset < total) {
2526
+ const response = await this.callApi("post", "show-domains", {
2527
+ "details-level": "full",
2528
+ "limit": limit,
2529
+ "offset": offset
2530
+ });
2531
+ if (response.objects) {
2532
+ for (const obj of response.objects) {
2533
+ if (obj.name && obj.type) {
2534
+ allDomains.push({
2535
+ name: obj.name,
2536
+ type: obj.type,
2537
+ servers: obj.servers || []
2538
+ });
2539
+ }
2486
2540
  }
2487
2541
  }
2542
+ total = typeof response.total === "number" ? response.total : allDomains.length;
2543
+ offset += limit;
2544
+ if (!response.objects || response.objects.length === 0) {
2545
+ break;
2546
+ }
2488
2547
  }
2489
- this.domains = domains;
2490
- return domains;
2548
+ this.domains = allDomains;
2549
+ return this.domains;
2491
2550
  }
2492
2551
  /**
2493
2552
  * Create an API manager instance
@@ -2531,9 +2590,18 @@ var APIManagerBase = class {
2531
2590
  return domainClient;
2532
2591
  }
2533
2592
  /**
2534
- * Get the appropriate API client for a specific domain, handling MDS domain routing
2535
- * This method handles multi-MDS environments where domains may be distributed across
2536
- * different MDS servers with active/standby configurations.
2593
+ * Get the appropriate API client for a specific domain, handling MDS domain routing.
2594
+ * Uses login -d (credential-based domain login) as the primary path.
2595
+ *
2596
+ * Flow:
2597
+ * 1. login -d on current MDS root (works for both local and standby domains)
2598
+ * 2. Cross-MDS: find target MDS root IP via show-mdss, then login -d there
2599
+ * 3. Last resort: login directly to the active DMS virtual IP
2600
+ *
2601
+ * NOTE: This server currently exposes read-only APIs only. For reads, landing on a
2602
+ * standby DMS is acceptable — the data is replicated. If write operations are added
2603
+ * in the future, step 1 must be changed to enforce routing to the ACTIVE DMS server
2604
+ * (use getMDSServerForDomain which selects the active server from show-domains).
2537
2605
  */
2538
2606
  async getDomainApiClientByDomain(domainName) {
2539
2607
  const isMDS = await this.client.isMDSEnvironment();
@@ -2544,35 +2612,40 @@ var APIManagerBase = class {
2544
2612
  if (existingDomainClient && existingDomainClient.hasValidSession()) {
2545
2613
  return existingDomainClient;
2546
2614
  }
2547
- const isOnCurrentMDS = await this.isDomainOnCurrentMDS(domainName);
2548
- if (isOnCurrentMDS) {
2549
- const domainSid2 = await this.loginToDomain(domainName);
2550
- const domainClient2 = this.createClientWithSid(domainSid2);
2551
- this.domainClients.set(domainName, domainClient2);
2552
- return domainClient2;
2553
- }
2554
- const targetMDSIP = await this.getMDSServerForDomain(domainName);
2555
- if (!targetMDSIP) {
2556
- throw new Error(`Domain '${domainName}' not found or has no available MDS servers. Make sure the domain exists and you have access to it.`);
2557
- }
2558
2615
  const currentHost = this.client.getHost();
2559
2616
  const portMatch = currentHost.match(/:(\d+)/);
2560
2617
  const port = portMatch ? portMatch[1] : "443";
2561
- const newMDSClient = this.createClientForMDS(targetMDSIP, port);
2562
- if ("debug" in newMDSClient) {
2563
- newMDSClient.debug = this._debug;
2618
+ try {
2619
+ const domainClient = this.createClientForMDS(this.client.managementHost, port, domainName);
2620
+ if ("debug" in domainClient)
2621
+ domainClient.debug = this._debug;
2622
+ await domainClient.login();
2623
+ this.domainClients.set(domainName, domainClient);
2624
+ return domainClient;
2625
+ } catch {
2564
2626
  }
2565
- await newMDSClient.login();
2566
- const loginResponse = await newMDSClient.callApi("post", "login-to-domain", {
2567
- "domain": domainName
2568
- }, void 0);
2569
- if (!loginResponse.response.sid) {
2570
- throw new Error(`Failed to login to domain '${domainName}' on MDS server ${targetMDSIP}`);
2627
+ const targetMDSIP = await this.getMDSRootForDomain(domainName);
2628
+ if (targetMDSIP) {
2629
+ try {
2630
+ const crossMDSClient = this.createClientForMDS(targetMDSIP, port, domainName);
2631
+ if ("debug" in crossMDSClient)
2632
+ crossMDSClient.debug = this._debug;
2633
+ await crossMDSClient.login();
2634
+ this.domainClients.set(domainName, crossMDSClient);
2635
+ return crossMDSClient;
2636
+ } catch {
2637
+ }
2571
2638
  }
2572
- const domainSid = loginResponse.response.sid;
2573
- const domainClient = this.createClientWithSid(domainSid);
2574
- this.domainClients.set(domainName, domainClient);
2575
- return domainClient;
2639
+ const dmsIP = await this.getMDSServerForDomain(domainName);
2640
+ if (!dmsIP) {
2641
+ throw new Error(`Domain '${domainName}' not found or has no available servers. Make sure the domain exists and you have access to it.`);
2642
+ }
2643
+ const targetClient = this.createClientForMDS(dmsIP, port);
2644
+ if ("debug" in targetClient)
2645
+ targetClient.debug = this._debug;
2646
+ await targetClient.login();
2647
+ this.domainClients.set(domainName, targetClient);
2648
+ return targetClient;
2576
2649
  }
2577
2650
  /**
2578
2651
  * Get gateway information from show-gateways-and-servers
@@ -2611,20 +2684,53 @@ var APIManagerBase = class {
2611
2684
  }
2612
2685
  }
2613
2686
  /**
2614
- * Check if a domain exists on the current MDS server (either active or standby)
2687
+ * Get MDS server list from show-mdss with caching
2688
+ */
2689
+ async getMDSServers() {
2690
+ if (this.mdsServers !== null) {
2691
+ return this.mdsServers;
2692
+ }
2693
+ try {
2694
+ const response = await this.callApi("post", "show-mdss", {
2695
+ "details-level": "full",
2696
+ "limit": 500
2697
+ });
2698
+ const servers = [];
2699
+ if (response.objects) {
2700
+ for (const obj of response.objects) {
2701
+ if (obj.name) {
2702
+ servers.push({
2703
+ name: obj.name,
2704
+ "ipv4-address": obj["ipv4-address"],
2705
+ "ipv6-address": obj["ipv6-address"]
2706
+ });
2707
+ }
2708
+ }
2709
+ }
2710
+ this.mdsServers = servers;
2711
+ } catch {
2712
+ this.mdsServers = [];
2713
+ }
2714
+ return this.mdsServers;
2715
+ }
2716
+ /**
2717
+ * Return the MDS root IP for the domain's active server.
2718
+ * Maps the domain's `multi-domain-server` name (from show-domains) to an MDS
2719
+ * root IP (from show-mdss). Returns null if the domain is not found or the MDS
2720
+ * root IP cannot be determined.
2615
2721
  */
2616
- async isDomainOnCurrentMDS(domainName) {
2722
+ async getMDSRootForDomain(domainName) {
2617
2723
  const domains = await this.getDomains();
2618
2724
  const domain = domains.find((d) => d.name === domainName);
2619
- if (!domain?.servers || domain.servers.length === 0) {
2620
- return false;
2621
- }
2622
- const currentHost = this.client.getHost();
2623
- return domain.servers.some((server2) => {
2624
- const ipv4 = server2["ipv4-address"];
2625
- const ipv6 = server2["ipv6-address"];
2626
- return ipv4 && currentHost.includes(ipv4) || ipv6 && currentHost.includes(ipv6);
2627
- });
2725
+ if (!domain?.servers?.length)
2726
+ return null;
2727
+ const activeServer = domain.servers.find((s) => s.active === true) ?? domain.servers[0];
2728
+ const targetMDSName = activeServer?.["multi-domain-server"];
2729
+ if (!targetMDSName)
2730
+ return null;
2731
+ const mdsServers = await this.getMDSServers();
2732
+ const mdsServer = mdsServers.find((m) => m.name === targetMDSName);
2733
+ return mdsServer?.["ipv4-address"] ?? mdsServer?.["ipv6-address"] ?? null;
2628
2734
  }
2629
2735
  /**
2630
2736
  * Get the appropriate MDS server IP for a domain
@@ -2654,15 +2760,16 @@ var APIManagerBase = class {
2654
2760
  return ipv6Server?.["ipv6-address"] || null;
2655
2761
  }
2656
2762
  /**
2657
- * Create a new API client for a different MDS server
2658
- * Handles both IPv4 and IPv6 addresses
2659
- * Only supports OnPremAPIClient for multi-MDS scenarios
2763
+ * Create a new API client targeting a specific host (MDS root or DMS IP).
2764
+ * When `domain` is provided it is included in the login payload, causing the
2765
+ * server to return a domain-scoped session (equivalent to login -d).
2766
+ * Handles both IPv4 and IPv6 addresses.
2660
2767
  */
2661
- createClientForMDS(mdsIP, port = "443") {
2768
+ createClientForMDS(mdsIP, port = "443", domain) {
2662
2769
  if (this.client instanceof OnPremAPIClient) {
2663
2770
  const currentClient = this.client;
2664
2771
  const formattedHost = mdsIP.includes(":") && !mdsIP.startsWith("[") ? `[${mdsIP}]` : mdsIP;
2665
- return new OnPremAPIClient(currentClient.authToken || void 0, formattedHost, port, currentClient.username, currentClient.password);
2772
+ return new OnPremAPIClient(currentClient.authToken || void 0, formattedHost, port, currentClient.username, currentClient.password, domain);
2666
2773
  } else if (this.client instanceof SmartOneCloudAPIClient) {
2667
2774
  throw new Error("Multi-MDS routing is not supported for SmartOneCloud environments");
2668
2775
  } else {
@@ -2729,10 +2836,11 @@ var APIManagerForAPIKey = class extends APIManagerBase {
2729
2836
  managementHost: args.managementHost,
2730
2837
  managementPort: args.managementPort,
2731
2838
  s1cUrl: args.s1cUrl,
2732
- cloudInfraToken: args.cloudInfraToken ? "***" : void 0
2839
+ cloudInfraToken: args.cloudInfraToken ? "***" : void 0,
2840
+ sid: args.sid ? "***" : void 0
2733
2841
  });
2734
2842
  }
2735
- const hasAnyValue = args.apiKey || args.username || args.password || args.s1cUrl || args.managementHost || args.cloudInfraToken;
2843
+ const hasAnyValue = args.apiKey || args.username || args.password || args.s1cUrl || args.managementHost || args.cloudInfraToken || args.sid;
2736
2844
  if (!hasAnyValue) {
2737
2845
  if (verbose) {
2738
2846
  console.error("[APIManagerForAPIKey.create] Verbose: ERROR - Args object is effectively empty, no values provided");
@@ -2745,6 +2853,12 @@ var APIManagerForAPIKey = class extends APIManagerBase {
2745
2853
  console.error("[APIManagerForAPIKey.create] Verbose: Using on-prem management with host:", args.managementHost);
2746
2854
  }
2747
2855
  const onPremClient = new OnPremAPIClient(args.apiKey, args.managementHost, args.managementPort || "443", args.username, args.password);
2856
+ if (args.sid) {
2857
+ if (verbose) {
2858
+ console.error("[APIManagerForAPIKey.create] Verbose: Setting external SID on on-prem client (skipping login)");
2859
+ }
2860
+ onPremClient.setExternalSid(args.sid);
2861
+ }
2748
2862
  return new this(onPremClient);
2749
2863
  }
2750
2864
  if (verbose) {
@@ -2773,13 +2887,26 @@ var APIManagerForAPIKey = class extends APIManagerBase {
2773
2887
  }
2774
2888
  keyType = TokenType.API_KEY;
2775
2889
  key = args.apiKey;
2890
+ } else if (args.sid) {
2891
+ if (verbose) {
2892
+ console.error("[APIManagerForAPIKey.create] Verbose: Using external SID with S1C (no auth token needed)");
2893
+ }
2894
+ keyType = TokenType.API_KEY;
2895
+ key = "";
2776
2896
  } else {
2777
2897
  if (verbose) {
2778
2898
  console.error("[APIManagerForAPIKey.create] Verbose: ERROR - No API key or cloud infra token provided");
2779
2899
  }
2780
2900
  throw new Error("API key or cloud infrastructure token is required");
2781
2901
  }
2782
- return new this(SmartOneCloudAPIClient.create(key, keyType, args.s1cUrl));
2902
+ const s1cClient = SmartOneCloudAPIClient.create(key, keyType, args.s1cUrl, !!args.cloudConnected);
2903
+ if (args.sid) {
2904
+ if (verbose) {
2905
+ console.error("[APIManagerForAPIKey.create] Verbose: Setting external SID on S1C client (skipping login)");
2906
+ }
2907
+ s1cClient.setExternalSid(args.sid);
2908
+ }
2909
+ return new this(s1cClient);
2783
2910
  }
2784
2911
  };
2785
2912
 
@@ -2818,7 +2945,7 @@ var Settings = class _Settings {
2818
2945
  return "STG";
2819
2946
  return void 0;
2820
2947
  }
2821
- 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 } = {}) {
2948
+ 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, cloudConnected = process.env.CLOUD_CONNECTED === "true", sid, clientId = process.env.CLIENT_ID, secretKey = process.env.SECRET_KEY, region = process.env.REGION || "EU", devPort = process.env.DEV_PORT || "8006", gatewayUrl } = {}) {
2822
2949
  this.region = "EU";
2823
2950
  this.devPort = "8006";
2824
2951
  this.gatewayUrl = "";
@@ -2845,6 +2972,8 @@ var Settings = class _Settings {
2845
2972
  this.managementHost = managementHost;
2846
2973
  this.managementPort = managementPort;
2847
2974
  this.cloudInfraToken = cloudInfraToken;
2975
+ this.cloudConnected = cloudConnected;
2976
+ this.sid = sid;
2848
2977
  this.clientId = clientId;
2849
2978
  this.secretKey = secretKey;
2850
2979
  this.region = this.normalizeRegion(region) || "EU";
@@ -2868,7 +2997,7 @@ var Settings = class _Settings {
2868
2997
  * Check if the provided string is a valid region
2869
2998
  */
2870
2999
  isValidRegion(region) {
2871
- return ["EU", "US", "STG", "LOCAL"].includes(region.toUpperCase());
3000
+ return ["EU", "US", "STG", "DEV", "LOCAL"].includes(region.toUpperCase());
2872
3001
  }
2873
3002
  /**
2874
3003
  * Get the base gateway URL for a given region
@@ -2880,6 +3009,7 @@ var Settings = class _Settings {
2880
3009
  case "US":
2881
3010
  return "https://cloudinfra-gw-us.portal.checkpoint.com";
2882
3011
  case "STG":
3012
+ case "DEV":
2883
3013
  case "LOCAL":
2884
3014
  return "https://dev-cloudinfra-gw.kube1.iaas.checkpoint.com";
2885
3015
  default:
@@ -2917,6 +3047,7 @@ var Settings = class _Settings {
2917
3047
  const verbose = SettingsManager.globalDebugState;
2918
3048
  if (verbose) {
2919
3049
  console.error("[Settings] Verbose: Validating settings...");
3050
+ console.error("[Settings] Verbose: sid:", this.sid ? "***" : "(empty)");
2920
3051
  console.error("[Settings] Verbose: s1cUrl:", this.s1cUrl || "(empty)");
2921
3052
  console.error("[Settings] Verbose: managementHost:", this.managementHost || "(empty)");
2922
3053
  console.error("[Settings] Verbose: apiKey:", this.apiKey ? "***" : "(empty)");
@@ -2924,17 +3055,35 @@ var Settings = class _Settings {
2924
3055
  console.error("[Settings] Verbose: username:", this.username ? "***" : "(empty)");
2925
3056
  console.error("[Settings] Verbose: password:", this.password ? "***" : "(empty)");
2926
3057
  }
2927
- if (!nullOrEmpty(this.s1cUrl) && nullOrEmpty(this.apiKey) && nullOrEmpty(this.cloudInfraToken)) {
3058
+ if (!nullOrEmpty(this.sid)) {
2928
3059
  if (verbose) {
2929
- console.error("[Settings] Verbose: Validation FAILED - S1C URL provided but no API key or CI token");
3060
+ console.error("[Settings] Verbose: Pre-authenticated SID provided, skipping credential validation");
3061
+ }
3062
+ return;
3063
+ }
3064
+ if (!nullOrEmpty(this.s1cUrl) && nullOrEmpty(this.apiKey) && nullOrEmpty(this.cloudInfraToken)) {
3065
+ if (process.env.MCP_TRANSPORT_TYPE?.toLowerCase() === "http") {
3066
+ if (verbose) {
3067
+ console.error("[Settings] Verbose: S1C URL provided without credentials, but HTTP transport mode allows per-request auth via headers");
3068
+ }
3069
+ } else {
3070
+ if (verbose) {
3071
+ console.error("[Settings] Verbose: Validation FAILED - S1C URL provided but no API key or CI token");
3072
+ }
3073
+ throw new Error("API key or CI Token is required for S1C (via --api-key or API_KEY env var)");
2930
3074
  }
2931
- throw new Error("API key or CI Token is required for S1C (via --api-key or API_KEY env var)");
2932
3075
  }
2933
3076
  if (!nullOrEmpty(this.managementHost) && nullOrEmpty(this.apiKey) && (nullOrEmpty(this.username) || nullOrEmpty(this.password))) {
2934
- if (verbose) {
2935
- console.error("[Settings] Verbose: Validation FAILED - Management host provided but no API key or credentials");
3077
+ if (process.env.MCP_TRANSPORT_TYPE?.toLowerCase() === "http") {
3078
+ if (verbose) {
3079
+ console.error("[Settings] Verbose: Management host provided without credentials, but HTTP transport mode allows per-request auth via headers");
3080
+ }
3081
+ } else {
3082
+ if (verbose) {
3083
+ console.error("[Settings] Verbose: Validation FAILED - Management host provided but no API key or credentials");
3084
+ }
3085
+ throw new Error("Either API key or username/password are required for on-prem management (via CLI args or env vars)");
2936
3086
  }
2937
- throw new Error("Either API key or username/password are required for on-prem management (via CLI args or env vars)");
2938
3087
  }
2939
3088
  if (nullOrEmpty(this.s1cUrl) && nullOrEmpty(this.managementHost)) {
2940
3089
  if (verbose) {
@@ -2976,6 +3125,7 @@ var Settings = class _Settings {
2976
3125
  managementHost: args.managementHost,
2977
3126
  managementPort: args.managementPort,
2978
3127
  cloudInfraToken: args.cloudInfraToken,
3128
+ cloudConnected: args.cloudConnected,
2979
3129
  clientId: args.clientId,
2980
3130
  secretKey: args.secretKey,
2981
3131
  region: typeof args.region === "string" ? args.region.trim().toUpperCase() : void 0,
@@ -3001,6 +3151,8 @@ var Settings = class _Settings {
3001
3151
  managementHost: getHeaderValue(headers, "MANAGEMENT-HOST"),
3002
3152
  managementPort: getHeaderValue(headers, "MANAGEMENT-PORT"),
3003
3153
  cloudInfraToken: getHeaderValue(headers, "CLOUD-INFRA-TOKEN"),
3154
+ cloudConnected: getHeaderValue(headers, "CLOUD-CONNECTED"),
3155
+ sid: getHeaderValue(headers, "X-chkp-sid"),
3004
3156
  clientId: getHeaderValue(headers, "CLIENT-ID"),
3005
3157
  secretKey: getHeaderValue(headers, "SECRET-KEY"),
3006
3158
  region: getHeaderValue(headers, "REGION"),
@@ -3033,6 +3185,8 @@ var Settings = class _Settings {
3033
3185
  managementHost: extractedValues.managementHost,
3034
3186
  managementPort: extractedValues.managementPort,
3035
3187
  cloudInfraToken: extractedValues.cloudInfraToken,
3188
+ cloudConnected: extractedValues.cloudConnected === "true",
3189
+ sid: extractedValues.sid,
3036
3190
  clientId: extractedValues.clientId,
3037
3191
  secretKey: extractedValues.secretKey,
3038
3192
  region: extractedValues.region?.toUpperCase(),
@@ -3150,7 +3304,8 @@ async function executeApiTool(toolName, definition, validatedArgs, extra) {
3150
3304
  }
3151
3305
  const requestBody = validatedArgs?.["requestBody"] || {};
3152
3306
  if (validatedArgs.domains_to_process) {
3153
- requestBody["domains-to-process"] = typeof validatedArgs.domain === "string" && validatedArgs.domain.trim() !== "" ? validatedArgs.domain : void 0;
3307
+ requestBody["domains-to-process"] = [validatedArgs.domains_to_process];
3308
+ requestBody["ignore-warnings"] = true;
3154
3309
  }
3155
3310
  const resp = await runApi("POST", urlPath, requestBody, extra, domain);
3156
3311
  console.error(`=== DEBUG: Response received ===`);
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chkp/policy-insights-mcp",
3
- "version": "0.2.0",
3
+ "version": "0.3.4",
4
4
  "bin": {
5
5
  "policy-insights-mcp": "dist/index.js"
6
6
  },
@@ -20,9 +20,13 @@
20
20
  "build:bundle": "node ../../bundle-mcp.js",
21
21
  "build:tsc": "npx tsc && npx shx chmod +x ./dist/index.js && npx shx cp src/server-config.json dist/",
22
22
  "dev": "tsc --watch",
23
- "start": "node dist/index.js"
23
+ "start": "node dist/index.js",
24
+ "prepack": "node ../../scripts/strip-bundled-deps.js",
25
+ "postpack": "node ../../scripts/strip-bundled-deps.js restore"
24
26
  },
25
27
  "dependencies": {
28
+ "@chkp/mcp-utils": "*",
29
+ "@chkp/quantum-infra": "*",
26
30
  "@modelcontextprotocol/sdk": "^1.26.0",
27
31
  "axios": "^1.13.5",
28
32
  "commander": "^13.1.0",
@@ -30,8 +34,6 @@
30
34
  "zod": "^3.22.4"
31
35
  },
32
36
  "devDependencies": {
33
- "@chkp/mcp-utils": "*",
34
- "@chkp/quantum-infra": "*",
35
37
  "@types/node": "^22.15.2",
36
38
  "@typescript-eslint/eslint-plugin": "^8.38.0",
37
39
  "@typescript-eslint/parser": "^8.38.0",
@@ -23,6 +23,13 @@
23
23
  "type": "string",
24
24
  "hidden": true
25
25
  },
26
+ {
27
+ "flag": "--cloud-connected",
28
+ "description": "Enable cloud-connected mode",
29
+ "env": "CLOUD_CONNECTED",
30
+ "type": "boolean",
31
+ "hidden": true
32
+ },
26
33
  {
27
34
  "flag": "--username <username>",
28
35
  "description": "Username for on-prem authentication",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chkp/policy-insights-mcp",
3
- "version": "0.2.0",
3
+ "version": "0.3.4",
4
4
  "bin": {
5
5
  "policy-insights-mcp": "dist/index.js"
6
6
  },
@@ -20,7 +20,9 @@
20
20
  "build:bundle": "node ../../bundle-mcp.js",
21
21
  "build:tsc": "npx tsc && npx shx chmod +x ./dist/index.js && npx shx cp src/server-config.json dist/",
22
22
  "dev": "tsc --watch",
23
- "start": "node dist/index.js"
23
+ "start": "node dist/index.js",
24
+ "prepack": "node ../../scripts/strip-bundled-deps.js",
25
+ "postpack": "node ../../scripts/strip-bundled-deps.js restore"
24
26
  },
25
27
  "dependencies": {
26
28
  "@modelcontextprotocol/sdk": "^1.26.0",
@@ -30,8 +32,6 @@
30
32
  "zod": "^3.24.4"
31
33
  },
32
34
  "devDependencies": {
33
- "@chkp/mcp-utils": "*",
34
- "@chkp/quantum-infra": "*",
35
35
  "@types/node": "^22.15.2",
36
36
  "@typescript-eslint/eslint-plugin": "^8.38.0",
37
37
  "@typescript-eslint/parser": "^8.38.0",
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "@chkp/policy-insights-mcp",
3
+ "version": "0.3.4",
4
+ "bin": {
5
+ "policy-insights-mcp": "dist/index.js"
6
+ },
7
+ "description": "Official MCP server for Check Point Policy Insights",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "https://github.com/CheckPointSW/mcp-servers.git",
11
+ "directory": "packages/policy-insights"
12
+ },
13
+ "license": "MIT",
14
+ "type": "module",
15
+ "main": "dist/index.js",
16
+ "types": "dist/index.d.ts",
17
+ "scripts": {
18
+ "clean": "rimraf dist",
19
+ "build": "npm run build:bundle && npx shx chmod +x ./dist/index.js && npx shx cp src/server-config.json dist/",
20
+ "build:bundle": "node ../../bundle-mcp.js",
21
+ "build:tsc": "npx tsc && npx shx chmod +x ./dist/index.js && npx shx cp src/server-config.json dist/",
22
+ "dev": "tsc --watch",
23
+ "start": "node dist/index.js",
24
+ "prepack": "node ../../scripts/strip-bundled-deps.js",
25
+ "postpack": "node ../../scripts/strip-bundled-deps.js restore"
26
+ },
27
+ "dependencies": {
28
+ "@chkp/mcp-utils": "*",
29
+ "@chkp/quantum-infra": "*",
30
+ "@modelcontextprotocol/sdk": "^1.26.0",
31
+ "commander": "^13.1.0",
32
+ "axios": "^1.13.5",
33
+ "node-machine-id": "^1.1.12",
34
+ "zod": "^3.24.4"
35
+ },
36
+ "devDependencies": {
37
+ "@types/node": "^22.15.2",
38
+ "@typescript-eslint/eslint-plugin": "^8.38.0",
39
+ "@typescript-eslint/parser": "^8.38.0",
40
+ "eslint": "^8.57.0",
41
+ "eslint-config-prettier": "^9.1.0",
42
+ "eslint-plugin-prettier": "^5.2.1",
43
+ "prettier": "^3.6.2",
44
+ "typescript": "^5.8.3"
45
+ },
46
+ "engines": {
47
+ "node": ">=20.0.0"
48
+ },
49
+ "keywords": [],
50
+ "author": ""
51
+ }