@probelabs/probe 0.6.0-rc207 → 0.6.0-rc208
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/bin/binaries/probe-v0.6.0-rc208-aarch64-apple-darwin.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc208-aarch64-unknown-linux-musl.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc208-x86_64-apple-darwin.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc208-x86_64-pc-windows-msvc.zip +0 -0
- package/bin/binaries/probe-v0.6.0-rc208-x86_64-unknown-linux-musl.tar.gz +0 -0
- package/build/agent/bashPermissions.js +88 -7
- package/build/agent/index.js +334 -16
- package/build/agent/mcp/client.js +234 -4
- package/build/agent/mcp/config.js +87 -0
- package/build/agent/mcp/xmlBridge.js +15 -5
- package/build/agent/simpleTelemetry.js +26 -0
- package/build/tools/bash.js +5 -3
- package/cjs/agent/ProbeAgent.cjs +312 -16
- package/cjs/agent/simpleTelemetry.cjs +22 -0
- package/cjs/index.cjs +334 -16
- package/package.json +1 -1
- package/src/agent/bashPermissions.js +88 -7
- package/src/agent/mcp/client.js +234 -4
- package/src/agent/mcp/config.js +87 -0
- package/src/agent/mcp/xmlBridge.js +15 -5
- package/src/agent/simpleTelemetry.js +26 -0
- package/src/tools/bash.js +5 -3
- package/bin/binaries/probe-v0.6.0-rc207-aarch64-apple-darwin.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc207-aarch64-unknown-linux-musl.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc207-x86_64-apple-darwin.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc207-x86_64-pc-windows-msvc.zip +0 -0
- package/bin/binaries/probe-v0.6.0-rc207-x86_64-unknown-linux-musl.tar.gz +0 -0
package/cjs/agent/ProbeAgent.cjs
CHANGED
|
@@ -37549,9 +37549,11 @@ var init_bashPermissions = __esm({
|
|
|
37549
37549
|
* @param {boolean} [config.disableDefaultAllow] - Disable default allow list
|
|
37550
37550
|
* @param {boolean} [config.disableDefaultDeny] - Disable default deny list
|
|
37551
37551
|
* @param {boolean} [config.debug] - Enable debug logging
|
|
37552
|
+
* @param {Object} [config.tracer] - Optional tracer for telemetry
|
|
37552
37553
|
*/
|
|
37553
37554
|
constructor(config = {}) {
|
|
37554
37555
|
this.debug = config.debug || false;
|
|
37556
|
+
this.tracer = config.tracer || null;
|
|
37555
37557
|
this.allowPatterns = [];
|
|
37556
37558
|
if (!config.disableDefaultAllow) {
|
|
37557
37559
|
this.allowPatterns.push(...DEFAULT_ALLOW_PATTERNS);
|
|
@@ -37581,6 +37583,24 @@ var init_bashPermissions = __esm({
|
|
|
37581
37583
|
if (this.debug) {
|
|
37582
37584
|
console.log(`[BashPermissions] Total patterns - Allow: ${this.allowPatterns.length}, Deny: ${this.denyPatterns.length}`);
|
|
37583
37585
|
}
|
|
37586
|
+
this.recordBashEvent("permissions.initialized", {
|
|
37587
|
+
allowPatternCount: this.allowPatterns.length,
|
|
37588
|
+
denyPatternCount: this.denyPatterns.length,
|
|
37589
|
+
hasCustomAllowPatterns: !!(config.allow && config.allow.length > 0),
|
|
37590
|
+
hasCustomDenyPatterns: !!(config.deny && config.deny.length > 0),
|
|
37591
|
+
disableDefaultAllow: !!config.disableDefaultAllow,
|
|
37592
|
+
disableDefaultDeny: !!config.disableDefaultDeny
|
|
37593
|
+
});
|
|
37594
|
+
}
|
|
37595
|
+
/**
|
|
37596
|
+
* Record a bash telemetry event if tracer is available
|
|
37597
|
+
* @param {string} eventType - Event type (e.g., 'permission.checked', 'permission.denied')
|
|
37598
|
+
* @param {Object} data - Event data
|
|
37599
|
+
*/
|
|
37600
|
+
recordBashEvent(eventType, data2 = {}) {
|
|
37601
|
+
if (this.tracer && typeof this.tracer.recordBashEvent === "function") {
|
|
37602
|
+
this.tracer.recordBashEvent(eventType, data2);
|
|
37603
|
+
}
|
|
37584
37604
|
}
|
|
37585
37605
|
/**
|
|
37586
37606
|
* Check if a simple command is allowed (complex commands allowed if they match patterns)
|
|
@@ -37589,11 +37609,17 @@ var init_bashPermissions = __esm({
|
|
|
37589
37609
|
*/
|
|
37590
37610
|
check(command) {
|
|
37591
37611
|
if (!command || typeof command !== "string") {
|
|
37592
|
-
|
|
37612
|
+
const result2 = {
|
|
37593
37613
|
allowed: false,
|
|
37594
37614
|
reason: "Invalid or empty command",
|
|
37595
37615
|
command
|
|
37596
37616
|
};
|
|
37617
|
+
this.recordBashEvent("permission.denied", {
|
|
37618
|
+
command: String(command),
|
|
37619
|
+
reason: result2.reason,
|
|
37620
|
+
isComplex: false
|
|
37621
|
+
});
|
|
37622
|
+
return result2;
|
|
37597
37623
|
}
|
|
37598
37624
|
const commandIsComplex = isComplexCommand(command);
|
|
37599
37625
|
if (commandIsComplex) {
|
|
@@ -37601,18 +37627,31 @@ var init_bashPermissions = __esm({
|
|
|
37601
37627
|
}
|
|
37602
37628
|
const parsed = parseCommand(command);
|
|
37603
37629
|
if (parsed.error) {
|
|
37604
|
-
|
|
37630
|
+
const result2 = {
|
|
37605
37631
|
allowed: false,
|
|
37606
37632
|
reason: parsed.error,
|
|
37607
37633
|
command
|
|
37608
37634
|
};
|
|
37635
|
+
this.recordBashEvent("permission.denied", {
|
|
37636
|
+
command,
|
|
37637
|
+
reason: result2.reason,
|
|
37638
|
+
isComplex: false,
|
|
37639
|
+
parseError: true
|
|
37640
|
+
});
|
|
37641
|
+
return result2;
|
|
37609
37642
|
}
|
|
37610
37643
|
if (!parsed.command) {
|
|
37611
|
-
|
|
37644
|
+
const result2 = {
|
|
37612
37645
|
allowed: false,
|
|
37613
37646
|
reason: "No valid command found",
|
|
37614
37647
|
command
|
|
37615
37648
|
};
|
|
37649
|
+
this.recordBashEvent("permission.denied", {
|
|
37650
|
+
command,
|
|
37651
|
+
reason: result2.reason,
|
|
37652
|
+
isComplex: false
|
|
37653
|
+
});
|
|
37654
|
+
return result2;
|
|
37616
37655
|
}
|
|
37617
37656
|
if (this.debug) {
|
|
37618
37657
|
console.log(`[BashPermissions] Checking simple command: "${command}"`);
|
|
@@ -37620,22 +37659,37 @@ var init_bashPermissions = __esm({
|
|
|
37620
37659
|
}
|
|
37621
37660
|
if (matchesAnyPattern(parsed, this.denyPatterns)) {
|
|
37622
37661
|
const matchedPatterns = this.denyPatterns.filter((pattern) => matchesPattern(parsed, pattern));
|
|
37623
|
-
|
|
37662
|
+
const result2 = {
|
|
37624
37663
|
allowed: false,
|
|
37625
37664
|
reason: `Command matches deny pattern: ${matchedPatterns[0]}`,
|
|
37626
37665
|
command,
|
|
37627
37666
|
parsed,
|
|
37628
37667
|
matchedPatterns
|
|
37629
37668
|
};
|
|
37669
|
+
this.recordBashEvent("permission.denied", {
|
|
37670
|
+
command,
|
|
37671
|
+
parsedCommand: parsed.command,
|
|
37672
|
+
reason: "matches_deny_pattern",
|
|
37673
|
+
matchedPattern: matchedPatterns[0],
|
|
37674
|
+
isComplex: false
|
|
37675
|
+
});
|
|
37676
|
+
return result2;
|
|
37630
37677
|
}
|
|
37631
37678
|
if (this.allowPatterns.length > 0) {
|
|
37632
37679
|
if (!matchesAnyPattern(parsed, this.allowPatterns)) {
|
|
37633
|
-
|
|
37680
|
+
const result2 = {
|
|
37634
37681
|
allowed: false,
|
|
37635
37682
|
reason: "Command not in allow list",
|
|
37636
37683
|
command,
|
|
37637
37684
|
parsed
|
|
37638
37685
|
};
|
|
37686
|
+
this.recordBashEvent("permission.denied", {
|
|
37687
|
+
command,
|
|
37688
|
+
parsedCommand: parsed.command,
|
|
37689
|
+
reason: "not_in_allow_list",
|
|
37690
|
+
isComplex: false
|
|
37691
|
+
});
|
|
37692
|
+
return result2;
|
|
37639
37693
|
}
|
|
37640
37694
|
}
|
|
37641
37695
|
const result = {
|
|
@@ -37647,6 +37701,11 @@ var init_bashPermissions = __esm({
|
|
|
37647
37701
|
if (this.debug) {
|
|
37648
37702
|
console.log(`[BashPermissions] ALLOWED - command passed all checks`);
|
|
37649
37703
|
}
|
|
37704
|
+
this.recordBashEvent("permission.allowed", {
|
|
37705
|
+
command,
|
|
37706
|
+
parsedCommand: parsed.command,
|
|
37707
|
+
isComplex: false
|
|
37708
|
+
});
|
|
37650
37709
|
return result;
|
|
37651
37710
|
}
|
|
37652
37711
|
/**
|
|
@@ -37670,13 +37729,20 @@ var init_bashPermissions = __esm({
|
|
|
37670
37729
|
if (this.debug) {
|
|
37671
37730
|
console.log(`[BashPermissions] DENIED - matches complex deny pattern: ${pattern}`);
|
|
37672
37731
|
}
|
|
37673
|
-
|
|
37732
|
+
const result = {
|
|
37674
37733
|
allowed: false,
|
|
37675
37734
|
reason: `Command matches deny pattern: ${pattern}`,
|
|
37676
37735
|
command,
|
|
37677
37736
|
isComplex: true,
|
|
37678
37737
|
matchedPatterns: [pattern]
|
|
37679
37738
|
};
|
|
37739
|
+
this.recordBashEvent("permission.denied", {
|
|
37740
|
+
command,
|
|
37741
|
+
reason: "matches_deny_pattern",
|
|
37742
|
+
matchedPattern: pattern,
|
|
37743
|
+
isComplex: true
|
|
37744
|
+
});
|
|
37745
|
+
return result;
|
|
37680
37746
|
}
|
|
37681
37747
|
}
|
|
37682
37748
|
for (const pattern of complexAllowPatterns) {
|
|
@@ -37684,17 +37750,28 @@ var init_bashPermissions = __esm({
|
|
|
37684
37750
|
if (this.debug) {
|
|
37685
37751
|
console.log(`[BashPermissions] ALLOWED - matches complex allow pattern: ${pattern}`);
|
|
37686
37752
|
}
|
|
37687
|
-
|
|
37753
|
+
const result = {
|
|
37688
37754
|
allowed: true,
|
|
37689
37755
|
command,
|
|
37690
37756
|
isComplex: true,
|
|
37691
37757
|
matchedPattern: pattern
|
|
37692
37758
|
};
|
|
37759
|
+
this.recordBashEvent("permission.allowed", {
|
|
37760
|
+
command,
|
|
37761
|
+
matchedPattern: pattern,
|
|
37762
|
+
isComplex: true
|
|
37763
|
+
});
|
|
37764
|
+
return result;
|
|
37693
37765
|
}
|
|
37694
37766
|
}
|
|
37695
37767
|
if (this.debug) {
|
|
37696
37768
|
console.log(`[BashPermissions] DENIED - no matching complex pattern found`);
|
|
37697
37769
|
}
|
|
37770
|
+
this.recordBashEvent("permission.denied", {
|
|
37771
|
+
command,
|
|
37772
|
+
reason: "no_matching_complex_pattern",
|
|
37773
|
+
isComplex: true
|
|
37774
|
+
});
|
|
37698
37775
|
return {
|
|
37699
37776
|
allowed: false,
|
|
37700
37777
|
reason: 'Complex shell commands require explicit allow patterns (e.g., "cd * && git *")',
|
|
@@ -37993,14 +38070,16 @@ var init_bash = __esm({
|
|
|
37993
38070
|
bashConfig = {},
|
|
37994
38071
|
debug = false,
|
|
37995
38072
|
cwd,
|
|
37996
|
-
allowedFolders = []
|
|
38073
|
+
allowedFolders = [],
|
|
38074
|
+
tracer = null
|
|
37997
38075
|
} = options;
|
|
37998
38076
|
const permissionChecker = new BashPermissionChecker({
|
|
37999
38077
|
allow: bashConfig.allow,
|
|
38000
38078
|
deny: bashConfig.deny,
|
|
38001
38079
|
disableDefaultAllow: bashConfig.disableDefaultAllow,
|
|
38002
38080
|
disableDefaultDeny: bashConfig.disableDefaultDeny,
|
|
38003
|
-
debug
|
|
38081
|
+
debug,
|
|
38082
|
+
tracer
|
|
38004
38083
|
});
|
|
38005
38084
|
const getDefaultWorkingDirectory = () => {
|
|
38006
38085
|
if (bashConfig.workingDirectory) {
|
|
@@ -84617,6 +84696,47 @@ function validateTimeout(value) {
|
|
|
84617
84696
|
if (!Number.isFinite(num) || num < 0) return void 0;
|
|
84618
84697
|
return Math.min(num, MAX_TIMEOUT);
|
|
84619
84698
|
}
|
|
84699
|
+
function validateMethodFilter(serverConfig, serverName = "unknown") {
|
|
84700
|
+
const result = { allowedMethods: null, blockedMethods: null };
|
|
84701
|
+
const debug = process.env.DEBUG === "1" || process.env.DEBUG_MCP === "1";
|
|
84702
|
+
if (serverConfig.allowedMethods && serverConfig.blockedMethods) {
|
|
84703
|
+
console.error(`[MCP WARN] Server '${serverName}' has both allowedMethods and blockedMethods - using allowedMethods only`);
|
|
84704
|
+
}
|
|
84705
|
+
if (serverConfig.allowedMethods) {
|
|
84706
|
+
if (!Array.isArray(serverConfig.allowedMethods)) {
|
|
84707
|
+
console.error(`[MCP WARN] Server '${serverName}' allowedMethods must be an array, ignoring`);
|
|
84708
|
+
} else {
|
|
84709
|
+
const validMethods = serverConfig.allowedMethods.filter((m4) => typeof m4 === "string" && m4.length > 0);
|
|
84710
|
+
if (validMethods.length !== serverConfig.allowedMethods.length) {
|
|
84711
|
+
console.error(`[MCP WARN] Server '${serverName}' allowedMethods contains non-string values, skipping those`);
|
|
84712
|
+
}
|
|
84713
|
+
if (validMethods.length > 0) {
|
|
84714
|
+
result.allowedMethods = validMethods;
|
|
84715
|
+
if (debug) {
|
|
84716
|
+
console.error(`[MCP DEBUG] Server '${serverName}' allowedMethods: ${validMethods.join(", ")}`);
|
|
84717
|
+
}
|
|
84718
|
+
}
|
|
84719
|
+
}
|
|
84720
|
+
return result;
|
|
84721
|
+
}
|
|
84722
|
+
if (serverConfig.blockedMethods) {
|
|
84723
|
+
if (!Array.isArray(serverConfig.blockedMethods)) {
|
|
84724
|
+
console.error(`[MCP WARN] Server '${serverName}' blockedMethods must be an array, ignoring`);
|
|
84725
|
+
} else {
|
|
84726
|
+
const validMethods = serverConfig.blockedMethods.filter((m4) => typeof m4 === "string" && m4.length > 0);
|
|
84727
|
+
if (validMethods.length !== serverConfig.blockedMethods.length) {
|
|
84728
|
+
console.error(`[MCP WARN] Server '${serverName}' blockedMethods contains non-string values, skipping those`);
|
|
84729
|
+
}
|
|
84730
|
+
if (validMethods.length > 0) {
|
|
84731
|
+
result.blockedMethods = validMethods;
|
|
84732
|
+
if (debug) {
|
|
84733
|
+
console.error(`[MCP DEBUG] Server '${serverName}' blockedMethods: ${validMethods.join(", ")}`);
|
|
84734
|
+
}
|
|
84735
|
+
}
|
|
84736
|
+
}
|
|
84737
|
+
}
|
|
84738
|
+
return result;
|
|
84739
|
+
}
|
|
84620
84740
|
function loadMCPConfigurationFromPath(configPath) {
|
|
84621
84741
|
if (!configPath) {
|
|
84622
84742
|
throw new Error("Config path is required");
|
|
@@ -84710,6 +84830,12 @@ function mergeWithEnvironment(config) {
|
|
|
84710
84830
|
console.error(`[MCP WARN] Invalid timeout value for ${normalizedName}: ${value}`);
|
|
84711
84831
|
}
|
|
84712
84832
|
break;
|
|
84833
|
+
case "ALLOWLIST":
|
|
84834
|
+
config.mcpServers[normalizedName].allowedMethods = value.split(",").map((m4) => m4.trim()).filter(Boolean);
|
|
84835
|
+
break;
|
|
84836
|
+
case "BLOCKLIST":
|
|
84837
|
+
config.mcpServers[normalizedName].blockedMethods = value.split(",").map((m4) => m4.trim()).filter(Boolean);
|
|
84838
|
+
break;
|
|
84713
84839
|
}
|
|
84714
84840
|
}
|
|
84715
84841
|
}
|
|
@@ -84760,6 +84886,9 @@ function parseEnabledServers(config) {
|
|
|
84760
84886
|
}
|
|
84761
84887
|
server.timeout = validatedTimeout;
|
|
84762
84888
|
}
|
|
84889
|
+
const methodFilter = validateMethodFilter(serverConfig, name14);
|
|
84890
|
+
server.allowedMethods = methodFilter.allowedMethods;
|
|
84891
|
+
server.blockedMethods = methodFilter.blockedMethods;
|
|
84763
84892
|
servers.push(server);
|
|
84764
84893
|
}
|
|
84765
84894
|
return servers;
|
|
@@ -84797,6 +84926,22 @@ var init_config = __esm({
|
|
|
84797
84926
|
});
|
|
84798
84927
|
|
|
84799
84928
|
// src/agent/mcp/client.js
|
|
84929
|
+
function isMethodAllowed(methodName, allowedMethods, blockedMethods) {
|
|
84930
|
+
const matchesPattern2 = (name14, pattern) => {
|
|
84931
|
+
if (!pattern.includes("*")) {
|
|
84932
|
+
return name14 === pattern;
|
|
84933
|
+
}
|
|
84934
|
+
const regexPattern = pattern.replace(/[.+?^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*");
|
|
84935
|
+
return new RegExp(`^${regexPattern}$`).test(name14);
|
|
84936
|
+
};
|
|
84937
|
+
if (allowedMethods && allowedMethods.length > 0) {
|
|
84938
|
+
return allowedMethods.some((pattern) => matchesPattern2(methodName, pattern));
|
|
84939
|
+
}
|
|
84940
|
+
if (blockedMethods && blockedMethods.length > 0) {
|
|
84941
|
+
return !blockedMethods.some((pattern) => matchesPattern2(methodName, pattern));
|
|
84942
|
+
}
|
|
84943
|
+
return true;
|
|
84944
|
+
}
|
|
84800
84945
|
function createTransport(serverConfig) {
|
|
84801
84946
|
const { transport, command, args, url, env } = serverConfig;
|
|
84802
84947
|
switch (transport) {
|
|
@@ -84881,6 +85026,17 @@ var init_client2 = __esm({
|
|
|
84881
85026
|
this.tools = /* @__PURE__ */ new Map();
|
|
84882
85027
|
this.debug = options.debug || process.env.DEBUG_MCP === "1";
|
|
84883
85028
|
this.config = null;
|
|
85029
|
+
this.tracer = options.tracer || null;
|
|
85030
|
+
}
|
|
85031
|
+
/**
|
|
85032
|
+
* Record an MCP telemetry event if tracer is available
|
|
85033
|
+
* @param {string} eventType - Event type (e.g., 'server.connect', 'tool.discovered')
|
|
85034
|
+
* @param {Object} data - Event data
|
|
85035
|
+
*/
|
|
85036
|
+
recordMcpEvent(eventType, data2 = {}) {
|
|
85037
|
+
if (this.tracer && typeof this.tracer.recordMcpEvent === "function") {
|
|
85038
|
+
this.tracer.recordMcpEvent(eventType, data2);
|
|
85039
|
+
}
|
|
84884
85040
|
}
|
|
84885
85041
|
/**
|
|
84886
85042
|
* Initialize MCP clients from configuration
|
|
@@ -84889,10 +85045,20 @@ var init_client2 = __esm({
|
|
|
84889
85045
|
async initialize(config = null) {
|
|
84890
85046
|
this.config = config || loadMCPConfiguration();
|
|
84891
85047
|
const servers = parseEnabledServers(this.config);
|
|
85048
|
+
this.recordMcpEvent("initialization.started", {
|
|
85049
|
+
serverCount: servers.length,
|
|
85050
|
+
serverNames: servers.map((s4) => s4.name)
|
|
85051
|
+
});
|
|
84892
85052
|
console.error(`[MCP INFO] Found ${servers.length} enabled MCP server${servers.length !== 1 ? "s" : ""}`);
|
|
84893
85053
|
if (servers.length === 0) {
|
|
84894
85054
|
console.error("[MCP INFO] No MCP servers configured or enabled");
|
|
84895
85055
|
console.error("[MCP INFO] 0 MCP tools available");
|
|
85056
|
+
this.recordMcpEvent("initialization.completed", {
|
|
85057
|
+
connected: 0,
|
|
85058
|
+
total: 0,
|
|
85059
|
+
toolCount: 0,
|
|
85060
|
+
tools: []
|
|
85061
|
+
});
|
|
84896
85062
|
return {
|
|
84897
85063
|
connected: 0,
|
|
84898
85064
|
total: 0,
|
|
@@ -84929,10 +85095,17 @@ var init_client2 = __esm({
|
|
|
84929
85095
|
console.error(`[MCP DEBUG] - ${toolName}`);
|
|
84930
85096
|
});
|
|
84931
85097
|
}
|
|
85098
|
+
const toolNames = Array.from(this.tools.keys());
|
|
85099
|
+
this.recordMcpEvent("initialization.completed", {
|
|
85100
|
+
connected: connectedCount,
|
|
85101
|
+
total: servers.length,
|
|
85102
|
+
toolCount: this.tools.size,
|
|
85103
|
+
tools: toolNames
|
|
85104
|
+
});
|
|
84932
85105
|
return {
|
|
84933
85106
|
connected: connectedCount,
|
|
84934
85107
|
total: servers.length,
|
|
84935
|
-
tools:
|
|
85108
|
+
tools: toolNames
|
|
84936
85109
|
};
|
|
84937
85110
|
}
|
|
84938
85111
|
/**
|
|
@@ -84941,6 +85114,12 @@ var init_client2 = __esm({
|
|
|
84941
85114
|
*/
|
|
84942
85115
|
async connectToServer(serverConfig) {
|
|
84943
85116
|
const { name: name14 } = serverConfig;
|
|
85117
|
+
this.recordMcpEvent("server.connecting", {
|
|
85118
|
+
serverName: name14,
|
|
85119
|
+
transport: serverConfig.transport,
|
|
85120
|
+
hasAllowedMethods: !!(serverConfig.allowedMethods && serverConfig.allowedMethods.length > 0),
|
|
85121
|
+
hasBlockedMethods: !!(serverConfig.blockedMethods && serverConfig.blockedMethods.length > 0)
|
|
85122
|
+
});
|
|
84944
85123
|
try {
|
|
84945
85124
|
if (this.debug) {
|
|
84946
85125
|
console.error(`[MCP DEBUG] Connecting to ${name14} via ${serverConfig.transport}...`);
|
|
@@ -84962,27 +85141,92 @@ var init_client2 = __esm({
|
|
|
84962
85141
|
config: serverConfig
|
|
84963
85142
|
});
|
|
84964
85143
|
const toolsResponse = await client.listTools();
|
|
84965
|
-
const
|
|
85144
|
+
const totalToolCount = toolsResponse?.tools?.length || 0;
|
|
85145
|
+
let registeredCount = 0;
|
|
85146
|
+
let filteredCount = 0;
|
|
85147
|
+
const registeredTools = [];
|
|
85148
|
+
const filteredTools = [];
|
|
84966
85149
|
if (toolsResponse && toolsResponse.tools) {
|
|
85150
|
+
const { allowedMethods, blockedMethods } = serverConfig;
|
|
85151
|
+
const allToolNames = toolsResponse.tools.map((t4) => t4.name);
|
|
85152
|
+
this.recordMcpEvent("tools.discovered", {
|
|
85153
|
+
serverName: name14,
|
|
85154
|
+
toolCount: totalToolCount,
|
|
85155
|
+
tools: allToolNames
|
|
85156
|
+
});
|
|
84967
85157
|
for (const tool4 of toolsResponse.tools) {
|
|
85158
|
+
if (!isMethodAllowed(tool4.name, allowedMethods, blockedMethods)) {
|
|
85159
|
+
filteredCount++;
|
|
85160
|
+
filteredTools.push(tool4.name);
|
|
85161
|
+
if (this.debug) {
|
|
85162
|
+
console.error(`[MCP DEBUG] Filtered out tool: ${tool4.name} (not allowed by method filter)`);
|
|
85163
|
+
}
|
|
85164
|
+
continue;
|
|
85165
|
+
}
|
|
84968
85166
|
const qualifiedName = `${name14}_${tool4.name}`;
|
|
84969
85167
|
this.tools.set(qualifiedName, {
|
|
84970
85168
|
...tool4,
|
|
84971
85169
|
serverName: name14,
|
|
84972
85170
|
originalName: tool4.name
|
|
84973
85171
|
});
|
|
85172
|
+
registeredCount++;
|
|
85173
|
+
registeredTools.push(qualifiedName);
|
|
84974
85174
|
if (this.debug) {
|
|
84975
85175
|
console.error(`[MCP DEBUG] Registered tool: ${qualifiedName}`);
|
|
84976
85176
|
}
|
|
84977
85177
|
}
|
|
85178
|
+
if (filteredCount > 0) {
|
|
85179
|
+
this.recordMcpEvent("tools.filtered", {
|
|
85180
|
+
serverName: name14,
|
|
85181
|
+
filteredCount,
|
|
85182
|
+
filteredTools,
|
|
85183
|
+
allowedMethods: allowedMethods || [],
|
|
85184
|
+
blockedMethods: blockedMethods || []
|
|
85185
|
+
});
|
|
85186
|
+
}
|
|
85187
|
+
if (allowedMethods && allowedMethods.length > 0) {
|
|
85188
|
+
const unmatchedPatterns = allowedMethods.filter((pattern) => {
|
|
85189
|
+
return !allToolNames.some((toolName) => isMethodAllowed(toolName, [pattern], null));
|
|
85190
|
+
});
|
|
85191
|
+
if (unmatchedPatterns.length > 0) {
|
|
85192
|
+
console.error(`[MCP WARN] Server '${name14}': The following allowedMethods patterns did not match any tools: ${unmatchedPatterns.join(", ")}`);
|
|
85193
|
+
console.error(`[MCP WARN] Available methods from '${name14}': ${allToolNames.join(", ")}`);
|
|
85194
|
+
}
|
|
85195
|
+
}
|
|
85196
|
+
if (blockedMethods && blockedMethods.length > 0) {
|
|
85197
|
+
const unmatchedPatterns = blockedMethods.filter((pattern) => {
|
|
85198
|
+
return !allToolNames.some((toolName) => !isMethodAllowed(toolName, null, [pattern]));
|
|
85199
|
+
});
|
|
85200
|
+
if (unmatchedPatterns.length > 0) {
|
|
85201
|
+
console.error(`[MCP WARN] Server '${name14}': The following blockedMethods patterns did not match any tools: ${unmatchedPatterns.join(", ")}`);
|
|
85202
|
+
console.error(`[MCP WARN] Available methods from '${name14}': ${allToolNames.join(", ")}`);
|
|
85203
|
+
}
|
|
85204
|
+
}
|
|
84978
85205
|
}
|
|
84979
|
-
|
|
85206
|
+
if (filteredCount > 0) {
|
|
85207
|
+
console.error(`[MCP INFO] Connected to ${name14}: ${registeredCount} tool${registeredCount !== 1 ? "s" : ""} loaded (${filteredCount} filtered out)`);
|
|
85208
|
+
} else {
|
|
85209
|
+
console.error(`[MCP INFO] Connected to ${name14}: ${registeredCount} tool${registeredCount !== 1 ? "s" : ""} loaded`);
|
|
85210
|
+
}
|
|
85211
|
+
this.recordMcpEvent("server.connected", {
|
|
85212
|
+
serverName: name14,
|
|
85213
|
+
transport: serverConfig.transport,
|
|
85214
|
+
totalToolCount,
|
|
85215
|
+
registeredCount,
|
|
85216
|
+
filteredCount,
|
|
85217
|
+
registeredTools
|
|
85218
|
+
});
|
|
84980
85219
|
return true;
|
|
84981
85220
|
} catch (error2) {
|
|
84982
85221
|
console.error(`[MCP ERROR] Error connecting to ${name14}:`, error2.message);
|
|
84983
85222
|
if (this.debug) {
|
|
84984
85223
|
console.error(`[MCP DEBUG] Full error details:`, error2);
|
|
84985
85224
|
}
|
|
85225
|
+
this.recordMcpEvent("server.connection_failed", {
|
|
85226
|
+
serverName: name14,
|
|
85227
|
+
transport: serverConfig.transport,
|
|
85228
|
+
error: error2.message
|
|
85229
|
+
});
|
|
84986
85230
|
return false;
|
|
84987
85231
|
}
|
|
84988
85232
|
}
|
|
@@ -84994,12 +85238,27 @@ var init_client2 = __esm({
|
|
|
84994
85238
|
async callTool(toolName, args) {
|
|
84995
85239
|
const tool4 = this.tools.get(toolName);
|
|
84996
85240
|
if (!tool4) {
|
|
85241
|
+
this.recordMcpEvent("tool.call_failed", {
|
|
85242
|
+
toolName,
|
|
85243
|
+
error: "Unknown tool"
|
|
85244
|
+
});
|
|
84997
85245
|
throw new Error(`Unknown tool: ${toolName}`);
|
|
84998
85246
|
}
|
|
84999
85247
|
const clientInfo = this.clients.get(tool4.serverName);
|
|
85000
85248
|
if (!clientInfo) {
|
|
85249
|
+
this.recordMcpEvent("tool.call_failed", {
|
|
85250
|
+
toolName,
|
|
85251
|
+
serverName: tool4.serverName,
|
|
85252
|
+
error: "Server not connected"
|
|
85253
|
+
});
|
|
85001
85254
|
throw new Error(`Server ${tool4.serverName} not connected`);
|
|
85002
85255
|
}
|
|
85256
|
+
const startTime = Date.now();
|
|
85257
|
+
this.recordMcpEvent("tool.call_started", {
|
|
85258
|
+
toolName,
|
|
85259
|
+
serverName: tool4.serverName,
|
|
85260
|
+
originalToolName: tool4.originalName
|
|
85261
|
+
});
|
|
85003
85262
|
try {
|
|
85004
85263
|
if (this.debug) {
|
|
85005
85264
|
console.error(`[MCP DEBUG] Calling ${toolName} with args:`, JSON.stringify(args, null, 2));
|
|
@@ -85019,15 +85278,31 @@ var init_client2 = __esm({
|
|
|
85019
85278
|
}),
|
|
85020
85279
|
timeoutPromise
|
|
85021
85280
|
]);
|
|
85281
|
+
const durationMs = Date.now() - startTime;
|
|
85022
85282
|
if (this.debug) {
|
|
85023
85283
|
console.error(`[MCP DEBUG] Tool ${toolName} executed successfully`);
|
|
85024
85284
|
}
|
|
85285
|
+
this.recordMcpEvent("tool.call_completed", {
|
|
85286
|
+
toolName,
|
|
85287
|
+
serverName: tool4.serverName,
|
|
85288
|
+
originalToolName: tool4.originalName,
|
|
85289
|
+
durationMs
|
|
85290
|
+
});
|
|
85025
85291
|
return result;
|
|
85026
85292
|
} catch (error2) {
|
|
85293
|
+
const durationMs = Date.now() - startTime;
|
|
85027
85294
|
console.error(`[MCP ERROR] Error calling tool ${toolName}:`, error2.message);
|
|
85028
85295
|
if (this.debug) {
|
|
85029
85296
|
console.error(`[MCP DEBUG] Full error details:`, error2);
|
|
85030
85297
|
}
|
|
85298
|
+
this.recordMcpEvent("tool.call_failed", {
|
|
85299
|
+
toolName,
|
|
85300
|
+
serverName: tool4.serverName,
|
|
85301
|
+
originalToolName: tool4.originalName,
|
|
85302
|
+
error: error2.message,
|
|
85303
|
+
durationMs,
|
|
85304
|
+
isTimeout: error2.message.includes("timeout")
|
|
85305
|
+
});
|
|
85031
85306
|
throw error2;
|
|
85032
85307
|
}
|
|
85033
85308
|
}
|
|
@@ -85072,12 +85347,17 @@ var init_client2 = __esm({
|
|
|
85072
85347
|
*/
|
|
85073
85348
|
async disconnect() {
|
|
85074
85349
|
const disconnectPromises = [];
|
|
85350
|
+
const serverNames = Array.from(this.clients.keys());
|
|
85075
85351
|
if (this.clients.size === 0) {
|
|
85076
85352
|
if (this.debug) {
|
|
85077
85353
|
console.error("[MCP DEBUG] No MCP clients to disconnect");
|
|
85078
85354
|
}
|
|
85079
85355
|
return;
|
|
85080
85356
|
}
|
|
85357
|
+
this.recordMcpEvent("disconnection.started", {
|
|
85358
|
+
serverCount: this.clients.size,
|
|
85359
|
+
serverNames
|
|
85360
|
+
});
|
|
85081
85361
|
if (this.debug) {
|
|
85082
85362
|
console.error(`[MCP DEBUG] Disconnecting from ${this.clients.size} MCP server${this.clients.size !== 1 ? "s" : ""}...`);
|
|
85083
85363
|
}
|
|
@@ -85087,14 +85367,25 @@ var init_client2 = __esm({
|
|
|
85087
85367
|
if (this.debug) {
|
|
85088
85368
|
console.error(`[MCP DEBUG] Disconnected from ${name14}`);
|
|
85089
85369
|
}
|
|
85370
|
+
this.recordMcpEvent("server.disconnected", {
|
|
85371
|
+
serverName: name14
|
|
85372
|
+
});
|
|
85090
85373
|
}).catch((error2) => {
|
|
85091
85374
|
console.error(`[MCP ERROR] Error disconnecting from ${name14}:`, error2.message);
|
|
85375
|
+
this.recordMcpEvent("server.disconnect_failed", {
|
|
85376
|
+
serverName: name14,
|
|
85377
|
+
error: error2.message
|
|
85378
|
+
});
|
|
85092
85379
|
})
|
|
85093
85380
|
);
|
|
85094
85381
|
}
|
|
85095
85382
|
await Promise.all(disconnectPromises);
|
|
85096
85383
|
this.clients.clear();
|
|
85097
85384
|
this.tools.clear();
|
|
85385
|
+
this.recordMcpEvent("disconnection.completed", {
|
|
85386
|
+
serverCount: serverNames.length,
|
|
85387
|
+
serverNames
|
|
85388
|
+
});
|
|
85098
85389
|
if (this.debug) {
|
|
85099
85390
|
console.error("[MCP DEBUG] All MCP connections closed");
|
|
85100
85391
|
}
|
|
@@ -85238,6 +85529,7 @@ var init_xmlBridge = __esm({
|
|
|
85238
85529
|
MCPXmlBridge = class {
|
|
85239
85530
|
constructor(options = {}) {
|
|
85240
85531
|
this.debug = options.debug || false;
|
|
85532
|
+
this.tracer = options.tracer || null;
|
|
85241
85533
|
this.mcpTools = {};
|
|
85242
85534
|
this.mcpManager = null;
|
|
85243
85535
|
this.xmlDefinitions = {};
|
|
@@ -85280,7 +85572,7 @@ var init_xmlBridge = __esm({
|
|
|
85280
85572
|
if (this.debug) {
|
|
85281
85573
|
console.error("[MCP DEBUG] Initializing MCP client manager...");
|
|
85282
85574
|
}
|
|
85283
|
-
this.mcpManager = new MCPClientManager({ debug: this.debug });
|
|
85575
|
+
this.mcpManager = new MCPClientManager({ debug: this.debug, tracer: this.tracer });
|
|
85284
85576
|
const result = await this.mcpManager.initialize(mcpConfigs);
|
|
85285
85577
|
const vercelTools = this.mcpManager.getVercelTools();
|
|
85286
85578
|
this.mcpTools = vercelTools;
|
|
@@ -85304,11 +85596,15 @@ var init_xmlBridge = __esm({
|
|
|
85304
85596
|
}
|
|
85305
85597
|
}
|
|
85306
85598
|
/**
|
|
85307
|
-
* Get
|
|
85599
|
+
* Get XML tool definitions for inclusion in system prompt
|
|
85600
|
+
* @param {Array<string>|null} filterToolNames - Optional list of tool names to include (if null, include all)
|
|
85308
85601
|
* @returns {string} Combined XML tool definitions
|
|
85309
85602
|
*/
|
|
85310
|
-
getXmlToolDefinitions() {
|
|
85311
|
-
|
|
85603
|
+
getXmlToolDefinitions(filterToolNames = null) {
|
|
85604
|
+
if (filterToolNames === null) {
|
|
85605
|
+
return Object.values(this.xmlDefinitions).join("\n\n");
|
|
85606
|
+
}
|
|
85607
|
+
return Object.entries(this.xmlDefinitions).filter(([name14]) => filterToolNames.includes(name14)).map(([, def]) => def).join("\n\n");
|
|
85312
85608
|
}
|
|
85313
85609
|
/**
|
|
85314
85610
|
* Get list of MCP tool names
|
|
@@ -215,6 +215,28 @@ var SimpleAppTracer = class {
|
|
|
215
215
|
...data
|
|
216
216
|
});
|
|
217
217
|
}
|
|
218
|
+
/**
|
|
219
|
+
* Record MCP (Model Context Protocol) events
|
|
220
|
+
* Tracks server connections, tool discovery, method filtering, and tool execution
|
|
221
|
+
*/
|
|
222
|
+
recordMcpEvent(eventType, data = {}) {
|
|
223
|
+
if (!this.isEnabled()) return;
|
|
224
|
+
this.addEvent(`mcp.${eventType}`, {
|
|
225
|
+
"session.id": this.sessionId,
|
|
226
|
+
...data
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Record bash tool events
|
|
231
|
+
* Tracks command permission checks, allowed/denied commands, and execution
|
|
232
|
+
*/
|
|
233
|
+
recordBashEvent(eventType, data = {}) {
|
|
234
|
+
if (!this.isEnabled()) return;
|
|
235
|
+
this.addEvent(`bash.${eventType}`, {
|
|
236
|
+
"session.id": this.sessionId,
|
|
237
|
+
...data
|
|
238
|
+
});
|
|
239
|
+
}
|
|
218
240
|
setAttributes(attributes) {
|
|
219
241
|
if (this.telemetry && this.telemetry.enableConsole) {
|
|
220
242
|
console.log("[Attributes]", attributes);
|