@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.
- package/bin/binaries/probe-v0.6.0-rc209-aarch64-apple-darwin.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc209-aarch64-unknown-linux-musl.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc209-x86_64-apple-darwin.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc209-x86_64-pc-windows-msvc.zip +0 -0
- package/bin/binaries/probe-v0.6.0-rc209-x86_64-unknown-linux-musl.tar.gz +0 -0
- package/build/agent/ProbeAgent.d.ts +4 -2
- package/build/agent/ProbeAgent.js +2 -1
- package/build/agent/bashPermissions.js +88 -7
- package/build/agent/index.js +342 -24
- package/build/agent/mcp/client.js +236 -5
- 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 +314 -18
- package/cjs/agent/simpleTelemetry.cjs +22 -0
- package/cjs/index.cjs +336 -18
- package/index.d.ts +4 -2
- package/package.json +1 -1
- package/src/agent/ProbeAgent.d.ts +4 -2
- package/src/agent/ProbeAgent.js +2 -1
- package/src/agent/bashPermissions.js +88 -7
- package/src/agent/index.js +5 -5
- package/src/agent/mcp/client.js +236 -5
- 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/index.cjs
CHANGED
|
@@ -82300,6 +82300,47 @@ function validateTimeout(value) {
|
|
|
82300
82300
|
if (!Number.isFinite(num) || num < 0) return void 0;
|
|
82301
82301
|
return Math.min(num, MAX_TIMEOUT);
|
|
82302
82302
|
}
|
|
82303
|
+
function validateMethodFilter(serverConfig, serverName = "unknown") {
|
|
82304
|
+
const result = { allowedMethods: null, blockedMethods: null };
|
|
82305
|
+
const debug = process.env.DEBUG === "1" || process.env.DEBUG_MCP === "1";
|
|
82306
|
+
if (serverConfig.allowedMethods && serverConfig.blockedMethods) {
|
|
82307
|
+
console.error(`[MCP WARN] Server '${serverName}' has both allowedMethods and blockedMethods - using allowedMethods only`);
|
|
82308
|
+
}
|
|
82309
|
+
if (serverConfig.allowedMethods) {
|
|
82310
|
+
if (!Array.isArray(serverConfig.allowedMethods)) {
|
|
82311
|
+
console.error(`[MCP WARN] Server '${serverName}' allowedMethods must be an array, ignoring`);
|
|
82312
|
+
} else {
|
|
82313
|
+
const validMethods = serverConfig.allowedMethods.filter((m4) => typeof m4 === "string" && m4.length > 0);
|
|
82314
|
+
if (validMethods.length !== serverConfig.allowedMethods.length) {
|
|
82315
|
+
console.error(`[MCP WARN] Server '${serverName}' allowedMethods contains non-string values, skipping those`);
|
|
82316
|
+
}
|
|
82317
|
+
if (validMethods.length > 0) {
|
|
82318
|
+
result.allowedMethods = validMethods;
|
|
82319
|
+
if (debug) {
|
|
82320
|
+
console.error(`[MCP DEBUG] Server '${serverName}' allowedMethods: ${validMethods.join(", ")}`);
|
|
82321
|
+
}
|
|
82322
|
+
}
|
|
82323
|
+
}
|
|
82324
|
+
return result;
|
|
82325
|
+
}
|
|
82326
|
+
if (serverConfig.blockedMethods) {
|
|
82327
|
+
if (!Array.isArray(serverConfig.blockedMethods)) {
|
|
82328
|
+
console.error(`[MCP WARN] Server '${serverName}' blockedMethods must be an array, ignoring`);
|
|
82329
|
+
} else {
|
|
82330
|
+
const validMethods = serverConfig.blockedMethods.filter((m4) => typeof m4 === "string" && m4.length > 0);
|
|
82331
|
+
if (validMethods.length !== serverConfig.blockedMethods.length) {
|
|
82332
|
+
console.error(`[MCP WARN] Server '${serverName}' blockedMethods contains non-string values, skipping those`);
|
|
82333
|
+
}
|
|
82334
|
+
if (validMethods.length > 0) {
|
|
82335
|
+
result.blockedMethods = validMethods;
|
|
82336
|
+
if (debug) {
|
|
82337
|
+
console.error(`[MCP DEBUG] Server '${serverName}' blockedMethods: ${validMethods.join(", ")}`);
|
|
82338
|
+
}
|
|
82339
|
+
}
|
|
82340
|
+
}
|
|
82341
|
+
}
|
|
82342
|
+
return result;
|
|
82343
|
+
}
|
|
82303
82344
|
function loadMCPConfigurationFromPath(configPath) {
|
|
82304
82345
|
if (!configPath) {
|
|
82305
82346
|
throw new Error("Config path is required");
|
|
@@ -82393,6 +82434,12 @@ function mergeWithEnvironment(config) {
|
|
|
82393
82434
|
console.error(`[MCP WARN] Invalid timeout value for ${normalizedName}: ${value}`);
|
|
82394
82435
|
}
|
|
82395
82436
|
break;
|
|
82437
|
+
case "ALLOWLIST":
|
|
82438
|
+
config.mcpServers[normalizedName].allowedMethods = value.split(",").map((m4) => m4.trim()).filter(Boolean);
|
|
82439
|
+
break;
|
|
82440
|
+
case "BLOCKLIST":
|
|
82441
|
+
config.mcpServers[normalizedName].blockedMethods = value.split(",").map((m4) => m4.trim()).filter(Boolean);
|
|
82442
|
+
break;
|
|
82396
82443
|
}
|
|
82397
82444
|
}
|
|
82398
82445
|
}
|
|
@@ -82443,6 +82490,9 @@ function parseEnabledServers(config) {
|
|
|
82443
82490
|
}
|
|
82444
82491
|
server.timeout = validatedTimeout;
|
|
82445
82492
|
}
|
|
82493
|
+
const methodFilter = validateMethodFilter(serverConfig, name14);
|
|
82494
|
+
server.allowedMethods = methodFilter.allowedMethods;
|
|
82495
|
+
server.blockedMethods = methodFilter.blockedMethods;
|
|
82446
82496
|
servers.push(server);
|
|
82447
82497
|
}
|
|
82448
82498
|
return servers;
|
|
@@ -82480,6 +82530,22 @@ var init_config = __esm({
|
|
|
82480
82530
|
});
|
|
82481
82531
|
|
|
82482
82532
|
// src/agent/mcp/client.js
|
|
82533
|
+
function isMethodAllowed(methodName, allowedMethods, blockedMethods) {
|
|
82534
|
+
const matchesPattern2 = (name14, pattern) => {
|
|
82535
|
+
if (!pattern.includes("*")) {
|
|
82536
|
+
return name14 === pattern;
|
|
82537
|
+
}
|
|
82538
|
+
const regexPattern = pattern.replace(/[.+?^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*");
|
|
82539
|
+
return new RegExp(`^${regexPattern}$`).test(name14);
|
|
82540
|
+
};
|
|
82541
|
+
if (allowedMethods && allowedMethods.length > 0) {
|
|
82542
|
+
return allowedMethods.some((pattern) => matchesPattern2(methodName, pattern));
|
|
82543
|
+
}
|
|
82544
|
+
if (blockedMethods && blockedMethods.length > 0) {
|
|
82545
|
+
return !blockedMethods.some((pattern) => matchesPattern2(methodName, pattern));
|
|
82546
|
+
}
|
|
82547
|
+
return true;
|
|
82548
|
+
}
|
|
82483
82549
|
function createTransport(serverConfig) {
|
|
82484
82550
|
const { transport, command, args, url, env } = serverConfig;
|
|
82485
82551
|
switch (transport) {
|
|
@@ -82564,6 +82630,17 @@ var init_client2 = __esm({
|
|
|
82564
82630
|
this.tools = /* @__PURE__ */ new Map();
|
|
82565
82631
|
this.debug = options.debug || process.env.DEBUG_MCP === "1";
|
|
82566
82632
|
this.config = null;
|
|
82633
|
+
this.tracer = options.tracer || null;
|
|
82634
|
+
}
|
|
82635
|
+
/**
|
|
82636
|
+
* Record an MCP telemetry event if tracer is available
|
|
82637
|
+
* @param {string} eventType - Event type (e.g., 'server.connect', 'tool.discovered')
|
|
82638
|
+
* @param {Object} data - Event data
|
|
82639
|
+
*/
|
|
82640
|
+
recordMcpEvent(eventType, data2 = {}) {
|
|
82641
|
+
if (this.tracer && typeof this.tracer.recordMcpEvent === "function") {
|
|
82642
|
+
this.tracer.recordMcpEvent(eventType, data2);
|
|
82643
|
+
}
|
|
82567
82644
|
}
|
|
82568
82645
|
/**
|
|
82569
82646
|
* Initialize MCP clients from configuration
|
|
@@ -82572,10 +82649,20 @@ var init_client2 = __esm({
|
|
|
82572
82649
|
async initialize(config = null) {
|
|
82573
82650
|
this.config = config || loadMCPConfiguration();
|
|
82574
82651
|
const servers = parseEnabledServers(this.config);
|
|
82652
|
+
this.recordMcpEvent("initialization.started", {
|
|
82653
|
+
serverCount: servers.length,
|
|
82654
|
+
serverNames: servers.map((s4) => s4.name)
|
|
82655
|
+
});
|
|
82575
82656
|
console.error(`[MCP INFO] Found ${servers.length} enabled MCP server${servers.length !== 1 ? "s" : ""}`);
|
|
82576
82657
|
if (servers.length === 0) {
|
|
82577
82658
|
console.error("[MCP INFO] No MCP servers configured or enabled");
|
|
82578
82659
|
console.error("[MCP INFO] 0 MCP tools available");
|
|
82660
|
+
this.recordMcpEvent("initialization.completed", {
|
|
82661
|
+
connected: 0,
|
|
82662
|
+
total: 0,
|
|
82663
|
+
toolCount: 0,
|
|
82664
|
+
tools: []
|
|
82665
|
+
});
|
|
82579
82666
|
return {
|
|
82580
82667
|
connected: 0,
|
|
82581
82668
|
total: 0,
|
|
@@ -82612,10 +82699,17 @@ var init_client2 = __esm({
|
|
|
82612
82699
|
console.error(`[MCP DEBUG] - ${toolName}`);
|
|
82613
82700
|
});
|
|
82614
82701
|
}
|
|
82702
|
+
const toolNames = Array.from(this.tools.keys());
|
|
82703
|
+
this.recordMcpEvent("initialization.completed", {
|
|
82704
|
+
connected: connectedCount,
|
|
82705
|
+
total: servers.length,
|
|
82706
|
+
toolCount: this.tools.size,
|
|
82707
|
+
tools: toolNames
|
|
82708
|
+
});
|
|
82615
82709
|
return {
|
|
82616
82710
|
connected: connectedCount,
|
|
82617
82711
|
total: servers.length,
|
|
82618
|
-
tools:
|
|
82712
|
+
tools: toolNames
|
|
82619
82713
|
};
|
|
82620
82714
|
}
|
|
82621
82715
|
/**
|
|
@@ -82624,6 +82718,12 @@ var init_client2 = __esm({
|
|
|
82624
82718
|
*/
|
|
82625
82719
|
async connectToServer(serverConfig) {
|
|
82626
82720
|
const { name: name14 } = serverConfig;
|
|
82721
|
+
this.recordMcpEvent("server.connecting", {
|
|
82722
|
+
serverName: name14,
|
|
82723
|
+
transport: serverConfig.transport,
|
|
82724
|
+
hasAllowedMethods: !!(serverConfig.allowedMethods && serverConfig.allowedMethods.length > 0),
|
|
82725
|
+
hasBlockedMethods: !!(serverConfig.blockedMethods && serverConfig.blockedMethods.length > 0)
|
|
82726
|
+
});
|
|
82627
82727
|
try {
|
|
82628
82728
|
if (this.debug) {
|
|
82629
82729
|
console.error(`[MCP DEBUG] Connecting to ${name14} via ${serverConfig.transport}...`);
|
|
@@ -82645,27 +82745,92 @@ var init_client2 = __esm({
|
|
|
82645
82745
|
config: serverConfig
|
|
82646
82746
|
});
|
|
82647
82747
|
const toolsResponse = await client.listTools();
|
|
82648
|
-
const
|
|
82748
|
+
const totalToolCount = toolsResponse?.tools?.length || 0;
|
|
82749
|
+
let registeredCount = 0;
|
|
82750
|
+
let filteredCount = 0;
|
|
82751
|
+
const registeredTools = [];
|
|
82752
|
+
const filteredTools = [];
|
|
82649
82753
|
if (toolsResponse && toolsResponse.tools) {
|
|
82754
|
+
const { allowedMethods, blockedMethods } = serverConfig;
|
|
82755
|
+
const allToolNames = toolsResponse.tools.map((t4) => t4.name);
|
|
82756
|
+
this.recordMcpEvent("tools.discovered", {
|
|
82757
|
+
serverName: name14,
|
|
82758
|
+
toolCount: totalToolCount,
|
|
82759
|
+
tools: allToolNames
|
|
82760
|
+
});
|
|
82650
82761
|
for (const tool4 of toolsResponse.tools) {
|
|
82762
|
+
if (!isMethodAllowed(tool4.name, allowedMethods, blockedMethods)) {
|
|
82763
|
+
filteredCount++;
|
|
82764
|
+
filteredTools.push(tool4.name);
|
|
82765
|
+
if (this.debug) {
|
|
82766
|
+
console.error(`[MCP DEBUG] Filtered out tool: ${tool4.name} (not allowed by method filter)`);
|
|
82767
|
+
}
|
|
82768
|
+
continue;
|
|
82769
|
+
}
|
|
82651
82770
|
const qualifiedName = `${name14}_${tool4.name}`;
|
|
82652
82771
|
this.tools.set(qualifiedName, {
|
|
82653
82772
|
...tool4,
|
|
82654
82773
|
serverName: name14,
|
|
82655
82774
|
originalName: tool4.name
|
|
82656
82775
|
});
|
|
82776
|
+
registeredCount++;
|
|
82777
|
+
registeredTools.push(qualifiedName);
|
|
82657
82778
|
if (this.debug) {
|
|
82658
82779
|
console.error(`[MCP DEBUG] Registered tool: ${qualifiedName}`);
|
|
82659
82780
|
}
|
|
82660
82781
|
}
|
|
82782
|
+
if (filteredCount > 0) {
|
|
82783
|
+
this.recordMcpEvent("tools.filtered", {
|
|
82784
|
+
serverName: name14,
|
|
82785
|
+
filteredCount,
|
|
82786
|
+
filteredTools,
|
|
82787
|
+
allowedMethods: allowedMethods || [],
|
|
82788
|
+
blockedMethods: blockedMethods || []
|
|
82789
|
+
});
|
|
82790
|
+
}
|
|
82791
|
+
if (allowedMethods && allowedMethods.length > 0) {
|
|
82792
|
+
const unmatchedPatterns = allowedMethods.filter((pattern) => {
|
|
82793
|
+
return !allToolNames.some((toolName) => isMethodAllowed(toolName, [pattern], null));
|
|
82794
|
+
});
|
|
82795
|
+
if (unmatchedPatterns.length > 0) {
|
|
82796
|
+
console.error(`[MCP WARN] Server '${name14}': The following allowedMethods patterns did not match any tools: ${unmatchedPatterns.join(", ")}`);
|
|
82797
|
+
console.error(`[MCP WARN] Available methods from '${name14}': ${allToolNames.join(", ")}`);
|
|
82798
|
+
}
|
|
82799
|
+
}
|
|
82800
|
+
if (blockedMethods && blockedMethods.length > 0) {
|
|
82801
|
+
const unmatchedPatterns = blockedMethods.filter((pattern) => {
|
|
82802
|
+
return !allToolNames.some((toolName) => !isMethodAllowed(toolName, null, [pattern]));
|
|
82803
|
+
});
|
|
82804
|
+
if (unmatchedPatterns.length > 0) {
|
|
82805
|
+
console.error(`[MCP WARN] Server '${name14}': The following blockedMethods patterns did not match any tools: ${unmatchedPatterns.join(", ")}`);
|
|
82806
|
+
console.error(`[MCP WARN] Available methods from '${name14}': ${allToolNames.join(", ")}`);
|
|
82807
|
+
}
|
|
82808
|
+
}
|
|
82661
82809
|
}
|
|
82662
|
-
|
|
82810
|
+
if (filteredCount > 0) {
|
|
82811
|
+
console.error(`[MCP INFO] Connected to ${name14}: ${registeredCount} tool${registeredCount !== 1 ? "s" : ""} loaded (${filteredCount} filtered out)`);
|
|
82812
|
+
} else {
|
|
82813
|
+
console.error(`[MCP INFO] Connected to ${name14}: ${registeredCount} tool${registeredCount !== 1 ? "s" : ""} loaded`);
|
|
82814
|
+
}
|
|
82815
|
+
this.recordMcpEvent("server.connected", {
|
|
82816
|
+
serverName: name14,
|
|
82817
|
+
transport: serverConfig.transport,
|
|
82818
|
+
totalToolCount,
|
|
82819
|
+
registeredCount,
|
|
82820
|
+
filteredCount,
|
|
82821
|
+
registeredTools
|
|
82822
|
+
});
|
|
82663
82823
|
return true;
|
|
82664
82824
|
} catch (error2) {
|
|
82665
82825
|
console.error(`[MCP ERROR] Error connecting to ${name14}:`, error2.message);
|
|
82666
82826
|
if (this.debug) {
|
|
82667
82827
|
console.error(`[MCP DEBUG] Full error details:`, error2);
|
|
82668
82828
|
}
|
|
82829
|
+
this.recordMcpEvent("server.connection_failed", {
|
|
82830
|
+
serverName: name14,
|
|
82831
|
+
transport: serverConfig.transport,
|
|
82832
|
+
error: error2.message
|
|
82833
|
+
});
|
|
82669
82834
|
return false;
|
|
82670
82835
|
}
|
|
82671
82836
|
}
|
|
@@ -82677,12 +82842,27 @@ var init_client2 = __esm({
|
|
|
82677
82842
|
async callTool(toolName, args) {
|
|
82678
82843
|
const tool4 = this.tools.get(toolName);
|
|
82679
82844
|
if (!tool4) {
|
|
82845
|
+
this.recordMcpEvent("tool.call_failed", {
|
|
82846
|
+
toolName,
|
|
82847
|
+
error: "Unknown tool"
|
|
82848
|
+
});
|
|
82680
82849
|
throw new Error(`Unknown tool: ${toolName}`);
|
|
82681
82850
|
}
|
|
82682
82851
|
const clientInfo = this.clients.get(tool4.serverName);
|
|
82683
82852
|
if (!clientInfo) {
|
|
82853
|
+
this.recordMcpEvent("tool.call_failed", {
|
|
82854
|
+
toolName,
|
|
82855
|
+
serverName: tool4.serverName,
|
|
82856
|
+
error: "Server not connected"
|
|
82857
|
+
});
|
|
82684
82858
|
throw new Error(`Server ${tool4.serverName} not connected`);
|
|
82685
82859
|
}
|
|
82860
|
+
const startTime = Date.now();
|
|
82861
|
+
this.recordMcpEvent("tool.call_started", {
|
|
82862
|
+
toolName,
|
|
82863
|
+
serverName: tool4.serverName,
|
|
82864
|
+
originalToolName: tool4.originalName
|
|
82865
|
+
});
|
|
82686
82866
|
try {
|
|
82687
82867
|
if (this.debug) {
|
|
82688
82868
|
console.error(`[MCP DEBUG] Calling ${toolName} with args:`, JSON.stringify(args, null, 2));
|
|
@@ -82699,18 +82879,34 @@ var init_client2 = __esm({
|
|
|
82699
82879
|
clientInfo.client.callTool({
|
|
82700
82880
|
name: tool4.originalName,
|
|
82701
82881
|
arguments: args
|
|
82702
|
-
}),
|
|
82882
|
+
}, void 0, { timeout }),
|
|
82703
82883
|
timeoutPromise
|
|
82704
82884
|
]);
|
|
82885
|
+
const durationMs = Date.now() - startTime;
|
|
82705
82886
|
if (this.debug) {
|
|
82706
82887
|
console.error(`[MCP DEBUG] Tool ${toolName} executed successfully`);
|
|
82707
82888
|
}
|
|
82889
|
+
this.recordMcpEvent("tool.call_completed", {
|
|
82890
|
+
toolName,
|
|
82891
|
+
serverName: tool4.serverName,
|
|
82892
|
+
originalToolName: tool4.originalName,
|
|
82893
|
+
durationMs
|
|
82894
|
+
});
|
|
82708
82895
|
return result;
|
|
82709
82896
|
} catch (error2) {
|
|
82897
|
+
const durationMs = Date.now() - startTime;
|
|
82710
82898
|
console.error(`[MCP ERROR] Error calling tool ${toolName}:`, error2.message);
|
|
82711
82899
|
if (this.debug) {
|
|
82712
82900
|
console.error(`[MCP DEBUG] Full error details:`, error2);
|
|
82713
82901
|
}
|
|
82902
|
+
this.recordMcpEvent("tool.call_failed", {
|
|
82903
|
+
toolName,
|
|
82904
|
+
serverName: tool4.serverName,
|
|
82905
|
+
originalToolName: tool4.originalName,
|
|
82906
|
+
error: error2.message,
|
|
82907
|
+
durationMs,
|
|
82908
|
+
isTimeout: error2.message.includes("timeout")
|
|
82909
|
+
});
|
|
82714
82910
|
throw error2;
|
|
82715
82911
|
}
|
|
82716
82912
|
}
|
|
@@ -82755,12 +82951,17 @@ var init_client2 = __esm({
|
|
|
82755
82951
|
*/
|
|
82756
82952
|
async disconnect() {
|
|
82757
82953
|
const disconnectPromises = [];
|
|
82954
|
+
const serverNames = Array.from(this.clients.keys());
|
|
82758
82955
|
if (this.clients.size === 0) {
|
|
82759
82956
|
if (this.debug) {
|
|
82760
82957
|
console.error("[MCP DEBUG] No MCP clients to disconnect");
|
|
82761
82958
|
}
|
|
82762
82959
|
return;
|
|
82763
82960
|
}
|
|
82961
|
+
this.recordMcpEvent("disconnection.started", {
|
|
82962
|
+
serverCount: this.clients.size,
|
|
82963
|
+
serverNames
|
|
82964
|
+
});
|
|
82764
82965
|
if (this.debug) {
|
|
82765
82966
|
console.error(`[MCP DEBUG] Disconnecting from ${this.clients.size} MCP server${this.clients.size !== 1 ? "s" : ""}...`);
|
|
82766
82967
|
}
|
|
@@ -82770,14 +82971,25 @@ var init_client2 = __esm({
|
|
|
82770
82971
|
if (this.debug) {
|
|
82771
82972
|
console.error(`[MCP DEBUG] Disconnected from ${name14}`);
|
|
82772
82973
|
}
|
|
82974
|
+
this.recordMcpEvent("server.disconnected", {
|
|
82975
|
+
serverName: name14
|
|
82976
|
+
});
|
|
82773
82977
|
}).catch((error2) => {
|
|
82774
82978
|
console.error(`[MCP ERROR] Error disconnecting from ${name14}:`, error2.message);
|
|
82979
|
+
this.recordMcpEvent("server.disconnect_failed", {
|
|
82980
|
+
serverName: name14,
|
|
82981
|
+
error: error2.message
|
|
82982
|
+
});
|
|
82775
82983
|
})
|
|
82776
82984
|
);
|
|
82777
82985
|
}
|
|
82778
82986
|
await Promise.all(disconnectPromises);
|
|
82779
82987
|
this.clients.clear();
|
|
82780
82988
|
this.tools.clear();
|
|
82989
|
+
this.recordMcpEvent("disconnection.completed", {
|
|
82990
|
+
serverCount: serverNames.length,
|
|
82991
|
+
serverNames
|
|
82992
|
+
});
|
|
82781
82993
|
if (this.debug) {
|
|
82782
82994
|
console.error("[MCP DEBUG] All MCP connections closed");
|
|
82783
82995
|
}
|
|
@@ -82921,6 +83133,7 @@ var init_xmlBridge = __esm({
|
|
|
82921
83133
|
MCPXmlBridge = class {
|
|
82922
83134
|
constructor(options = {}) {
|
|
82923
83135
|
this.debug = options.debug || false;
|
|
83136
|
+
this.tracer = options.tracer || null;
|
|
82924
83137
|
this.mcpTools = {};
|
|
82925
83138
|
this.mcpManager = null;
|
|
82926
83139
|
this.xmlDefinitions = {};
|
|
@@ -82963,7 +83176,7 @@ var init_xmlBridge = __esm({
|
|
|
82963
83176
|
if (this.debug) {
|
|
82964
83177
|
console.error("[MCP DEBUG] Initializing MCP client manager...");
|
|
82965
83178
|
}
|
|
82966
|
-
this.mcpManager = new MCPClientManager({ debug: this.debug });
|
|
83179
|
+
this.mcpManager = new MCPClientManager({ debug: this.debug, tracer: this.tracer });
|
|
82967
83180
|
const result = await this.mcpManager.initialize(mcpConfigs);
|
|
82968
83181
|
const vercelTools = this.mcpManager.getVercelTools();
|
|
82969
83182
|
this.mcpTools = vercelTools;
|
|
@@ -82987,11 +83200,15 @@ var init_xmlBridge = __esm({
|
|
|
82987
83200
|
}
|
|
82988
83201
|
}
|
|
82989
83202
|
/**
|
|
82990
|
-
* Get
|
|
83203
|
+
* Get XML tool definitions for inclusion in system prompt
|
|
83204
|
+
* @param {Array<string>|null} filterToolNames - Optional list of tool names to include (if null, include all)
|
|
82991
83205
|
* @returns {string} Combined XML tool definitions
|
|
82992
83206
|
*/
|
|
82993
|
-
getXmlToolDefinitions() {
|
|
82994
|
-
|
|
83207
|
+
getXmlToolDefinitions(filterToolNames = null) {
|
|
83208
|
+
if (filterToolNames === null) {
|
|
83209
|
+
return Object.values(this.xmlDefinitions).join("\n\n");
|
|
83210
|
+
}
|
|
83211
|
+
return Object.entries(this.xmlDefinitions).filter(([name14]) => filterToolNames.includes(name14)).map(([, def]) => def).join("\n\n");
|
|
82995
83212
|
}
|
|
82996
83213
|
/**
|
|
82997
83214
|
* Get list of MCP tool names
|
|
@@ -93216,7 +93433,7 @@ var init_ProbeAgent = __esm({
|
|
|
93216
93433
|
this.maxIterations = options.maxIterations || null;
|
|
93217
93434
|
this.disableMermaidValidation = !!options.disableMermaidValidation;
|
|
93218
93435
|
this.disableJsonValidation = !!options.disableJsonValidation;
|
|
93219
|
-
this.enableSkills = options.disableSkills ? false : options.
|
|
93436
|
+
this.enableSkills = options.disableSkills ? false : !!(options.allowSkills || options.enableSkills);
|
|
93220
93437
|
if (Array.isArray(options.skillDirs)) {
|
|
93221
93438
|
this.skillDirs = options.skillDirs;
|
|
93222
93439
|
} else if (typeof options.skillDirs === "string") {
|
|
@@ -97864,9 +98081,11 @@ var init_bashPermissions = __esm({
|
|
|
97864
98081
|
* @param {boolean} [config.disableDefaultAllow] - Disable default allow list
|
|
97865
98082
|
* @param {boolean} [config.disableDefaultDeny] - Disable default deny list
|
|
97866
98083
|
* @param {boolean} [config.debug] - Enable debug logging
|
|
98084
|
+
* @param {Object} [config.tracer] - Optional tracer for telemetry
|
|
97867
98085
|
*/
|
|
97868
98086
|
constructor(config = {}) {
|
|
97869
98087
|
this.debug = config.debug || false;
|
|
98088
|
+
this.tracer = config.tracer || null;
|
|
97870
98089
|
this.allowPatterns = [];
|
|
97871
98090
|
if (!config.disableDefaultAllow) {
|
|
97872
98091
|
this.allowPatterns.push(...DEFAULT_ALLOW_PATTERNS);
|
|
@@ -97896,6 +98115,24 @@ var init_bashPermissions = __esm({
|
|
|
97896
98115
|
if (this.debug) {
|
|
97897
98116
|
console.log(`[BashPermissions] Total patterns - Allow: ${this.allowPatterns.length}, Deny: ${this.denyPatterns.length}`);
|
|
97898
98117
|
}
|
|
98118
|
+
this.recordBashEvent("permissions.initialized", {
|
|
98119
|
+
allowPatternCount: this.allowPatterns.length,
|
|
98120
|
+
denyPatternCount: this.denyPatterns.length,
|
|
98121
|
+
hasCustomAllowPatterns: !!(config.allow && config.allow.length > 0),
|
|
98122
|
+
hasCustomDenyPatterns: !!(config.deny && config.deny.length > 0),
|
|
98123
|
+
disableDefaultAllow: !!config.disableDefaultAllow,
|
|
98124
|
+
disableDefaultDeny: !!config.disableDefaultDeny
|
|
98125
|
+
});
|
|
98126
|
+
}
|
|
98127
|
+
/**
|
|
98128
|
+
* Record a bash telemetry event if tracer is available
|
|
98129
|
+
* @param {string} eventType - Event type (e.g., 'permission.checked', 'permission.denied')
|
|
98130
|
+
* @param {Object} data - Event data
|
|
98131
|
+
*/
|
|
98132
|
+
recordBashEvent(eventType, data2 = {}) {
|
|
98133
|
+
if (this.tracer && typeof this.tracer.recordBashEvent === "function") {
|
|
98134
|
+
this.tracer.recordBashEvent(eventType, data2);
|
|
98135
|
+
}
|
|
97899
98136
|
}
|
|
97900
98137
|
/**
|
|
97901
98138
|
* Check if a simple command is allowed (complex commands allowed if they match patterns)
|
|
@@ -97904,11 +98141,17 @@ var init_bashPermissions = __esm({
|
|
|
97904
98141
|
*/
|
|
97905
98142
|
check(command) {
|
|
97906
98143
|
if (!command || typeof command !== "string") {
|
|
97907
|
-
|
|
98144
|
+
const result2 = {
|
|
97908
98145
|
allowed: false,
|
|
97909
98146
|
reason: "Invalid or empty command",
|
|
97910
98147
|
command
|
|
97911
98148
|
};
|
|
98149
|
+
this.recordBashEvent("permission.denied", {
|
|
98150
|
+
command: String(command),
|
|
98151
|
+
reason: result2.reason,
|
|
98152
|
+
isComplex: false
|
|
98153
|
+
});
|
|
98154
|
+
return result2;
|
|
97912
98155
|
}
|
|
97913
98156
|
const commandIsComplex = isComplexCommand(command);
|
|
97914
98157
|
if (commandIsComplex) {
|
|
@@ -97916,18 +98159,31 @@ var init_bashPermissions = __esm({
|
|
|
97916
98159
|
}
|
|
97917
98160
|
const parsed = parseCommand(command);
|
|
97918
98161
|
if (parsed.error) {
|
|
97919
|
-
|
|
98162
|
+
const result2 = {
|
|
97920
98163
|
allowed: false,
|
|
97921
98164
|
reason: parsed.error,
|
|
97922
98165
|
command
|
|
97923
98166
|
};
|
|
98167
|
+
this.recordBashEvent("permission.denied", {
|
|
98168
|
+
command,
|
|
98169
|
+
reason: result2.reason,
|
|
98170
|
+
isComplex: false,
|
|
98171
|
+
parseError: true
|
|
98172
|
+
});
|
|
98173
|
+
return result2;
|
|
97924
98174
|
}
|
|
97925
98175
|
if (!parsed.command) {
|
|
97926
|
-
|
|
98176
|
+
const result2 = {
|
|
97927
98177
|
allowed: false,
|
|
97928
98178
|
reason: "No valid command found",
|
|
97929
98179
|
command
|
|
97930
98180
|
};
|
|
98181
|
+
this.recordBashEvent("permission.denied", {
|
|
98182
|
+
command,
|
|
98183
|
+
reason: result2.reason,
|
|
98184
|
+
isComplex: false
|
|
98185
|
+
});
|
|
98186
|
+
return result2;
|
|
97931
98187
|
}
|
|
97932
98188
|
if (this.debug) {
|
|
97933
98189
|
console.log(`[BashPermissions] Checking simple command: "${command}"`);
|
|
@@ -97935,22 +98191,37 @@ var init_bashPermissions = __esm({
|
|
|
97935
98191
|
}
|
|
97936
98192
|
if (matchesAnyPattern(parsed, this.denyPatterns)) {
|
|
97937
98193
|
const matchedPatterns = this.denyPatterns.filter((pattern) => matchesPattern(parsed, pattern));
|
|
97938
|
-
|
|
98194
|
+
const result2 = {
|
|
97939
98195
|
allowed: false,
|
|
97940
98196
|
reason: `Command matches deny pattern: ${matchedPatterns[0]}`,
|
|
97941
98197
|
command,
|
|
97942
98198
|
parsed,
|
|
97943
98199
|
matchedPatterns
|
|
97944
98200
|
};
|
|
98201
|
+
this.recordBashEvent("permission.denied", {
|
|
98202
|
+
command,
|
|
98203
|
+
parsedCommand: parsed.command,
|
|
98204
|
+
reason: "matches_deny_pattern",
|
|
98205
|
+
matchedPattern: matchedPatterns[0],
|
|
98206
|
+
isComplex: false
|
|
98207
|
+
});
|
|
98208
|
+
return result2;
|
|
97945
98209
|
}
|
|
97946
98210
|
if (this.allowPatterns.length > 0) {
|
|
97947
98211
|
if (!matchesAnyPattern(parsed, this.allowPatterns)) {
|
|
97948
|
-
|
|
98212
|
+
const result2 = {
|
|
97949
98213
|
allowed: false,
|
|
97950
98214
|
reason: "Command not in allow list",
|
|
97951
98215
|
command,
|
|
97952
98216
|
parsed
|
|
97953
98217
|
};
|
|
98218
|
+
this.recordBashEvent("permission.denied", {
|
|
98219
|
+
command,
|
|
98220
|
+
parsedCommand: parsed.command,
|
|
98221
|
+
reason: "not_in_allow_list",
|
|
98222
|
+
isComplex: false
|
|
98223
|
+
});
|
|
98224
|
+
return result2;
|
|
97954
98225
|
}
|
|
97955
98226
|
}
|
|
97956
98227
|
const result = {
|
|
@@ -97962,6 +98233,11 @@ var init_bashPermissions = __esm({
|
|
|
97962
98233
|
if (this.debug) {
|
|
97963
98234
|
console.log(`[BashPermissions] ALLOWED - command passed all checks`);
|
|
97964
98235
|
}
|
|
98236
|
+
this.recordBashEvent("permission.allowed", {
|
|
98237
|
+
command,
|
|
98238
|
+
parsedCommand: parsed.command,
|
|
98239
|
+
isComplex: false
|
|
98240
|
+
});
|
|
97965
98241
|
return result;
|
|
97966
98242
|
}
|
|
97967
98243
|
/**
|
|
@@ -97985,13 +98261,20 @@ var init_bashPermissions = __esm({
|
|
|
97985
98261
|
if (this.debug) {
|
|
97986
98262
|
console.log(`[BashPermissions] DENIED - matches complex deny pattern: ${pattern}`);
|
|
97987
98263
|
}
|
|
97988
|
-
|
|
98264
|
+
const result = {
|
|
97989
98265
|
allowed: false,
|
|
97990
98266
|
reason: `Command matches deny pattern: ${pattern}`,
|
|
97991
98267
|
command,
|
|
97992
98268
|
isComplex: true,
|
|
97993
98269
|
matchedPatterns: [pattern]
|
|
97994
98270
|
};
|
|
98271
|
+
this.recordBashEvent("permission.denied", {
|
|
98272
|
+
command,
|
|
98273
|
+
reason: "matches_deny_pattern",
|
|
98274
|
+
matchedPattern: pattern,
|
|
98275
|
+
isComplex: true
|
|
98276
|
+
});
|
|
98277
|
+
return result;
|
|
97995
98278
|
}
|
|
97996
98279
|
}
|
|
97997
98280
|
for (const pattern of complexAllowPatterns) {
|
|
@@ -97999,17 +98282,28 @@ var init_bashPermissions = __esm({
|
|
|
97999
98282
|
if (this.debug) {
|
|
98000
98283
|
console.log(`[BashPermissions] ALLOWED - matches complex allow pattern: ${pattern}`);
|
|
98001
98284
|
}
|
|
98002
|
-
|
|
98285
|
+
const result = {
|
|
98003
98286
|
allowed: true,
|
|
98004
98287
|
command,
|
|
98005
98288
|
isComplex: true,
|
|
98006
98289
|
matchedPattern: pattern
|
|
98007
98290
|
};
|
|
98291
|
+
this.recordBashEvent("permission.allowed", {
|
|
98292
|
+
command,
|
|
98293
|
+
matchedPattern: pattern,
|
|
98294
|
+
isComplex: true
|
|
98295
|
+
});
|
|
98296
|
+
return result;
|
|
98008
98297
|
}
|
|
98009
98298
|
}
|
|
98010
98299
|
if (this.debug) {
|
|
98011
98300
|
console.log(`[BashPermissions] DENIED - no matching complex pattern found`);
|
|
98012
98301
|
}
|
|
98302
|
+
this.recordBashEvent("permission.denied", {
|
|
98303
|
+
command,
|
|
98304
|
+
reason: "no_matching_complex_pattern",
|
|
98305
|
+
isComplex: true
|
|
98306
|
+
});
|
|
98013
98307
|
return {
|
|
98014
98308
|
allowed: false,
|
|
98015
98309
|
reason: 'Complex shell commands require explicit allow patterns (e.g., "cd * && git *")',
|
|
@@ -98308,14 +98602,16 @@ var init_bash = __esm({
|
|
|
98308
98602
|
bashConfig = {},
|
|
98309
98603
|
debug = false,
|
|
98310
98604
|
cwd,
|
|
98311
|
-
allowedFolders = []
|
|
98605
|
+
allowedFolders = [],
|
|
98606
|
+
tracer = null
|
|
98312
98607
|
} = options;
|
|
98313
98608
|
const permissionChecker = new BashPermissionChecker({
|
|
98314
98609
|
allow: bashConfig.allow,
|
|
98315
98610
|
deny: bashConfig.deny,
|
|
98316
98611
|
disableDefaultAllow: bashConfig.disableDefaultAllow,
|
|
98317
98612
|
disableDefaultDeny: bashConfig.disableDefaultDeny,
|
|
98318
|
-
debug
|
|
98613
|
+
debug,
|
|
98614
|
+
tracer
|
|
98319
98615
|
});
|
|
98320
98616
|
const getDefaultWorkingDirectory = () => {
|
|
98321
98617
|
if (bashConfig.workingDirectory) {
|
|
@@ -99059,6 +99355,28 @@ var init_simpleTelemetry = __esm({
|
|
|
99059
99355
|
...data2
|
|
99060
99356
|
});
|
|
99061
99357
|
}
|
|
99358
|
+
/**
|
|
99359
|
+
* Record MCP (Model Context Protocol) events
|
|
99360
|
+
* Tracks server connections, tool discovery, method filtering, and tool execution
|
|
99361
|
+
*/
|
|
99362
|
+
recordMcpEvent(eventType, data2 = {}) {
|
|
99363
|
+
if (!this.isEnabled()) return;
|
|
99364
|
+
this.addEvent(`mcp.${eventType}`, {
|
|
99365
|
+
"session.id": this.sessionId,
|
|
99366
|
+
...data2
|
|
99367
|
+
});
|
|
99368
|
+
}
|
|
99369
|
+
/**
|
|
99370
|
+
* Record bash tool events
|
|
99371
|
+
* Tracks command permission checks, allowed/denied commands, and execution
|
|
99372
|
+
*/
|
|
99373
|
+
recordBashEvent(eventType, data2 = {}) {
|
|
99374
|
+
if (!this.isEnabled()) return;
|
|
99375
|
+
this.addEvent(`bash.${eventType}`, {
|
|
99376
|
+
"session.id": this.sessionId,
|
|
99377
|
+
...data2
|
|
99378
|
+
});
|
|
99379
|
+
}
|
|
99062
99380
|
setAttributes(attributes) {
|
|
99063
99381
|
if (this.telemetry && this.telemetry.enableConsole) {
|
|
99064
99382
|
console.log("[Attributes]", attributes);
|
package/index.d.ts
CHANGED
|
@@ -49,9 +49,11 @@ export interface ProbeAgentOptions {
|
|
|
49
49
|
disableMermaidValidation?: boolean;
|
|
50
50
|
/** Disable automatic JSON validation and fixing (prevents infinite recursion in JsonFixingAgent) */
|
|
51
51
|
disableJsonValidation?: boolean;
|
|
52
|
-
/** Enable agent skills discovery and activation */
|
|
52
|
+
/** Enable agent skills discovery and activation (disabled by default) */
|
|
53
|
+
allowSkills?: boolean;
|
|
54
|
+
/** @deprecated Use allowSkills instead. Enable agent skills discovery and activation (disabled by default) */
|
|
53
55
|
enableSkills?: boolean;
|
|
54
|
-
/** Disable agent skills (overrides enableSkills) */
|
|
56
|
+
/** Disable agent skills (overrides allowSkills/enableSkills) */
|
|
55
57
|
disableSkills?: boolean;
|
|
56
58
|
/** Skill directories to scan relative to repo root */
|
|
57
59
|
skillDirs?: string[];
|
package/package.json
CHANGED
|
@@ -68,9 +68,11 @@ export interface ProbeAgentOptions {
|
|
|
68
68
|
disableMermaidValidation?: boolean;
|
|
69
69
|
/** Disable automatic JSON validation and fixing (prevents infinite recursion in JsonFixingAgent) */
|
|
70
70
|
disableJsonValidation?: boolean;
|
|
71
|
-
/** Enable agent skills discovery and activation */
|
|
71
|
+
/** Enable agent skills discovery and activation (disabled by default) */
|
|
72
|
+
allowSkills?: boolean;
|
|
73
|
+
/** @deprecated Use allowSkills instead. Enable agent skills discovery and activation (disabled by default) */
|
|
72
74
|
enableSkills?: boolean;
|
|
73
|
-
/** Disable agent skills (overrides enableSkills) */
|
|
75
|
+
/** Disable agent skills (overrides allowSkills/enableSkills) */
|
|
74
76
|
disableSkills?: boolean;
|
|
75
77
|
/** Skill directories to scan relative to repo root */
|
|
76
78
|
skillDirs?: string[];
|