@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/build/agent/index.js
CHANGED
|
@@ -10601,9 +10601,11 @@ var init_bashPermissions = __esm({
|
|
|
10601
10601
|
* @param {boolean} [config.disableDefaultAllow] - Disable default allow list
|
|
10602
10602
|
* @param {boolean} [config.disableDefaultDeny] - Disable default deny list
|
|
10603
10603
|
* @param {boolean} [config.debug] - Enable debug logging
|
|
10604
|
+
* @param {Object} [config.tracer] - Optional tracer for telemetry
|
|
10604
10605
|
*/
|
|
10605
10606
|
constructor(config = {}) {
|
|
10606
10607
|
this.debug = config.debug || false;
|
|
10608
|
+
this.tracer = config.tracer || null;
|
|
10607
10609
|
this.allowPatterns = [];
|
|
10608
10610
|
if (!config.disableDefaultAllow) {
|
|
10609
10611
|
this.allowPatterns.push(...DEFAULT_ALLOW_PATTERNS);
|
|
@@ -10633,6 +10635,24 @@ var init_bashPermissions = __esm({
|
|
|
10633
10635
|
if (this.debug) {
|
|
10634
10636
|
console.log(`[BashPermissions] Total patterns - Allow: ${this.allowPatterns.length}, Deny: ${this.denyPatterns.length}`);
|
|
10635
10637
|
}
|
|
10638
|
+
this.recordBashEvent("permissions.initialized", {
|
|
10639
|
+
allowPatternCount: this.allowPatterns.length,
|
|
10640
|
+
denyPatternCount: this.denyPatterns.length,
|
|
10641
|
+
hasCustomAllowPatterns: !!(config.allow && config.allow.length > 0),
|
|
10642
|
+
hasCustomDenyPatterns: !!(config.deny && config.deny.length > 0),
|
|
10643
|
+
disableDefaultAllow: !!config.disableDefaultAllow,
|
|
10644
|
+
disableDefaultDeny: !!config.disableDefaultDeny
|
|
10645
|
+
});
|
|
10646
|
+
}
|
|
10647
|
+
/**
|
|
10648
|
+
* Record a bash telemetry event if tracer is available
|
|
10649
|
+
* @param {string} eventType - Event type (e.g., 'permission.checked', 'permission.denied')
|
|
10650
|
+
* @param {Object} data - Event data
|
|
10651
|
+
*/
|
|
10652
|
+
recordBashEvent(eventType, data = {}) {
|
|
10653
|
+
if (this.tracer && typeof this.tracer.recordBashEvent === "function") {
|
|
10654
|
+
this.tracer.recordBashEvent(eventType, data);
|
|
10655
|
+
}
|
|
10636
10656
|
}
|
|
10637
10657
|
/**
|
|
10638
10658
|
* Check if a simple command is allowed (complex commands allowed if they match patterns)
|
|
@@ -10641,11 +10661,17 @@ var init_bashPermissions = __esm({
|
|
|
10641
10661
|
*/
|
|
10642
10662
|
check(command) {
|
|
10643
10663
|
if (!command || typeof command !== "string") {
|
|
10644
|
-
|
|
10664
|
+
const result2 = {
|
|
10645
10665
|
allowed: false,
|
|
10646
10666
|
reason: "Invalid or empty command",
|
|
10647
10667
|
command
|
|
10648
10668
|
};
|
|
10669
|
+
this.recordBashEvent("permission.denied", {
|
|
10670
|
+
command: String(command),
|
|
10671
|
+
reason: result2.reason,
|
|
10672
|
+
isComplex: false
|
|
10673
|
+
});
|
|
10674
|
+
return result2;
|
|
10649
10675
|
}
|
|
10650
10676
|
const commandIsComplex = isComplexCommand(command);
|
|
10651
10677
|
if (commandIsComplex) {
|
|
@@ -10653,18 +10679,31 @@ var init_bashPermissions = __esm({
|
|
|
10653
10679
|
}
|
|
10654
10680
|
const parsed = parseCommand(command);
|
|
10655
10681
|
if (parsed.error) {
|
|
10656
|
-
|
|
10682
|
+
const result2 = {
|
|
10657
10683
|
allowed: false,
|
|
10658
10684
|
reason: parsed.error,
|
|
10659
10685
|
command
|
|
10660
10686
|
};
|
|
10687
|
+
this.recordBashEvent("permission.denied", {
|
|
10688
|
+
command,
|
|
10689
|
+
reason: result2.reason,
|
|
10690
|
+
isComplex: false,
|
|
10691
|
+
parseError: true
|
|
10692
|
+
});
|
|
10693
|
+
return result2;
|
|
10661
10694
|
}
|
|
10662
10695
|
if (!parsed.command) {
|
|
10663
|
-
|
|
10696
|
+
const result2 = {
|
|
10664
10697
|
allowed: false,
|
|
10665
10698
|
reason: "No valid command found",
|
|
10666
10699
|
command
|
|
10667
10700
|
};
|
|
10701
|
+
this.recordBashEvent("permission.denied", {
|
|
10702
|
+
command,
|
|
10703
|
+
reason: result2.reason,
|
|
10704
|
+
isComplex: false
|
|
10705
|
+
});
|
|
10706
|
+
return result2;
|
|
10668
10707
|
}
|
|
10669
10708
|
if (this.debug) {
|
|
10670
10709
|
console.log(`[BashPermissions] Checking simple command: "${command}"`);
|
|
@@ -10672,22 +10711,37 @@ var init_bashPermissions = __esm({
|
|
|
10672
10711
|
}
|
|
10673
10712
|
if (matchesAnyPattern(parsed, this.denyPatterns)) {
|
|
10674
10713
|
const matchedPatterns = this.denyPatterns.filter((pattern) => matchesPattern(parsed, pattern));
|
|
10675
|
-
|
|
10714
|
+
const result2 = {
|
|
10676
10715
|
allowed: false,
|
|
10677
10716
|
reason: `Command matches deny pattern: ${matchedPatterns[0]}`,
|
|
10678
10717
|
command,
|
|
10679
10718
|
parsed,
|
|
10680
10719
|
matchedPatterns
|
|
10681
10720
|
};
|
|
10721
|
+
this.recordBashEvent("permission.denied", {
|
|
10722
|
+
command,
|
|
10723
|
+
parsedCommand: parsed.command,
|
|
10724
|
+
reason: "matches_deny_pattern",
|
|
10725
|
+
matchedPattern: matchedPatterns[0],
|
|
10726
|
+
isComplex: false
|
|
10727
|
+
});
|
|
10728
|
+
return result2;
|
|
10682
10729
|
}
|
|
10683
10730
|
if (this.allowPatterns.length > 0) {
|
|
10684
10731
|
if (!matchesAnyPattern(parsed, this.allowPatterns)) {
|
|
10685
|
-
|
|
10732
|
+
const result2 = {
|
|
10686
10733
|
allowed: false,
|
|
10687
10734
|
reason: "Command not in allow list",
|
|
10688
10735
|
command,
|
|
10689
10736
|
parsed
|
|
10690
10737
|
};
|
|
10738
|
+
this.recordBashEvent("permission.denied", {
|
|
10739
|
+
command,
|
|
10740
|
+
parsedCommand: parsed.command,
|
|
10741
|
+
reason: "not_in_allow_list",
|
|
10742
|
+
isComplex: false
|
|
10743
|
+
});
|
|
10744
|
+
return result2;
|
|
10691
10745
|
}
|
|
10692
10746
|
}
|
|
10693
10747
|
const result = {
|
|
@@ -10699,6 +10753,11 @@ var init_bashPermissions = __esm({
|
|
|
10699
10753
|
if (this.debug) {
|
|
10700
10754
|
console.log(`[BashPermissions] ALLOWED - command passed all checks`);
|
|
10701
10755
|
}
|
|
10756
|
+
this.recordBashEvent("permission.allowed", {
|
|
10757
|
+
command,
|
|
10758
|
+
parsedCommand: parsed.command,
|
|
10759
|
+
isComplex: false
|
|
10760
|
+
});
|
|
10702
10761
|
return result;
|
|
10703
10762
|
}
|
|
10704
10763
|
/**
|
|
@@ -10722,13 +10781,20 @@ var init_bashPermissions = __esm({
|
|
|
10722
10781
|
if (this.debug) {
|
|
10723
10782
|
console.log(`[BashPermissions] DENIED - matches complex deny pattern: ${pattern}`);
|
|
10724
10783
|
}
|
|
10725
|
-
|
|
10784
|
+
const result = {
|
|
10726
10785
|
allowed: false,
|
|
10727
10786
|
reason: `Command matches deny pattern: ${pattern}`,
|
|
10728
10787
|
command,
|
|
10729
10788
|
isComplex: true,
|
|
10730
10789
|
matchedPatterns: [pattern]
|
|
10731
10790
|
};
|
|
10791
|
+
this.recordBashEvent("permission.denied", {
|
|
10792
|
+
command,
|
|
10793
|
+
reason: "matches_deny_pattern",
|
|
10794
|
+
matchedPattern: pattern,
|
|
10795
|
+
isComplex: true
|
|
10796
|
+
});
|
|
10797
|
+
return result;
|
|
10732
10798
|
}
|
|
10733
10799
|
}
|
|
10734
10800
|
for (const pattern of complexAllowPatterns) {
|
|
@@ -10736,17 +10802,28 @@ var init_bashPermissions = __esm({
|
|
|
10736
10802
|
if (this.debug) {
|
|
10737
10803
|
console.log(`[BashPermissions] ALLOWED - matches complex allow pattern: ${pattern}`);
|
|
10738
10804
|
}
|
|
10739
|
-
|
|
10805
|
+
const result = {
|
|
10740
10806
|
allowed: true,
|
|
10741
10807
|
command,
|
|
10742
10808
|
isComplex: true,
|
|
10743
10809
|
matchedPattern: pattern
|
|
10744
10810
|
};
|
|
10811
|
+
this.recordBashEvent("permission.allowed", {
|
|
10812
|
+
command,
|
|
10813
|
+
matchedPattern: pattern,
|
|
10814
|
+
isComplex: true
|
|
10815
|
+
});
|
|
10816
|
+
return result;
|
|
10745
10817
|
}
|
|
10746
10818
|
}
|
|
10747
10819
|
if (this.debug) {
|
|
10748
10820
|
console.log(`[BashPermissions] DENIED - no matching complex pattern found`);
|
|
10749
10821
|
}
|
|
10822
|
+
this.recordBashEvent("permission.denied", {
|
|
10823
|
+
command,
|
|
10824
|
+
reason: "no_matching_complex_pattern",
|
|
10825
|
+
isComplex: true
|
|
10826
|
+
});
|
|
10750
10827
|
return {
|
|
10751
10828
|
allowed: false,
|
|
10752
10829
|
reason: 'Complex shell commands require explicit allow patterns (e.g., "cd * && git *")',
|
|
@@ -11044,14 +11121,16 @@ var init_bash = __esm({
|
|
|
11044
11121
|
bashConfig = {},
|
|
11045
11122
|
debug = false,
|
|
11046
11123
|
cwd,
|
|
11047
|
-
allowedFolders = []
|
|
11124
|
+
allowedFolders = [],
|
|
11125
|
+
tracer = null
|
|
11048
11126
|
} = options;
|
|
11049
11127
|
const permissionChecker = new BashPermissionChecker({
|
|
11050
11128
|
allow: bashConfig.allow,
|
|
11051
11129
|
deny: bashConfig.deny,
|
|
11052
11130
|
disableDefaultAllow: bashConfig.disableDefaultAllow,
|
|
11053
11131
|
disableDefaultDeny: bashConfig.disableDefaultDeny,
|
|
11054
|
-
debug
|
|
11132
|
+
debug,
|
|
11133
|
+
tracer
|
|
11055
11134
|
});
|
|
11056
11135
|
const getDefaultWorkingDirectory = () => {
|
|
11057
11136
|
if (bashConfig.workingDirectory) {
|
|
@@ -11681,6 +11760,28 @@ var init_simpleTelemetry = __esm({
|
|
|
11681
11760
|
...data
|
|
11682
11761
|
});
|
|
11683
11762
|
}
|
|
11763
|
+
/**
|
|
11764
|
+
* Record MCP (Model Context Protocol) events
|
|
11765
|
+
* Tracks server connections, tool discovery, method filtering, and tool execution
|
|
11766
|
+
*/
|
|
11767
|
+
recordMcpEvent(eventType, data = {}) {
|
|
11768
|
+
if (!this.isEnabled()) return;
|
|
11769
|
+
this.addEvent(`mcp.${eventType}`, {
|
|
11770
|
+
"session.id": this.sessionId,
|
|
11771
|
+
...data
|
|
11772
|
+
});
|
|
11773
|
+
}
|
|
11774
|
+
/**
|
|
11775
|
+
* Record bash tool events
|
|
11776
|
+
* Tracks command permission checks, allowed/denied commands, and execution
|
|
11777
|
+
*/
|
|
11778
|
+
recordBashEvent(eventType, data = {}) {
|
|
11779
|
+
if (!this.isEnabled()) return;
|
|
11780
|
+
this.addEvent(`bash.${eventType}`, {
|
|
11781
|
+
"session.id": this.sessionId,
|
|
11782
|
+
...data
|
|
11783
|
+
});
|
|
11784
|
+
}
|
|
11684
11785
|
setAttributes(attributes) {
|
|
11685
11786
|
if (this.telemetry && this.telemetry.enableConsole) {
|
|
11686
11787
|
console.log("[Attributes]", attributes);
|
|
@@ -57907,6 +58008,47 @@ function validateTimeout(value) {
|
|
|
57907
58008
|
if (!Number.isFinite(num) || num < 0) return void 0;
|
|
57908
58009
|
return Math.min(num, MAX_TIMEOUT);
|
|
57909
58010
|
}
|
|
58011
|
+
function validateMethodFilter(serverConfig, serverName = "unknown") {
|
|
58012
|
+
const result = { allowedMethods: null, blockedMethods: null };
|
|
58013
|
+
const debug = process.env.DEBUG === "1" || process.env.DEBUG_MCP === "1";
|
|
58014
|
+
if (serverConfig.allowedMethods && serverConfig.blockedMethods) {
|
|
58015
|
+
console.error(`[MCP WARN] Server '${serverName}' has both allowedMethods and blockedMethods - using allowedMethods only`);
|
|
58016
|
+
}
|
|
58017
|
+
if (serverConfig.allowedMethods) {
|
|
58018
|
+
if (!Array.isArray(serverConfig.allowedMethods)) {
|
|
58019
|
+
console.error(`[MCP WARN] Server '${serverName}' allowedMethods must be an array, ignoring`);
|
|
58020
|
+
} else {
|
|
58021
|
+
const validMethods = serverConfig.allowedMethods.filter((m) => typeof m === "string" && m.length > 0);
|
|
58022
|
+
if (validMethods.length !== serverConfig.allowedMethods.length) {
|
|
58023
|
+
console.error(`[MCP WARN] Server '${serverName}' allowedMethods contains non-string values, skipping those`);
|
|
58024
|
+
}
|
|
58025
|
+
if (validMethods.length > 0) {
|
|
58026
|
+
result.allowedMethods = validMethods;
|
|
58027
|
+
if (debug) {
|
|
58028
|
+
console.error(`[MCP DEBUG] Server '${serverName}' allowedMethods: ${validMethods.join(", ")}`);
|
|
58029
|
+
}
|
|
58030
|
+
}
|
|
58031
|
+
}
|
|
58032
|
+
return result;
|
|
58033
|
+
}
|
|
58034
|
+
if (serverConfig.blockedMethods) {
|
|
58035
|
+
if (!Array.isArray(serverConfig.blockedMethods)) {
|
|
58036
|
+
console.error(`[MCP WARN] Server '${serverName}' blockedMethods must be an array, ignoring`);
|
|
58037
|
+
} else {
|
|
58038
|
+
const validMethods = serverConfig.blockedMethods.filter((m) => typeof m === "string" && m.length > 0);
|
|
58039
|
+
if (validMethods.length !== serverConfig.blockedMethods.length) {
|
|
58040
|
+
console.error(`[MCP WARN] Server '${serverName}' blockedMethods contains non-string values, skipping those`);
|
|
58041
|
+
}
|
|
58042
|
+
if (validMethods.length > 0) {
|
|
58043
|
+
result.blockedMethods = validMethods;
|
|
58044
|
+
if (debug) {
|
|
58045
|
+
console.error(`[MCP DEBUG] Server '${serverName}' blockedMethods: ${validMethods.join(", ")}`);
|
|
58046
|
+
}
|
|
58047
|
+
}
|
|
58048
|
+
}
|
|
58049
|
+
}
|
|
58050
|
+
return result;
|
|
58051
|
+
}
|
|
57910
58052
|
function loadMCPConfigurationFromPath(configPath) {
|
|
57911
58053
|
if (!configPath) {
|
|
57912
58054
|
throw new Error("Config path is required");
|
|
@@ -58000,6 +58142,12 @@ function mergeWithEnvironment(config) {
|
|
|
58000
58142
|
console.error(`[MCP WARN] Invalid timeout value for ${normalizedName}: ${value}`);
|
|
58001
58143
|
}
|
|
58002
58144
|
break;
|
|
58145
|
+
case "ALLOWLIST":
|
|
58146
|
+
config.mcpServers[normalizedName].allowedMethods = value.split(",").map((m) => m.trim()).filter(Boolean);
|
|
58147
|
+
break;
|
|
58148
|
+
case "BLOCKLIST":
|
|
58149
|
+
config.mcpServers[normalizedName].blockedMethods = value.split(",").map((m) => m.trim()).filter(Boolean);
|
|
58150
|
+
break;
|
|
58003
58151
|
}
|
|
58004
58152
|
}
|
|
58005
58153
|
}
|
|
@@ -58050,6 +58198,9 @@ function parseEnabledServers(config) {
|
|
|
58050
58198
|
}
|
|
58051
58199
|
server.timeout = validatedTimeout;
|
|
58052
58200
|
}
|
|
58201
|
+
const methodFilter = validateMethodFilter(serverConfig, name);
|
|
58202
|
+
server.allowedMethods = methodFilter.allowedMethods;
|
|
58203
|
+
server.blockedMethods = methodFilter.blockedMethods;
|
|
58053
58204
|
servers.push(server);
|
|
58054
58205
|
}
|
|
58055
58206
|
return servers;
|
|
@@ -58087,6 +58238,22 @@ import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
|
58087
58238
|
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
|
|
58088
58239
|
import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
|
|
58089
58240
|
import { WebSocketClientTransport } from "@modelcontextprotocol/sdk/client/websocket.js";
|
|
58241
|
+
function isMethodAllowed(methodName, allowedMethods, blockedMethods) {
|
|
58242
|
+
const matchesPattern2 = (name, pattern) => {
|
|
58243
|
+
if (!pattern.includes("*")) {
|
|
58244
|
+
return name === pattern;
|
|
58245
|
+
}
|
|
58246
|
+
const regexPattern = pattern.replace(/[.+?^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*");
|
|
58247
|
+
return new RegExp(`^${regexPattern}$`).test(name);
|
|
58248
|
+
};
|
|
58249
|
+
if (allowedMethods && allowedMethods.length > 0) {
|
|
58250
|
+
return allowedMethods.some((pattern) => matchesPattern2(methodName, pattern));
|
|
58251
|
+
}
|
|
58252
|
+
if (blockedMethods && blockedMethods.length > 0) {
|
|
58253
|
+
return !blockedMethods.some((pattern) => matchesPattern2(methodName, pattern));
|
|
58254
|
+
}
|
|
58255
|
+
return true;
|
|
58256
|
+
}
|
|
58090
58257
|
function createTransport(serverConfig) {
|
|
58091
58258
|
const { transport, command, args, url, env } = serverConfig;
|
|
58092
58259
|
switch (transport) {
|
|
@@ -58167,6 +58334,17 @@ var init_client = __esm({
|
|
|
58167
58334
|
this.tools = /* @__PURE__ */ new Map();
|
|
58168
58335
|
this.debug = options.debug || process.env.DEBUG_MCP === "1";
|
|
58169
58336
|
this.config = null;
|
|
58337
|
+
this.tracer = options.tracer || null;
|
|
58338
|
+
}
|
|
58339
|
+
/**
|
|
58340
|
+
* Record an MCP telemetry event if tracer is available
|
|
58341
|
+
* @param {string} eventType - Event type (e.g., 'server.connect', 'tool.discovered')
|
|
58342
|
+
* @param {Object} data - Event data
|
|
58343
|
+
*/
|
|
58344
|
+
recordMcpEvent(eventType, data = {}) {
|
|
58345
|
+
if (this.tracer && typeof this.tracer.recordMcpEvent === "function") {
|
|
58346
|
+
this.tracer.recordMcpEvent(eventType, data);
|
|
58347
|
+
}
|
|
58170
58348
|
}
|
|
58171
58349
|
/**
|
|
58172
58350
|
* Initialize MCP clients from configuration
|
|
@@ -58175,10 +58353,20 @@ var init_client = __esm({
|
|
|
58175
58353
|
async initialize(config = null) {
|
|
58176
58354
|
this.config = config || loadMCPConfiguration();
|
|
58177
58355
|
const servers = parseEnabledServers(this.config);
|
|
58356
|
+
this.recordMcpEvent("initialization.started", {
|
|
58357
|
+
serverCount: servers.length,
|
|
58358
|
+
serverNames: servers.map((s) => s.name)
|
|
58359
|
+
});
|
|
58178
58360
|
console.error(`[MCP INFO] Found ${servers.length} enabled MCP server${servers.length !== 1 ? "s" : ""}`);
|
|
58179
58361
|
if (servers.length === 0) {
|
|
58180
58362
|
console.error("[MCP INFO] No MCP servers configured or enabled");
|
|
58181
58363
|
console.error("[MCP INFO] 0 MCP tools available");
|
|
58364
|
+
this.recordMcpEvent("initialization.completed", {
|
|
58365
|
+
connected: 0,
|
|
58366
|
+
total: 0,
|
|
58367
|
+
toolCount: 0,
|
|
58368
|
+
tools: []
|
|
58369
|
+
});
|
|
58182
58370
|
return {
|
|
58183
58371
|
connected: 0,
|
|
58184
58372
|
total: 0,
|
|
@@ -58215,10 +58403,17 @@ var init_client = __esm({
|
|
|
58215
58403
|
console.error(`[MCP DEBUG] - ${toolName}`);
|
|
58216
58404
|
});
|
|
58217
58405
|
}
|
|
58406
|
+
const toolNames = Array.from(this.tools.keys());
|
|
58407
|
+
this.recordMcpEvent("initialization.completed", {
|
|
58408
|
+
connected: connectedCount,
|
|
58409
|
+
total: servers.length,
|
|
58410
|
+
toolCount: this.tools.size,
|
|
58411
|
+
tools: toolNames
|
|
58412
|
+
});
|
|
58218
58413
|
return {
|
|
58219
58414
|
connected: connectedCount,
|
|
58220
58415
|
total: servers.length,
|
|
58221
|
-
tools:
|
|
58416
|
+
tools: toolNames
|
|
58222
58417
|
};
|
|
58223
58418
|
}
|
|
58224
58419
|
/**
|
|
@@ -58227,6 +58422,12 @@ var init_client = __esm({
|
|
|
58227
58422
|
*/
|
|
58228
58423
|
async connectToServer(serverConfig) {
|
|
58229
58424
|
const { name } = serverConfig;
|
|
58425
|
+
this.recordMcpEvent("server.connecting", {
|
|
58426
|
+
serverName: name,
|
|
58427
|
+
transport: serverConfig.transport,
|
|
58428
|
+
hasAllowedMethods: !!(serverConfig.allowedMethods && serverConfig.allowedMethods.length > 0),
|
|
58429
|
+
hasBlockedMethods: !!(serverConfig.blockedMethods && serverConfig.blockedMethods.length > 0)
|
|
58430
|
+
});
|
|
58230
58431
|
try {
|
|
58231
58432
|
if (this.debug) {
|
|
58232
58433
|
console.error(`[MCP DEBUG] Connecting to ${name} via ${serverConfig.transport}...`);
|
|
@@ -58248,27 +58449,92 @@ var init_client = __esm({
|
|
|
58248
58449
|
config: serverConfig
|
|
58249
58450
|
});
|
|
58250
58451
|
const toolsResponse = await client.listTools();
|
|
58251
|
-
const
|
|
58452
|
+
const totalToolCount = toolsResponse?.tools?.length || 0;
|
|
58453
|
+
let registeredCount = 0;
|
|
58454
|
+
let filteredCount = 0;
|
|
58455
|
+
const registeredTools = [];
|
|
58456
|
+
const filteredTools = [];
|
|
58252
58457
|
if (toolsResponse && toolsResponse.tools) {
|
|
58458
|
+
const { allowedMethods, blockedMethods } = serverConfig;
|
|
58459
|
+
const allToolNames = toolsResponse.tools.map((t) => t.name);
|
|
58460
|
+
this.recordMcpEvent("tools.discovered", {
|
|
58461
|
+
serverName: name,
|
|
58462
|
+
toolCount: totalToolCount,
|
|
58463
|
+
tools: allToolNames
|
|
58464
|
+
});
|
|
58253
58465
|
for (const tool4 of toolsResponse.tools) {
|
|
58466
|
+
if (!isMethodAllowed(tool4.name, allowedMethods, blockedMethods)) {
|
|
58467
|
+
filteredCount++;
|
|
58468
|
+
filteredTools.push(tool4.name);
|
|
58469
|
+
if (this.debug) {
|
|
58470
|
+
console.error(`[MCP DEBUG] Filtered out tool: ${tool4.name} (not allowed by method filter)`);
|
|
58471
|
+
}
|
|
58472
|
+
continue;
|
|
58473
|
+
}
|
|
58254
58474
|
const qualifiedName = `${name}_${tool4.name}`;
|
|
58255
58475
|
this.tools.set(qualifiedName, {
|
|
58256
58476
|
...tool4,
|
|
58257
58477
|
serverName: name,
|
|
58258
58478
|
originalName: tool4.name
|
|
58259
58479
|
});
|
|
58480
|
+
registeredCount++;
|
|
58481
|
+
registeredTools.push(qualifiedName);
|
|
58260
58482
|
if (this.debug) {
|
|
58261
58483
|
console.error(`[MCP DEBUG] Registered tool: ${qualifiedName}`);
|
|
58262
58484
|
}
|
|
58263
58485
|
}
|
|
58486
|
+
if (filteredCount > 0) {
|
|
58487
|
+
this.recordMcpEvent("tools.filtered", {
|
|
58488
|
+
serverName: name,
|
|
58489
|
+
filteredCount,
|
|
58490
|
+
filteredTools,
|
|
58491
|
+
allowedMethods: allowedMethods || [],
|
|
58492
|
+
blockedMethods: blockedMethods || []
|
|
58493
|
+
});
|
|
58494
|
+
}
|
|
58495
|
+
if (allowedMethods && allowedMethods.length > 0) {
|
|
58496
|
+
const unmatchedPatterns = allowedMethods.filter((pattern) => {
|
|
58497
|
+
return !allToolNames.some((toolName) => isMethodAllowed(toolName, [pattern], null));
|
|
58498
|
+
});
|
|
58499
|
+
if (unmatchedPatterns.length > 0) {
|
|
58500
|
+
console.error(`[MCP WARN] Server '${name}': The following allowedMethods patterns did not match any tools: ${unmatchedPatterns.join(", ")}`);
|
|
58501
|
+
console.error(`[MCP WARN] Available methods from '${name}': ${allToolNames.join(", ")}`);
|
|
58502
|
+
}
|
|
58503
|
+
}
|
|
58504
|
+
if (blockedMethods && blockedMethods.length > 0) {
|
|
58505
|
+
const unmatchedPatterns = blockedMethods.filter((pattern) => {
|
|
58506
|
+
return !allToolNames.some((toolName) => !isMethodAllowed(toolName, null, [pattern]));
|
|
58507
|
+
});
|
|
58508
|
+
if (unmatchedPatterns.length > 0) {
|
|
58509
|
+
console.error(`[MCP WARN] Server '${name}': The following blockedMethods patterns did not match any tools: ${unmatchedPatterns.join(", ")}`);
|
|
58510
|
+
console.error(`[MCP WARN] Available methods from '${name}': ${allToolNames.join(", ")}`);
|
|
58511
|
+
}
|
|
58512
|
+
}
|
|
58264
58513
|
}
|
|
58265
|
-
|
|
58514
|
+
if (filteredCount > 0) {
|
|
58515
|
+
console.error(`[MCP INFO] Connected to ${name}: ${registeredCount} tool${registeredCount !== 1 ? "s" : ""} loaded (${filteredCount} filtered out)`);
|
|
58516
|
+
} else {
|
|
58517
|
+
console.error(`[MCP INFO] Connected to ${name}: ${registeredCount} tool${registeredCount !== 1 ? "s" : ""} loaded`);
|
|
58518
|
+
}
|
|
58519
|
+
this.recordMcpEvent("server.connected", {
|
|
58520
|
+
serverName: name,
|
|
58521
|
+
transport: serverConfig.transport,
|
|
58522
|
+
totalToolCount,
|
|
58523
|
+
registeredCount,
|
|
58524
|
+
filteredCount,
|
|
58525
|
+
registeredTools
|
|
58526
|
+
});
|
|
58266
58527
|
return true;
|
|
58267
58528
|
} catch (error) {
|
|
58268
58529
|
console.error(`[MCP ERROR] Error connecting to ${name}:`, error.message);
|
|
58269
58530
|
if (this.debug) {
|
|
58270
58531
|
console.error(`[MCP DEBUG] Full error details:`, error);
|
|
58271
58532
|
}
|
|
58533
|
+
this.recordMcpEvent("server.connection_failed", {
|
|
58534
|
+
serverName: name,
|
|
58535
|
+
transport: serverConfig.transport,
|
|
58536
|
+
error: error.message
|
|
58537
|
+
});
|
|
58272
58538
|
return false;
|
|
58273
58539
|
}
|
|
58274
58540
|
}
|
|
@@ -58280,12 +58546,27 @@ var init_client = __esm({
|
|
|
58280
58546
|
async callTool(toolName, args) {
|
|
58281
58547
|
const tool4 = this.tools.get(toolName);
|
|
58282
58548
|
if (!tool4) {
|
|
58549
|
+
this.recordMcpEvent("tool.call_failed", {
|
|
58550
|
+
toolName,
|
|
58551
|
+
error: "Unknown tool"
|
|
58552
|
+
});
|
|
58283
58553
|
throw new Error(`Unknown tool: ${toolName}`);
|
|
58284
58554
|
}
|
|
58285
58555
|
const clientInfo = this.clients.get(tool4.serverName);
|
|
58286
58556
|
if (!clientInfo) {
|
|
58557
|
+
this.recordMcpEvent("tool.call_failed", {
|
|
58558
|
+
toolName,
|
|
58559
|
+
serverName: tool4.serverName,
|
|
58560
|
+
error: "Server not connected"
|
|
58561
|
+
});
|
|
58287
58562
|
throw new Error(`Server ${tool4.serverName} not connected`);
|
|
58288
58563
|
}
|
|
58564
|
+
const startTime = Date.now();
|
|
58565
|
+
this.recordMcpEvent("tool.call_started", {
|
|
58566
|
+
toolName,
|
|
58567
|
+
serverName: tool4.serverName,
|
|
58568
|
+
originalToolName: tool4.originalName
|
|
58569
|
+
});
|
|
58289
58570
|
try {
|
|
58290
58571
|
if (this.debug) {
|
|
58291
58572
|
console.error(`[MCP DEBUG] Calling ${toolName} with args:`, JSON.stringify(args, null, 2));
|
|
@@ -58305,15 +58586,31 @@ var init_client = __esm({
|
|
|
58305
58586
|
}),
|
|
58306
58587
|
timeoutPromise
|
|
58307
58588
|
]);
|
|
58589
|
+
const durationMs = Date.now() - startTime;
|
|
58308
58590
|
if (this.debug) {
|
|
58309
58591
|
console.error(`[MCP DEBUG] Tool ${toolName} executed successfully`);
|
|
58310
58592
|
}
|
|
58593
|
+
this.recordMcpEvent("tool.call_completed", {
|
|
58594
|
+
toolName,
|
|
58595
|
+
serverName: tool4.serverName,
|
|
58596
|
+
originalToolName: tool4.originalName,
|
|
58597
|
+
durationMs
|
|
58598
|
+
});
|
|
58311
58599
|
return result;
|
|
58312
58600
|
} catch (error) {
|
|
58601
|
+
const durationMs = Date.now() - startTime;
|
|
58313
58602
|
console.error(`[MCP ERROR] Error calling tool ${toolName}:`, error.message);
|
|
58314
58603
|
if (this.debug) {
|
|
58315
58604
|
console.error(`[MCP DEBUG] Full error details:`, error);
|
|
58316
58605
|
}
|
|
58606
|
+
this.recordMcpEvent("tool.call_failed", {
|
|
58607
|
+
toolName,
|
|
58608
|
+
serverName: tool4.serverName,
|
|
58609
|
+
originalToolName: tool4.originalName,
|
|
58610
|
+
error: error.message,
|
|
58611
|
+
durationMs,
|
|
58612
|
+
isTimeout: error.message.includes("timeout")
|
|
58613
|
+
});
|
|
58317
58614
|
throw error;
|
|
58318
58615
|
}
|
|
58319
58616
|
}
|
|
@@ -58358,12 +58655,17 @@ var init_client = __esm({
|
|
|
58358
58655
|
*/
|
|
58359
58656
|
async disconnect() {
|
|
58360
58657
|
const disconnectPromises = [];
|
|
58658
|
+
const serverNames = Array.from(this.clients.keys());
|
|
58361
58659
|
if (this.clients.size === 0) {
|
|
58362
58660
|
if (this.debug) {
|
|
58363
58661
|
console.error("[MCP DEBUG] No MCP clients to disconnect");
|
|
58364
58662
|
}
|
|
58365
58663
|
return;
|
|
58366
58664
|
}
|
|
58665
|
+
this.recordMcpEvent("disconnection.started", {
|
|
58666
|
+
serverCount: this.clients.size,
|
|
58667
|
+
serverNames
|
|
58668
|
+
});
|
|
58367
58669
|
if (this.debug) {
|
|
58368
58670
|
console.error(`[MCP DEBUG] Disconnecting from ${this.clients.size} MCP server${this.clients.size !== 1 ? "s" : ""}...`);
|
|
58369
58671
|
}
|
|
@@ -58373,14 +58675,25 @@ var init_client = __esm({
|
|
|
58373
58675
|
if (this.debug) {
|
|
58374
58676
|
console.error(`[MCP DEBUG] Disconnected from ${name}`);
|
|
58375
58677
|
}
|
|
58678
|
+
this.recordMcpEvent("server.disconnected", {
|
|
58679
|
+
serverName: name
|
|
58680
|
+
});
|
|
58376
58681
|
}).catch((error) => {
|
|
58377
58682
|
console.error(`[MCP ERROR] Error disconnecting from ${name}:`, error.message);
|
|
58683
|
+
this.recordMcpEvent("server.disconnect_failed", {
|
|
58684
|
+
serverName: name,
|
|
58685
|
+
error: error.message
|
|
58686
|
+
});
|
|
58378
58687
|
})
|
|
58379
58688
|
);
|
|
58380
58689
|
}
|
|
58381
58690
|
await Promise.all(disconnectPromises);
|
|
58382
58691
|
this.clients.clear();
|
|
58383
58692
|
this.tools.clear();
|
|
58693
|
+
this.recordMcpEvent("disconnection.completed", {
|
|
58694
|
+
serverCount: serverNames.length,
|
|
58695
|
+
serverNames
|
|
58696
|
+
});
|
|
58384
58697
|
if (this.debug) {
|
|
58385
58698
|
console.error("[MCP DEBUG] All MCP connections closed");
|
|
58386
58699
|
}
|
|
@@ -58524,6 +58837,7 @@ var init_xmlBridge = __esm({
|
|
|
58524
58837
|
MCPXmlBridge = class {
|
|
58525
58838
|
constructor(options = {}) {
|
|
58526
58839
|
this.debug = options.debug || false;
|
|
58840
|
+
this.tracer = options.tracer || null;
|
|
58527
58841
|
this.mcpTools = {};
|
|
58528
58842
|
this.mcpManager = null;
|
|
58529
58843
|
this.xmlDefinitions = {};
|
|
@@ -58566,7 +58880,7 @@ var init_xmlBridge = __esm({
|
|
|
58566
58880
|
if (this.debug) {
|
|
58567
58881
|
console.error("[MCP DEBUG] Initializing MCP client manager...");
|
|
58568
58882
|
}
|
|
58569
|
-
this.mcpManager = new MCPClientManager({ debug: this.debug });
|
|
58883
|
+
this.mcpManager = new MCPClientManager({ debug: this.debug, tracer: this.tracer });
|
|
58570
58884
|
const result = await this.mcpManager.initialize(mcpConfigs);
|
|
58571
58885
|
const vercelTools = this.mcpManager.getVercelTools();
|
|
58572
58886
|
this.mcpTools = vercelTools;
|
|
@@ -58590,11 +58904,15 @@ var init_xmlBridge = __esm({
|
|
|
58590
58904
|
}
|
|
58591
58905
|
}
|
|
58592
58906
|
/**
|
|
58593
|
-
* Get
|
|
58907
|
+
* Get XML tool definitions for inclusion in system prompt
|
|
58908
|
+
* @param {Array<string>|null} filterToolNames - Optional list of tool names to include (if null, include all)
|
|
58594
58909
|
* @returns {string} Combined XML tool definitions
|
|
58595
58910
|
*/
|
|
58596
|
-
getXmlToolDefinitions() {
|
|
58597
|
-
|
|
58911
|
+
getXmlToolDefinitions(filterToolNames = null) {
|
|
58912
|
+
if (filterToolNames === null) {
|
|
58913
|
+
return Object.values(this.xmlDefinitions).join("\n\n");
|
|
58914
|
+
}
|
|
58915
|
+
return Object.entries(this.xmlDefinitions).filter(([name]) => filterToolNames.includes(name)).map(([, def]) => def).join("\n\n");
|
|
58598
58916
|
}
|
|
58599
58917
|
/**
|
|
58600
58918
|
* Get list of MCP tool names
|