agentaudit 3.6.0 → 3.7.0
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/cli.mjs +64 -5
- package/package.json +1 -1
package/cli.mjs
CHANGED
|
@@ -806,7 +806,9 @@ async function resolveSourceUrl(server) {
|
|
|
806
806
|
return null;
|
|
807
807
|
}
|
|
808
808
|
|
|
809
|
-
async function discoverCommand() {
|
|
809
|
+
async function discoverCommand(options = {}) {
|
|
810
|
+
const autoScan = options.scan || false;
|
|
811
|
+
|
|
810
812
|
console.log(` ${c.bold}Discovering local MCP servers...${c.reset}`);
|
|
811
813
|
console.log();
|
|
812
814
|
|
|
@@ -830,6 +832,7 @@ async function discoverCommand() {
|
|
|
830
832
|
let auditedServers = 0;
|
|
831
833
|
let unauditedServers = 0;
|
|
832
834
|
const unauditedWithUrls = [];
|
|
835
|
+
const allServersWithUrls = []; // For --scan: all servers we can scan
|
|
833
836
|
|
|
834
837
|
for (const config of configs) {
|
|
835
838
|
const servers = extractServersFromConfig(config.content);
|
|
@@ -874,20 +877,23 @@ async function discoverCommand() {
|
|
|
874
877
|
else if (server.url) sourceLabel = `${c.dim}${server.url.length > 60 ? server.url.slice(0, 57) + '...' : server.url}${c.reset}`;
|
|
875
878
|
else if (server.command) sourceLabel = `${c.dim}${[server.command, ...server.args.slice(0, 2)].join(' ')}${c.reset}`;
|
|
876
879
|
|
|
880
|
+
// Always resolve source URL (needed for --scan)
|
|
881
|
+
const resolvedUrl = await resolveSourceUrl(server);
|
|
882
|
+
|
|
877
883
|
if (regData) {
|
|
878
884
|
auditedServers++;
|
|
879
885
|
const riskScore = regData.risk_score ?? regData.latest_risk_score ?? 0;
|
|
880
886
|
const hasOfficial = regData.has_official_audit;
|
|
881
887
|
console.log(`${branch} ${c.bold}${server.name}${c.reset} ${sourceLabel}`);
|
|
882
888
|
console.log(`${pipe} ${riskBadge(riskScore)} Risk ${riskScore} ${hasOfficial ? `${c.green}✔ official${c.reset} ` : ''}${c.dim}${REGISTRY_URL}/skills/${slug}${c.reset}`);
|
|
889
|
+
if (resolvedUrl) allServersWithUrls.push({ name: server.name, sourceUrl: resolvedUrl, hasAudit: true, regData });
|
|
883
890
|
} else {
|
|
884
891
|
unauditedServers++;
|
|
885
|
-
// Resolve source URL
|
|
886
|
-
const resolvedUrl = await resolveSourceUrl(server);
|
|
887
892
|
console.log(`${branch} ${c.bold}${server.name}${c.reset} ${sourceLabel}`);
|
|
888
893
|
if (resolvedUrl) {
|
|
889
894
|
console.log(`${pipe} ${c.yellow}⚠ not audited${c.reset} ${c.dim}Run: ${c.cyan}agentaudit audit ${resolvedUrl}${c.reset}`);
|
|
890
895
|
unauditedWithUrls.push({ name: server.name, sourceUrl: resolvedUrl });
|
|
896
|
+
allServersWithUrls.push({ name: server.name, sourceUrl: resolvedUrl, hasAudit: false });
|
|
891
897
|
} else {
|
|
892
898
|
console.log(`${pipe} ${c.yellow}⚠ not audited${c.reset} ${c.dim}Source URL unknown — check the package's GitHub/npm page${c.reset}`);
|
|
893
899
|
}
|
|
@@ -909,7 +915,55 @@ async function discoverCommand() {
|
|
|
909
915
|
if (unauditedServers > 0) console.log(` ${icons.caution} ${c.yellow}${unauditedServers} not audited${c.reset}`);
|
|
910
916
|
console.log();
|
|
911
917
|
|
|
912
|
-
|
|
918
|
+
// --scan: automatically scan all servers with resolved source URLs
|
|
919
|
+
if (autoScan) {
|
|
920
|
+
const scanTargets = allServersWithUrls.filter(s => s.sourceUrl && s.sourceUrl.startsWith('http'));
|
|
921
|
+
if (scanTargets.length > 0) {
|
|
922
|
+
console.log(`${c.dim}${'─'.repeat(60)}${c.reset}`);
|
|
923
|
+
console.log(` ${c.bold}${icons.scan} Auto-scanning ${scanTargets.length} server${scanTargets.length !== 1 ? 's' : ''}...${c.reset}`);
|
|
924
|
+
console.log();
|
|
925
|
+
|
|
926
|
+
const scanResults = [];
|
|
927
|
+
for (const target of scanTargets) {
|
|
928
|
+
const result = await scanRepo(target.sourceUrl);
|
|
929
|
+
if (result) scanResults.push({ ...result, serverName: target.name });
|
|
930
|
+
}
|
|
931
|
+
|
|
932
|
+
if (scanResults.length > 1) {
|
|
933
|
+
// Print combined scan summary
|
|
934
|
+
console.log(`${c.dim}${'─'.repeat(60)}${c.reset}`);
|
|
935
|
+
console.log(` ${c.bold}Scan Summary${c.reset} ${scanResults.length} server${scanResults.length !== 1 ? 's' : ''} scanned`);
|
|
936
|
+
console.log();
|
|
937
|
+
|
|
938
|
+
let totalFindings = 0;
|
|
939
|
+
let serversWithFindings = 0;
|
|
940
|
+
|
|
941
|
+
for (const r of scanResults) {
|
|
942
|
+
const findingCount = r.findings ? r.findings.length : 0;
|
|
943
|
+
totalFindings += findingCount;
|
|
944
|
+
if (findingCount > 0) serversWithFindings++;
|
|
945
|
+
|
|
946
|
+
const status = findingCount === 0
|
|
947
|
+
? `${icons.safe} ${c.green}clean${c.reset}`
|
|
948
|
+
: `${icons.caution} ${c.yellow}${findingCount} finding${findingCount !== 1 ? 's' : ''}${c.reset}`;
|
|
949
|
+
console.log(` ${status} ${c.bold}${r.serverName || r.slug}${c.reset} ${c.dim}(${r.duration})${c.reset}`);
|
|
950
|
+
}
|
|
951
|
+
|
|
952
|
+
console.log();
|
|
953
|
+
if (serversWithFindings > 0) {
|
|
954
|
+
console.log(` ${c.yellow}${serversWithFindings}/${scanResults.length} server${scanResults.length !== 1 ? 's' : ''} with findings (${totalFindings} total)${c.reset}`);
|
|
955
|
+
console.log(` ${c.dim}Run ${c.cyan}agentaudit audit <url>${c.dim} for deep LLM analysis on flagged servers${c.reset}`);
|
|
956
|
+
} else {
|
|
957
|
+
console.log(` ${c.green}All servers passed quick scan${c.reset}`);
|
|
958
|
+
console.log(` ${c.dim}Run ${c.cyan}agentaudit audit <url>${c.dim} for thorough LLM-powered analysis${c.reset}`);
|
|
959
|
+
}
|
|
960
|
+
console.log();
|
|
961
|
+
}
|
|
962
|
+
} else {
|
|
963
|
+
console.log(` ${c.dim}No scannable source URLs found.${c.reset}`);
|
|
964
|
+
console.log();
|
|
965
|
+
}
|
|
966
|
+
} else if (unauditedServers > 0) {
|
|
913
967
|
if (unauditedWithUrls.length > 0) {
|
|
914
968
|
console.log(` ${c.dim}To audit unaudited servers:${c.reset}`);
|
|
915
969
|
for (const { name, sourceUrl } of unauditedWithUrls) {
|
|
@@ -920,6 +974,8 @@ async function discoverCommand() {
|
|
|
920
974
|
console.log(` ${c.cyan}agentaudit audit <source-url>${c.reset}`);
|
|
921
975
|
}
|
|
922
976
|
console.log();
|
|
977
|
+
console.log(` ${c.dim}Or run ${c.cyan}agentaudit discover --scan${c.dim} to auto-scan all servers${c.reset}`);
|
|
978
|
+
console.log();
|
|
923
979
|
}
|
|
924
980
|
}
|
|
925
981
|
|
|
@@ -1210,6 +1266,7 @@ async function main() {
|
|
|
1210
1266
|
console.log(` ${c.bold}Commands:${c.reset}`);
|
|
1211
1267
|
console.log();
|
|
1212
1268
|
console.log(` ${c.cyan}agentaudit discover${c.reset} Find local MCP servers + check registry`);
|
|
1269
|
+
console.log(` ${c.cyan}agentaudit discover --scan${c.reset} Discover + auto-scan all servers`);
|
|
1213
1270
|
console.log(` ${c.cyan}agentaudit scan${c.reset} <url> [url...] Quick static scan (regex, local)`);
|
|
1214
1271
|
console.log(` ${c.cyan}agentaudit audit${c.reset} <url> [url...] Deep LLM-powered security audit`);
|
|
1215
1272
|
console.log(` ${c.cyan}agentaudit check${c.reset} <name> Look up package in registry`);
|
|
@@ -1221,6 +1278,7 @@ async function main() {
|
|
|
1221
1278
|
console.log();
|
|
1222
1279
|
console.log(` ${c.bold}Examples:${c.reset}`);
|
|
1223
1280
|
console.log(` agentaudit discover`);
|
|
1281
|
+
console.log(` agentaudit discover --scan`);
|
|
1224
1282
|
console.log(` agentaudit scan https://github.com/owner/repo`);
|
|
1225
1283
|
console.log(` agentaudit audit https://github.com/owner/repo`);
|
|
1226
1284
|
console.log(` agentaudit check fastmcp`);
|
|
@@ -1252,7 +1310,8 @@ async function main() {
|
|
|
1252
1310
|
}
|
|
1253
1311
|
|
|
1254
1312
|
if (command === 'discover') {
|
|
1255
|
-
|
|
1313
|
+
const scanFlag = targets.includes('--scan') || targets.includes('-s');
|
|
1314
|
+
await discoverCommand({ scan: scanFlag });
|
|
1256
1315
|
return;
|
|
1257
1316
|
}
|
|
1258
1317
|
|