@modular-intelligence/code-audit
v1.0.0
Published
MCP server for SAST & dependency scanning
Downloads
84
Readme
Code Audit MCP Server
A Model Context Protocol (MCP) server providing comprehensive code security analysis and dependency auditing. Performs Static Application Security Testing (SAST), dependency vulnerability scanning, secret/credential detection, and Software Bill of Materials (SBOM) generation.
Overview
The Code Audit MCP server integrates industry-standard security scanning tools into Claude, enabling AI-assisted code auditing. It combines multiple security disciplines:
- SAST Analysis: Semgrep pattern-based vulnerability detection
- Dependency Auditing: npm, pip, and cargo vulnerability checking
- Secret Detection: Credential and API key discovery via gitleaks or trufflehog
- SBOM Generation: Software composition tracking with CycloneDX/SPDX formats
All scanning operates within a secure, path-validated environment with timeout protection.
Tools
Available Security Scanning Tools
| Tool | Purpose | Input | Output |
|------|---------|-------|--------|
| semgrep_scan | Run Semgrep SAST rules against source code | Directory path, config profile | Security findings with severity and location |
| dep_audit | Check dependencies for known vulnerabilities | Directory path, package manager | CVEs, versions, and severity levels |
| secret_scan | Detect secrets and credentials in code | Directory path, max results | Matched credential patterns with file location |
| sbom_generate | Generate Software Bill of Materials | Directory path, format | Component inventory with versions and licenses |
Tool Details
semgrep_scan
Runs Semgrep rules to identify security vulnerabilities and code quality issues using pattern-based static analysis.
Input Schema:
{
"target": "string (required)",
"config": "string (default: 'auto')",
"max_findings": "integer (default: 100, range: 1-500)"
}Parameters:
target: Absolute path to project directory to scanconfig: Semgrep configuration to use. Options include:auto(default) - Uses Semgrep's default rulesp/security-audit- Security-focused rulesetp/owasp-top-ten- OWASP Top 10 vulnerabilitiesp/cwe-top-25- CWE Top 25 weaknesses- Custom registry path or local rulefile
max_findings: Maximum number of findings to return (default: 100)
Example Request:
{
"target": "/home/user/projects/webapp",
"config": "p/security-audit",
"max_findings": 50
}Example Output:
{
"target": "/home/user/projects/webapp",
"config": "p/security-audit",
"total_findings": 12,
"findings": [
{
"rule_id": "python.django.security.injection.sql_injection.sql_string_formatting",
"severity": "HIGH",
"message": "Potential SQL injection via string formatting",
"file": "/home/user/projects/webapp/models.py",
"line_start": 45,
"line_end": 45,
"code_snippet": "User.objects.raw(f\"SELECT * FROM users WHERE id={user_id}\")"
},
{
"rule_id": "python.django.security.injection.xss.template_tag_xss",
"severity": "MEDIUM",
"message": "Potential XSS vulnerability in template",
"file": "/home/user/projects/webapp/templates/profile.html",
"line_start": 12,
"line_end": 12,
"code_snippet": "{{ user_input | safe }}"
},
{
"rule_id": "python.django.security.hardcoded_secrets.hardcoded_secret_in_settings",
"severity": "CRITICAL",
"message": "Hardcoded secret key detected",
"file": "/home/user/projects/webapp/settings.py",
"line_start": 78,
"line_end": 78,
"code_snippet": "SECRET_KEY = 'django-insecure-a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6'"
}
],
"errors": []
}dep_audit
Audits project dependencies for known security vulnerabilities. Automatically detects package manager (npm, pip, cargo) or accepts explicit specification.
Input Schema:
{
"target": "string (required)",
"package_manager": "string (default: 'auto')"
}Parameters:
target: Absolute path to project directory containing dependency filespackage_manager: Package manager to audit. Options:auto(default) - Auto-detect from lock files (package-lock.json, requirements.txt, Cargo.lock)npm- Node.js packages (npm audit)pip- Python packages (pip-audit)cargo- Rust packages (cargo audit)
Detection Logic:
- npm: Looks for
package-lock.jsonorpackage.json - pip: Looks for
requirements.txt,setup.py, orpyproject.toml - cargo: Looks for
Cargo.lockorCargo.toml
Example Request:
{
"target": "/home/user/projects/api-server",
"package_manager": "auto"
}Example Output (npm vulnerabilities):
{
"target": "/home/user/projects/api-server",
"package_manager": "npm",
"total_vulnerabilities": 3,
"vulnerabilities": [
{
"package_name": "express",
"severity": "HIGH",
"title": "Express open redirect vulnerability",
"installed_version": "4.17.1",
"patched_version": "4.17.3",
"cve": "CVE-2022-24999",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2022-24999"
},
{
"package_name": "lodash",
"severity": "MEDIUM",
"title": "Lodash isEqual prototype pollution",
"installed_version": "4.17.20",
"patched_version": "4.17.21",
"cve": "CVE-2021-23337",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2021-23337"
},
{
"package_name": "handlebars",
"severity": "HIGH",
"title": "Handlebars template injection",
"installed_version": "4.7.6",
"patched_version": "4.7.7",
"cve": "CVE-2021-23369",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2021-23369"
}
],
"summary": {
"high": 2,
"medium": 1,
"low": 0
}
}Example Output (pip vulnerabilities):
{
"target": "/home/user/projects/data-pipeline",
"package_manager": "pip",
"total_vulnerabilities": 2,
"vulnerabilities": [
{
"package_name": "requests",
"severity": "HIGH",
"title": "CVE-2023-32681",
"installed_version": "2.27.1",
"patched_version": "2.28.1",
"cve": "CVE-2023-32681",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2023-32681"
},
{
"package_name": "urllib3",
"severity": "MEDIUM",
"title": "CVE-2020-26137",
"installed_version": "1.26.5",
"patched_version": "1.26.16",
"cve": "CVE-2020-26137",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2020-26137"
}
],
"summary": {}
}Example Output (cargo vulnerabilities):
{
"target": "/home/user/projects/rust-service",
"package_manager": "cargo",
"total_vulnerabilities": 1,
"vulnerabilities": [
{
"package_name": "openssl",
"severity": "HIGH",
"title": "Use-after-free in OpenSSL",
"installed_version": "0.10.35",
"patched_version": "0.10.38",
"cve": "CVE-2022-3358",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2022-3358"
}
],
"summary": {}
}secret_scan
Scans source code for hardcoded secrets, credentials, and API keys. Uses gitleaks or trufflehog for pattern-based detection.
Input Schema:
{
"target": "string (required)",
"max_results": "integer (default: 100, range: 1-500)"
}Parameters:
target: Absolute path to project directory to scanmax_results: Maximum number of secret findings to return (default: 100)
Detection Patterns (varies by tool):
- AWS credentials and API keys
- GitHub tokens and personal access tokens
- Database connection strings
- Private encryption keys
- Slack webhooks
- Stripe and payment API keys
- Generic passwords and secrets
Example Request:
{
"target": "/home/user/projects/mobile-app",
"max_results": 50
}Example Output (gitleaks):
{
"target": "/home/user/projects/mobile-app",
"tool": "gitleaks",
"total_secrets": 4,
"secrets": [
{
"rule_id": "AWS API Key",
"file": "/home/user/projects/mobile-app/config/aws.js",
"line": 3,
"match": "AKIAIOSFODNN7EXAMPLE...",
"entropy": 4.2
},
{
"rule_id": "GitHub Token",
"file": "/home/user/projects/mobile-app/.env",
"line": 12,
"match": "ghp_1234567890abcdefghijklmnopqrstuv...",
"entropy": 5.1
},
{
"rule_id": "Slack Webhook URL",
"file": "/home/user/projects/mobile-app/src/notifications.ts",
"line": 45,
"match": "https://hooks.slack.com/services/T00000000/B00000000...",
"entropy": 3.8
},
{
"rule_id": "Private Key",
"file": "/home/user/projects/mobile-app/keys/id_rsa",
"line": 1,
"match": "-----BEGIN RSA PRIVATE KEY-----...",
"entropy": 4.9
}
]
}Example Output (trufflehog):
{
"target": "/home/user/projects/mobile-app",
"tool": "trufflehog",
"total_secrets": 2,
"secrets": [
{
"rule_id": "Stripe API Key",
"file": "/home/user/projects/mobile-app/config/stripe.py",
"line": 8,
"match": "sk_live_4eC39HqLyjWDarhtT657j8Wp...",
"entropy": null
},
{
"rule_id": "Database Connection String",
"file": "/home/user/projects/mobile-app/database.js",
"line": 2,
"match": "postgresql://user:password@localhost:5432/db...",
"entropy": null
}
]
}sbom_generate
Generates a Software Bill of Materials (SBOM) documenting all software components, versions, and licenses. Supports CycloneDX and SPDX formats.
Input Schema:
{
"target": "string (required)",
"format": "string (default: 'cyclonedx')"
}Parameters:
target: Absolute path to project directoryformat: SBOM output format. Options:cyclonedx(default) - CycloneDX JSON format (OWASP standard)spdx- SPDX JSON format (Linux Foundation standard)
Example Request:
{
"target": "/home/user/projects/warehouse",
"format": "cyclonedx"
}Example Output (CycloneDX):
{
"target": "/home/user/projects/warehouse",
"format": "cyclonedx",
"total_components": 47,
"components": [
{
"type": "library",
"name": "fastapi",
"version": "0.104.1",
"purl": "pkg:pypi/[email protected]",
"license": "MIT"
},
{
"type": "library",
"name": "sqlalchemy",
"version": "2.0.23",
"purl": "pkg:pypi/[email protected]",
"license": "MIT"
},
{
"type": "library",
"name": "pydantic",
"version": "2.5.0",
"purl": "pkg:pypi/[email protected]",
"license": "MIT"
},
{
"type": "library",
"name": "requests",
"version": "2.31.0",
"purl": "pkg:pypi/[email protected]",
"license": "Apache-2.0"
},
{
"type": "library",
"name": "redis",
"version": "5.0.1",
"purl": "pkg:pypi/[email protected]",
"license": "MIT"
}
]
}Example Output (SPDX):
{
"target": "/home/user/projects/warehouse",
"format": "spdx",
"total_components": 47,
"components": [
{
"type": "library",
"name": "express",
"version": "4.18.2",
"purl": "pkg:npm/[email protected]",
"license": "MIT"
},
{
"type": "library",
"name": "mongoose",
"version": "7.6.3",
"purl": "pkg:npm/[email protected]",
"license": "Apache-2.0"
},
{
"type": "library",
"name": "dotenv",
"version": "16.3.1",
"purl": "pkg:npm/[email protected]",
"license": "BSD-2-Clause"
}
]
}Prerequisites
System Requirements
- Node.js 18+ or Bun runtime
- Unix-like system (macOS, Linux) or WSL on Windows
Required External Tools
The server delegates to command-line security tools. Install before use:
Semgrep (SAST)
# macOS
brew install semgrep
# Linux / Python (any OS)
pip install semgrep
# Verify installation
semgrep --versionDependency Auditors
# npm (built-in with Node.js)
npm --version
# Python
pip install pip-audit
pip-audit --version
# Rust
cargo install cargo-audit
cargo audit --versionSecret Scanning (choose one or both)
# gitleaks (recommended)
brew install gitleaks
gitleaks version
# OR trufflehog (alternative)
brew install trufflehog
trufflehog versionSBOM Generation
npm install -g @cyclonedx/cdxgen
cdxgen --versionVerification Script
Verify all dependencies are installed:
#!/bin/bash
echo "Checking required tools..."
command -v semgrep >/dev/null 2>&1 && echo "✓ semgrep" || echo "✗ semgrep"
command -v pip-audit >/dev/null 2>&1 && echo "✓ pip-audit" || echo "✗ pip-audit"
command -v cargo >/dev/null 2>&1 && echo "✓ cargo-audit" || echo "✗ cargo-audit (install: cargo install cargo-audit)"
command -v gitleaks >/dev/null 2>&1 && echo "✓ gitleaks" || echo "✗ gitleaks (or trufflehog)"
command -v cdxgen >/dev/null 2>&1 && echo "✓ cdxgen" || echo "✗ cdxgen"Installation
Option 1: Using Bun (Recommended)
# Clone the repository
git clone https://github.com/your-org/mcp-servers.git
cd mcp-servers/code-audit
# Install dependencies
bun install
# Build the server
bun run build
# Start the server (stdio mode)
bun run src/index.tsOption 2: Using npm
# Install dependencies
npm install
# Build (requires build script in package.json)
npm run build
# Start
node dist/index.jsBuild Output
The build process generates:
dist/index.js- Compiled server entry pointdist/tools/*.js- Compiled tool modulesdist/*.js- All compiled TypeScript files
Usage
Stdio Transport (Default)
The server uses stdio (stdin/stdout) for MCP communication. The server reads requests from stdin and writes responses to stdout.
# Start the server in your terminal
bun run src/index.ts
# In another terminal, send requests via stdio
# (handled by MCP client implementations)Claude Desktop Configuration
Add to ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"code-audit": {
"command": "bun",
"args": ["/absolute/path/to/code-audit/src/index.ts"],
"env": {}
}
}
}Note: Use absolute path to the index.ts file. Bun will handle compilation automatically.
Claude Code MCP Settings
In your Claude Code IDE settings, add the MCP configuration:
{
"mcpServers": {
"code-audit": {
"command": "bun",
"args": ["/Users/username/Documents/code/mcp-servers/code-audit/src/index.ts"]
}
}
}Environment Variables
Optional environment variables for tool configuration:
# Semgrep registry endpoint (if using custom registry)
SEMGREP_REGISTRY_ENDPOINT="https://registry.semgrep.dev"
# Gitleaks configuration
GITLEAKS_CONFIG="/path/to/gitleaks.toml"
# Tool timeout (milliseconds, default 120000)
TOOL_TIMEOUT_MS="120000"Example Usage in Claude
Once configured, you can ask Claude to:
"Audit the security of the code in /home/user/projects/api-server"
Claude will:
1. Run semgrep_scan to find SAST issues
2. Run dep_audit to check dependencies
3. Run secret_scan for hardcoded credentials
4. Run sbom_generate to document components
5. Synthesize findings into a security reportSecurity Considerations
Path Validation
All directory paths are validated before scanning:
Resolution: Paths are normalized and resolved to absolute form
Blocking: Access to sensitive system directories is blocked:
/etc- System configuration/proc- Process information/sys- System kernel interface/dev- Device files/var/run- Runtime state
Existence Check: Only existing directories are scanned
Type Check: Target must be a directory, not a file
Error Examples:
{
"content": [
{
"type": "text",
"text": "Error: Access to /etc is not allowed"
}
],
"isError": true
}Timeout Protection
Each tool invocation has timeout protection:
- Default Timeout: 120 seconds (120,000 ms)
- Configurable: Via optional env variable
- Process Termination: Killed automatically on timeout
Error Example:
{
"content": [
{
"type": "text",
"text": "Error: Command timed out after 120000ms"
}
],
"isError": true
}Tool Execution Safety
- execFile API: Uses Node.js execFile (not shell exec), preventing command injection
- Max Buffer: 20 MB output limit per command
- Error Handling: Non-zero exit codes captured as errors
- No Shell Interpolation: Tool arguments passed as array elements
Recommended Practices
- Limit Directory Scope: Scan only necessary directories (not entire filesystem)
- Monitor Timeout: Increase timeout for large repositories if needed
- Review Credentials: Verify secret_scan findings manually before remediation
- Dependency Updates: Keep semgrep, gitleaks, and audit tools current
- Configuration Hardening: Use restricted-access rules in Semgrep for high-security contexts
Performance Notes
Scanning Time Estimates
| Tool | Small Project (< 1K files) | Medium Project (1-10K files) | Large Project (> 10K files) | |------|---------------------------|------------------------------|----------------------------| | semgrep_scan | 10-30s | 30-60s | 60-120s | | dep_audit | 5-10s | 10-20s | 20-30s | | secret_scan | 5-15s | 15-40s | 40-120s | | sbom_generate | 5-20s | 20-50s | 50-120s |
Optimization Tips
- Exclude Directories: Use
.semgrep.ymlto exclude large test/vendor directories - Parallel Execution: Run multiple tools concurrently in Claude
- Incremental Scanning: Scan changed files only when possible
- Result Limiting: Use
max_findingsandmax_resultsparameters
Troubleshooting
"Tool not found" Errors
Semgrep:
# Error: "semgrep not found"
pip install semgrep
semgrep --versiongitleaks:
# Error: "gitleaks not found"
brew install gitleaks
gitleaks versioncdxgen:
# Error: "cdxgen not found"
npm install -g @cyclonedx/cdxgen
cdxgen --versionTimeout Issues
Increase timeout for large repositories:
# Set environment variable (Linux/macOS)
export TOOL_TIMEOUT_MS="300000" # 5 minutes
bun run src/index.tsParse Errors
If tools output non-JSON results:
- Verify tool version compatibility
- Check tool output manually:
cd /path/to/project semgrep scan --config auto --json . - Report issue with tool output format
Empty Dependency Audit Results
If dep_audit returns no vulnerabilities:
Verify correct project structure:
- npm: Has
package-lock.jsonorpackage.json - pip: Has
requirements.txt,setup.py, orpyproject.toml - cargo: Has
Cargo.lockorCargo.toml
- npm: Has
Run audit manually to debug:
cd /path/to/project npm audit --json
API Reference
Tool Input/Output Format
All tools accept Zod-validated JSON schemas and return structured JSON responses.
Request Format (internal MCP protocol):
{
"name": "tool_name",
"arguments": {
"target": "/path/to/project",
"config": "auto"
}
}Response Format (all tools):
{
"content": [
{
"type": "text",
"text": "{...JSON result...}"
}
],
"isError": false
}Error Responses
On error, the response includes isError: true:
{
"content": [
{
"type": "text",
"text": "Error: Invalid target directory"
}
],
"isError": true
}License
MIT
Contributing
To contribute improvements to the Code Audit MCP server:
- Fork the repository
- Create a feature branch
- Make changes and test thoroughly
- Submit a pull request with clear description
Testing Requirements:
- Test all four tools with sample projects
- Verify timeout and error handling
- Confirm path validation works correctly
