@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 +37 -0
- package/dist/index.js +231 -76
- package/dist/package.json +6 -4
- package/dist/server-config.json +7 -0
- package/package.json +4 -4
- package/package.json.bak +51 -0
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
|
-
*
|
|
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 },
|
|
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
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
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 =
|
|
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
|
-
*
|
|
2536
|
-
*
|
|
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
|
-
|
|
2562
|
-
|
|
2563
|
-
|
|
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
|
|
2566
|
-
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
|
|
2570
|
-
|
|
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
|
|
2573
|
-
|
|
2574
|
-
|
|
2575
|
-
|
|
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
|
-
*
|
|
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
|
|
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
|
|
2620
|
-
return
|
|
2621
|
-
|
|
2622
|
-
const
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
|
|
2626
|
-
|
|
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
|
|
2658
|
-
*
|
|
2659
|
-
*
|
|
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
|
-
|
|
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.
|
|
3058
|
+
if (!nullOrEmpty(this.sid)) {
|
|
2928
3059
|
if (verbose) {
|
|
2929
|
-
console.error("[Settings] Verbose:
|
|
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 (
|
|
2935
|
-
|
|
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"] =
|
|
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.
|
|
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",
|
package/dist/server-config.json
CHANGED
|
@@ -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.
|
|
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",
|
package/package.json.bak
ADDED
|
@@ -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
|
+
}
|