@chkp/documentation-mcp 1.4.10 → 1.4.13
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 +354 -62
- package/dist/package.json +1 -1
- package/package.json +1 -1
- package/package.json.bak +1 -1
package/dist/index.js
CHANGED
|
@@ -368,6 +368,84 @@ var init_ui_dialog = __esm({
|
|
|
368
368
|
// src/index.ts
|
|
369
369
|
import { z } from "zod";
|
|
370
370
|
|
|
371
|
+
// ../mcp-utils/dist/cli-options.js
|
|
372
|
+
function booleanOptionDefault(envValue, optionDefault) {
|
|
373
|
+
return envValue === "true" || optionDefault === "true";
|
|
374
|
+
}
|
|
375
|
+
function resolveTransportType(transportOption, env = process.env) {
|
|
376
|
+
return (transportOption || env.MCP_TRANSPORT_TYPE || "stdio").toLowerCase() === "http" ? "http" : "stdio";
|
|
377
|
+
}
|
|
378
|
+
function optionKey(flag) {
|
|
379
|
+
const long = flag.split(/[,\s]+/).find((part) => part.startsWith("--"));
|
|
380
|
+
if (!long)
|
|
381
|
+
return void 0;
|
|
382
|
+
const negated = long.startsWith("--no-");
|
|
383
|
+
return {
|
|
384
|
+
key: long.replace(/^--(no-)?/, "").replace(/-([a-z])/g, (_match, char) => char.toUpperCase()),
|
|
385
|
+
negated
|
|
386
|
+
};
|
|
387
|
+
}
|
|
388
|
+
function operatorValues(options, parsed, env = process.env) {
|
|
389
|
+
const values = { ...env };
|
|
390
|
+
for (const option of options) {
|
|
391
|
+
const derived = option.env ? optionKey(option.flag) : void 0;
|
|
392
|
+
if (!derived || derived.negated)
|
|
393
|
+
continue;
|
|
394
|
+
const value = parsed[derived.key];
|
|
395
|
+
if (value !== void 0)
|
|
396
|
+
values[option.env] = value;
|
|
397
|
+
}
|
|
398
|
+
return values;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
// ../mcp-utils/dist/debug-view.js
|
|
402
|
+
import { createHash } from "node:crypto";
|
|
403
|
+
var BUILTIN_LOGGABLE_KEYS = [
|
|
404
|
+
"accept",
|
|
405
|
+
"accept-encoding",
|
|
406
|
+
"accept-language",
|
|
407
|
+
"connection",
|
|
408
|
+
"content-length",
|
|
409
|
+
"content-type",
|
|
410
|
+
"host",
|
|
411
|
+
"mcp-protocol-version",
|
|
412
|
+
"traceparent",
|
|
413
|
+
"user-agent",
|
|
414
|
+
"x-correlation-id",
|
|
415
|
+
"x-gw-auth-method",
|
|
416
|
+
"x-request-id",
|
|
417
|
+
// Launcher options
|
|
418
|
+
"debug",
|
|
419
|
+
"telemetry",
|
|
420
|
+
"telemetry-url",
|
|
421
|
+
"transport",
|
|
422
|
+
"transport-port"
|
|
423
|
+
];
|
|
424
|
+
function normalizeDebugKey(key) {
|
|
425
|
+
const split = /[-_]/.test(key) ? key : key.replace(/([a-z][0-9]*)([A-Z])/g, "$1-$2");
|
|
426
|
+
return split.replace(/_/g, "-").toLowerCase();
|
|
427
|
+
}
|
|
428
|
+
function debugLoggableKeys(extra = []) {
|
|
429
|
+
return new Set([...BUILTIN_LOGGABLE_KEYS, ...extra].map(normalizeDebugKey));
|
|
430
|
+
}
|
|
431
|
+
function describe(key, value, loggable) {
|
|
432
|
+
if (value === void 0 || value === null || value === "")
|
|
433
|
+
return "(unset)";
|
|
434
|
+
if (loggable.has(normalizeDebugKey(key))) {
|
|
435
|
+
return typeof value === "string" ? value : JSON.stringify(value);
|
|
436
|
+
}
|
|
437
|
+
const text = typeof value === "string" ? value : Array.isArray(value) ? value.join(", ") : void 0;
|
|
438
|
+
return text === void 0 ? "(hidden)" : `(hidden, ${text.length} chars)`;
|
|
439
|
+
}
|
|
440
|
+
function debugView(record, loggable = debugLoggableKeys()) {
|
|
441
|
+
return Object.fromEntries(Object.entries(record ?? {}).map(([key, value]) => [key, describe(key, value, loggable)]));
|
|
442
|
+
}
|
|
443
|
+
function sessionLogLabel(sessionId) {
|
|
444
|
+
if (!sessionId || sessionId === "default")
|
|
445
|
+
return "default";
|
|
446
|
+
return `session#${createHash("sha256").update(sessionId).digest("hex").slice(0, 8)}`;
|
|
447
|
+
}
|
|
448
|
+
|
|
371
449
|
// ../mcp-utils/dist/launcher.js
|
|
372
450
|
import { Command } from "commander";
|
|
373
451
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
@@ -376,6 +454,89 @@ import fs from "fs";
|
|
|
376
454
|
import http from "http";
|
|
377
455
|
import { randomUUID } from "crypto";
|
|
378
456
|
|
|
457
|
+
// ../mcp-utils/dist/connection-source.js
|
|
458
|
+
function hasValue(value) {
|
|
459
|
+
return value !== void 0 && value !== null && value !== "" && !(Array.isArray(value) && value.length === 0);
|
|
460
|
+
}
|
|
461
|
+
function headersRead(fromHeaders, headers) {
|
|
462
|
+
const read = /* @__PURE__ */ new Set();
|
|
463
|
+
const recording = new Proxy(headers, {
|
|
464
|
+
get(target, prop, receiver) {
|
|
465
|
+
const value = Reflect.get(target, prop, receiver);
|
|
466
|
+
if (typeof prop === "string" && hasValue(value))
|
|
467
|
+
read.add(prop);
|
|
468
|
+
return value;
|
|
469
|
+
}
|
|
470
|
+
});
|
|
471
|
+
try {
|
|
472
|
+
fromHeaders(recording);
|
|
473
|
+
} catch {
|
|
474
|
+
}
|
|
475
|
+
return read;
|
|
476
|
+
}
|
|
477
|
+
function keySet(keys = []) {
|
|
478
|
+
return new Set(keys.map(normalizeDebugKey));
|
|
479
|
+
}
|
|
480
|
+
function chooseConnectionSource(read, basicKeys) {
|
|
481
|
+
for (const key of read) {
|
|
482
|
+
if (!basicKeys.has(normalizeDebugKey(key)))
|
|
483
|
+
return "caller";
|
|
484
|
+
}
|
|
485
|
+
return "operator";
|
|
486
|
+
}
|
|
487
|
+
function basicOnly(headers, basicKeys) {
|
|
488
|
+
return Object.fromEntries(Object.entries(headers).filter(([key]) => basicKeys.has(normalizeDebugKey(key))));
|
|
489
|
+
}
|
|
490
|
+
function mergeHeaders(base, overrides) {
|
|
491
|
+
const merged = {};
|
|
492
|
+
const index = /* @__PURE__ */ new Map();
|
|
493
|
+
for (const [key, value] of [...Object.entries(base), ...Object.entries(overrides)]) {
|
|
494
|
+
const id = normalizeDebugKey(key);
|
|
495
|
+
const previous = index.get(id);
|
|
496
|
+
if (previous !== void 0)
|
|
497
|
+
delete merged[previous];
|
|
498
|
+
index.set(id, key);
|
|
499
|
+
merged[key] = value;
|
|
500
|
+
}
|
|
501
|
+
return merged;
|
|
502
|
+
}
|
|
503
|
+
function operatorHeaders(values) {
|
|
504
|
+
const headers = {};
|
|
505
|
+
for (const [name, value] of Object.entries(values)) {
|
|
506
|
+
if (!hasValue(value))
|
|
507
|
+
continue;
|
|
508
|
+
headers[name.replace(/_/g, "-")] = Array.isArray(value) ? value.map(String) : String(value);
|
|
509
|
+
}
|
|
510
|
+
return headers;
|
|
511
|
+
}
|
|
512
|
+
function canonicalizeAliases(headers, aliases) {
|
|
513
|
+
if (aliases.size === 0)
|
|
514
|
+
return headers;
|
|
515
|
+
const canonical = new Set([...aliases.values()].map(normalizeDebugKey));
|
|
516
|
+
const present = new Set(Object.keys(headers).map(normalizeDebugKey).filter((key) => canonical.has(key)));
|
|
517
|
+
const result = {};
|
|
518
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
519
|
+
const target = aliases.get(normalizeDebugKey(key));
|
|
520
|
+
if (target === void 0) {
|
|
521
|
+
result[key] = value;
|
|
522
|
+
} else if (!present.has(normalizeDebugKey(target))) {
|
|
523
|
+
result[target] = value;
|
|
524
|
+
present.add(normalizeDebugKey(target));
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
return result;
|
|
528
|
+
}
|
|
529
|
+
function aliasMap(aliases = {}) {
|
|
530
|
+
return new Map(Object.entries(aliases).map(([alias, target]) => [normalizeDebugKey(alias), target]));
|
|
531
|
+
}
|
|
532
|
+
function sessionHeaders(source, callerHeaders, operator, basicKeys, operatorSettingsOverHttp) {
|
|
533
|
+
if (source === "caller") {
|
|
534
|
+
return mergeHeaders(basicOnly(operator, basicKeys), callerHeaders);
|
|
535
|
+
}
|
|
536
|
+
const base = operatorSettingsOverHttp ? operator : basicOnly(operator, basicKeys);
|
|
537
|
+
return mergeHeaders(base, basicOnly(callerHeaders, basicKeys));
|
|
538
|
+
}
|
|
539
|
+
|
|
379
540
|
// ../mcp-utils/dist/settings-manager.js
|
|
380
541
|
var SettingsManager = class _SettingsManager {
|
|
381
542
|
/**
|
|
@@ -385,7 +546,13 @@ var SettingsManager = class _SettingsManager {
|
|
|
385
546
|
constructor(settingsClass) {
|
|
386
547
|
this.settingsMap = /* @__PURE__ */ new Map();
|
|
387
548
|
this.defaultSessionId = "default";
|
|
549
|
+
this.operatorValues = {};
|
|
550
|
+
this.sessionSources = /* @__PURE__ */ new Map();
|
|
388
551
|
this.settingsClass = settingsClass;
|
|
552
|
+
this.loggableKeys = debugLoggableKeys(settingsClass?.debugLoggableKeys ?? []);
|
|
553
|
+
this.basicKeys = keySet(settingsClass?.basicKeys ?? []);
|
|
554
|
+
this.headerAliases = aliasMap(settingsClass?.headerAliases);
|
|
555
|
+
this.operatorSettingsOverHttp = settingsClass?.operatorSettingsOverHttp !== false;
|
|
389
556
|
}
|
|
390
557
|
/**
|
|
391
558
|
* Get settings for a specific session
|
|
@@ -412,12 +579,15 @@ var SettingsManager = class _SettingsManager {
|
|
|
412
579
|
* Injects debug settings from source into settings object
|
|
413
580
|
* @param settings The settings object to update
|
|
414
581
|
* @param source Source object containing debug information
|
|
582
|
+
* @param scope 'process' when the operator set debug (CLI/env), which also
|
|
583
|
+
* updates the process-wide state; 'session' when a caller set it through a
|
|
584
|
+
* header, which affects only that session's settings
|
|
415
585
|
* @private
|
|
416
586
|
*/
|
|
417
|
-
injectDebug(settings, source) {
|
|
587
|
+
injectDebug(settings, source, scope) {
|
|
418
588
|
const debug = source?.debug ?? _SettingsManager.globalDebugState ?? process.env.DEBUG;
|
|
419
589
|
if (typeof debug !== "undefined") {
|
|
420
|
-
if (source?.debug !== void 0) {
|
|
590
|
+
if (scope === "process" && source?.debug !== void 0) {
|
|
421
591
|
_SettingsManager.globalDebugState = source.debug;
|
|
422
592
|
}
|
|
423
593
|
if (typeof settings.set === "function") {
|
|
@@ -426,8 +596,8 @@ var SettingsManager = class _SettingsManager {
|
|
|
426
596
|
settings.debug = debug;
|
|
427
597
|
}
|
|
428
598
|
if (debug) {
|
|
429
|
-
console.error("Debug enabled. Source
|
|
430
|
-
|
|
599
|
+
console.error("Debug enabled. Source:");
|
|
600
|
+
this.printDebugView(source);
|
|
431
601
|
}
|
|
432
602
|
}
|
|
433
603
|
}
|
|
@@ -440,19 +610,21 @@ var SettingsManager = class _SettingsManager {
|
|
|
440
610
|
if (typeof settings.get === "function") {
|
|
441
611
|
console.error("Settings (using get method):");
|
|
442
612
|
if (settings.data && typeof settings.data === "object") {
|
|
443
|
-
|
|
444
|
-
console.error(` ${key}: ${JSON.stringify(value)}`);
|
|
445
|
-
});
|
|
613
|
+
this.printDebugView(settings.data);
|
|
446
614
|
} else {
|
|
447
615
|
console.error(" Unable to enumerate settings properties - no accessible data structure");
|
|
448
616
|
}
|
|
449
617
|
} else {
|
|
450
618
|
console.error("Settings (plain object):");
|
|
451
|
-
|
|
452
|
-
console.error(` ${key}: ${JSON.stringify(value)}`);
|
|
453
|
-
});
|
|
619
|
+
this.printDebugView(settings);
|
|
454
620
|
}
|
|
455
621
|
}
|
|
622
|
+
/** Print allowlisted values; everything else as "(hidden, N chars)". */
|
|
623
|
+
printDebugView(record) {
|
|
624
|
+
Object.entries(debugView(record, this.loggableKeys)).forEach(([key, value]) => {
|
|
625
|
+
console.error(` ${key}: ${value}`);
|
|
626
|
+
});
|
|
627
|
+
}
|
|
456
628
|
/**
|
|
457
629
|
* Create settings from command-line arguments
|
|
458
630
|
* @param args Command line arguments
|
|
@@ -461,10 +633,19 @@ var SettingsManager = class _SettingsManager {
|
|
|
461
633
|
*/
|
|
462
634
|
createFromArgs(args, sessionId) {
|
|
463
635
|
const settings = this.settingsClass.fromArgs(args);
|
|
464
|
-
this.injectDebug(settings, args);
|
|
636
|
+
this.injectDebug(settings, args, "process");
|
|
465
637
|
this.setSettings(settings, sessionId);
|
|
466
638
|
return settings;
|
|
467
639
|
}
|
|
640
|
+
/**
|
|
641
|
+
* Record the operator's values (environment variables and parsed CLI
|
|
642
|
+
* options, keyed by environment-variable name). HTTP sessions take basic
|
|
643
|
+
* keys from them when the caller doesn't send its own, and their whole
|
|
644
|
+
* connection set when the caller sends none of it.
|
|
645
|
+
*/
|
|
646
|
+
setOperatorValues(values) {
|
|
647
|
+
this.operatorValues = canonicalizeAliases(operatorHeaders(values), this.headerAliases);
|
|
648
|
+
}
|
|
468
649
|
/**
|
|
469
650
|
* Create settings from HTTP headers
|
|
470
651
|
* @param headers HTTP headers
|
|
@@ -474,13 +655,13 @@ var SettingsManager = class _SettingsManager {
|
|
|
474
655
|
createFromHeaders(headers, sessionId) {
|
|
475
656
|
const verbose = _SettingsManager.globalDebugState;
|
|
476
657
|
if (verbose) {
|
|
477
|
-
console.error("[SettingsManager.createFromHeaders] Verbose: Starting with
|
|
658
|
+
console.error("[SettingsManager.createFromHeaders] Verbose: Starting with session:", sessionLogLabel(sessionId));
|
|
478
659
|
console.error("[SettingsManager.createFromHeaders] Verbose: Incoming headers count:", Object.keys(headers).length);
|
|
479
660
|
}
|
|
480
661
|
if (_SettingsManager.globalDebugState) {
|
|
481
662
|
console.error("=== createFromHeaders Debug Info ===");
|
|
482
663
|
console.error("Incoming headers:");
|
|
483
|
-
|
|
664
|
+
this.printDebugView(headers);
|
|
484
665
|
}
|
|
485
666
|
if (verbose && (!headers || Object.keys(headers).length === 0)) {
|
|
486
667
|
console.error("[SettingsManager.createFromHeaders] Verbose: WARNING - Headers object is empty or undefined");
|
|
@@ -497,26 +678,32 @@ var SettingsManager = class _SettingsManager {
|
|
|
497
678
|
console.error("[SettingsManager.createFromHeaders] Verbose: Normalized headers count:", Object.keys(normalizedHeaders).length);
|
|
498
679
|
}
|
|
499
680
|
if (_SettingsManager.globalDebugState) {
|
|
500
|
-
console.error("Normalized
|
|
501
|
-
console.error(JSON.stringify(normalizedHeaders, null, 2));
|
|
681
|
+
console.error("Normalized header names:", Object.keys(normalizedHeaders));
|
|
502
682
|
}
|
|
503
683
|
const debugHeader = normalizedHeaders["debug"] || normalizedHeaders["Debug"] || normalizedHeaders["DEBUG"];
|
|
504
|
-
const
|
|
684
|
+
const requestedDebug = Array.isArray(debugHeader) ? debugHeader[0] : debugHeader;
|
|
685
|
+
const debugSource = {
|
|
686
|
+
debug: requestedDebug !== void 0 ? requestedDebug.toLowerCase() === "true" : _SettingsManager.globalDebugState
|
|
687
|
+
};
|
|
688
|
+
const callerHeaders = canonicalizeAliases(normalizedHeaders, this.headerAliases);
|
|
689
|
+
const source = this.connectionSource(callerHeaders, sessionId);
|
|
690
|
+
const inputHeaders = sessionHeaders(source, callerHeaders, this.operatorValues, this.basicKeys, this.operatorSettingsOverHttp);
|
|
505
691
|
if (verbose) {
|
|
692
|
+
console.error("[SettingsManager.createFromHeaders] Verbose: Connection settings source:", source);
|
|
506
693
|
console.error("[SettingsManager.createFromHeaders] Verbose: Calling settingsClass.fromHeaders");
|
|
507
694
|
}
|
|
508
|
-
const settings = this.settingsClass.fromHeaders(
|
|
695
|
+
const settings = this.settingsClass.fromHeaders(inputHeaders);
|
|
509
696
|
if (verbose) {
|
|
510
697
|
console.error("[SettingsManager.createFromHeaders] Verbose: Settings object created");
|
|
511
698
|
}
|
|
512
|
-
this.injectDebug(settings, debugSource);
|
|
699
|
+
this.injectDebug(settings, debugSource, "session");
|
|
513
700
|
if (_SettingsManager.globalDebugState) {
|
|
514
|
-
console.error("Final settings object for session:", sessionId
|
|
701
|
+
console.error("Final settings object for session:", sessionLogLabel(sessionId));
|
|
515
702
|
this.printSettingsDebug(settings);
|
|
516
703
|
console.error("=== End createFromHeaders Debug Info ===");
|
|
517
704
|
}
|
|
518
705
|
if (verbose) {
|
|
519
|
-
console.error("[SettingsManager.createFromHeaders] Verbose: Storing settings for session:", sessionId
|
|
706
|
+
console.error("[SettingsManager.createFromHeaders] Verbose: Storing settings for session:", sessionLogLabel(sessionId));
|
|
520
707
|
}
|
|
521
708
|
this.setSettings(settings, sessionId);
|
|
522
709
|
return settings;
|
|
@@ -528,14 +715,28 @@ var SettingsManager = class _SettingsManager {
|
|
|
528
715
|
clearSession(sessionId) {
|
|
529
716
|
if (sessionId !== this.defaultSessionId) {
|
|
530
717
|
this.settingsMap.delete(sessionId);
|
|
718
|
+
this.sessionSources.delete(sessionId);
|
|
531
719
|
}
|
|
532
720
|
}
|
|
721
|
+
/**
|
|
722
|
+
* The session's connection source: decided by the request that creates the
|
|
723
|
+
* session and kept for its lifetime, so a later request cannot switch it.
|
|
724
|
+
*/
|
|
725
|
+
connectionSource(headers, sessionId) {
|
|
726
|
+
const known = sessionId ? this.sessionSources.get(sessionId) : void 0;
|
|
727
|
+
if (known)
|
|
728
|
+
return known;
|
|
729
|
+
const source = chooseConnectionSource(headersRead((h) => this.settingsClass.fromHeaders(h), headers), this.basicKeys);
|
|
730
|
+
if (sessionId)
|
|
731
|
+
this.sessionSources.set(sessionId, source);
|
|
732
|
+
return source;
|
|
733
|
+
}
|
|
533
734
|
};
|
|
534
735
|
SettingsManager.globalDebugState = void 0;
|
|
535
736
|
|
|
536
737
|
// ../mcp-utils/dist/telemetry.js
|
|
537
738
|
import machineIdPkg from "node-machine-id";
|
|
538
|
-
import { createHash } from "crypto";
|
|
739
|
+
import { createHash as createHash2 } from "crypto";
|
|
539
740
|
var { machineIdSync } = machineIdPkg;
|
|
540
741
|
var machineId = null;
|
|
541
742
|
var hashedMachineId = null;
|
|
@@ -550,7 +751,7 @@ function getTelemetryUrl() {
|
|
|
550
751
|
return process.env.TELEMETRY_URL || "https://metrics.security.ai.checkpoint.com/api/v1/metrics/collect";
|
|
551
752
|
}
|
|
552
753
|
function hashString(input) {
|
|
553
|
-
return
|
|
754
|
+
return createHash2("sha256").update(input).digest("hex");
|
|
554
755
|
}
|
|
555
756
|
function getMachineId() {
|
|
556
757
|
if (!machineId) {
|
|
@@ -598,6 +799,21 @@ async function trackToolCall(mcpName, toolName, clientVersion, extra) {
|
|
|
598
799
|
}
|
|
599
800
|
|
|
600
801
|
// ../mcp-utils/dist/launcher.js
|
|
802
|
+
function mirrorBooleanFlagsToEnv(config, options) {
|
|
803
|
+
for (const option of config.options) {
|
|
804
|
+
if (option.type !== "boolean" || !option.env)
|
|
805
|
+
continue;
|
|
806
|
+
const derived = optionKey(option.flag);
|
|
807
|
+
if (!derived)
|
|
808
|
+
continue;
|
|
809
|
+
if (derived.negated) {
|
|
810
|
+
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.`);
|
|
811
|
+
}
|
|
812
|
+
if (options[derived.key] === true) {
|
|
813
|
+
process.env[option.env] = "true";
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
}
|
|
601
817
|
async function launchMCPServer(configPath, serverModule2) {
|
|
602
818
|
const config = JSON.parse(fs.readFileSync(configPath, "utf8"));
|
|
603
819
|
const program = new Command();
|
|
@@ -608,7 +824,7 @@ async function launchMCPServer(configPath, serverModule2) {
|
|
|
608
824
|
const envValue = option.env ? process.env[option.env] : void 0;
|
|
609
825
|
const defaultValue = envValue || option.default;
|
|
610
826
|
if (option.type === "boolean") {
|
|
611
|
-
const boolDefault = envValue
|
|
827
|
+
const boolDefault = booleanOptionDefault(envValue, option.default);
|
|
612
828
|
program.option(option.flag, option.description, boolDefault);
|
|
613
829
|
} else {
|
|
614
830
|
program.option(option.flag, option.description, defaultValue);
|
|
@@ -632,17 +848,24 @@ async function launchMCPServer(configPath, serverModule2) {
|
|
|
632
848
|
if (options.telemetryUrl) {
|
|
633
849
|
process.env.TELEMETRY_URL = options.telemetryUrl;
|
|
634
850
|
}
|
|
851
|
+
mirrorBooleanFlagsToEnv(config, options);
|
|
852
|
+
const transportType2 = resolveTransportType(options.transport);
|
|
853
|
+
process.env.MCP_TRANSPORT_TYPE = transportType2;
|
|
635
854
|
if (!serverModule2.settingsManager) {
|
|
636
855
|
throw new Error("ServerModule must have a settingsManager. Create it with createServerModule.");
|
|
637
856
|
}
|
|
638
857
|
const settings = serverModule2.settingsManager.createFromArgs(options);
|
|
858
|
+
serverModule2.settingsManager.setOperatorValues?.(operatorValues(config.options, options));
|
|
639
859
|
if (typeof serverModule2.server.applyToolPolicy === "function") {
|
|
640
860
|
console.error("[launchMCPServer] Applying tool policy before connecting");
|
|
641
861
|
serverModule2.server.applyToolPolicy();
|
|
642
862
|
}
|
|
643
|
-
const transportType2 = (options.transport || process.env.MCP_TRANSPORT_TYPE || "stdio").toLowerCase() === "http" ? "http" : "stdio";
|
|
644
863
|
const transportPort = options.transportPort ? parseInt(options.transportPort, 10) : process.env.MCP_TRANSPORT_PORT ? parseInt(process.env.MCP_TRANSPORT_PORT, 10) : 3e3;
|
|
645
864
|
if (transportType2 === "http") {
|
|
865
|
+
const refusal = serverModule2.httpStartupCheck?.();
|
|
866
|
+
if (refusal) {
|
|
867
|
+
throw new Error(refusal);
|
|
868
|
+
}
|
|
646
869
|
setTransportType("http");
|
|
647
870
|
await launchHTTPServer(config, serverModule2, transportPort);
|
|
648
871
|
} else {
|
|
@@ -691,7 +914,7 @@ async function launchHTTPServer(config, serverModule2, port) {
|
|
|
691
914
|
if (sessionId && transports[sessionId]) {
|
|
692
915
|
const verbose = SettingsManager.globalDebugState;
|
|
693
916
|
if (verbose) {
|
|
694
|
-
console.error("[launchHTTPServer] Verbose: Reusing existing transport for session:", sessionId);
|
|
917
|
+
console.error("[launchHTTPServer] Verbose: Reusing existing transport for session:", sessionLogLabel(sessionId));
|
|
695
918
|
}
|
|
696
919
|
transport = transports[sessionId];
|
|
697
920
|
if (!serverModule2.settingsManager) {
|
|
@@ -711,7 +934,7 @@ async function launchHTTPServer(config, serverModule2, port) {
|
|
|
711
934
|
onsessioninitialized: (sid) => {
|
|
712
935
|
const verbose = SettingsManager.globalDebugState;
|
|
713
936
|
if (verbose) {
|
|
714
|
-
console.error("[launchHTTPServer] Verbose: New session initialized:", sid);
|
|
937
|
+
console.error("[launchHTTPServer] Verbose: New session initialized:", sessionLogLabel(sid));
|
|
715
938
|
}
|
|
716
939
|
transports[sid] = transport;
|
|
717
940
|
if (verbose) {
|
|
@@ -914,7 +1137,6 @@ function headersToEnvVars(headers, config) {
|
|
|
914
1137
|
}
|
|
915
1138
|
if (verbose) {
|
|
916
1139
|
console.error("[headersToEnvVars] Verbose: Final result keys:", Object.keys(result));
|
|
917
|
-
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])));
|
|
918
1140
|
}
|
|
919
1141
|
return result;
|
|
920
1142
|
}
|
|
@@ -941,7 +1163,7 @@ var APIManagerFactory = class {
|
|
|
941
1163
|
const verbose = SettingsManager.globalDebugState;
|
|
942
1164
|
const sid = sessionId || this.defaultSessionId;
|
|
943
1165
|
if (verbose) {
|
|
944
|
-
console.error("[APIManagerFactory.getAPIManager] Verbose: Getting API manager for session:", sid);
|
|
1166
|
+
console.error("[APIManagerFactory.getAPIManager] Verbose: Getting API manager for session:", sessionLogLabel(sid));
|
|
945
1167
|
}
|
|
946
1168
|
if (!this.apiManagerMap.has(sid)) {
|
|
947
1169
|
if (verbose) {
|
|
@@ -1039,16 +1261,15 @@ var SessionContext = class {
|
|
|
1039
1261
|
/**
|
|
1040
1262
|
* Get the current session ID from the MCP extra context
|
|
1041
1263
|
* @param extra Extra context passed to MCP tool callbacks
|
|
1042
|
-
* @returns The session ID or DEFAULT_SESSION_ID
|
|
1264
|
+
* @returns The session ID, or DEFAULT_SESSION_ID under stdio
|
|
1265
|
+
* @throws Under HTTP transport when the context carries no session ID
|
|
1043
1266
|
*/
|
|
1044
1267
|
static getSessionId(extra) {
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
if (extra.sessionId) {
|
|
1051
|
-
return extra.sessionId;
|
|
1268
|
+
const sessionId = extra?.transport?.sessionId || extra?.sessionId;
|
|
1269
|
+
if (sessionId)
|
|
1270
|
+
return sessionId;
|
|
1271
|
+
if (process.env.MCP_TRANSPORT_TYPE === "http") {
|
|
1272
|
+
throw new Error("No MCP session in this request context; HTTP transport requires one");
|
|
1052
1273
|
}
|
|
1053
1274
|
return this.DEFAULT_SESSION_ID;
|
|
1054
1275
|
}
|
|
@@ -1165,10 +1386,10 @@ var SessionContext = class {
|
|
|
1165
1386
|
}
|
|
1166
1387
|
}
|
|
1167
1388
|
}
|
|
1168
|
-
console.error(`Using cached user data for
|
|
1389
|
+
console.error(`Using cached user data for ${sessionLogLabel(sessionId)}, key: ${options.cacheKey}`);
|
|
1169
1390
|
return { cancelled: false, data: dataToReturn2 };
|
|
1170
1391
|
}
|
|
1171
|
-
console.error(`Prompting user for data for
|
|
1392
|
+
console.error(`Prompting user for data for ${sessionLogLabel(sessionId)}, key: ${options.cacheKey}`);
|
|
1172
1393
|
let result;
|
|
1173
1394
|
if (options.showLoginDialog) {
|
|
1174
1395
|
const { showLoginDialog: showLoginDialog2 } = await Promise.resolve().then(() => (init_ui_dialog(), ui_dialog_exports));
|
|
@@ -1376,10 +1597,11 @@ function wrapServerWithTracking(server2, createServerFn) {
|
|
|
1376
1597
|
newServer[reg.method](...reg.args);
|
|
1377
1598
|
}
|
|
1378
1599
|
}
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1600
|
+
const toolPolicy = typeof server2.getToolPolicy === "function" ? server2.getToolPolicy() : void 0;
|
|
1601
|
+
if (toolPolicy && typeof newServer.setToolPolicy === "function") {
|
|
1602
|
+
newServer.setToolPolicy(toolPolicy);
|
|
1603
|
+
if (typeof newServer.applyToolPolicy === "function") {
|
|
1604
|
+
newServer.applyToolPolicy();
|
|
1383
1605
|
}
|
|
1384
1606
|
}
|
|
1385
1607
|
return newServer;
|
|
@@ -1435,35 +1657,61 @@ var CPMcpServer = class extends McpServer {
|
|
|
1435
1657
|
console.error("[CPMcpServer] Setting tool policy callback");
|
|
1436
1658
|
this.toolPolicyCallback = callback;
|
|
1437
1659
|
}
|
|
1660
|
+
/**
|
|
1661
|
+
* Get the tool policy callback, if one was set.
|
|
1662
|
+
*
|
|
1663
|
+
* Needed so the policy can be carried onto the per-session server instances
|
|
1664
|
+
* created for HTTP transport. A typed accessor keeps that transfer honest:
|
|
1665
|
+
* callers do not have to reach into the private field, where a misspelling
|
|
1666
|
+
* would go unnoticed by the compiler.
|
|
1667
|
+
*/
|
|
1668
|
+
getToolPolicy() {
|
|
1669
|
+
return this.toolPolicyCallback;
|
|
1670
|
+
}
|
|
1438
1671
|
/**
|
|
1439
1672
|
* Apply the tool policy by checking all registered tools
|
|
1440
1673
|
* This should be called after all tools are registered but before connecting
|
|
1674
|
+
*
|
|
1675
|
+
* Per-tool tracing is behind the debug flag. This used to run once per process
|
|
1676
|
+
* on the template server, where a line per tool was a cheap startup banner.
|
|
1677
|
+
* It now also runs per session under HTTP transport, so unconditional tracing
|
|
1678
|
+
* would scale stderr with sessions x tools and bury the summary. The summary
|
|
1679
|
+
* line always prints — it is the fact worth having for every session.
|
|
1441
1680
|
*/
|
|
1442
1681
|
applyToolPolicy() {
|
|
1682
|
+
const verbose = SettingsManager.globalDebugState === true || SettingsManager.globalDebugState === "true";
|
|
1443
1683
|
if (!this.toolPolicyCallback) {
|
|
1444
|
-
|
|
1684
|
+
if (verbose) {
|
|
1685
|
+
console.error("[CPMcpServer] No tool policy callback set, allowing all tools");
|
|
1686
|
+
}
|
|
1445
1687
|
return;
|
|
1446
1688
|
}
|
|
1447
|
-
console.error("[CPMcpServer] Applying tool policy");
|
|
1448
1689
|
const registeredTools = this._registeredTools;
|
|
1449
1690
|
if (!registeredTools || typeof registeredTools !== "object") {
|
|
1450
1691
|
console.error("[CPMcpServer] No tools registered yet");
|
|
1451
1692
|
return;
|
|
1452
1693
|
}
|
|
1453
1694
|
const toolNames = Object.keys(registeredTools);
|
|
1454
|
-
|
|
1695
|
+
if (verbose) {
|
|
1696
|
+
console.error(`[CPMcpServer] Applying tool policy`);
|
|
1697
|
+
console.error(`[CPMcpServer] Found ${toolNames.length} registered tools:`, toolNames);
|
|
1698
|
+
}
|
|
1455
1699
|
let enabledCount = 0;
|
|
1456
1700
|
let disabledCount = 0;
|
|
1457
1701
|
for (const [toolName, tool] of Object.entries(registeredTools)) {
|
|
1458
1702
|
const isAllowed = this.toolPolicyCallback(toolName);
|
|
1459
1703
|
if (!isAllowed) {
|
|
1460
|
-
|
|
1704
|
+
if (verbose) {
|
|
1705
|
+
console.error(`[CPMcpServer] Tool '${toolName}' is NOT allowed by policy - disabling`);
|
|
1706
|
+
}
|
|
1461
1707
|
if (typeof tool.disable === "function") {
|
|
1462
1708
|
tool.disable();
|
|
1463
1709
|
disabledCount++;
|
|
1464
1710
|
}
|
|
1465
1711
|
} else {
|
|
1466
|
-
|
|
1712
|
+
if (verbose) {
|
|
1713
|
+
console.error(`[CPMcpServer] Tool '${toolName}' is allowed by policy`);
|
|
1714
|
+
}
|
|
1467
1715
|
enabledCount++;
|
|
1468
1716
|
}
|
|
1469
1717
|
}
|
|
@@ -1526,6 +1774,23 @@ import axios3 from "axios";
|
|
|
1526
1774
|
// ../infra/dist/api-client.js
|
|
1527
1775
|
import axios from "axios";
|
|
1528
1776
|
import https from "https";
|
|
1777
|
+
var DEBUG_LOGGABLE_REQUEST_KEYS = debugLoggableKeys([
|
|
1778
|
+
"details-level",
|
|
1779
|
+
"domain",
|
|
1780
|
+
"filter",
|
|
1781
|
+
"layer",
|
|
1782
|
+
"limit",
|
|
1783
|
+
"name",
|
|
1784
|
+
"offset",
|
|
1785
|
+
"order",
|
|
1786
|
+
"package",
|
|
1787
|
+
"show-membership",
|
|
1788
|
+
"targets",
|
|
1789
|
+
"task-id",
|
|
1790
|
+
"type",
|
|
1791
|
+
"uid",
|
|
1792
|
+
"use-object-dictionary"
|
|
1793
|
+
]);
|
|
1529
1794
|
var TokenType;
|
|
1530
1795
|
(function(TokenType2) {
|
|
1531
1796
|
TokenType2["API_KEY"] = "API_KEY";
|
|
@@ -1572,7 +1837,9 @@ var Settings = class _Settings {
|
|
|
1572
1837
|
return "STG";
|
|
1573
1838
|
return void 0;
|
|
1574
1839
|
}
|
|
1575
|
-
|
|
1840
|
+
// Takes only what it is given: the environment is read by fromArgs, so
|
|
1841
|
+
// settings built from request headers never pick up the process's values.
|
|
1842
|
+
constructor({ apiKey, username, password, s1cUrl, managementHost, managementPort = "443", cloudInfraToken, cloudConnected = false, sid, clientId, secretKey, region = "EU", devPort = "8006", gatewayUrl } = {}) {
|
|
1576
1843
|
this.region = "EU";
|
|
1577
1844
|
this.devPort = "8006";
|
|
1578
1845
|
this.gatewayUrl = "";
|
|
@@ -1752,19 +2019,20 @@ var Settings = class _Settings {
|
|
|
1752
2019
|
console.error("[Settings.fromArgs] Verbose: WARNING - Args object appears empty, no authentication values found");
|
|
1753
2020
|
}
|
|
1754
2021
|
}
|
|
2022
|
+
const env = process.env;
|
|
1755
2023
|
return new _Settings({
|
|
1756
|
-
apiKey: args.apiKey,
|
|
1757
|
-
username: args.username,
|
|
1758
|
-
password: args.password,
|
|
1759
|
-
s1cUrl: args.s1cUrl,
|
|
1760
|
-
managementHost: args.managementHost,
|
|
1761
|
-
managementPort: args.managementPort,
|
|
1762
|
-
cloudInfraToken: args.cloudInfraToken,
|
|
1763
|
-
cloudConnected: args.cloudConnected,
|
|
1764
|
-
clientId: args.clientId,
|
|
1765
|
-
secretKey: args.secretKey,
|
|
1766
|
-
region: typeof args.region === "string" ? args.region.trim().toUpperCase() : void 0,
|
|
1767
|
-
devPort: args.devPort,
|
|
2024
|
+
apiKey: args.apiKey ?? env.API_KEY,
|
|
2025
|
+
username: args.username ?? env.USERNAME,
|
|
2026
|
+
password: args.password ?? env.PASSWORD,
|
|
2027
|
+
s1cUrl: args.s1cUrl ?? env.S1C_URL,
|
|
2028
|
+
managementHost: args.managementHost ?? env.MANAGEMENT_HOST,
|
|
2029
|
+
managementPort: args.managementPort ?? (env.MANAGEMENT_PORT || void 0),
|
|
2030
|
+
cloudInfraToken: args.cloudInfraToken ?? env.CLOUD_INFRA_TOKEN,
|
|
2031
|
+
cloudConnected: args.cloudConnected ?? env.CLOUD_CONNECTED === "true",
|
|
2032
|
+
clientId: args.clientId ?? env.CLIENT_ID,
|
|
2033
|
+
secretKey: args.secretKey ?? env.SECRET_KEY,
|
|
2034
|
+
region: typeof args.region === "string" ? args.region.trim().toUpperCase() : env.REGION || void 0,
|
|
2035
|
+
devPort: args.devPort ?? (env.DEV_PORT || void 0),
|
|
1768
2036
|
gatewayUrl: args.gatewayUrl
|
|
1769
2037
|
});
|
|
1770
2038
|
}
|
|
@@ -1809,7 +2077,6 @@ var Settings = class _Settings {
|
|
|
1809
2077
|
const hasAnyValue = extractedValues.apiKey || extractedValues.username || extractedValues.password || extractedValues.s1cUrl || extractedValues.managementHost || extractedValues.cloudInfraToken;
|
|
1810
2078
|
if (!hasAnyValue) {
|
|
1811
2079
|
console.error("[Settings.fromHeaders] Verbose: WARNING - No authentication values found in headers");
|
|
1812
|
-
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])));
|
|
1813
2080
|
}
|
|
1814
2081
|
}
|
|
1815
2082
|
return new _Settings({
|
|
@@ -1830,6 +2097,17 @@ var Settings = class _Settings {
|
|
|
1830
2097
|
});
|
|
1831
2098
|
}
|
|
1832
2099
|
};
|
|
2100
|
+
Settings.debugLoggableKeys = [
|
|
2101
|
+
"management-host",
|
|
2102
|
+
"management-port",
|
|
2103
|
+
"s1c-url",
|
|
2104
|
+
"gateway-url",
|
|
2105
|
+
"region",
|
|
2106
|
+
"dev-port",
|
|
2107
|
+
"cloud-connected",
|
|
2108
|
+
"write-mode"
|
|
2109
|
+
];
|
|
2110
|
+
Settings.basicKeys = ["REGION"];
|
|
1833
2111
|
|
|
1834
2112
|
// ../infra/dist/external-user-token-manager.js
|
|
1835
2113
|
import axios2 from "axios";
|
|
@@ -1989,6 +2267,16 @@ var DocumentationToolAPIManager = class _DocumentationToolAPIManager {
|
|
|
1989
2267
|
|
|
1990
2268
|
// src/settings.ts
|
|
1991
2269
|
var DocumentationToolSettings = class _DocumentationToolSettings extends Settings {
|
|
2270
|
+
static {
|
|
2271
|
+
/**
|
|
2272
|
+
* Keys whose values debug output may print (see debugView in mcp-utils).
|
|
2273
|
+
* Anything not listed, including every credential, is shown hidden.
|
|
2274
|
+
*/
|
|
2275
|
+
this.debugLoggableKeys = [
|
|
2276
|
+
...Settings.debugLoggableKeys,
|
|
2277
|
+
"auth-url"
|
|
2278
|
+
];
|
|
2279
|
+
}
|
|
1992
2280
|
constructor(args = {}) {
|
|
1993
2281
|
super({
|
|
1994
2282
|
...args,
|
|
@@ -2004,8 +2292,12 @@ var DocumentationToolSettings = class _DocumentationToolSettings extends Setting
|
|
|
2004
2292
|
"Provide either --auth-url (Authentication URL from the API key creation dialog) or --region (EU, US, STG, or LOCAL)"
|
|
2005
2293
|
);
|
|
2006
2294
|
}
|
|
2295
|
+
const env = process.env;
|
|
2007
2296
|
return new _DocumentationToolSettings({
|
|
2008
|
-
...args
|
|
2297
|
+
...args,
|
|
2298
|
+
clientId: args.clientId ?? env.CLIENT_ID,
|
|
2299
|
+
secretKey: args.secretKey ?? env.SECRET_KEY,
|
|
2300
|
+
region: args.region ?? (env.REGION || void 0)
|
|
2009
2301
|
});
|
|
2010
2302
|
}
|
|
2011
2303
|
static fromHeaders(headers) {
|
package/dist/package.json
CHANGED
package/package.json
CHANGED
package/package.json.bak
CHANGED