@chkp/policy-insights-mcp 0.4.1 → 0.4.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/dist/index.js CHANGED
@@ -1270,583 +1270,464 @@ var toolDefinitionMap = [
1270
1270
  // ../infra/dist/api-client.js
1271
1271
  import axios from "axios";
1272
1272
  import https from "https";
1273
- var TokenType;
1274
- (function(TokenType2) {
1275
- TokenType2["API_KEY"] = "API_KEY";
1276
- TokenType2["CI_TOKEN"] = "CI_TOKEN";
1277
- })(TokenType || (TokenType = {}));
1278
- function getMainPackageUserAgent() {
1279
- if (process.env.CP_MCP_MAIN_PKG) {
1280
- if (process.env.CP_MCP_MAIN_PKG.includes("quantum-management-mcp")) {
1281
- return "mgmt-mcp";
1282
- }
1273
+
1274
+ // ../mcp-utils/dist/cli-options.js
1275
+ function booleanOptionDefault(envValue, optionDefault) {
1276
+ return envValue === "true" || optionDefault === "true";
1277
+ }
1278
+ function resolveTransportType(transportOption, env = process.env) {
1279
+ return (transportOption || env.MCP_TRANSPORT_TYPE || "stdio").toLowerCase() === "http" ? "http" : "stdio";
1280
+ }
1281
+ function optionKey(flag) {
1282
+ const long = flag.split(/[,\s]+/).find((part) => part.startsWith("--"));
1283
+ if (!long)
1284
+ return void 0;
1285
+ const negated = long.startsWith("--no-");
1286
+ return {
1287
+ key: long.replace(/^--(no-)?/, "").replace(/-([a-z])/g, (_match, char) => char.toUpperCase()),
1288
+ negated
1289
+ };
1290
+ }
1291
+ function operatorValues(options, parsed, env = process.env) {
1292
+ const values = { ...env };
1293
+ for (const option of options) {
1294
+ const derived = option.env ? optionKey(option.flag) : void 0;
1295
+ if (!derived || derived.negated)
1296
+ continue;
1297
+ const value = parsed[derived.key];
1298
+ if (value !== void 0)
1299
+ values[option.env] = value;
1283
1300
  }
1284
- return "Check Point MCP API Client";
1301
+ return values;
1285
1302
  }
1286
- var ClientResponse = class {
1287
- constructor(status, response) {
1288
- this.status = status;
1289
- this.response = response;
1303
+
1304
+ // ../mcp-utils/dist/debug-view.js
1305
+ import { createHash } from "node:crypto";
1306
+ var BUILTIN_LOGGABLE_KEYS = [
1307
+ "accept",
1308
+ "accept-encoding",
1309
+ "accept-language",
1310
+ "connection",
1311
+ "content-length",
1312
+ "content-type",
1313
+ "host",
1314
+ "mcp-protocol-version",
1315
+ "traceparent",
1316
+ "user-agent",
1317
+ "x-correlation-id",
1318
+ "x-gw-auth-method",
1319
+ "x-request-id",
1320
+ // Launcher options
1321
+ "debug",
1322
+ "telemetry",
1323
+ "telemetry-url",
1324
+ "transport",
1325
+ "transport-port"
1326
+ ];
1327
+ function normalizeDebugKey(key) {
1328
+ const split = /[-_]/.test(key) ? key : key.replace(/([a-z][0-9]*)([A-Z])/g, "$1-$2");
1329
+ return split.replace(/_/g, "-").toLowerCase();
1330
+ }
1331
+ function debugLoggableKeys(extra = []) {
1332
+ return new Set([...BUILTIN_LOGGABLE_KEYS, ...extra].map(normalizeDebugKey));
1333
+ }
1334
+ function describe(key, value, loggable) {
1335
+ if (value === void 0 || value === null || value === "")
1336
+ return "(unset)";
1337
+ if (loggable.has(normalizeDebugKey(key))) {
1338
+ return typeof value === "string" ? value : JSON.stringify(value);
1339
+ }
1340
+ const text = typeof value === "string" ? value : Array.isArray(value) ? value.join(", ") : void 0;
1341
+ return text === void 0 ? "(hidden)" : `(hidden, ${text.length} chars)`;
1342
+ }
1343
+ function debugView(record, loggable = debugLoggableKeys()) {
1344
+ return Object.fromEntries(Object.entries(record ?? {}).map(([key, value]) => [key, describe(key, value, loggable)]));
1345
+ }
1346
+ function sessionLogLabel(sessionId) {
1347
+ if (!sessionId || sessionId === "default")
1348
+ return "default";
1349
+ return `session#${createHash("sha256").update(sessionId).digest("hex").slice(0, 8)}`;
1350
+ }
1351
+
1352
+ // ../mcp-utils/dist/launcher.js
1353
+ import { Command } from "commander";
1354
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
1355
+ import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
1356
+ import fs from "fs";
1357
+ import http from "http";
1358
+ import { randomUUID } from "crypto";
1359
+
1360
+ // ../mcp-utils/dist/connection-source.js
1361
+ function hasValue(value) {
1362
+ return value !== void 0 && value !== null && value !== "" && !(Array.isArray(value) && value.length === 0);
1363
+ }
1364
+ function headersRead(fromHeaders, headers) {
1365
+ const read = /* @__PURE__ */ new Set();
1366
+ const recording = new Proxy(headers, {
1367
+ get(target, prop, receiver) {
1368
+ const value = Reflect.get(target, prop, receiver);
1369
+ if (typeof prop === "string" && hasValue(value))
1370
+ read.add(prop);
1371
+ return value;
1372
+ }
1373
+ });
1374
+ try {
1375
+ fromHeaders(recording);
1376
+ } catch {
1290
1377
  }
1291
- };
1292
- var APIClientBase = class {
1293
- constructor(authToken = "", tokenType = TokenType.API_KEY, cloudConnected = false) {
1294
- this.authToken = authToken;
1295
- this.tokenType = tokenType;
1296
- this.cloudConnected = cloudConnected;
1297
- this.sid = null;
1298
- this.sessionTimeout = null;
1299
- this.sessionStart = null;
1300
- this.isMDS = false;
1301
- this._externalSid = false;
1378
+ return read;
1379
+ }
1380
+ function keySet(keys = []) {
1381
+ return new Set(keys.map(normalizeDebugKey));
1382
+ }
1383
+ function chooseConnectionSource(read, basicKeys) {
1384
+ for (const key of read) {
1385
+ if (!basicKeys.has(normalizeDebugKey(key)))
1386
+ return "caller";
1302
1387
  }
1303
- /**
1304
- * Create an API client instance - generic method for creating clients
1305
- */
1306
- static create(...args) {
1307
- return new this(...args);
1388
+ return "operator";
1389
+ }
1390
+ function basicOnly(headers, basicKeys) {
1391
+ return Object.fromEntries(Object.entries(headers).filter(([key]) => basicKeys.has(normalizeDebugKey(key))));
1392
+ }
1393
+ function mergeHeaders(base, overrides) {
1394
+ const merged = {};
1395
+ const index = /* @__PURE__ */ new Map();
1396
+ for (const [key, value] of [...Object.entries(base), ...Object.entries(overrides)]) {
1397
+ const id = normalizeDebugKey(key);
1398
+ const previous = index.get(id);
1399
+ if (previous !== void 0)
1400
+ delete merged[previous];
1401
+ index.set(id, key);
1402
+ merged[key] = value;
1403
+ }
1404
+ return merged;
1405
+ }
1406
+ function operatorHeaders(values) {
1407
+ const headers = {};
1408
+ for (const [name, value] of Object.entries(values)) {
1409
+ if (!hasValue(value))
1410
+ continue;
1411
+ headers[name.replace(/_/g, "-")] = Array.isArray(value) ? value.map(String) : String(value);
1308
1412
  }
1309
- /**
1310
- * Get headers for the API requests
1311
- */
1312
- getHeaders() {
1313
- const headers = {
1314
- "Content-Type": "application/json",
1315
- "User-Agent": getMainPackageUserAgent()
1316
- };
1317
- if (this.sid) {
1318
- headers["X-chkp-sid"] = this.sid;
1319
- }
1320
- if (this.cloudConnected && this.tokenType === TokenType.CI_TOKEN) {
1321
- headers["Authorization"] = `Bearer ${this.authToken}`;
1322
- headers["CLOUD-INFRA-TOKEN"] = this.authToken;
1323
- }
1413
+ return headers;
1414
+ }
1415
+ function canonicalizeAliases(headers, aliases) {
1416
+ if (aliases.size === 0)
1324
1417
  return headers;
1418
+ const canonical = new Set([...aliases.values()].map(normalizeDebugKey));
1419
+ const present = new Set(Object.keys(headers).map(normalizeDebugKey).filter((key) => canonical.has(key)));
1420
+ const result = {};
1421
+ for (const [key, value] of Object.entries(headers)) {
1422
+ const target = aliases.get(normalizeDebugKey(key));
1423
+ if (target === void 0) {
1424
+ result[key] = value;
1425
+ } else if (!present.has(normalizeDebugKey(target))) {
1426
+ result[target] = value;
1427
+ present.add(normalizeDebugKey(target));
1428
+ }
1429
+ }
1430
+ return result;
1431
+ }
1432
+ function aliasMap(aliases = {}) {
1433
+ return new Map(Object.entries(aliases).map(([alias, target]) => [normalizeDebugKey(alias), target]));
1434
+ }
1435
+ function sessionHeaders(source, callerHeaders, operator, basicKeys, operatorSettingsOverHttp) {
1436
+ if (source === "caller") {
1437
+ return mergeHeaders(basicOnly(operator, basicKeys), callerHeaders);
1325
1438
  }
1439
+ const base = operatorSettingsOverHttp ? operator : basicOnly(operator, basicKeys);
1440
+ return mergeHeaders(base, basicOnly(callerHeaders, basicKeys));
1441
+ }
1442
+
1443
+ // ../mcp-utils/dist/settings-manager.js
1444
+ var SettingsManager = class _SettingsManager {
1326
1445
  /**
1327
- * Get debug mode
1446
+ * Creates a new SettingsManager
1447
+ * @param settingsClass The Settings class to use for creating settings instances
1328
1448
  */
1329
- get debug() {
1330
- return !!this._debug;
1449
+ constructor(settingsClass) {
1450
+ this.settingsMap = /* @__PURE__ */ new Map();
1451
+ this.defaultSessionId = "default";
1452
+ this.operatorValues = {};
1453
+ this.sessionSources = /* @__PURE__ */ new Map();
1454
+ this.settingsClass = settingsClass;
1455
+ this.loggableKeys = debugLoggableKeys(settingsClass?.debugLoggableKeys ?? []);
1456
+ this.basicKeys = keySet(settingsClass?.basicKeys ?? []);
1457
+ this.headerAliases = aliasMap(settingsClass?.headerAliases);
1458
+ this.operatorSettingsOverHttp = settingsClass?.operatorSettingsOverHttp !== false;
1331
1459
  }
1332
1460
  /**
1333
- * Set debug mode
1461
+ * Get settings for a specific session
1462
+ * @param sessionId The session ID (defaults to 'default' for stdio mode)
1463
+ * @returns Settings instance for the session
1334
1464
  */
1335
- set debug(value) {
1336
- this._debug = value;
1465
+ getSettings(sessionId) {
1466
+ const sid = sessionId || this.defaultSessionId;
1467
+ if (!this.settingsMap.has(sid)) {
1468
+ this.settingsMap.set(sid, new this.settingsClass());
1469
+ }
1470
+ return this.settingsMap.get(sid);
1337
1471
  }
1338
1472
  /**
1339
- * Set a pre-authenticated session ID provided externally (e.g. via X-chkp-sid header).
1340
- * When set, the client will skip login and use this SID directly for all requests.
1341
- */
1342
- setExternalSid(sid) {
1343
- this.sid = sid;
1344
- this._externalSid = true;
1345
- this.sessionStart = Date.now();
1346
- this.sessionTimeout = Number.MAX_SAFE_INTEGER / 1e3;
1473
+ * Set settings for a specific session
1474
+ * @param settings The settings object to set
1475
+ * @param sessionId The session ID (defaults to 'default' for stdio mode)
1476
+ */
1477
+ setSettings(settings, sessionId) {
1478
+ const sid = sessionId || this.defaultSessionId;
1479
+ this.settingsMap.set(sid, settings);
1347
1480
  }
1348
1481
  /**
1349
- * Check if this client needs to perform login before making API calls
1482
+ * Injects debug settings from source into settings object
1483
+ * @param settings The settings object to update
1484
+ * @param source Source object containing debug information
1485
+ * @param scope 'process' when the operator set debug (CLI/env), which also
1486
+ * updates the process-wide state; 'session' when a caller set it through a
1487
+ * header, which affects only that session's settings
1488
+ * @private
1350
1489
  */
1351
- needsLogin() {
1352
- if (this._externalSid) {
1353
- return false;
1490
+ injectDebug(settings, source, scope) {
1491
+ const debug = source?.debug ?? _SettingsManager.globalDebugState ?? process.env.DEBUG;
1492
+ if (typeof debug !== "undefined") {
1493
+ if (scope === "process" && source?.debug !== void 0) {
1494
+ _SettingsManager.globalDebugState = source.debug;
1495
+ }
1496
+ if (typeof settings.set === "function") {
1497
+ settings.set("debug", debug);
1498
+ } else {
1499
+ settings.debug = debug;
1500
+ }
1501
+ if (debug) {
1502
+ console.error("Debug enabled. Source:");
1503
+ this.printDebugView(source);
1504
+ }
1354
1505
  }
1355
- return true;
1356
1506
  }
1357
1507
  /**
1358
- * Check if this client is in an MDS environment
1508
+ * Print settings object for debugging by dynamically discovering its properties
1509
+ * @param settings The settings object to print
1510
+ * @private
1359
1511
  */
1360
- async isMDSEnvironment() {
1361
- if (!this.hasValidSession()) {
1362
- await this.login();
1512
+ printSettingsDebug(settings) {
1513
+ if (typeof settings.get === "function") {
1514
+ console.error("Settings (using get method):");
1515
+ if (settings.data && typeof settings.data === "object") {
1516
+ this.printDebugView(settings.data);
1517
+ } else {
1518
+ console.error(" Unable to enumerate settings properties - no accessible data structure");
1519
+ }
1520
+ } else {
1521
+ console.error("Settings (plain object):");
1522
+ this.printDebugView(settings);
1363
1523
  }
1364
- return this.isMDS;
1365
1524
  }
1366
- /**
1367
- * Check if the client has a valid session
1368
- */
1369
- hasValidSession() {
1370
- return !!this.sid && !this.isSessionExpired();
1525
+ /** Print allowlisted values; everything else as "(hidden, N chars)". */
1526
+ printDebugView(record) {
1527
+ Object.entries(debugView(record, this.loggableKeys)).forEach(([key, value]) => {
1528
+ console.error(` ${key}: ${value}`);
1529
+ });
1371
1530
  }
1372
1531
  /**
1373
- * Get the current session ID (for debugging/logging purposes)
1532
+ * Create settings from command-line arguments
1533
+ * @param args Command line arguments
1534
+ * @param sessionId Optional session ID
1535
+ * @returns Settings instance
1374
1536
  */
1375
- getSessionId() {
1376
- return this.sid;
1537
+ createFromArgs(args, sessionId) {
1538
+ const settings = this.settingsClass.fromArgs(args);
1539
+ this.injectDebug(settings, args, "process");
1540
+ this.setSettings(settings, sessionId);
1541
+ return settings;
1377
1542
  }
1378
1543
  /**
1379
- * Create a new API client instance with a specific session ID
1380
- * Used for domain-specific clients in MDS environments
1544
+ * Record the operator's values (environment variables and parsed CLI
1545
+ * options, keyed by environment-variable name). HTTP sessions take basic
1546
+ * keys from them when the caller doesn't send its own, and their whole
1547
+ * connection set when the caller sends none of it.
1381
1548
  */
1382
- static createWithSid(originalClient, sid) {
1383
- const newClient = Object.create(Object.getPrototypeOf(originalClient));
1384
- Object.assign(newClient, originalClient);
1385
- newClient.sid = sid;
1386
- newClient.sessionStart = Date.now();
1387
- return newClient;
1549
+ setOperatorValues(values) {
1550
+ this.operatorValues = canonicalizeAliases(operatorHeaders(values), this.headerAliases);
1388
1551
  }
1389
1552
  /**
1390
- * Call an API endpoint
1553
+ * Create settings from HTTP headers
1554
+ * @param headers HTTP headers
1555
+ * @param sessionId Optional session ID
1556
+ * @returns Settings instance
1391
1557
  */
1392
- async callApi(method, uri, data, params) {
1393
- if (this.needsLogin() && (!this.sid || this.isSessionExpired())) {
1394
- try {
1395
- await this.login();
1396
- } catch (error) {
1397
- if (error instanceof ClientResponse) {
1398
- console.error(`Login failed with status ${error.status}:`, error.response);
1399
- return error;
1400
- }
1401
- console.error("Login failed with unexpected error:", error);
1402
- return new ClientResponse(500, { error: "Authentication failed", message: error.message });
1403
- }
1558
+ createFromHeaders(headers, sessionId) {
1559
+ const verbose = _SettingsManager.globalDebugState;
1560
+ if (verbose) {
1561
+ console.error("[SettingsManager.createFromHeaders] Verbose: Starting with session:", sessionLogLabel(sessionId));
1562
+ console.error("[SettingsManager.createFromHeaders] Verbose: Incoming headers count:", Object.keys(headers).length);
1404
1563
  }
1405
- let httpsAgent;
1406
- if (this instanceof OnPremAPIClient) {
1407
- httpsAgent = new https.Agent({ rejectUnauthorized: false });
1564
+ if (_SettingsManager.globalDebugState) {
1565
+ console.error("=== createFromHeaders Debug Info ===");
1566
+ console.error("Incoming headers:");
1567
+ this.printDebugView(headers);
1408
1568
  }
1409
- try {
1410
- return await this.makeRequest(this.getHost(), method, uri, data, this.getHeaders(), params, httpsAgent);
1411
- } catch (error) {
1412
- if ((error.message?.includes("401") || error.response?.status === 401) && error.message?.toLowerCase().includes("session")) {
1413
- if (this._externalSid) {
1414
- throw new Error("Pre-authenticated session (X-chkp-sid) has expired. Provide a new session ID.");
1415
- }
1416
- console.error("Session expired (401), resetting session and retrying...");
1417
- this.sid = null;
1418
- this.sessionStart = null;
1419
- try {
1420
- await this.login();
1421
- } catch (loginError) {
1422
- if (loginError instanceof ClientResponse) {
1423
- console.error(`Login retry failed with status ${loginError.status}:`, loginError.response);
1424
- return loginError;
1425
- }
1426
- console.error("Login retry failed with unexpected error:", loginError);
1427
- throw loginError;
1428
- }
1429
- return await this.makeRequest(this.getHost(), method, uri, data, this.getHeaders(), params, httpsAgent);
1569
+ if (verbose && (!headers || Object.keys(headers).length === 0)) {
1570
+ console.error("[SettingsManager.createFromHeaders] Verbose: WARNING - Headers object is empty or undefined");
1571
+ }
1572
+ const normalizedHeaders = {};
1573
+ for (const [key, value] of Object.entries(headers)) {
1574
+ const normalizedKey = key.includes("_") ? key.replace(/_/g, "-") : key;
1575
+ normalizedHeaders[normalizedKey] = value;
1576
+ if (verbose) {
1577
+ console.error(`[SettingsManager.createFromHeaders] Verbose: Header normalized: "${key}" -> "${normalizedKey}"`);
1430
1578
  }
1431
- throw error;
1432
1579
  }
1433
- }
1434
- /**
1435
- * Check if the session is expired based on sessionTimeout and sessionStart
1436
- */
1437
- isSessionExpired() {
1438
- if (!this.sid || !this.sessionTimeout || !this.sessionStart)
1439
- return true;
1440
- const now = Date.now();
1441
- return now > this.sessionStart + (this.sessionTimeout - 5) * 1e3;
1442
- }
1443
- getHeadersForLogin() {
1444
- return { "Content-Type": "application/json" };
1445
- }
1446
- /**
1447
- * Login to the API using the API key
1448
- */
1449
- async login() {
1450
- if (this._externalSid) {
1451
- if (!this.sid)
1452
- throw new Error("External SID has expired");
1453
- return this.sid;
1580
+ if (verbose) {
1581
+ console.error("[SettingsManager.createFromHeaders] Verbose: Normalized headers count:", Object.keys(normalizedHeaders).length);
1454
1582
  }
1455
- const apiTokenHeader = this.tokenType === TokenType.API_KEY ? "api-key" : "ci-token";
1456
- const loginResp = await this.makeRequest(this.getHost(), "POST", "login", { [apiTokenHeader]: this.authToken }, this.getHeadersForLogin());
1457
- if (loginResp.status !== 200 || !loginResp.response || !loginResp.response.sid) {
1458
- throw loginResp;
1583
+ if (_SettingsManager.globalDebugState) {
1584
+ console.error("Normalized header names:", Object.keys(normalizedHeaders));
1459
1585
  }
1460
- this.sid = loginResp.response.sid;
1461
- this.sessionTimeout = loginResp.response["session-timeout"] || null;
1462
- this.sessionStart = Date.now();
1463
- if (loginResp.response.uid) {
1464
- await this.detectMDS(loginResp.response.uid);
1586
+ const debugHeader = normalizedHeaders["debug"] || normalizedHeaders["Debug"] || normalizedHeaders["DEBUG"];
1587
+ const requestedDebug = Array.isArray(debugHeader) ? debugHeader[0] : debugHeader;
1588
+ const debugSource = {
1589
+ debug: requestedDebug !== void 0 ? requestedDebug.toLowerCase() === "true" : _SettingsManager.globalDebugState
1590
+ };
1591
+ const callerHeaders = canonicalizeAliases(normalizedHeaders, this.headerAliases);
1592
+ const source = this.connectionSource(callerHeaders, sessionId);
1593
+ const inputHeaders = sessionHeaders(source, callerHeaders, this.operatorValues, this.basicKeys, this.operatorSettingsOverHttp);
1594
+ if (verbose) {
1595
+ console.error("[SettingsManager.createFromHeaders] Verbose: Connection settings source:", source);
1596
+ console.error("[SettingsManager.createFromHeaders] Verbose: Calling settingsClass.fromHeaders");
1465
1597
  }
1466
- return loginResp.response.sid;
1598
+ const settings = this.settingsClass.fromHeaders(inputHeaders);
1599
+ if (verbose) {
1600
+ console.error("[SettingsManager.createFromHeaders] Verbose: Settings object created");
1601
+ }
1602
+ this.injectDebug(settings, debugSource, "session");
1603
+ if (_SettingsManager.globalDebugState) {
1604
+ console.error("Final settings object for session:", sessionLogLabel(sessionId));
1605
+ this.printSettingsDebug(settings);
1606
+ console.error("=== End createFromHeaders Debug Info ===");
1607
+ }
1608
+ if (verbose) {
1609
+ console.error("[SettingsManager.createFromHeaders] Verbose: Storing settings for session:", sessionLogLabel(sessionId));
1610
+ }
1611
+ this.setSettings(settings, sessionId);
1612
+ return settings;
1467
1613
  }
1468
1614
  /**
1469
- * Detect if this is an MDS environment by checking the session details
1615
+ * Clear settings for a session
1616
+ * @param sessionId The session ID to clear
1470
1617
  */
1471
- async detectMDS(sessionUid, handleSelfSigned = false) {
1472
- try {
1473
- let httpsAgent;
1474
- if (handleSelfSigned) {
1475
- httpsAgent = new https.Agent({ rejectUnauthorized: false });
1476
- }
1477
- const sessionResp = await this.makeRequest(this.getHost(), "POST", "show-session", { uid: sessionUid }, this.getHeaders(), null, httpsAgent);
1478
- if (sessionResp.status === 200 && sessionResp.response?.domain?.["domain-type"] === "mds") {
1479
- this.isMDS = true;
1480
- }
1481
- } catch (error) {
1482
- console.warn("Could not determine MDS status:", error);
1483
- this.isMDS = false;
1618
+ clearSession(sessionId) {
1619
+ if (sessionId !== this.defaultSessionId) {
1620
+ this.settingsMap.delete(sessionId);
1621
+ this.sessionSources.delete(sessionId);
1484
1622
  }
1485
1623
  }
1486
1624
  /**
1487
- * Make a request to a Check Point API
1625
+ * The session's connection source: decided by the request that creates the
1626
+ * session and kept for its lifetime, so a later request cannot switch it.
1488
1627
  */
1489
- async makeRequest(host, method, uri, data, headers = {}, params = null, httpsAgent) {
1490
- uri = uri.replace(/^\//, "");
1491
- const url = `${host}/${uri}`;
1492
- const config = {
1493
- method: method.toUpperCase(),
1494
- url,
1495
- headers,
1496
- params: params || void 0
1497
- };
1498
- if (httpsAgent) {
1499
- config.httpsAgent = httpsAgent;
1500
- }
1501
- if (method.toUpperCase() !== "GET" && data !== void 0) {
1502
- config.data = data;
1503
- }
1504
- console.error(`API Request: ${method} ${url}`);
1505
- try {
1506
- const response = await axios(config);
1507
- return new ClientResponse(response.status, response.data);
1508
- } catch (error) {
1509
- if (error.response) {
1510
- console.error(`\u274C API Error (${error.response.status}):`);
1511
- console.error("Headers:", error.response.headers);
1512
- console.error("Data:", error.response.data);
1513
- if (this.debug) {
1514
- console.error("Debug mode: Printing request details:");
1515
- console.error("Request Method:", method);
1516
- console.error("Request URL:", url);
1517
- console.error("Request Headers:", config.headers);
1518
- console.error("Request Data:", config.data);
1519
- console.error("Request Params:", config.params);
1520
- }
1521
- }
1522
- if (error.response) {
1523
- throw new Error(`API request failed: ${error.response.status} - ${JSON.stringify(error.response.data)}`);
1524
- }
1525
- throw error;
1526
- }
1628
+ connectionSource(headers, sessionId) {
1629
+ const known = sessionId ? this.sessionSources.get(sessionId) : void 0;
1630
+ if (known)
1631
+ return known;
1632
+ const source = chooseConnectionSource(headersRead((h) => this.settingsClass.fromHeaders(h), headers), this.basicKeys);
1633
+ if (sessionId)
1634
+ this.sessionSources.set(sessionId, source);
1635
+ return source;
1527
1636
  }
1528
1637
  };
1529
- var SmartOneCloudAPIClient = class extends APIClientBase {
1530
- constructor(authToken, tokenType, s1cUrl, cloudConnected = false) {
1531
- super(authToken, tokenType, cloudConnected);
1532
- this.s1cUrl = s1cUrl;
1533
- }
1534
- getHost() {
1535
- return this.s1cUrl;
1536
- }
1537
- getHeadersForLogin() {
1538
- const headers = { "Content-Type": "application/json" };
1539
- if (this.cloudConnected && this.tokenType === TokenType.CI_TOKEN) {
1540
- headers["Authorization"] = `Bearer ${this.authToken}`;
1638
+ SettingsManager.globalDebugState = void 0;
1639
+
1640
+ // ../mcp-utils/dist/telemetry.js
1641
+ import machineIdPkg from "node-machine-id";
1642
+ import { createHash as createHash2 } from "crypto";
1643
+ var { machineIdSync } = machineIdPkg;
1644
+ var machineId = null;
1645
+ var hashedMachineId = null;
1646
+ var transportType = "stdio";
1647
+ function setTransportType(type) {
1648
+ transportType = type;
1649
+ }
1650
+ function isTelemetryDisabled() {
1651
+ return process.env.TELEMETRY_DISABLED === "true" || process.env.TELEMETRY_DISABLED === "1";
1652
+ }
1653
+ function getTelemetryUrl() {
1654
+ return process.env.TELEMETRY_URL || "https://metrics.security.ai.checkpoint.com/api/v1/metrics/collect";
1655
+ }
1656
+ function hashString(input) {
1657
+ return createHash2("sha256").update(input).digest("hex");
1658
+ }
1659
+ function getMachineId() {
1660
+ if (!machineId) {
1661
+ try {
1662
+ machineId = machineIdSync();
1663
+ } catch (error) {
1664
+ console.warn("Failed to get machine ID for telemetry:", error);
1665
+ machineId = "unknown";
1541
1666
  }
1542
- return headers;
1543
1667
  }
1544
- };
1545
- var OnPremAPIClient = class extends APIClientBase {
1546
- constructor(apiKey, managementHost, managementPort = "443", username, password, domain) {
1547
- super(apiKey || "");
1548
- this.managementHost = managementHost;
1549
- this.managementPort = managementPort;
1550
- this.domain = domain;
1551
- this.username = username;
1552
- this.password = password;
1668
+ return machineId;
1669
+ }
1670
+ function getHashedMachineId() {
1671
+ if (!hashedMachineId) {
1672
+ hashedMachineId = hashString(getMachineId());
1553
1673
  }
1554
- getHost() {
1555
- const managementHost = this.managementHost;
1556
- const port = this.managementPort;
1557
- return `https://${managementHost}:${port}/web_api`;
1674
+ return hashedMachineId;
1675
+ }
1676
+ function calculateChecksum(mcpName, toolName, machineId2, clientVersion) {
1677
+ const data = mcpName + machineId2.slice(0, 16) + toolName + clientVersion;
1678
+ return hashString(data);
1679
+ }
1680
+ async function trackToolCall(mcpName, toolName, clientVersion, extra) {
1681
+ if (isTelemetryDisabled()) {
1682
+ return;
1558
1683
  }
1559
- /**
1560
- * Override login() to support both api-key and username/password authentication
1561
- * and allow self-signed certificates
1562
- */
1563
- async login() {
1564
- if (this._externalSid) {
1565
- if (!this.sid)
1566
- throw new Error("External SID has expired");
1567
- return this.sid;
1568
- }
1569
- const isUsingApiKey = !!this.authToken;
1570
- const isUsingCredentials = !!(this.username && this.password);
1571
- if (!isUsingApiKey && !isUsingCredentials) {
1572
- throw new ClientResponse(401, { message: "Authentication failed: No API key or username/password provided" });
1573
- }
1574
- const httpsAgent = new https.Agent({ rejectUnauthorized: false });
1575
- const loginPayload = isUsingApiKey ? { "api-key": this.authToken } : { "user": this.username, "password": this.password };
1576
- if (this.domain) {
1577
- loginPayload["domain"] = this.domain;
1578
- }
1579
- const loginResp = await this.makeRequest(this.getHost(), "POST", "login", loginPayload, { "Content-Type": "application/json" }, null, httpsAgent);
1580
- if (loginResp.status !== 200 || !loginResp.response || !loginResp.response.sid) {
1581
- throw loginResp;
1582
- }
1583
- this.sid = loginResp.response.sid;
1584
- this.sessionTimeout = loginResp.response["session-timeout"] || null;
1585
- this.sessionStart = Date.now();
1586
- if (loginResp.response.uid) {
1587
- await this.detectMDS(loginResp.response.uid, true);
1588
- }
1589
- return loginResp.response.sid;
1684
+ try {
1685
+ const machineId2 = getHashedMachineId();
1686
+ const checksum = calculateChecksum(mcpName, toolName, machineId2, clientVersion);
1687
+ fetch(getTelemetryUrl(), {
1688
+ method: "POST",
1689
+ headers: { "Content-Type": "application/json" },
1690
+ body: JSON.stringify({
1691
+ mcp_name: mcpName,
1692
+ tool_name: toolName,
1693
+ machine_id: machineId2,
1694
+ client_version: clientVersion,
1695
+ transport_type: transportType,
1696
+ checksum
1697
+ })
1698
+ }).catch(() => {
1699
+ });
1700
+ } catch (error) {
1590
1701
  }
1591
- };
1592
-
1593
- // ../infra/dist/string-utils.js
1594
- function nullOrEmpty(val) {
1595
- return val === void 0 || val === null || typeof val === "string" && (val.trim() === "" || val === "undefined" || val === "null");
1596
1702
  }
1597
- function sanitizeData(kwargs) {
1598
- const data = {};
1599
- for (const [key, value] of Object.entries(kwargs)) {
1600
- if (value === null || value === void 0 || value === "" || Array.isArray(value) && value.length === 0) {
1703
+
1704
+ // ../mcp-utils/dist/launcher.js
1705
+ function mirrorBooleanFlagsToEnv(config, options) {
1706
+ for (const option of config.options) {
1707
+ if (option.type !== "boolean" || !option.env)
1601
1708
  continue;
1709
+ const derived = optionKey(option.flag);
1710
+ if (!derived)
1711
+ continue;
1712
+ if (derived.negated) {
1713
+ throw new Error(`Option '${option.flag}' in the configuration for '${config.name}' is a negatable flag paired with env var '${option.env}', which cannot be mirrored automatically: commander keys it as '${derived.key}' and inverts its meaning, so whether the flag being present should set '${option.env}' to 'true' or 'false' depends on how that variable is named. Mirror it explicitly in launchMCPServer instead, the way --no-telemetry does for TELEMETRY_DISABLED.`);
1714
+ }
1715
+ if (options[derived.key] === true) {
1716
+ process.env[option.env] = "true";
1602
1717
  }
1603
- const safeKey = key.replace(/_/g, "-");
1604
- data[safeKey] = value;
1605
1718
  }
1606
- return data;
1607
1719
  }
1608
-
1609
- // ../mcp-utils/dist/launcher.js
1610
- import { Command } from "commander";
1611
- import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
1612
- import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
1613
- import fs from "fs";
1614
- import http from "http";
1615
- import { randomUUID } from "crypto";
1616
-
1617
- // ../mcp-utils/dist/settings-manager.js
1618
- var SettingsManager = class _SettingsManager {
1619
- /**
1620
- * Creates a new SettingsManager
1621
- * @param settingsClass The Settings class to use for creating settings instances
1622
- */
1623
- constructor(settingsClass) {
1624
- this.settingsMap = /* @__PURE__ */ new Map();
1625
- this.defaultSessionId = "default";
1626
- this.settingsClass = settingsClass;
1627
- }
1628
- /**
1629
- * Get settings for a specific session
1630
- * @param sessionId The session ID (defaults to 'default' for stdio mode)
1631
- * @returns Settings instance for the session
1632
- */
1633
- getSettings(sessionId) {
1634
- const sid = sessionId || this.defaultSessionId;
1635
- if (!this.settingsMap.has(sid)) {
1636
- this.settingsMap.set(sid, new this.settingsClass());
1637
- }
1638
- return this.settingsMap.get(sid);
1639
- }
1640
- /**
1641
- * Set settings for a specific session
1642
- * @param settings The settings object to set
1643
- * @param sessionId The session ID (defaults to 'default' for stdio mode)
1644
- */
1645
- setSettings(settings, sessionId) {
1646
- const sid = sessionId || this.defaultSessionId;
1647
- this.settingsMap.set(sid, settings);
1648
- }
1649
- /**
1650
- * Injects debug settings from source into settings object
1651
- * @param settings The settings object to update
1652
- * @param source Source object containing debug information
1653
- * @private
1654
- */
1655
- injectDebug(settings, source) {
1656
- const debug = source?.debug ?? _SettingsManager.globalDebugState ?? process.env.DEBUG;
1657
- if (typeof debug !== "undefined") {
1658
- if (source?.debug !== void 0) {
1659
- _SettingsManager.globalDebugState = source.debug;
1660
- }
1661
- if (typeof settings.set === "function") {
1662
- settings.set("debug", debug);
1663
- } else {
1664
- settings.debug = debug;
1665
- }
1666
- if (debug) {
1667
- console.error("Debug enabled. Source object contents:");
1668
- console.error(JSON.stringify(source, null, 2));
1669
- }
1670
- }
1671
- }
1672
- /**
1673
- * Print settings object for debugging by dynamically discovering its properties
1674
- * @param settings The settings object to print
1675
- * @private
1676
- */
1677
- printSettingsDebug(settings) {
1678
- if (typeof settings.get === "function") {
1679
- console.error("Settings (using get method):");
1680
- if (settings.data && typeof settings.data === "object") {
1681
- Object.entries(settings.data).forEach(([key, value]) => {
1682
- console.error(` ${key}: ${JSON.stringify(value)}`);
1683
- });
1684
- } else {
1685
- console.error(" Unable to enumerate settings properties - no accessible data structure");
1686
- }
1687
- } else {
1688
- console.error("Settings (plain object):");
1689
- Object.entries(settings).forEach(([key, value]) => {
1690
- console.error(` ${key}: ${JSON.stringify(value)}`);
1691
- });
1692
- }
1693
- }
1694
- /**
1695
- * Create settings from command-line arguments
1696
- * @param args Command line arguments
1697
- * @param sessionId Optional session ID
1698
- * @returns Settings instance
1699
- */
1700
- createFromArgs(args, sessionId) {
1701
- const settings = this.settingsClass.fromArgs(args);
1702
- this.injectDebug(settings, args);
1703
- this.setSettings(settings, sessionId);
1704
- return settings;
1705
- }
1706
- /**
1707
- * Create settings from HTTP headers
1708
- * @param headers HTTP headers
1709
- * @param sessionId Optional session ID
1710
- * @returns Settings instance
1711
- */
1712
- createFromHeaders(headers, sessionId) {
1713
- const verbose = _SettingsManager.globalDebugState;
1714
- if (verbose) {
1715
- console.error("[SettingsManager.createFromHeaders] Verbose: Starting with sessionId:", sessionId || "(default)");
1716
- console.error("[SettingsManager.createFromHeaders] Verbose: Incoming headers count:", Object.keys(headers).length);
1717
- }
1718
- if (_SettingsManager.globalDebugState) {
1719
- console.error("=== createFromHeaders Debug Info ===");
1720
- console.error("Incoming headers:");
1721
- console.error(JSON.stringify(headers, null, 2));
1722
- }
1723
- if (verbose && (!headers || Object.keys(headers).length === 0)) {
1724
- console.error("[SettingsManager.createFromHeaders] Verbose: WARNING - Headers object is empty or undefined");
1725
- }
1726
- const normalizedHeaders = {};
1727
- for (const [key, value] of Object.entries(headers)) {
1728
- const normalizedKey = key.includes("_") ? key.replace(/_/g, "-") : key;
1729
- normalizedHeaders[normalizedKey] = value;
1730
- if (verbose) {
1731
- console.error(`[SettingsManager.createFromHeaders] Verbose: Header normalized: "${key}" -> "${normalizedKey}"`);
1732
- }
1733
- }
1734
- if (verbose) {
1735
- console.error("[SettingsManager.createFromHeaders] Verbose: Normalized headers count:", Object.keys(normalizedHeaders).length);
1736
- }
1737
- if (_SettingsManager.globalDebugState) {
1738
- console.error("Normalized headers:");
1739
- console.error(JSON.stringify(normalizedHeaders, null, 2));
1740
- }
1741
- const debugHeader = normalizedHeaders["debug"] || normalizedHeaders["Debug"] || normalizedHeaders["DEBUG"];
1742
- const debugSource = { debug: debugHeader !== void 0 ? debugHeader : _SettingsManager.globalDebugState };
1743
- if (verbose) {
1744
- console.error("[SettingsManager.createFromHeaders] Verbose: Calling settingsClass.fromHeaders");
1745
- }
1746
- const settings = this.settingsClass.fromHeaders(normalizedHeaders);
1747
- if (verbose) {
1748
- console.error("[SettingsManager.createFromHeaders] Verbose: Settings object created");
1749
- }
1750
- this.injectDebug(settings, debugSource);
1751
- if (_SettingsManager.globalDebugState) {
1752
- console.error("Final settings object for session:", sessionId || "(default)");
1753
- this.printSettingsDebug(settings);
1754
- console.error("=== End createFromHeaders Debug Info ===");
1755
- }
1756
- if (verbose) {
1757
- console.error("[SettingsManager.createFromHeaders] Verbose: Storing settings for session:", sessionId || "(default)");
1758
- }
1759
- this.setSettings(settings, sessionId);
1760
- return settings;
1761
- }
1762
- /**
1763
- * Clear settings for a session
1764
- * @param sessionId The session ID to clear
1765
- */
1766
- clearSession(sessionId) {
1767
- if (sessionId !== this.defaultSessionId) {
1768
- this.settingsMap.delete(sessionId);
1769
- }
1770
- }
1771
- };
1772
- SettingsManager.globalDebugState = void 0;
1773
-
1774
- // ../mcp-utils/dist/telemetry.js
1775
- import machineIdPkg from "node-machine-id";
1776
- import { createHash } from "crypto";
1777
- var { machineIdSync } = machineIdPkg;
1778
- var machineId = null;
1779
- var hashedMachineId = null;
1780
- var transportType = "stdio";
1781
- function setTransportType(type) {
1782
- transportType = type;
1783
- }
1784
- function isTelemetryDisabled() {
1785
- return process.env.TELEMETRY_DISABLED === "true" || process.env.TELEMETRY_DISABLED === "1";
1786
- }
1787
- function getTelemetryUrl() {
1788
- return process.env.TELEMETRY_URL || "https://metrics.security.ai.checkpoint.com/api/v1/metrics/collect";
1789
- }
1790
- function hashString(input) {
1791
- return createHash("sha256").update(input).digest("hex");
1792
- }
1793
- function getMachineId() {
1794
- if (!machineId) {
1795
- try {
1796
- machineId = machineIdSync();
1797
- } catch (error) {
1798
- console.warn("Failed to get machine ID for telemetry:", error);
1799
- machineId = "unknown";
1800
- }
1801
- }
1802
- return machineId;
1803
- }
1804
- function getHashedMachineId() {
1805
- if (!hashedMachineId) {
1806
- hashedMachineId = hashString(getMachineId());
1807
- }
1808
- return hashedMachineId;
1809
- }
1810
- function calculateChecksum(mcpName, toolName, machineId2, clientVersion) {
1811
- const data = mcpName + machineId2.slice(0, 16) + toolName + clientVersion;
1812
- return hashString(data);
1813
- }
1814
- async function trackToolCall(mcpName, toolName, clientVersion, extra) {
1815
- if (isTelemetryDisabled()) {
1816
- return;
1817
- }
1818
- try {
1819
- const machineId2 = getHashedMachineId();
1820
- const checksum = calculateChecksum(mcpName, toolName, machineId2, clientVersion);
1821
- fetch(getTelemetryUrl(), {
1822
- method: "POST",
1823
- headers: { "Content-Type": "application/json" },
1824
- body: JSON.stringify({
1825
- mcp_name: mcpName,
1826
- tool_name: toolName,
1827
- machine_id: machineId2,
1828
- client_version: clientVersion,
1829
- transport_type: transportType,
1830
- checksum
1831
- })
1832
- }).catch(() => {
1833
- });
1834
- } catch (error) {
1835
- }
1836
- }
1837
-
1838
- // ../mcp-utils/dist/launcher.js
1839
- async function launchMCPServer(configPath, serverModule2) {
1840
- const config = JSON.parse(fs.readFileSync(configPath, "utf8"));
1841
- const program = new Command();
1842
- if (config.description) {
1843
- program.description(config.description);
1720
+ async function launchMCPServer(configPath, serverModule2) {
1721
+ const config = JSON.parse(fs.readFileSync(configPath, "utf8"));
1722
+ const program = new Command();
1723
+ if (config.description) {
1724
+ program.description(config.description);
1844
1725
  }
1845
1726
  config.options.forEach((option) => {
1846
1727
  const envValue = option.env ? process.env[option.env] : void 0;
1847
1728
  const defaultValue = envValue || option.default;
1848
1729
  if (option.type === "boolean") {
1849
- const boolDefault = envValue === "true" || option.default === "true";
1730
+ const boolDefault = booleanOptionDefault(envValue, option.default);
1850
1731
  program.option(option.flag, option.description, boolDefault);
1851
1732
  } else {
1852
1733
  program.option(option.flag, option.description, defaultValue);
@@ -1870,17 +1751,24 @@ async function launchMCPServer(configPath, serverModule2) {
1870
1751
  if (options.telemetryUrl) {
1871
1752
  process.env.TELEMETRY_URL = options.telemetryUrl;
1872
1753
  }
1754
+ mirrorBooleanFlagsToEnv(config, options);
1755
+ const transportType2 = resolveTransportType(options.transport);
1756
+ process.env.MCP_TRANSPORT_TYPE = transportType2;
1873
1757
  if (!serverModule2.settingsManager) {
1874
1758
  throw new Error("ServerModule must have a settingsManager. Create it with createServerModule.");
1875
1759
  }
1876
1760
  const settings = serverModule2.settingsManager.createFromArgs(options);
1761
+ serverModule2.settingsManager.setOperatorValues?.(operatorValues(config.options, options));
1877
1762
  if (typeof serverModule2.server.applyToolPolicy === "function") {
1878
1763
  console.error("[launchMCPServer] Applying tool policy before connecting");
1879
1764
  serverModule2.server.applyToolPolicy();
1880
1765
  }
1881
- const transportType2 = (options.transport || process.env.MCP_TRANSPORT_TYPE || "stdio").toLowerCase() === "http" ? "http" : "stdio";
1882
1766
  const transportPort = options.transportPort ? parseInt(options.transportPort, 10) : process.env.MCP_TRANSPORT_PORT ? parseInt(process.env.MCP_TRANSPORT_PORT, 10) : 3e3;
1883
1767
  if (transportType2 === "http") {
1768
+ const refusal = serverModule2.httpStartupCheck?.();
1769
+ if (refusal) {
1770
+ throw new Error(refusal);
1771
+ }
1884
1772
  setTransportType("http");
1885
1773
  await launchHTTPServer(config, serverModule2, transportPort);
1886
1774
  } else {
@@ -1929,7 +1817,7 @@ async function launchHTTPServer(config, serverModule2, port) {
1929
1817
  if (sessionId && transports[sessionId]) {
1930
1818
  const verbose = SettingsManager.globalDebugState;
1931
1819
  if (verbose) {
1932
- console.error("[launchHTTPServer] Verbose: Reusing existing transport for session:", sessionId);
1820
+ console.error("[launchHTTPServer] Verbose: Reusing existing transport for session:", sessionLogLabel(sessionId));
1933
1821
  }
1934
1822
  transport = transports[sessionId];
1935
1823
  if (!serverModule2.settingsManager) {
@@ -1949,7 +1837,7 @@ async function launchHTTPServer(config, serverModule2, port) {
1949
1837
  onsessioninitialized: (sid) => {
1950
1838
  const verbose = SettingsManager.globalDebugState;
1951
1839
  if (verbose) {
1952
- console.error("[launchHTTPServer] Verbose: New session initialized:", sid);
1840
+ console.error("[launchHTTPServer] Verbose: New session initialized:", sessionLogLabel(sid));
1953
1841
  }
1954
1842
  transports[sid] = transport;
1955
1843
  if (verbose) {
@@ -2152,7 +2040,6 @@ function headersToEnvVars(headers, config) {
2152
2040
  }
2153
2041
  if (verbose) {
2154
2042
  console.error("[headersToEnvVars] Verbose: Final result keys:", Object.keys(result));
2155
- 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])));
2156
2043
  }
2157
2044
  return result;
2158
2045
  }
@@ -2179,7 +2066,7 @@ var APIManagerFactory = class {
2179
2066
  const verbose = SettingsManager.globalDebugState;
2180
2067
  const sid = sessionId || this.defaultSessionId;
2181
2068
  if (verbose) {
2182
- console.error("[APIManagerFactory.getAPIManager] Verbose: Getting API manager for session:", sid);
2069
+ console.error("[APIManagerFactory.getAPIManager] Verbose: Getting API manager for session:", sessionLogLabel(sid));
2183
2070
  }
2184
2071
  if (!this.apiManagerMap.has(sid)) {
2185
2072
  if (verbose) {
@@ -2277,16 +2164,15 @@ var SessionContext = class {
2277
2164
  /**
2278
2165
  * Get the current session ID from the MCP extra context
2279
2166
  * @param extra Extra context passed to MCP tool callbacks
2280
- * @returns The session ID or DEFAULT_SESSION_ID if not available
2167
+ * @returns The session ID, or DEFAULT_SESSION_ID under stdio
2168
+ * @throws Under HTTP transport when the context carries no session ID
2281
2169
  */
2282
2170
  static getSessionId(extra) {
2283
- if (!extra)
2284
- return this.DEFAULT_SESSION_ID;
2285
- if (extra.transport && extra.transport.sessionId) {
2286
- return extra.transport.sessionId;
2287
- }
2288
- if (extra.sessionId) {
2289
- return extra.sessionId;
2171
+ const sessionId = extra?.transport?.sessionId || extra?.sessionId;
2172
+ if (sessionId)
2173
+ return sessionId;
2174
+ if (process.env.MCP_TRANSPORT_TYPE === "http") {
2175
+ throw new Error("No MCP session in this request context; HTTP transport requires one");
2290
2176
  }
2291
2177
  return this.DEFAULT_SESSION_ID;
2292
2178
  }
@@ -2403,10 +2289,10 @@ var SessionContext = class {
2403
2289
  }
2404
2290
  }
2405
2291
  }
2406
- console.error(`Using cached user data for session: ${sessionId}, key: ${options.cacheKey}`);
2292
+ console.error(`Using cached user data for ${sessionLogLabel(sessionId)}, key: ${options.cacheKey}`);
2407
2293
  return { cancelled: false, data: dataToReturn2 };
2408
2294
  }
2409
- console.error(`Prompting user for data for session: ${sessionId}, key: ${options.cacheKey}`);
2295
+ console.error(`Prompting user for data for ${sessionLogLabel(sessionId)}, key: ${options.cacheKey}`);
2410
2296
  let result;
2411
2297
  if (options.showLoginDialog) {
2412
2298
  const { showLoginDialog: showLoginDialog2 } = await Promise.resolve().then(() => (init_ui_dialog(), ui_dialog_exports));
@@ -2450,308 +2336,688 @@ var SessionContext = class {
2450
2336
  return { cancelled: false, data: dataToReturn };
2451
2337
  }
2452
2338
  /**
2453
- * Clear cached user data for a specific key
2454
- * @param cacheKey The cache key to clear
2455
- * @param extra Extra context with session information
2456
- */
2457
- static clearUserData(cacheKey, extra) {
2458
- const sessionId = this.getSessionId(extra);
2459
- if (this.sessionData.has(sessionId)) {
2460
- const sessionInfo = this.sessionData.get(sessionId);
2461
- sessionInfo.data.delete(cacheKey);
2462
- sessionInfo.lastAccessed = Date.now();
2463
- }
2339
+ * Clear cached user data for a specific key
2340
+ * @param cacheKey The cache key to clear
2341
+ * @param extra Extra context with session information
2342
+ */
2343
+ static clearUserData(cacheKey, extra) {
2344
+ const sessionId = this.getSessionId(extra);
2345
+ if (this.sessionData.has(sessionId)) {
2346
+ const sessionInfo = this.sessionData.get(sessionId);
2347
+ sessionInfo.data.delete(cacheKey);
2348
+ sessionInfo.lastAccessed = Date.now();
2349
+ }
2350
+ }
2351
+ /**
2352
+ * Check if user data exists and is not expired
2353
+ * @param cacheKey The cache key to check
2354
+ * @param extra Extra context with session information
2355
+ * @returns true if valid cached data exists, false otherwise
2356
+ */
2357
+ static hasValidUserData(cacheKey, extra) {
2358
+ const cachedData = this.getData(cacheKey, extra);
2359
+ if (!cachedData || !cachedData.expiresAt) {
2360
+ return false;
2361
+ }
2362
+ return Date.now() < cachedData.expiresAt;
2363
+ }
2364
+ };
2365
+ _a = SessionContext;
2366
+ SessionContext.DEFAULT_SESSION_ID = "default";
2367
+ SessionContext.sessionData = /* @__PURE__ */ new Map();
2368
+ SessionContext.SESSION_TIMEOUT_MS = 24 * 60 * 60 * 1e3;
2369
+ SessionContext.CLEANUP_INTERVAL_MS = 60 * 60 * 1e3;
2370
+ SessionContext.MAX_SESSIONS = 1e3;
2371
+ SessionContext.cleanupTimer = null;
2372
+ (() => {
2373
+ _a.startCleanupTimer();
2374
+ })();
2375
+
2376
+ // ../mcp-utils/dist/session-manager.js
2377
+ var DEFAULT_SESSION_TIMEOUT_MS = 15 * 60 * 1e3;
2378
+ var SessionManager = class {
2379
+ constructor() {
2380
+ this.sessions = /* @__PURE__ */ new Map();
2381
+ }
2382
+ /**
2383
+ * Create a new session
2384
+ * @param sessionId The session ID
2385
+ * @param metadata Optional metadata to store with the session
2386
+ * @returns Session info
2387
+ */
2388
+ createSession(sessionId, metadata = {}) {
2389
+ const now = /* @__PURE__ */ new Date();
2390
+ const sessionInfo = {
2391
+ sessionId,
2392
+ createdAt: now,
2393
+ lastActive: now,
2394
+ ...metadata
2395
+ };
2396
+ this.sessions.set(sessionId, sessionInfo);
2397
+ return sessionInfo;
2398
+ }
2399
+ /**
2400
+ * Get info for a session
2401
+ * @param sessionId The session ID
2402
+ * @returns Session info or undefined if not found
2403
+ */
2404
+ getSession(sessionId) {
2405
+ if (this.sessions.has(sessionId)) {
2406
+ this.touchSession(sessionId);
2407
+ }
2408
+ return this.sessions.get(sessionId);
2409
+ }
2410
+ /**
2411
+ * Update session activity timestamp
2412
+ * @param sessionId The session ID
2413
+ */
2414
+ touchSession(sessionId) {
2415
+ const session = this.sessions.get(sessionId);
2416
+ if (session) {
2417
+ session.lastActive = /* @__PURE__ */ new Date();
2418
+ }
2419
+ }
2420
+ /**
2421
+ * Remove a session
2422
+ * @param sessionId The session ID
2423
+ */
2424
+ removeSession(sessionId) {
2425
+ this.sessions.delete(sessionId);
2426
+ SessionContext.clearSessionData(sessionId);
2427
+ }
2428
+ /**
2429
+ * Get all active sessions
2430
+ * @returns Array of session info objects
2431
+ */
2432
+ getAllSessions() {
2433
+ return Array.from(this.sessions.values());
2434
+ }
2435
+ /**
2436
+ * Get count of active sessions
2437
+ * @returns Number of active sessions
2438
+ */
2439
+ getSessionCount() {
2440
+ return this.sessions.size;
2441
+ }
2442
+ /**
2443
+ * Clean up inactive sessions older than the specified timeout
2444
+ * @param timeoutMs Timeout in milliseconds (default: 30 minutes)
2445
+ * @returns Number of sessions removed
2446
+ */
2447
+ cleanupInactiveSessions(timeoutMs = DEFAULT_SESSION_TIMEOUT_MS) {
2448
+ const now = /* @__PURE__ */ new Date();
2449
+ let removedCount = 0;
2450
+ for (const [sessionId, session] of this.sessions.entries()) {
2451
+ const inactiveTime = now.getTime() - session.lastActive.getTime();
2452
+ if (inactiveTime > timeoutMs) {
2453
+ this.removeSession(sessionId);
2454
+ removedCount++;
2455
+ }
2456
+ }
2457
+ return removedCount;
2458
+ }
2459
+ };
2460
+
2461
+ // ../mcp-utils/dist/server-utils.js
2462
+ function getHeaderValue(headers, key) {
2463
+ const normalizedKey = key.replace(/_/g, "-");
2464
+ const value = headers[normalizedKey] || headers[normalizedKey.toUpperCase()] || headers[normalizedKey.toLowerCase()];
2465
+ return typeof value === "string" ? value : Array.isArray(value) ? value[0] : void 0;
2466
+ }
2467
+ function createApiRunner(serverModule2) {
2468
+ return async (method, uri, data, extra, domain) => {
2469
+ const apiManager = SessionContext.getAPIManager(serverModule2, extra);
2470
+ return await apiManager.callApi(method, uri, data, domain);
2471
+ };
2472
+ }
2473
+ function wrapServerWithTracking(server2, createServerFn) {
2474
+ const registrations = [];
2475
+ const originalTool = server2.tool?.bind(server2);
2476
+ const originalPrompt = server2.prompt?.bind(server2);
2477
+ const originalResource = server2.resource?.bind(server2);
2478
+ if (originalTool) {
2479
+ server2.tool = function(...args) {
2480
+ registrations.push({ type: "tool", method: "tool", args: [...args] });
2481
+ return originalTool(...args);
2482
+ };
2483
+ }
2484
+ if (originalPrompt) {
2485
+ server2.prompt = function(...args) {
2486
+ registrations.push({ type: "prompt", method: "prompt", args: [...args] });
2487
+ return originalPrompt(...args);
2488
+ };
2489
+ }
2490
+ if (originalResource) {
2491
+ server2.resource = function(...args) {
2492
+ registrations.push({ type: "resource", method: "resource", args: [...args] });
2493
+ return originalResource(...args);
2494
+ };
2495
+ }
2496
+ const createInstance = () => {
2497
+ const newServer = createServerFn();
2498
+ for (const reg of registrations) {
2499
+ if (newServer[reg.method]) {
2500
+ newServer[reg.method](...reg.args);
2501
+ }
2502
+ }
2503
+ const toolPolicy = typeof server2.getToolPolicy === "function" ? server2.getToolPolicy() : void 0;
2504
+ if (toolPolicy && typeof newServer.setToolPolicy === "function") {
2505
+ newServer.setToolPolicy(toolPolicy);
2506
+ if (typeof newServer.applyToolPolicy === "function") {
2507
+ newServer.applyToolPolicy();
2508
+ }
2509
+ }
2510
+ return newServer;
2511
+ };
2512
+ return { wrappedServer: server2, createInstance };
2513
+ }
2514
+ function createServerModule(server2, Settings2, pkg2, apiManagerClass, toolPolicyCallback, createServerFn) {
2515
+ const settingsManager = new SettingsManager(Settings2);
2516
+ const apiManagerFactory = new APIManagerFactory(apiManagerClass, settingsManager);
2517
+ const sessionManager = new SessionManager();
2518
+ if (toolPolicyCallback && typeof server2.setToolPolicy === "function") {
2519
+ console.error("[createServerModule] Setting tool policy callback on server");
2520
+ server2.setToolPolicy(toolPolicyCallback);
2521
+ }
2522
+ const serverFactory = createServerFn || server2._createServerFn;
2523
+ let createServerInstance;
2524
+ if (serverFactory) {
2525
+ const { wrappedServer, createInstance } = wrapServerWithTracking(server2, serverFactory);
2526
+ createServerInstance = createInstance;
2527
+ console.error("[createServerModule] Server factory enabled - HTTP multi-user support active");
2528
+ } else {
2529
+ console.error("[createServerModule] Warning: No server factory provided - HTTP multi-user may have issues");
2530
+ }
2531
+ return {
2532
+ server: server2,
2533
+ Settings: Settings2,
2534
+ settingsManager,
2535
+ apiManagerFactory,
2536
+ sessionManager,
2537
+ pkg: pkg2,
2538
+ toolPolicyCallback,
2539
+ createServerInstance
2540
+ };
2541
+ }
2542
+
2543
+ // ../mcp-utils/dist/index.js
2544
+ init_ui_dialog();
2545
+
2546
+ // ../mcp-utils/dist/mcp-server.js
2547
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2548
+ var CPMcpServer = class extends McpServer {
2549
+ constructor(serverInfo, options) {
2550
+ super(serverInfo, options);
2551
+ this.mcpName = serverInfo.name;
2552
+ this.mcpVersion = serverInfo.version || "0.0.0";
2553
+ }
2554
+ /**
2555
+ * Set a tool policy callback to filter which tools are available
2556
+ * This should be called after all tools are registered but before connecting
2557
+ * @param callback Function that returns true if a tool should be enabled
2558
+ */
2559
+ setToolPolicy(callback) {
2560
+ console.error("[CPMcpServer] Setting tool policy callback");
2561
+ this.toolPolicyCallback = callback;
2562
+ }
2563
+ /**
2564
+ * Get the tool policy callback, if one was set.
2565
+ *
2566
+ * Needed so the policy can be carried onto the per-session server instances
2567
+ * created for HTTP transport. A typed accessor keeps that transfer honest:
2568
+ * callers do not have to reach into the private field, where a misspelling
2569
+ * would go unnoticed by the compiler.
2570
+ */
2571
+ getToolPolicy() {
2572
+ return this.toolPolicyCallback;
2573
+ }
2574
+ /**
2575
+ * Apply the tool policy by checking all registered tools
2576
+ * This should be called after all tools are registered but before connecting
2577
+ *
2578
+ * Per-tool tracing is behind the debug flag. This used to run once per process
2579
+ * on the template server, where a line per tool was a cheap startup banner.
2580
+ * It now also runs per session under HTTP transport, so unconditional tracing
2581
+ * would scale stderr with sessions x tools and bury the summary. The summary
2582
+ * line always prints — it is the fact worth having for every session.
2583
+ */
2584
+ applyToolPolicy() {
2585
+ const verbose = SettingsManager.globalDebugState === true || SettingsManager.globalDebugState === "true";
2586
+ if (!this.toolPolicyCallback) {
2587
+ if (verbose) {
2588
+ console.error("[CPMcpServer] No tool policy callback set, allowing all tools");
2589
+ }
2590
+ return;
2591
+ }
2592
+ const registeredTools = this._registeredTools;
2593
+ if (!registeredTools || typeof registeredTools !== "object") {
2594
+ console.error("[CPMcpServer] No tools registered yet");
2595
+ return;
2596
+ }
2597
+ const toolNames = Object.keys(registeredTools);
2598
+ if (verbose) {
2599
+ console.error(`[CPMcpServer] Applying tool policy`);
2600
+ console.error(`[CPMcpServer] Found ${toolNames.length} registered tools:`, toolNames);
2601
+ }
2602
+ let enabledCount = 0;
2603
+ let disabledCount = 0;
2604
+ for (const [toolName, tool] of Object.entries(registeredTools)) {
2605
+ const isAllowed = this.toolPolicyCallback(toolName);
2606
+ if (!isAllowed) {
2607
+ if (verbose) {
2608
+ console.error(`[CPMcpServer] Tool '${toolName}' is NOT allowed by policy - disabling`);
2609
+ }
2610
+ if (typeof tool.disable === "function") {
2611
+ tool.disable();
2612
+ disabledCount++;
2613
+ }
2614
+ } else {
2615
+ if (verbose) {
2616
+ console.error(`[CPMcpServer] Tool '${toolName}' is allowed by policy`);
2617
+ }
2618
+ enabledCount++;
2619
+ }
2620
+ }
2621
+ console.error(`[CPMcpServer] Policy applied: ${enabledCount}/${toolNames.length} tools enabled, ${disabledCount} disabled`);
2622
+ }
2623
+ // Override the tool method to wrap callbacks with telemetry
2624
+ tool(...args) {
2625
+ const callback = args[args.length - 1];
2626
+ if (typeof callback === "function") {
2627
+ const toolName = args[0];
2628
+ const wrappedCallback = async (...callbackArgs) => {
2629
+ let extra = callbackArgs[1];
2630
+ if (!extra && callbackArgs[0]?.sessionId) {
2631
+ extra = callbackArgs[0];
2632
+ }
2633
+ trackToolCall(this.mcpName, toolName, this.mcpVersion, extra).catch(() => {
2634
+ });
2635
+ if (callbackArgs.length === 1 && callbackArgs[0]?.sessionId) {
2636
+ return callback({}, callbackArgs[0]);
2637
+ }
2638
+ return callback(...callbackArgs);
2639
+ };
2640
+ args[args.length - 1] = wrappedCallback;
2641
+ }
2642
+ return super.tool(...args);
2643
+ }
2644
+ };
2645
+
2646
+ // ../mcp-utils/dist/package-utils.js
2647
+ import { readFileSync } from "fs";
2648
+ import { join as join2, dirname } from "path";
2649
+ import { fileURLToPath } from "url";
2650
+ function readPackageJson(importMetaUrl) {
2651
+ const pkg2 = JSON.parse(readFileSync(join2(dirname(fileURLToPath(importMetaUrl)), "../package.json"), "utf-8"));
2652
+ process.env.CP_MCP_MAIN_PKG = `${pkg2.name} v${pkg2.version}`;
2653
+ return pkg2;
2654
+ }
2655
+ function createMcpServer(importMetaUrl, serverInfo, options) {
2656
+ const pkg2 = readPackageJson(importMetaUrl);
2657
+ const fullServerInfo = {
2658
+ ...serverInfo,
2659
+ name: serverInfo.name || pkg2.name,
2660
+ version: serverInfo.version || pkg2.version
2661
+ };
2662
+ const createServerFn = () => {
2663
+ return new CPMcpServer(fullServerInfo, options);
2664
+ };
2665
+ const server2 = new CPMcpServer(fullServerInfo, options);
2666
+ server2._createServerFn = createServerFn;
2667
+ return { server: server2, pkg: pkg2 };
2668
+ }
2669
+
2670
+ // ../infra/dist/api-client.js
2671
+ var DEBUG_LOGGABLE_REQUEST_KEYS = debugLoggableKeys([
2672
+ "details-level",
2673
+ "domain",
2674
+ "filter",
2675
+ "layer",
2676
+ "limit",
2677
+ "name",
2678
+ "offset",
2679
+ "order",
2680
+ "package",
2681
+ "show-membership",
2682
+ "targets",
2683
+ "task-id",
2684
+ "type",
2685
+ "uid",
2686
+ "use-object-dictionary"
2687
+ ]);
2688
+ var TokenType;
2689
+ (function(TokenType2) {
2690
+ TokenType2["API_KEY"] = "API_KEY";
2691
+ TokenType2["CI_TOKEN"] = "CI_TOKEN";
2692
+ })(TokenType || (TokenType = {}));
2693
+ function getMainPackageUserAgent() {
2694
+ if (process.env.CP_MCP_MAIN_PKG) {
2695
+ if (process.env.CP_MCP_MAIN_PKG.includes("quantum-management-mcp")) {
2696
+ return "mgmt-mcp";
2697
+ }
2698
+ }
2699
+ return "Check Point MCP API Client";
2700
+ }
2701
+ var ClientResponse = class {
2702
+ constructor(status, response) {
2703
+ this.status = status;
2704
+ this.response = response;
2705
+ }
2706
+ };
2707
+ var APIClientBase = class {
2708
+ constructor(authToken = "", tokenType = TokenType.API_KEY, cloudConnected = false) {
2709
+ this.authToken = authToken;
2710
+ this.tokenType = tokenType;
2711
+ this.cloudConnected = cloudConnected;
2712
+ this.sid = null;
2713
+ this.sessionTimeout = null;
2714
+ this.sessionStart = null;
2715
+ this.isMDS = false;
2716
+ this._externalSid = false;
2717
+ }
2718
+ /**
2719
+ * Create an API client instance - generic method for creating clients
2720
+ */
2721
+ static create(...args) {
2722
+ return new this(...args);
2464
2723
  }
2465
2724
  /**
2466
- * Check if user data exists and is not expired
2467
- * @param cacheKey The cache key to check
2468
- * @param extra Extra context with session information
2469
- * @returns true if valid cached data exists, false otherwise
2725
+ * Get headers for the API requests
2470
2726
  */
2471
- static hasValidUserData(cacheKey, extra) {
2472
- const cachedData = this.getData(cacheKey, extra);
2473
- if (!cachedData || !cachedData.expiresAt) {
2474
- return false;
2727
+ getHeaders() {
2728
+ const headers = {
2729
+ "Content-Type": "application/json",
2730
+ "User-Agent": getMainPackageUserAgent()
2731
+ };
2732
+ if (this.sid) {
2733
+ headers["X-chkp-sid"] = this.sid;
2475
2734
  }
2476
- return Date.now() < cachedData.expiresAt;
2735
+ if (this.cloudConnected && this.tokenType === TokenType.CI_TOKEN) {
2736
+ headers["Authorization"] = `Bearer ${this.authToken}`;
2737
+ headers["CLOUD-INFRA-TOKEN"] = this.authToken;
2738
+ }
2739
+ return headers;
2477
2740
  }
2478
- };
2479
- _a = SessionContext;
2480
- SessionContext.DEFAULT_SESSION_ID = "default";
2481
- SessionContext.sessionData = /* @__PURE__ */ new Map();
2482
- SessionContext.SESSION_TIMEOUT_MS = 24 * 60 * 60 * 1e3;
2483
- SessionContext.CLEANUP_INTERVAL_MS = 60 * 60 * 1e3;
2484
- SessionContext.MAX_SESSIONS = 1e3;
2485
- SessionContext.cleanupTimer = null;
2486
- (() => {
2487
- _a.startCleanupTimer();
2488
- })();
2489
-
2490
- // ../mcp-utils/dist/session-manager.js
2491
- var DEFAULT_SESSION_TIMEOUT_MS = 15 * 60 * 1e3;
2492
- var SessionManager = class {
2493
- constructor() {
2494
- this.sessions = /* @__PURE__ */ new Map();
2741
+ /**
2742
+ * Get debug mode
2743
+ */
2744
+ get debug() {
2745
+ return !!this._debug;
2495
2746
  }
2496
2747
  /**
2497
- * Create a new session
2498
- * @param sessionId The session ID
2499
- * @param metadata Optional metadata to store with the session
2500
- * @returns Session info
2748
+ * Set debug mode
2501
2749
  */
2502
- createSession(sessionId, metadata = {}) {
2503
- const now = /* @__PURE__ */ new Date();
2504
- const sessionInfo = {
2505
- sessionId,
2506
- createdAt: now,
2507
- lastActive: now,
2508
- ...metadata
2509
- };
2510
- this.sessions.set(sessionId, sessionInfo);
2511
- return sessionInfo;
2750
+ set debug(value) {
2751
+ this._debug = value;
2512
2752
  }
2513
2753
  /**
2514
- * Get info for a session
2515
- * @param sessionId The session ID
2516
- * @returns Session info or undefined if not found
2754
+ * Set a pre-authenticated session ID provided externally (e.g. via X-chkp-sid header).
2755
+ * When set, the client will skip login and use this SID directly for all requests.
2756
+ */
2757
+ setExternalSid(sid) {
2758
+ this.sid = sid;
2759
+ this._externalSid = true;
2760
+ this.sessionStart = Date.now();
2761
+ this.sessionTimeout = Number.MAX_SAFE_INTEGER / 1e3;
2762
+ }
2763
+ /**
2764
+ * Check if this client needs to perform login before making API calls
2517
2765
  */
2518
- getSession(sessionId) {
2519
- if (this.sessions.has(sessionId)) {
2520
- this.touchSession(sessionId);
2766
+ needsLogin() {
2767
+ if (this._externalSid) {
2768
+ return false;
2521
2769
  }
2522
- return this.sessions.get(sessionId);
2770
+ return true;
2523
2771
  }
2524
2772
  /**
2525
- * Update session activity timestamp
2526
- * @param sessionId The session ID
2773
+ * Check if this client is in an MDS environment
2527
2774
  */
2528
- touchSession(sessionId) {
2529
- const session = this.sessions.get(sessionId);
2530
- if (session) {
2531
- session.lastActive = /* @__PURE__ */ new Date();
2775
+ async isMDSEnvironment() {
2776
+ if (!this.hasValidSession()) {
2777
+ await this.login();
2532
2778
  }
2779
+ return this.isMDS;
2533
2780
  }
2534
2781
  /**
2535
- * Remove a session
2536
- * @param sessionId The session ID
2782
+ * Check if the client has a valid session
2537
2783
  */
2538
- removeSession(sessionId) {
2539
- this.sessions.delete(sessionId);
2540
- SessionContext.clearSessionData(sessionId);
2784
+ hasValidSession() {
2785
+ return !!this.sid && !this.isSessionExpired();
2541
2786
  }
2542
2787
  /**
2543
- * Get all active sessions
2544
- * @returns Array of session info objects
2788
+ * Get the current session ID (for debugging/logging purposes)
2545
2789
  */
2546
- getAllSessions() {
2547
- return Array.from(this.sessions.values());
2790
+ getSessionId() {
2791
+ return this.sid;
2548
2792
  }
2549
2793
  /**
2550
- * Get count of active sessions
2551
- * @returns Number of active sessions
2794
+ * Create a new API client instance with a specific session ID
2795
+ * Used for domain-specific clients in MDS environments
2552
2796
  */
2553
- getSessionCount() {
2554
- return this.sessions.size;
2797
+ static createWithSid(originalClient, sid) {
2798
+ const newClient = Object.create(Object.getPrototypeOf(originalClient));
2799
+ Object.assign(newClient, originalClient);
2800
+ newClient.sid = sid;
2801
+ newClient.sessionStart = Date.now();
2802
+ return newClient;
2555
2803
  }
2556
2804
  /**
2557
- * Clean up inactive sessions older than the specified timeout
2558
- * @param timeoutMs Timeout in milliseconds (default: 30 minutes)
2559
- * @returns Number of sessions removed
2805
+ * Call an API endpoint
2560
2806
  */
2561
- cleanupInactiveSessions(timeoutMs = DEFAULT_SESSION_TIMEOUT_MS) {
2562
- const now = /* @__PURE__ */ new Date();
2563
- let removedCount = 0;
2564
- for (const [sessionId, session] of this.sessions.entries()) {
2565
- const inactiveTime = now.getTime() - session.lastActive.getTime();
2566
- if (inactiveTime > timeoutMs) {
2567
- this.removeSession(sessionId);
2568
- removedCount++;
2569
- }
2570
- }
2571
- return removedCount;
2572
- }
2573
- };
2574
-
2575
- // ../mcp-utils/dist/server-utils.js
2576
- function getHeaderValue(headers, key) {
2577
- const normalizedKey = key.replace(/_/g, "-");
2578
- const value = headers[normalizedKey] || headers[normalizedKey.toUpperCase()] || headers[normalizedKey.toLowerCase()];
2579
- return typeof value === "string" ? value : Array.isArray(value) ? value[0] : void 0;
2580
- }
2581
- function createApiRunner(serverModule2) {
2582
- return async (method, uri, data, extra, domain) => {
2583
- const apiManager = SessionContext.getAPIManager(serverModule2, extra);
2584
- return await apiManager.callApi(method, uri, data, domain);
2585
- };
2586
- }
2587
- function wrapServerWithTracking(server2, createServerFn) {
2588
- const registrations = [];
2589
- const originalTool = server2.tool?.bind(server2);
2590
- const originalPrompt = server2.prompt?.bind(server2);
2591
- const originalResource = server2.resource?.bind(server2);
2592
- if (originalTool) {
2593
- server2.tool = function(...args) {
2594
- registrations.push({ type: "tool", method: "tool", args: [...args] });
2595
- return originalTool(...args);
2596
- };
2597
- }
2598
- if (originalPrompt) {
2599
- server2.prompt = function(...args) {
2600
- registrations.push({ type: "prompt", method: "prompt", args: [...args] });
2601
- return originalPrompt(...args);
2602
- };
2603
- }
2604
- if (originalResource) {
2605
- server2.resource = function(...args) {
2606
- registrations.push({ type: "resource", method: "resource", args: [...args] });
2607
- return originalResource(...args);
2608
- };
2609
- }
2610
- const createInstance = () => {
2611
- const newServer = createServerFn();
2612
- for (const reg of registrations) {
2613
- if (newServer[reg.method]) {
2614
- newServer[reg.method](...reg.args);
2807
+ async callApi(method, uri, data, params) {
2808
+ if (this.needsLogin() && (!this.sid || this.isSessionExpired())) {
2809
+ try {
2810
+ await this.login();
2811
+ } catch (error) {
2812
+ if (error instanceof ClientResponse) {
2813
+ console.error(`Login failed with status ${error.status}:`, error.response);
2814
+ return error;
2815
+ }
2816
+ console.error("Login failed with unexpected error:", error);
2817
+ return new ClientResponse(500, { error: "Authentication failed", message: error.message });
2615
2818
  }
2616
2819
  }
2617
- if (typeof server2.setToolPolicy === "function" && typeof newServer.setToolPolicy === "function") {
2618
- const toolPolicy = server2._toolPolicyCallback;
2619
- if (toolPolicy) {
2620
- newServer.setToolPolicy(toolPolicy);
2621
- }
2820
+ let httpsAgent;
2821
+ if (this instanceof OnPremAPIClient) {
2822
+ httpsAgent = new https.Agent({ rejectUnauthorized: false });
2823
+ }
2824
+ try {
2825
+ return await this.makeRequest(this.getHost(), method, uri, data, this.getHeaders(), params, httpsAgent);
2826
+ } catch (error) {
2827
+ if ((error.message?.includes("401") || error.response?.status === 401) && error.message?.toLowerCase().includes("session")) {
2828
+ if (this._externalSid) {
2829
+ throw new Error("Pre-authenticated session (X-chkp-sid) has expired. Provide a new session ID.");
2830
+ }
2831
+ console.error("Session expired (401), resetting session and retrying...");
2832
+ this.sid = null;
2833
+ this.sessionStart = null;
2834
+ try {
2835
+ await this.login();
2836
+ } catch (loginError) {
2837
+ if (loginError instanceof ClientResponse) {
2838
+ console.error(`Login retry failed with status ${loginError.status}:`, loginError.response);
2839
+ return loginError;
2840
+ }
2841
+ console.error("Login retry failed with unexpected error:", loginError);
2842
+ throw loginError;
2843
+ }
2844
+ return await this.makeRequest(this.getHost(), method, uri, data, this.getHeaders(), params, httpsAgent);
2845
+ }
2846
+ throw error;
2622
2847
  }
2623
- return newServer;
2624
- };
2625
- return { wrappedServer: server2, createInstance };
2626
- }
2627
- function createServerModule(server2, Settings2, pkg2, apiManagerClass, toolPolicyCallback, createServerFn) {
2628
- const settingsManager = new SettingsManager(Settings2);
2629
- const apiManagerFactory = new APIManagerFactory(apiManagerClass, settingsManager);
2630
- const sessionManager = new SessionManager();
2631
- if (toolPolicyCallback && typeof server2.setToolPolicy === "function") {
2632
- console.error("[createServerModule] Setting tool policy callback on server");
2633
- server2.setToolPolicy(toolPolicyCallback);
2634
2848
  }
2635
- const serverFactory = createServerFn || server2._createServerFn;
2636
- let createServerInstance;
2637
- if (serverFactory) {
2638
- const { wrappedServer, createInstance } = wrapServerWithTracking(server2, serverFactory);
2639
- createServerInstance = createInstance;
2640
- console.error("[createServerModule] Server factory enabled - HTTP multi-user support active");
2641
- } else {
2642
- console.error("[createServerModule] Warning: No server factory provided - HTTP multi-user may have issues");
2849
+ /**
2850
+ * Check if the session is expired based on sessionTimeout and sessionStart
2851
+ */
2852
+ isSessionExpired() {
2853
+ if (!this.sid || !this.sessionTimeout || !this.sessionStart)
2854
+ return true;
2855
+ const now = Date.now();
2856
+ return now > this.sessionStart + (this.sessionTimeout - 5) * 1e3;
2643
2857
  }
2644
- return {
2645
- server: server2,
2646
- Settings: Settings2,
2647
- settingsManager,
2648
- apiManagerFactory,
2649
- sessionManager,
2650
- pkg: pkg2,
2651
- toolPolicyCallback,
2652
- createServerInstance
2653
- };
2654
- }
2655
-
2656
- // ../mcp-utils/dist/index.js
2657
- init_ui_dialog();
2658
-
2659
- // ../mcp-utils/dist/mcp-server.js
2660
- import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2661
- var CPMcpServer = class extends McpServer {
2662
- constructor(serverInfo, options) {
2663
- super(serverInfo, options);
2664
- this.mcpName = serverInfo.name;
2665
- this.mcpVersion = serverInfo.version || "0.0.0";
2858
+ getHeadersForLogin() {
2859
+ return { "Content-Type": "application/json" };
2666
2860
  }
2667
2861
  /**
2668
- * Set a tool policy callback to filter which tools are available
2669
- * This should be called after all tools are registered but before connecting
2670
- * @param callback Function that returns true if a tool should be enabled
2862
+ * Login to the API using the API key
2671
2863
  */
2672
- setToolPolicy(callback) {
2673
- console.error("[CPMcpServer] Setting tool policy callback");
2674
- this.toolPolicyCallback = callback;
2864
+ async login() {
2865
+ if (this._externalSid) {
2866
+ if (!this.sid)
2867
+ throw new Error("External SID has expired");
2868
+ return this.sid;
2869
+ }
2870
+ const apiTokenHeader = this.tokenType === TokenType.API_KEY ? "api-key" : "ci-token";
2871
+ const loginResp = await this.makeRequest(this.getHost(), "POST", "login", { [apiTokenHeader]: this.authToken }, this.getHeadersForLogin());
2872
+ if (loginResp.status !== 200 || !loginResp.response || !loginResp.response.sid) {
2873
+ throw loginResp;
2874
+ }
2875
+ this.sid = loginResp.response.sid;
2876
+ this.sessionTimeout = loginResp.response["session-timeout"] || null;
2877
+ this.sessionStart = Date.now();
2878
+ if (loginResp.response.uid) {
2879
+ await this.detectMDS(loginResp.response.uid);
2880
+ }
2881
+ return loginResp.response.sid;
2675
2882
  }
2676
2883
  /**
2677
- * Apply the tool policy by checking all registered tools
2678
- * This should be called after all tools are registered but before connecting
2884
+ * Detect if this is an MDS environment by checking the session details
2679
2885
  */
2680
- applyToolPolicy() {
2681
- if (!this.toolPolicyCallback) {
2682
- console.error("[CPMcpServer] No tool policy callback set, allowing all tools");
2683
- return;
2886
+ async detectMDS(sessionUid, handleSelfSigned = false) {
2887
+ try {
2888
+ let httpsAgent;
2889
+ if (handleSelfSigned) {
2890
+ httpsAgent = new https.Agent({ rejectUnauthorized: false });
2891
+ }
2892
+ const sessionResp = await this.makeRequest(this.getHost(), "POST", "show-session", { uid: sessionUid }, this.getHeaders(), null, httpsAgent);
2893
+ if (sessionResp.status === 200 && sessionResp.response?.domain?.["domain-type"] === "mds") {
2894
+ this.isMDS = true;
2895
+ }
2896
+ } catch (error) {
2897
+ console.warn("Could not determine MDS status:", error);
2898
+ this.isMDS = false;
2684
2899
  }
2685
- console.error("[CPMcpServer] Applying tool policy");
2686
- const registeredTools = this._registeredTools;
2687
- if (!registeredTools || typeof registeredTools !== "object") {
2688
- console.error("[CPMcpServer] No tools registered yet");
2689
- return;
2900
+ }
2901
+ /**
2902
+ * Make a request to a Check Point API
2903
+ */
2904
+ async makeRequest(host, method, uri, data, headers = {}, params = null, httpsAgent) {
2905
+ uri = uri.replace(/^\//, "");
2906
+ const url = `${host}/${uri}`;
2907
+ const config = {
2908
+ method: method.toUpperCase(),
2909
+ url,
2910
+ headers,
2911
+ params: params || void 0
2912
+ };
2913
+ if (httpsAgent) {
2914
+ config.httpsAgent = httpsAgent;
2690
2915
  }
2691
- const toolNames = Object.keys(registeredTools);
2692
- console.error(`[CPMcpServer] Found ${toolNames.length} registered tools:`, toolNames);
2693
- let enabledCount = 0;
2694
- let disabledCount = 0;
2695
- for (const [toolName, tool] of Object.entries(registeredTools)) {
2696
- const isAllowed = this.toolPolicyCallback(toolName);
2697
- if (!isAllowed) {
2698
- console.error(`[CPMcpServer] Tool '${toolName}' is NOT allowed by policy - disabling`);
2699
- if (typeof tool.disable === "function") {
2700
- tool.disable();
2701
- disabledCount++;
2916
+ if (method.toUpperCase() !== "GET" && data !== void 0) {
2917
+ config.data = data;
2918
+ }
2919
+ console.error(`API Request: ${method} ${url}`);
2920
+ try {
2921
+ const response = await axios(config);
2922
+ return new ClientResponse(response.status, response.data);
2923
+ } catch (error) {
2924
+ if (error.response) {
2925
+ console.error(`\u274C API Error (${error.response.status}):`);
2926
+ console.error("Headers:", error.response.headers);
2927
+ console.error("Data:", error.response.data);
2928
+ if (this.debug) {
2929
+ console.error("Debug mode: Printing request details:");
2930
+ console.error("Request Method:", method);
2931
+ console.error("Request URL:", url);
2932
+ console.error("Request Headers:", debugView(config.headers));
2933
+ console.error("Request Data:", debugView(config.data && typeof config.data === "object" ? config.data : { body: config.data }, DEBUG_LOGGABLE_REQUEST_KEYS));
2702
2934
  }
2703
- } else {
2704
- console.error(`[CPMcpServer] Tool '${toolName}' is allowed by policy`);
2705
- enabledCount++;
2706
2935
  }
2936
+ if (error.response) {
2937
+ throw new Error(`API request failed: ${error.response.status} - ${JSON.stringify(error.response.data)}`);
2938
+ }
2939
+ throw error;
2707
2940
  }
2708
- console.error(`[CPMcpServer] Policy applied: ${enabledCount}/${toolNames.length} tools enabled, ${disabledCount} disabled`);
2709
2941
  }
2710
- // Override the tool method to wrap callbacks with telemetry
2711
- tool(...args) {
2712
- const callback = args[args.length - 1];
2713
- if (typeof callback === "function") {
2714
- const toolName = args[0];
2715
- const wrappedCallback = async (...callbackArgs) => {
2716
- let extra = callbackArgs[1];
2717
- if (!extra && callbackArgs[0]?.sessionId) {
2718
- extra = callbackArgs[0];
2719
- }
2720
- trackToolCall(this.mcpName, toolName, this.mcpVersion, extra).catch(() => {
2721
- });
2722
- if (callbackArgs.length === 1 && callbackArgs[0]?.sessionId) {
2723
- return callback({}, callbackArgs[0]);
2724
- }
2725
- return callback(...callbackArgs);
2726
- };
2727
- args[args.length - 1] = wrappedCallback;
2942
+ };
2943
+ var SmartOneCloudAPIClient = class extends APIClientBase {
2944
+ constructor(authToken, tokenType, s1cUrl, cloudConnected = false) {
2945
+ super(authToken, tokenType, cloudConnected);
2946
+ this.s1cUrl = s1cUrl;
2947
+ }
2948
+ getHost() {
2949
+ return this.s1cUrl;
2950
+ }
2951
+ getHeadersForLogin() {
2952
+ const headers = { "Content-Type": "application/json" };
2953
+ if (this.cloudConnected && this.tokenType === TokenType.CI_TOKEN) {
2954
+ headers["Authorization"] = `Bearer ${this.authToken}`;
2728
2955
  }
2729
- return super.tool(...args);
2956
+ return headers;
2957
+ }
2958
+ };
2959
+ var OnPremAPIClient = class extends APIClientBase {
2960
+ constructor(apiKey, managementHost, managementPort = "443", username, password, domain) {
2961
+ super(apiKey || "");
2962
+ this.managementHost = managementHost;
2963
+ this.managementPort = managementPort;
2964
+ this.domain = domain;
2965
+ this.username = username;
2966
+ this.password = password;
2967
+ }
2968
+ getHost() {
2969
+ const managementHost = this.managementHost;
2970
+ const port = this.managementPort;
2971
+ return `https://${managementHost}:${port}/web_api`;
2972
+ }
2973
+ /**
2974
+ * Override login() to support both api-key and username/password authentication
2975
+ * and allow self-signed certificates
2976
+ */
2977
+ async login() {
2978
+ if (this._externalSid) {
2979
+ if (!this.sid)
2980
+ throw new Error("External SID has expired");
2981
+ return this.sid;
2982
+ }
2983
+ const isUsingApiKey = !!this.authToken;
2984
+ const isUsingCredentials = !!(this.username && this.password);
2985
+ if (!isUsingApiKey && !isUsingCredentials) {
2986
+ throw new ClientResponse(401, { message: "Authentication failed: No API key or username/password provided" });
2987
+ }
2988
+ const httpsAgent = new https.Agent({ rejectUnauthorized: false });
2989
+ const loginPayload = isUsingApiKey ? { "api-key": this.authToken } : { "user": this.username, "password": this.password };
2990
+ if (this.domain) {
2991
+ loginPayload["domain"] = this.domain;
2992
+ }
2993
+ const loginResp = await this.makeRequest(this.getHost(), "POST", "login", loginPayload, { "Content-Type": "application/json" }, null, httpsAgent);
2994
+ if (loginResp.status !== 200 || !loginResp.response || !loginResp.response.sid) {
2995
+ throw loginResp;
2996
+ }
2997
+ this.sid = loginResp.response.sid;
2998
+ this.sessionTimeout = loginResp.response["session-timeout"] || null;
2999
+ this.sessionStart = Date.now();
3000
+ if (loginResp.response.uid) {
3001
+ await this.detectMDS(loginResp.response.uid, true);
3002
+ }
3003
+ return loginResp.response.sid;
2730
3004
  }
2731
3005
  };
2732
3006
 
2733
- // ../mcp-utils/dist/package-utils.js
2734
- import { readFileSync } from "fs";
2735
- import { join as join2, dirname } from "path";
2736
- import { fileURLToPath } from "url";
2737
- function readPackageJson(importMetaUrl) {
2738
- const pkg2 = JSON.parse(readFileSync(join2(dirname(fileURLToPath(importMetaUrl)), "../package.json"), "utf-8"));
2739
- process.env.CP_MCP_MAIN_PKG = `${pkg2.name} v${pkg2.version}`;
2740
- return pkg2;
3007
+ // ../infra/dist/string-utils.js
3008
+ function nullOrEmpty(val) {
3009
+ return val === void 0 || val === null || typeof val === "string" && (val.trim() === "" || val === "undefined" || val === "null");
2741
3010
  }
2742
- function createMcpServer(importMetaUrl, serverInfo, options) {
2743
- const pkg2 = readPackageJson(importMetaUrl);
2744
- const fullServerInfo = {
2745
- ...serverInfo,
2746
- name: serverInfo.name || pkg2.name,
2747
- version: serverInfo.version || pkg2.version
2748
- };
2749
- const createServerFn = () => {
2750
- return new CPMcpServer(fullServerInfo, options);
2751
- };
2752
- const server2 = new CPMcpServer(fullServerInfo, options);
2753
- server2._createServerFn = createServerFn;
2754
- return { server: server2, pkg: pkg2 };
3011
+ function sanitizeData(kwargs) {
3012
+ const data = {};
3013
+ for (const [key, value] of Object.entries(kwargs)) {
3014
+ if (value === null || value === void 0 || value === "" || Array.isArray(value) && value.length === 0) {
3015
+ continue;
3016
+ }
3017
+ const safeKey = key.replace(/_/g, "-");
3018
+ data[safeKey] = value;
3019
+ }
3020
+ return data;
2755
3021
  }
2756
3022
 
2757
3023
  // ../infra/dist/api-manager.js
@@ -3263,7 +3529,9 @@ var Settings = class _Settings {
3263
3529
  return "STG";
3264
3530
  return void 0;
3265
3531
  }
3266
- 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 } = {}) {
3532
+ // Takes only what it is given: the environment is read by fromArgs, so
3533
+ // settings built from request headers never pick up the process's values.
3534
+ constructor({ apiKey, username, password, s1cUrl, managementHost, managementPort = "443", cloudInfraToken, cloudConnected = false, sid, clientId, secretKey, region = "EU", devPort = "8006", gatewayUrl } = {}) {
3267
3535
  this.region = "EU";
3268
3536
  this.devPort = "8006";
3269
3537
  this.gatewayUrl = "";
@@ -3443,19 +3711,20 @@ var Settings = class _Settings {
3443
3711
  console.error("[Settings.fromArgs] Verbose: WARNING - Args object appears empty, no authentication values found");
3444
3712
  }
3445
3713
  }
3714
+ const env = process.env;
3446
3715
  return new _Settings({
3447
- apiKey: args.apiKey,
3448
- username: args.username,
3449
- password: args.password,
3450
- s1cUrl: args.s1cUrl,
3451
- managementHost: args.managementHost,
3452
- managementPort: args.managementPort,
3453
- cloudInfraToken: args.cloudInfraToken,
3454
- cloudConnected: args.cloudConnected,
3455
- clientId: args.clientId,
3456
- secretKey: args.secretKey,
3457
- region: typeof args.region === "string" ? args.region.trim().toUpperCase() : void 0,
3458
- devPort: args.devPort,
3716
+ apiKey: args.apiKey ?? env.API_KEY,
3717
+ username: args.username ?? env.USERNAME,
3718
+ password: args.password ?? env.PASSWORD,
3719
+ s1cUrl: args.s1cUrl ?? env.S1C_URL,
3720
+ managementHost: args.managementHost ?? env.MANAGEMENT_HOST,
3721
+ managementPort: args.managementPort ?? (env.MANAGEMENT_PORT || void 0),
3722
+ cloudInfraToken: args.cloudInfraToken ?? env.CLOUD_INFRA_TOKEN,
3723
+ cloudConnected: args.cloudConnected ?? env.CLOUD_CONNECTED === "true",
3724
+ clientId: args.clientId ?? env.CLIENT_ID,
3725
+ secretKey: args.secretKey ?? env.SECRET_KEY,
3726
+ region: typeof args.region === "string" ? args.region.trim().toUpperCase() : env.REGION || void 0,
3727
+ devPort: args.devPort ?? (env.DEV_PORT || void 0),
3459
3728
  gatewayUrl: args.gatewayUrl
3460
3729
  });
3461
3730
  }
@@ -3500,7 +3769,6 @@ var Settings = class _Settings {
3500
3769
  const hasAnyValue = extractedValues.apiKey || extractedValues.username || extractedValues.password || extractedValues.s1cUrl || extractedValues.managementHost || extractedValues.cloudInfraToken;
3501
3770
  if (!hasAnyValue) {
3502
3771
  console.error("[Settings.fromHeaders] Verbose: WARNING - No authentication values found in headers");
3503
- 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])));
3504
3772
  }
3505
3773
  }
3506
3774
  return new _Settings({
@@ -3521,6 +3789,17 @@ var Settings = class _Settings {
3521
3789
  });
3522
3790
  }
3523
3791
  };
3792
+ Settings.debugLoggableKeys = [
3793
+ "management-host",
3794
+ "management-port",
3795
+ "s1c-url",
3796
+ "gateway-url",
3797
+ "region",
3798
+ "dev-port",
3799
+ "cloud-connected",
3800
+ "write-mode"
3801
+ ];
3802
+ Settings.basicKeys = ["REGION"];
3524
3803
 
3525
3804
  // ../infra/dist/external-user-token-manager.js
3526
3805
  import axios2 from "axios";