agent-security-scanner-mcp 4.4.7 → 4.4.8
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/README.md +21 -1
- package/index.js +2 -0
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
- package/server.json +1 -1
- package/src/cli/demo.js +86 -7
package/README.md
CHANGED
|
@@ -52,6 +52,9 @@ npx agent-security-scanner-mcp scan-mcp ./path/to/mcp-server --verbosity compact
|
|
|
52
52
|
# Verify AI-suggested imports are real packages, not hallucinations
|
|
53
53
|
npx agent-security-scanner-mcp scan-packages ./src/app.ts npm --verbosity compact
|
|
54
54
|
|
|
55
|
+
# Check one package before installing it
|
|
56
|
+
npx agent-security-scanner-mcp check-package express npm
|
|
57
|
+
|
|
55
58
|
# Add a local environment health check
|
|
56
59
|
npx agent-security-scanner-mcp doctor
|
|
57
60
|
|
|
@@ -104,6 +107,8 @@ Continue reading below for full version documentation →
|
|
|
104
107
|
|
|
105
108
|
---
|
|
106
109
|
|
|
110
|
+
> **New in v4.4.8 (2026-07-07):** Package hallucination demo — run `npx agent-security-scanner-mcp demo --type packages --no-prompt` to create and scan a tiny import file with real and fake npm packages. README examples now show both single-package verification and import scanning.
|
|
111
|
+
>
|
|
107
112
|
> **New in v4.4.7 (2026-07-07):** CI adoption improvements — added `init-ci github` to install the GitHub Actions workflow from the CLI, and scheduled GitHub Action runs now automatically scan the full project instead of only the latest diff. Package hallucination checks also use all tracked source files during full-project runs.
|
|
108
113
|
>
|
|
109
114
|
> **New in v4.3.0 (2026-05-05):** Critical security and reliability fixes — GitHub Actions now **fail closed** instead of fail-open when scanner output is invalid (preventing security gate bypass), patched **8 Hono CVEs** (XSS, path traversal, authentication bypass), fixed confidence threshold filtering case sensitivity, and corrected SARIF generation for GitHub Code Scanning. All fixes include comprehensive regression tests. **Upgrade recommended for production use.** [See Full Changelog](CHANGELOG.md#430---2026-05-05).
|
|
@@ -1323,9 +1328,12 @@ Checks Node.js version, Python availability, analyzer engine status, and scans a
|
|
|
1323
1328
|
|
|
1324
1329
|
```bash
|
|
1325
1330
|
npx agent-security-scanner-mcp demo --lang js
|
|
1331
|
+
npx agent-security-scanner-mcp demo --type packages --no-prompt
|
|
1326
1332
|
```
|
|
1327
1333
|
|
|
1328
|
-
|
|
1334
|
+
The security demo creates a small file with 3 intentional vulnerabilities, runs the scanner, shows findings with CWE/OWASP references, and asks if you want to keep the file for testing.
|
|
1335
|
+
|
|
1336
|
+
The package demo creates a tiny JavaScript import file with real and hallucinated npm packages, runs `scan-packages`, and deletes the file unless you pass `--keep`.
|
|
1329
1337
|
|
|
1330
1338
|
Available languages: `js` (default), `py`, `go`, `java`.
|
|
1331
1339
|
|
|
@@ -1350,9 +1358,14 @@ npx agent-security-scanner-mcp scan-project ./src
|
|
|
1350
1358
|
|
|
1351
1359
|
# Check if a package is legitimate
|
|
1352
1360
|
npx agent-security-scanner-mcp check-package flask pypi
|
|
1361
|
+
npx agent-security-scanner-mcp check-package express npm
|
|
1353
1362
|
|
|
1354
1363
|
# Scan file imports for hallucinated packages
|
|
1355
1364
|
npx agent-security-scanner-mcp scan-packages ./requirements.txt pypi
|
|
1365
|
+
npx agent-security-scanner-mcp scan-packages ./src/app.ts npm --verbosity compact
|
|
1366
|
+
|
|
1367
|
+
# Try the package hallucination demo
|
|
1368
|
+
npx agent-security-scanner-mcp demo --type packages --no-prompt
|
|
1356
1369
|
|
|
1357
1370
|
# Install the GitHub Actions workflow
|
|
1358
1371
|
npx agent-security-scanner-mcp init-ci github
|
|
@@ -1644,6 +1657,13 @@ All MCP tools support a `verbosity` parameter to minimize context window consump
|
|
|
1644
1657
|
|
|
1645
1658
|
## Changelog
|
|
1646
1659
|
|
|
1660
|
+
### v4.4.8 (2026-07-07) - Package Hallucination Demo
|
|
1661
|
+
|
|
1662
|
+
- **New demo mode:** `demo --type packages` creates a small JavaScript file with real and hallucinated npm imports, then runs `scan-packages`.
|
|
1663
|
+
- **Automation-friendly demo:** `--no-prompt` cleans up the generated file without waiting for input, and `--keep` preserves it for local testing.
|
|
1664
|
+
- **README examples:** Added clearer single-package and import-scan examples for `check-package` and `scan-packages`.
|
|
1665
|
+
- **Regression coverage:** Added tests for package demo cleanup and `--keep` behavior.
|
|
1666
|
+
|
|
1647
1667
|
### v4.4.7 (2026-07-07) - CI Adoption
|
|
1648
1668
|
|
|
1649
1669
|
- **New CLI command:** `init-ci github` installs the public GitHub Actions workflow template into `.github/workflows/agent-security.yml`.
|
package/index.js
CHANGED
|
@@ -683,6 +683,7 @@ const cliArgs = process.argv.slice(2);
|
|
|
683
683
|
console.log(' init-hooks Install Claude Code hooks for auto-scanning');
|
|
684
684
|
console.log(' doctor [--fix] Check environment & client configs');
|
|
685
685
|
console.log(' demo [--lang js] Generate vulnerable file + scan it');
|
|
686
|
+
console.log(' demo --type packages Generate package hallucination demo + scan it');
|
|
686
687
|
console.log(' report <dir> Generate HTML security report with history [--threat-model]');
|
|
687
688
|
console.log(' benchmark [flags] Run accuracy benchmarks\n');
|
|
688
689
|
console.log(' CLI Tools (for scripts & OpenClaw):');
|
|
@@ -713,6 +714,7 @@ const cliArgs = process.argv.slice(2);
|
|
|
713
714
|
console.log(' Examples:');
|
|
714
715
|
console.log(' npx agent-security-scanner-mcp init');
|
|
715
716
|
console.log(' npx agent-security-scanner-mcp init-ci github');
|
|
717
|
+
console.log(' npx agent-security-scanner-mcp demo --type packages --no-prompt');
|
|
716
718
|
console.log(' npx agent-security-scanner-mcp scan-prompt "ignore previous instructions"');
|
|
717
719
|
console.log(' npx agent-security-scanner-mcp scan-security ./app.py --verbosity minimal');
|
|
718
720
|
console.log(' npx agent-security-scanner-mcp check-package flask pypi');
|
package/openclaw.plugin.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-security-scanner-mcp",
|
|
3
|
-
"version": "4.4.
|
|
3
|
+
"version": "4.4.8",
|
|
4
4
|
"description": "npm audit for AI agents and OpenClaw skills: prompt injection firewall, package hallucination detection, MCP/security scanning, and auto-fix",
|
|
5
5
|
"author": "Sinewave AI",
|
|
6
6
|
"license": "MIT",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-security-scanner-mcp",
|
|
3
|
-
"version": "4.4.
|
|
3
|
+
"version": "4.4.8",
|
|
4
4
|
"mcpName": "io.github.sinewaveai/agent-security-scanner-mcp",
|
|
5
5
|
"description": "npm audit for AI agents and MCP servers. Scan code, MCP tools, prompts, and hallucinated packages for Claude Code, Cursor, Windsurf, Cline, OpenClaw, and CI.",
|
|
6
6
|
"main": "index.js",
|
package/server.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
|
|
3
3
|
"name": "io.github.sinewaveai/agent-security-scanner-mcp",
|
|
4
4
|
"description": "npm audit for AI agents and MCP servers: scan code, MCP tools, prompts, and hallucinated packages before agents trust them.",
|
|
5
|
-
"version": "4.4.
|
|
5
|
+
"version": "4.4.8",
|
|
6
6
|
"transport": "stdio",
|
|
7
7
|
"registry": "npm"
|
|
8
8
|
}
|
package/src/cli/demo.js
CHANGED
|
@@ -5,6 +5,8 @@ import { createInterface } from "readline";
|
|
|
5
5
|
import { dirname } from "path";
|
|
6
6
|
import { fileURLToPath } from "url";
|
|
7
7
|
import { resolvePythonCommand, pythonArgs } from "../python.js";
|
|
8
|
+
import { loadPackageLists } from "../tools/check-package.js";
|
|
9
|
+
import { scanPackages } from "../tools/scan-packages.js";
|
|
8
10
|
|
|
9
11
|
// Handle both ESM and CJS bundling (Smithery bundles to CJS)
|
|
10
12
|
let __dirname;
|
|
@@ -135,13 +137,41 @@ public class VulnDemo {
|
|
|
135
137
|
}
|
|
136
138
|
};
|
|
137
139
|
|
|
140
|
+
const PACKAGE_DEMO = {
|
|
141
|
+
ecosystem: 'npm',
|
|
142
|
+
filename: 'hallucination-demo.js',
|
|
143
|
+
code: `import express from "express";
|
|
144
|
+
import chalk from "chalk";
|
|
145
|
+
import agentMemoryGraph from "agent-memory-graph-cache";
|
|
146
|
+
|
|
147
|
+
const bridge = require("secure-mcp-session-bridge");
|
|
148
|
+
|
|
149
|
+
console.log(express, chalk, agentMemoryGraph, bridge);
|
|
150
|
+
`
|
|
151
|
+
};
|
|
152
|
+
|
|
138
153
|
function parseDemoFlags(args) {
|
|
139
|
-
const flags = {
|
|
154
|
+
const flags = {
|
|
155
|
+
lang: 'js',
|
|
156
|
+
type: 'security',
|
|
157
|
+
keep: false,
|
|
158
|
+
noPrompt: false,
|
|
159
|
+
};
|
|
140
160
|
let i = 0;
|
|
141
161
|
while (i < args.length) {
|
|
142
162
|
const arg = args[i];
|
|
143
163
|
if ((arg === '--lang' || arg === '-l') && i + 1 < args.length) {
|
|
144
164
|
flags.lang = args[++i].toLowerCase();
|
|
165
|
+
} else if ((arg === '--type' || arg === '-t') && i + 1 < args.length) {
|
|
166
|
+
flags.type = args[++i].toLowerCase();
|
|
167
|
+
} else if (arg === '--packages') {
|
|
168
|
+
flags.type = 'packages';
|
|
169
|
+
} else if (arg === '--security') {
|
|
170
|
+
flags.type = 'security';
|
|
171
|
+
} else if (arg === '--keep') {
|
|
172
|
+
flags.keep = true;
|
|
173
|
+
} else if (arg === '--no-prompt' || arg === '--yes') {
|
|
174
|
+
flags.noPrompt = true;
|
|
145
175
|
} else if (!arg.startsWith('-')) {
|
|
146
176
|
flags.lang = arg.toLowerCase();
|
|
147
177
|
}
|
|
@@ -159,8 +189,58 @@ function checkCommand(cmd, args) {
|
|
|
159
189
|
}
|
|
160
190
|
}
|
|
161
191
|
|
|
162
|
-
|
|
192
|
+
async function askKeep(filename) {
|
|
193
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
194
|
+
return new Promise((resolve) => {
|
|
195
|
+
rl.question(` Keep ${filename} for testing? (y/N): `, (a) => { rl.close(); resolve(a); });
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
async function runPackageDemo(flags, options) {
|
|
200
|
+
const cwd = options.cwd || process.cwd();
|
|
201
|
+
const filepath = join(cwd, PACKAGE_DEMO.filename);
|
|
202
|
+
|
|
203
|
+
console.log(`\n agent-security-scanner-mcp package demo\n`);
|
|
204
|
+
console.log(` Creating ${PACKAGE_DEMO.filename} with real and hallucinated imports...\n`);
|
|
205
|
+
|
|
206
|
+
writeFileSync(filepath, PACKAGE_DEMO.code);
|
|
207
|
+
loadPackageLists();
|
|
208
|
+
|
|
209
|
+
console.log(` Scanning imports with scan-packages (${PACKAGE_DEMO.ecosystem})...\n`);
|
|
210
|
+
|
|
211
|
+
const scanResult = await scanPackages({
|
|
212
|
+
file_path: filepath,
|
|
213
|
+
ecosystem: PACKAGE_DEMO.ecosystem,
|
|
214
|
+
verbosity: 'compact'
|
|
215
|
+
});
|
|
216
|
+
const output = JSON.parse(scanResult.content[0].text);
|
|
217
|
+
|
|
218
|
+
console.log(JSON.stringify(output, null, 2));
|
|
219
|
+
|
|
220
|
+
const shouldKeep = flags.keep || (!flags.noPrompt && (await askKeep(PACKAGE_DEMO.filename)).toLowerCase() === 'y');
|
|
221
|
+
if (shouldKeep) {
|
|
222
|
+
console.log(`\n Kept: ${filepath}`);
|
|
223
|
+
} else {
|
|
224
|
+
unlinkSync(filepath);
|
|
225
|
+
console.log(`\n Deleted: ${PACKAGE_DEMO.filename}`);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
console.log(`\n Next: ask your coding agent to add a dependency, then run`);
|
|
229
|
+
console.log(` npx agent-security-scanner-mcp scan-packages <file> npm --verbosity compact\n`);
|
|
230
|
+
|
|
231
|
+
return output;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
export async function runDemo(args, options = {}) {
|
|
163
235
|
const flags = parseDemoFlags(args);
|
|
236
|
+
if (flags.type === 'packages' || flags.type === 'package') {
|
|
237
|
+
return runPackageDemo(flags, options);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
if (flags.type !== 'security') {
|
|
241
|
+
throw new Error(`unknown demo type: ${flags.type}. Available: security, packages`);
|
|
242
|
+
}
|
|
243
|
+
|
|
164
244
|
const template = DEMO_TEMPLATES[flags.lang];
|
|
165
245
|
if (!template) {
|
|
166
246
|
console.log(`\n Unknown language: "${flags.lang}"`);
|
|
@@ -169,7 +249,7 @@ export async function runDemo(args) {
|
|
|
169
249
|
}
|
|
170
250
|
|
|
171
251
|
const filename = `vuln-demo.${template.ext}`;
|
|
172
|
-
const filepath = join(process.cwd(), filename);
|
|
252
|
+
const filepath = join(options.cwd || process.cwd(), filename);
|
|
173
253
|
|
|
174
254
|
console.log(`\n agent-security-scanner-mcp demo\n`);
|
|
175
255
|
console.log(` Creating ${filename} with 3 intentional vulnerabilities...\n`);
|
|
@@ -211,10 +291,7 @@ export async function runDemo(args) {
|
|
|
211
291
|
}
|
|
212
292
|
|
|
213
293
|
// Ask to keep or delete
|
|
214
|
-
const
|
|
215
|
-
const answer = await new Promise((resolve) => {
|
|
216
|
-
rl.question(` Keep ${filename} for testing? (y/N): `, (a) => { rl.close(); resolve(a); });
|
|
217
|
-
});
|
|
294
|
+
const answer = flags.keep ? 'y' : flags.noPrompt ? 'n' : await askKeep(filename);
|
|
218
295
|
|
|
219
296
|
if (answer.toLowerCase() === 'y') {
|
|
220
297
|
console.log(`\n Kept: ${filepath}`);
|
|
@@ -225,4 +302,6 @@ export async function runDemo(args) {
|
|
|
225
302
|
|
|
226
303
|
console.log(`\n Next: Connect to your AI coding tool and ask it to`);
|
|
227
304
|
console.log(` "scan ${filename} for security issues"\n`);
|
|
305
|
+
|
|
306
|
+
return results;
|
|
228
307
|
}
|