@probelabs/probe 0.6.0-rc207 → 0.6.0-rc209

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.
Files changed (33) hide show
  1. package/bin/binaries/probe-v0.6.0-rc209-aarch64-apple-darwin.tar.gz +0 -0
  2. package/bin/binaries/probe-v0.6.0-rc209-aarch64-unknown-linux-musl.tar.gz +0 -0
  3. package/bin/binaries/probe-v0.6.0-rc209-x86_64-apple-darwin.tar.gz +0 -0
  4. package/bin/binaries/probe-v0.6.0-rc209-x86_64-pc-windows-msvc.zip +0 -0
  5. package/bin/binaries/probe-v0.6.0-rc209-x86_64-unknown-linux-musl.tar.gz +0 -0
  6. package/build/agent/ProbeAgent.d.ts +4 -2
  7. package/build/agent/ProbeAgent.js +2 -1
  8. package/build/agent/bashPermissions.js +88 -7
  9. package/build/agent/index.js +342 -24
  10. package/build/agent/mcp/client.js +236 -5
  11. package/build/agent/mcp/config.js +87 -0
  12. package/build/agent/mcp/xmlBridge.js +15 -5
  13. package/build/agent/simpleTelemetry.js +26 -0
  14. package/build/tools/bash.js +5 -3
  15. package/cjs/agent/ProbeAgent.cjs +314 -18
  16. package/cjs/agent/simpleTelemetry.cjs +22 -0
  17. package/cjs/index.cjs +336 -18
  18. package/index.d.ts +4 -2
  19. package/package.json +1 -1
  20. package/src/agent/ProbeAgent.d.ts +4 -2
  21. package/src/agent/ProbeAgent.js +2 -1
  22. package/src/agent/bashPermissions.js +88 -7
  23. package/src/agent/index.js +5 -5
  24. package/src/agent/mcp/client.js +236 -5
  25. package/src/agent/mcp/config.js +87 -0
  26. package/src/agent/mcp/xmlBridge.js +15 -5
  27. package/src/agent/simpleTelemetry.js +26 -0
  28. package/src/tools/bash.js +5 -3
  29. package/bin/binaries/probe-v0.6.0-rc207-aarch64-apple-darwin.tar.gz +0 -0
  30. package/bin/binaries/probe-v0.6.0-rc207-aarch64-unknown-linux-musl.tar.gz +0 -0
  31. package/bin/binaries/probe-v0.6.0-rc207-x86_64-apple-darwin.tar.gz +0 -0
  32. package/bin/binaries/probe-v0.6.0-rc207-x86_64-pc-windows-msvc.zip +0 -0
  33. package/bin/binaries/probe-v0.6.0-rc207-x86_64-unknown-linux-musl.tar.gz +0 -0
@@ -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
- return {
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
- return {
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
- return {
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
- return {
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
- return {
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
- return {
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
- return {
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: Array.from(this.tools.keys())
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 toolCount = toolsResponse?.tools?.length || 0;
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
- console.error(`[MCP INFO] Connected to ${name14}: ${toolCount} tool${toolCount !== 1 ? "s" : ""} loaded`);
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));
@@ -85016,18 +85275,34 @@ var init_client2 = __esm({
85016
85275
  clientInfo.client.callTool({
85017
85276
  name: tool4.originalName,
85018
85277
  arguments: args
85019
- }),
85278
+ }, void 0, { timeout }),
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 all XML tool definitions for inclusion in system prompt
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
- return Object.values(this.xmlDefinitions).join("\n\n");
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
@@ -95533,7 +95829,7 @@ var init_ProbeAgent = __esm({
95533
95829
  this.maxIterations = options.maxIterations || null;
95534
95830
  this.disableMermaidValidation = !!options.disableMermaidValidation;
95535
95831
  this.disableJsonValidation = !!options.disableJsonValidation;
95536
- this.enableSkills = options.disableSkills ? false : options.enableSkills !== void 0 ? !!options.enableSkills : true;
95832
+ this.enableSkills = options.disableSkills ? false : !!(options.allowSkills || options.enableSkills);
95537
95833
  if (Array.isArray(options.skillDirs)) {
95538
95834
  this.skillDirs = options.skillDirs;
95539
95835
  } else if (typeof options.skillDirs === "string") {
@@ -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);