agent-security-scanner-mcp 2.0.4 → 2.0.6

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 CHANGED
@@ -1,5 +1,11 @@
1
1
  # agent-security-scanner-mcp
2
2
 
3
+ [![npm version](https://img.shields.io/npm/v/agent-security-scanner-mcp.svg)](https://www.npmjs.com/package/agent-security-scanner-mcp)
4
+ [![npm downloads](https://img.shields.io/npm/dm/agent-security-scanner-mcp.svg)](https://www.npmjs.com/package/agent-security-scanner-mcp)
5
+ [![npm total downloads](https://img.shields.io/npm/dt/agent-security-scanner-mcp.svg)](https://www.npmjs.com/package/agent-security-scanner-mcp)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
+ [![GitHub stars](https://img.shields.io/github/stars/sinewaveai/agent-security-scanner-mcp.svg)](https://github.com/sinewaveai/agent-security-scanner-mcp/stargazers)
8
+
3
9
  A powerful MCP (Model Context Protocol) server for real-time security vulnerability scanning. Integrates with Claude Desktop, Claude Code, OpenCode.ai, Kilo Code, and any MCP-compatible client to automatically detect and fix security issues as you code.
4
10
 
5
11
  AI coding agents like **Claude Code**, **Cursor**, **Windsurf**, **Cline**, **Copilot**, and **Devin** are transforming software development. But they introduce attack surfaces that traditional security tools weren't designed to handle:
@@ -14,22 +20,35 @@ AI coding agents like **Claude Code**, **Cursor**, **Windsurf**, **Cline**, **Co
14
20
 
15
21
  **359 Semgrep-aligned security rules | 120 auto-fix templates | 6 ecosystems indexed | AI Agent prompt security**
16
22
 
17
- ## What's New in v2.0.2
23
+ ## Installation
18
24
 
19
- - **Prompt injection detection overhaul** - Detection rate improved from 33% to 80%+
20
- - **Code block scanning** - Detects attacks hidden inside markdown code blocks
21
- - **Base64 decode-and-rescan** - Runtime decoding of encoded payloads
22
- - **Security fix** - Command injection vulnerability patched (execFileSync)
23
- - **Test suite** - 51 vitest tests with GitHub Actions CI
24
- - **Bug fixes** - Package hallucination detection now correctly uses bloom filters
25
+ ### Default Package (Lightweight - 2.7 MB)
25
26
 
26
- ## What's New in v2.0.0
27
+ ```bash
28
+ npm install -g agent-security-scanner-mcp
29
+ ```
27
30
 
28
- - **AST-based analysis** - tree-sitter powered parsing for 12 languages with higher accuracy
29
- - **Taint analysis** - Track data flow from sources (user input) to sinks (dangerous functions)
30
- - **Graceful fallback** - Works out-of-the-box with regex; enhanced detection when tree-sitter installed
31
- - **Metavariable patterns** - Semgrep-style `$VAR` patterns for structural matching
32
- - **Doctor command upgrade** - Now checks for AST engine availability
31
+ Includes hallucination detection for: **PyPI, RubyGems, crates.io, pub.dev, CPAN, raku.land** (1M+ packages)
32
+
33
+ ### Full Package (With npm - 8.7 MB)
34
+
35
+ If you need **npm/JavaScript hallucination detection** (3.3M packages):
36
+
37
+ ```bash
38
+ npm install -g agent-security-scanner-mcp-full
39
+ ```
40
+
41
+ Or run directly with npx:
42
+
43
+ ```bash
44
+ npx agent-security-scanner-mcp
45
+ ```
46
+
47
+ ### Prerequisites
48
+
49
+ - **Node.js >= 18.0.0** (required)
50
+ - **Python 3.x** (required for the analyzer engine)
51
+ - **PyYAML** (`pip install pyyaml`) — required for rule loading
33
52
 
34
53
  ### Enhanced Detection with tree-sitter (Optional)
35
54
 
@@ -44,6 +63,40 @@ The scanner works without tree-sitter using regex-based detection, but AST analy
44
63
  - Taint tracking across function boundaries
45
64
  - Language-aware pattern matching
46
65
 
66
+ ---
67
+
68
+ ## What's New in v2.0.6
69
+
70
+ - **fix_security reliability overhaul** - Fixes now validated before applying to prevent malformed code output
71
+ - **Python f-string SQL injection** - Now detects AND fixes `f"SELECT...{var}"` patterns
72
+ - **Python .format() SQL injection** - Now fixes `"SELECT...{}".format(var)` patterns
73
+ - **JavaScript template literal SQL injection** - Now fixes `` `SELECT...${var}` `` patterns
74
+ - **Multi-pattern fix engine** - Each vulnerability type can have multiple language-specific fix patterns
75
+ - **Syntax validation** - Rejects fixes with unbalanced quotes, brackets, or obvious syntax errors
76
+
77
+ ## What's New in v2.0.5
78
+
79
+ - **Claude Code per-project fix** - `init claude-code` now uses `claude mcp add` CLI for reliable per-project configuration
80
+ - **Doctor command upgrade** - Now correctly checks Claude Code config via `claude mcp list` instead of file-based check
81
+ - **Documentation update** - README clarifies Claude Code's per-project MCP storage (`~/.claude.json` vs `~/.claude/settings.json`)
82
+
83
+ ## What's New in v2.0.2
84
+
85
+ - **Prompt injection detection overhaul** - Detection rate improved from 33% to 80%+
86
+ - **Code block scanning** - Detects attacks hidden inside markdown code blocks
87
+ - **Base64 decode-and-rescan** - Runtime decoding of encoded payloads
88
+ - **Security fix** - Command injection vulnerability patched (execFileSync)
89
+ - **Test suite** - 51 vitest tests with GitHub Actions CI
90
+ - **Bug fixes** - Package hallucination detection now correctly uses bloom filters
91
+
92
+ ## What's New in v2.0.0
93
+
94
+ - **AST-based analysis** - tree-sitter powered parsing for 12 languages with higher accuracy
95
+ - **Taint analysis** - Track data flow from sources (user input) to sinks (dangerous functions)
96
+ - **Graceful fallback** - Works out-of-the-box with regex; enhanced detection when tree-sitter installed
97
+ - **Metavariable patterns** - Semgrep-style `$VAR` patterns for structural matching
98
+ - **Doctor command upgrade** - Now checks for AST engine availability
99
+
47
100
  ## What's New in v1.5.0
48
101
 
49
102
  - **92% smaller package** - Only 2.7 MB (down from 84 MB)
@@ -76,37 +129,6 @@ The scanner works without tree-sitter using regex-based detection, but AST analy
76
129
  - **CWE & OWASP mapped** - Every rule includes CWE and OWASP references
77
130
  - **Hallucination detection** - Detect AI-invented package names across 7 ecosystems via bloom filters and text lists
78
131
 
79
- ## Installation
80
-
81
- ### Default Package (Lightweight - 2.7 MB)
82
-
83
- ```bash
84
- npm install -g agent-security-scanner-mcp
85
- ```
86
-
87
- Includes hallucination detection for: **PyPI, RubyGems, crates.io, pub.dev, CPAN, raku.land** (1M+ packages)
88
-
89
- ### Full Package (With npm - 8.7 MB)
90
-
91
- If you need **npm/JavaScript hallucination detection** (3.3M packages):
92
-
93
- ```bash
94
- npm install -g agent-security-scanner-mcp-full
95
- ```
96
-
97
- Or run directly with npx:
98
-
99
- ```bash
100
- npx agent-security-scanner-mcp
101
- ```
102
-
103
- ## Prerequisites
104
-
105
- - **Node.js >= 18.0.0** (required)
106
- - **Python 3.x** (required for the analyzer engine)
107
- - **PyYAML** (`pip install pyyaml`) — required for rule loading
108
- - **tree-sitter** (optional, for enhanced AST-based detection): `pip install tree-sitter tree-sitter-python tree-sitter-javascript`
109
-
110
132
  ## Works With All Major AI Coding Tools
111
133
 
112
134
  | Tool | Integration | Status |
@@ -139,12 +161,14 @@ npx agent-security-scanner-mcp init cursor
139
161
  npx agent-security-scanner-mcp init claude-desktop
140
162
  npx agent-security-scanner-mcp init windsurf
141
163
  npx agent-security-scanner-mcp init cline
142
- npx agent-security-scanner-mcp init claude-code
164
+ npx agent-security-scanner-mcp init claude-code # Run in each project folder!
143
165
  npx agent-security-scanner-mcp init kilo-code
144
166
  npx agent-security-scanner-mcp init opencode
145
167
  npx agent-security-scanner-mcp init cody
146
168
  ```
147
169
 
170
+ > **Claude Code users:** Run `init claude-code` in **each project folder** where you want security scanning. Claude Code uses per-project MCP configuration.
171
+
148
172
  **Interactive mode** — just run `init` with no client to pick from a list:
149
173
 
150
174
  ```bash
@@ -234,7 +258,17 @@ Add to your `claude_desktop_config.json`:
234
258
 
235
259
  ### Claude Code
236
260
 
237
- Add to your MCP settings (`~/.claude/settings.json`):
261
+ **Important:** Claude Code stores MCP servers **per-project** in `~/.claude.json`, not in `~/.claude/settings.json`. Use the CLI to configure:
262
+
263
+ ```bash
264
+ # Run this in EACH project folder where you want security scanning:
265
+ claude mcp add security-scanner -- npx -y agent-security-scanner-mcp
266
+
267
+ # Verify it's configured:
268
+ claude mcp list
269
+ ```
270
+
271
+ **Global configuration** (applies to new projects only) — add to `~/.claude/settings.json`:
238
272
 
239
273
  ```json
240
274
  {
@@ -247,6 +281,8 @@ Add to your MCP settings (`~/.claude/settings.json`):
247
281
  }
248
282
  ```
249
283
 
284
+ > **Note:** Existing projects won't automatically inherit from the global config. You must run `claude mcp add` in each project folder, or use the automated init command which handles this for you.
285
+
250
286
  ### OpenCode.ai
251
287
 
252
288
  Add to your `opencode.jsonc` configuration file:
package/index.js CHANGED
@@ -28,7 +28,73 @@ const FIX_TEMPLATES = {
28
28
  // ===========================================
29
29
  "sql-injection": {
30
30
  description: "Use parameterized queries instead of string concatenation",
31
- fix: (line) => line.replace(/["']([^"']*)\s*["']\s*\+\s*(\w+)/, '"$1?", [$2]')
31
+ patterns: [
32
+ // Python f-strings: cursor.execute(f"SELECT * FROM users WHERE id = {user_id}")
33
+ {
34
+ match: /f["'].*(?:SELECT|INSERT|UPDATE|DELETE).*\{(\w+)\}.*["']/i,
35
+ fix: (line) => {
36
+ // Extract the query and variable
37
+ const match = line.match(/(\w+\.(?:execute|query|run))\s*\(\s*f(["'])(.*?)(?:SELECT|INSERT|UPDATE|DELETE)(.*?)\{(\w+)\}(.*?)\2/i);
38
+ if (match) {
39
+ const [, method, quote, prefix, queryStart, varName, suffix] = match;
40
+ // Reconstruct as parameterized query
41
+ const cleanPrefix = prefix.replace(/\{[^}]+\}/g, '?');
42
+ const cleanSuffix = suffix.replace(/\{[^}]+\}/g, '?');
43
+ return line.replace(
44
+ /f(["']).*\1/,
45
+ `"${cleanPrefix}${queryStart.trim().toUpperCase()}${cleanSuffix}?", (${varName},)`
46
+ );
47
+ }
48
+ // Simpler fallback for f-strings
49
+ return line.replace(/f(["'])(.*?)\{(\w+)\}(.*?)\1/, '"$2?$4", ($3,)');
50
+ },
51
+ languages: ['python']
52
+ },
53
+ // Python .format(): "SELECT ... WHERE id = {}".format(user_id)
54
+ {
55
+ match: /["'].*(?:SELECT|INSERT|UPDATE|DELETE).*\{\}.*["']\.format\s*\(/i,
56
+ fix: (line) => {
57
+ return line.replace(
58
+ /(["'])(.*?)\{\}(.*?)\1\.format\s*\(\s*(\w+)\s*\)/,
59
+ '"$2?$3", [$4]'
60
+ );
61
+ },
62
+ languages: ['python']
63
+ },
64
+ // Python % formatting: "SELECT ... WHERE id = %s" % user_id
65
+ {
66
+ match: /["'].*(?:SELECT|INSERT|UPDATE|DELETE).*%s.*["']\s*%\s*\(/i,
67
+ fix: (line) => {
68
+ return line.replace(
69
+ /(["'])(.*?)%s(.*?)\1\s*%\s*\(\s*(\w+)\s*,?\s*\)/,
70
+ '"$2?$3", [$4]'
71
+ );
72
+ },
73
+ languages: ['python']
74
+ },
75
+ // JS template literals: `SELECT * FROM users WHERE id = ${userId}`
76
+ {
77
+ match: /`.*(?:SELECT|INSERT|UPDATE|DELETE).*\$\{.*\}.*`/i,
78
+ fix: (line) => {
79
+ return line.replace(
80
+ /`(.*?)\$\{(\w+)\}(.*?)`/,
81
+ '"$1?$3", [$2]'
82
+ );
83
+ },
84
+ languages: ['javascript', 'typescript']
85
+ },
86
+ // Simple concatenation (no quotes inside): "SELECT ... WHERE id = " + userId
87
+ {
88
+ match: /["'](?:SELECT|INSERT|UPDATE|DELETE)[^"']+["']\s*\+\s*\w+(?!\s*\+\s*["'])/i,
89
+ fix: (line) => {
90
+ return line.replace(
91
+ /(["'])((?:SELECT|INSERT|UPDATE|DELETE)[^"']+)\1\s*\+\s*(\w+)/i,
92
+ '"$2?", [$3]'
93
+ );
94
+ },
95
+ languages: ['javascript', 'python', 'java', 'go', 'ruby', 'php']
96
+ }
97
+ ]
32
98
  },
33
99
  "nosql-injection": {
34
100
  description: "Sanitize MongoDB query inputs",
@@ -765,17 +831,96 @@ function runAnalyzer(filePath) {
765
831
  }
766
832
  }
767
833
 
834
+ // Validate that a fix produces valid syntax
835
+ function validateFix(original, fixed, language) {
836
+ // Rule 1: Fix must be different from original
837
+ if (fixed === original || !fixed) {
838
+ return { valid: false, reason: 'no_change' };
839
+ }
840
+
841
+ // Rule 2: Balanced quotes (ignore escaped quotes)
842
+ const unescaped = fixed.replace(/\\["'`]/g, '');
843
+ const singleQuotes = (unescaped.match(/'/g) || []).length;
844
+ const doubleQuotes = (unescaped.match(/"/g) || []).length;
845
+ const backticks = (unescaped.match(/`/g) || []).length;
846
+ if (singleQuotes % 2 !== 0 || doubleQuotes % 2 !== 0 || backticks % 2 !== 0) {
847
+ return { valid: false, reason: 'unbalanced_quotes' };
848
+ }
849
+
850
+ // Rule 3: Balanced brackets
851
+ const brackets = { '(': 0, '[': 0, '{': 0 };
852
+ const closers = { ')': '(', ']': '[', '}': '{' };
853
+ for (const char of unescaped) {
854
+ if (brackets[char] !== undefined) brackets[char]++;
855
+ if (closers[char]) brackets[closers[char]]--;
856
+ }
857
+ if (Object.values(brackets).some(v => v !== 0)) {
858
+ return { valid: false, reason: 'unbalanced_brackets' };
859
+ }
860
+
861
+ // Rule 4: No obvious syntax errors
862
+ const badPatterns = [
863
+ /""[^,\s\]);}]/, // empty string followed by unexpected char
864
+ /\+\s*[)\]}]/, // + followed by closing bracket
865
+ /,\s*\+/, // comma followed by +
866
+ /\(\s*\+/, // open paren followed by +
867
+ ];
868
+ for (const pattern of badPatterns) {
869
+ if (pattern.test(fixed)) {
870
+ return { valid: false, reason: 'syntax_error' };
871
+ }
872
+ }
873
+
874
+ return { valid: true };
875
+ }
876
+
768
877
  // Generate fix suggestion for an issue
769
878
  function generateFix(issue, line, language) {
770
879
  const ruleId = issue.ruleId.toLowerCase();
771
880
 
772
- for (const [pattern, template] of Object.entries(FIX_TEMPLATES)) {
773
- if (ruleId.includes(pattern)) {
774
- return {
775
- description: template.description,
776
- original: line,
777
- fixed: template.fix(line, language)
778
- };
881
+ for (const [templateId, template] of Object.entries(FIX_TEMPLATES)) {
882
+ if (!ruleId.includes(templateId)) continue;
883
+
884
+ // New: handle patterns array
885
+ if (template.patterns && Array.isArray(template.patterns)) {
886
+ for (const pattern of template.patterns) {
887
+ // Skip if language doesn't match
888
+ if (pattern.languages && !pattern.languages.includes(language)) {
889
+ continue;
890
+ }
891
+
892
+ // Skip if pattern doesn't match the line
893
+ if (!pattern.match.test(line)) {
894
+ continue;
895
+ }
896
+
897
+ // Try the fix
898
+ const candidate = pattern.fix(line, language);
899
+ const validation = validateFix(line, candidate, language);
900
+
901
+ if (validation.valid) {
902
+ return {
903
+ description: template.description,
904
+ original: line,
905
+ fixed: candidate
906
+ };
907
+ }
908
+ // If invalid, try next pattern
909
+ }
910
+ }
911
+
912
+ // Fallback: old-style single fix function (backward compatible)
913
+ if (template.fix && typeof template.fix === 'function') {
914
+ const candidate = template.fix(line, language);
915
+ const validation = validateFix(line, candidate, language);
916
+
917
+ if (validation.valid) {
918
+ return {
919
+ description: template.description,
920
+ original: line,
921
+ fixed: candidate
922
+ };
923
+ }
779
924
  }
780
925
  }
781
926
 
@@ -1724,7 +1869,10 @@ const CLIENT_CONFIGS = {
1724
1869
  name: 'Claude Code',
1725
1870
  configKey: 'mcpServers',
1726
1871
  configPath: () => join(homedir(), '.claude', 'settings.json'),
1727
- buildEntry: () => ({ ...MCP_SERVER_ENTRY })
1872
+ buildEntry: () => ({ ...MCP_SERVER_ENTRY }),
1873
+ // Claude Code stores MCP config per-project in ~/.claude.json, not in settings.json
1874
+ // Use the 'claude mcp add' CLI for reliable per-project configuration
1875
+ useCliCommand: true
1728
1876
  },
1729
1877
  'cursor': {
1730
1878
  name: 'Cursor',
@@ -1843,6 +1991,91 @@ function printInitUsage() {
1843
1991
  console.log(' npx agent-security-scanner-mcp init cline --force --name my-scanner\n');
1844
1992
  }
1845
1993
 
1994
+ // Special init handler for clients that use CLI commands (e.g., Claude Code)
1995
+ async function runCliInit(client, flags) {
1996
+ const serverName = flags.name;
1997
+ const cwd = process.cwd();
1998
+
1999
+ console.log(`\n Client: ${client.name}`);
2000
+ console.log(` Project: ${cwd}`);
2001
+ console.log(` OS: ${platform()} (${process.arch})`);
2002
+ console.log(` Key: ${serverName}\n`);
2003
+
2004
+ // Check if claude CLI is available
2005
+ const claudeCheck = checkCommand('claude', ['--version']);
2006
+ if (!claudeCheck.ok) {
2007
+ console.log(' ERROR: Claude Code CLI not found.');
2008
+ console.log(' Please install Claude Code first: https://claude.ai/download\n');
2009
+ console.log(' Alternative: Use --path to write to ~/.claude/settings.json directly:\n');
2010
+ console.log(` npx agent-security-scanner-mcp init claude-code --path ~/.claude/settings.json\n`);
2011
+ process.exit(1);
2012
+ }
2013
+
2014
+ // Check if already configured for this project
2015
+ const listCheck = checkCommand('claude', ['mcp', 'list']);
2016
+ if (listCheck.ok && listCheck.output.includes(serverName)) {
2017
+ if (!flags.force) {
2018
+ console.log(` ${serverName} is already configured for this project.`);
2019
+ console.log(` Use --force to reconfigure.\n`);
2020
+ process.exit(0);
2021
+ }
2022
+ // Remove existing entry first if --force
2023
+ console.log(` Removing existing ${serverName} configuration...`);
2024
+ try {
2025
+ execFileSync('claude', ['mcp', 'remove', serverName], { encoding: 'utf-8', stdio: 'pipe' });
2026
+ } catch {
2027
+ // Ignore errors - might not exist
2028
+ }
2029
+ }
2030
+
2031
+ // Build the CLI command
2032
+ const cliArgs = ['mcp', 'add', serverName, '--', 'npx', '-y', 'agent-security-scanner-mcp'];
2033
+ const fullCommand = `claude ${cliArgs.join(' ')}`;
2034
+
2035
+ if (flags.dryRun) {
2036
+ console.log(` [dry-run] Would run: ${fullCommand}`);
2037
+ console.log(` [dry-run] In directory: ${cwd}`);
2038
+ console.log(`\n No changes made.\n`);
2039
+ process.exit(0);
2040
+ }
2041
+
2042
+ console.log(` Running: ${fullCommand}`);
2043
+ console.log(` In directory: ${cwd}\n`);
2044
+
2045
+ try {
2046
+ const result = execFileSync('claude', cliArgs, { encoding: 'utf-8', stdio: 'pipe', cwd });
2047
+ console.log(` ${result.trim()}\n`);
2048
+ } catch (e) {
2049
+ console.error(` ERROR: Failed to add MCP server.`);
2050
+ console.error(` ${e.message}\n`);
2051
+ console.log(' Alternative: Add manually to ~/.claude/settings.json:\n');
2052
+ console.log(` {
2053
+ "mcpServers": {
2054
+ "${serverName}": {
2055
+ "command": "npx",
2056
+ "args": ["-y", "agent-security-scanner-mcp"]
2057
+ }
2058
+ }
2059
+ }\n`);
2060
+ process.exit(1);
2061
+ }
2062
+
2063
+ // Verify it was added
2064
+ const verifyCheck = checkCommand('claude', ['mcp', 'list']);
2065
+ if (verifyCheck.ok && verifyCheck.output.includes(serverName)) {
2066
+ console.log(` ✓ Successfully configured ${serverName} for this project!\n`);
2067
+ } else {
2068
+ console.log(` ⚠ Configuration may have succeeded but verification failed.`);
2069
+ console.log(` Run 'claude mcp list' to check.\n`);
2070
+ }
2071
+
2072
+ console.log(` Next steps:`);
2073
+ console.log(` 1. Restart Claude Code in this folder`);
2074
+ console.log(` 2. Verify by asking: "What MCP tools do you have?"`);
2075
+ console.log(` 3. Test: "Scan this file for security issues"\n`);
2076
+ console.log(` Note: Run this command in each project folder where you want security scanning.\n`);
2077
+ }
2078
+
1846
2079
  async function runInit(flags) {
1847
2080
  let clientName = flags.client;
1848
2081
 
@@ -1863,6 +2096,12 @@ async function runInit(flags) {
1863
2096
  process.exit(1);
1864
2097
  }
1865
2098
 
2099
+ // Special handling for clients that use CLI commands (like Claude Code)
2100
+ if (client.useCliCommand && !flags.path) {
2101
+ await runCliInit(client, flags);
2102
+ return;
2103
+ }
2104
+
1866
2105
  const configPath = flags.path || client.configPath();
1867
2106
  const serverName = flags.name;
1868
2107
  const entry = client.buildEntry();
@@ -2067,6 +2306,53 @@ async function runDoctor(flags) {
2067
2306
  console.log('\n Client Configurations');
2068
2307
 
2069
2308
  for (const [key, client] of Object.entries(CLIENT_CONFIGS)) {
2309
+ // Special handling for Claude Code - uses per-project config via CLI
2310
+ if (client.useCliCommand) {
2311
+ const claudeCheck = checkCommand('claude', ['--version']);
2312
+ if (!claudeCheck.ok) {
2313
+ console.log(` \u2014 ${client.name.padEnd(20)} not installed (claude CLI not found)`);
2314
+ continue;
2315
+ }
2316
+
2317
+ // Check if configured for current project using claude mcp list
2318
+ const listCheck = checkCommand('claude', ['mcp', 'list']);
2319
+ if (listCheck.ok && listCheck.output) {
2320
+ const output = listCheck.output.toLowerCase();
2321
+ const hasScanner = output.includes('security-scanner') ||
2322
+ output.includes('agentic-security') ||
2323
+ output.includes('agent-security-scanner');
2324
+ if (hasScanner) {
2325
+ // Extract the actual server name from output
2326
+ let serverName = 'security-scanner';
2327
+ if (output.includes('agentic-security')) serverName = 'agentic-security';
2328
+ console.log(` \u2713 ${client.name.padEnd(20)} configured (${serverName})`);
2329
+ } else if (output.includes('no mcp servers configured')) {
2330
+ console.log(` \u2717 ${client.name.padEnd(20)} not configured for this project`);
2331
+ if (fix) {
2332
+ try {
2333
+ execFileSync('claude', ['mcp', 'add', 'security-scanner', '--', 'npx', '-y', 'agent-security-scanner-mcp'],
2334
+ { encoding: 'utf-8', stdio: 'pipe' });
2335
+ console.log(` \u2713 Fixed: added security-scanner via claude mcp add`);
2336
+ fixed++;
2337
+ } catch {
2338
+ console.log(` \u2717 Auto-fix failed. Run: npx agent-security-scanner-mcp init claude-code`);
2339
+ issues++;
2340
+ }
2341
+ } else {
2342
+ console.log(` Fix: npx agent-security-scanner-mcp init claude-code`);
2343
+ issues++;
2344
+ }
2345
+ } else {
2346
+ console.log(` \u2717 ${client.name.padEnd(20)} entry missing from project config`);
2347
+ console.log(` Fix: npx agent-security-scanner-mcp init claude-code`);
2348
+ issues++;
2349
+ }
2350
+ } else {
2351
+ console.log(` \u26a0 ${client.name.padEnd(20)} could not check config (run 'claude mcp list' manually)`);
2352
+ }
2353
+ continue;
2354
+ }
2355
+
2070
2356
  let configPath;
2071
2357
  try { configPath = client.configPath(); } catch { continue; }
2072
2358
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-security-scanner-mcp",
3
- "version": "2.0.4",
3
+ "version": "2.0.6",
4
4
  "mcpName": "io.github.sinewaveai/agent-security-scanner-mcp",
5
5
  "description": "Security scanner MCP server for AI coding agents. Prompt injection firewall, package hallucination detection (4.3M+ packages), 359 vulnerability rules with auto-fix. For Claude Code, Cursor, Windsurf, Cline.",
6
6
  "main": "index.js",
@@ -23630,7 +23630,6 @@ cinnog
23630
23630
  cint
23631
23631
  cio
23632
23632
  cio-api
23633
- cioqLsBmIV3xEUGI6XQRx411QEIZwwaDh7c
23634
23633
  cip
23635
23634
  cip_rust
23636
23635
  cipepser-bicycle-book-wordcount