@modular-intelligence/semgrep
v1.0.2
Published
MCP server wrapping semgrep for static analysis and SAST scanning
Readme
Semgrep MCP Server
A comprehensive static analysis and SAST (Static Application Security Testing) service that integrates the Semgrep command-line tool through the Model Context Protocol. This MCP server enables Claude to perform code security scanning, vulnerability detection, secret detection, supply chain analysis, and custom rule validation.
Overview
This server provides access to powerful static analysis capabilities through a unified interface:
- Semgrep - Industry-standard static analysis tool for finding bugs, detecting vulnerabilities, and enforcing code standards across 30+ languages
Perfect for security auditing, code quality checks, vulnerability research, compliance enforcement, and CI/CD integration.
Tools
| Tool | Description |
|------|-------------|
| semgrep_scan | Scan files or directories with configurable Semgrep rulesets |
| semgrep_scan_code | Scan source code snippets directly without writing to disk |
| semgrep_list_rules | List available Semgrep rules from a config or registry |
| semgrep_validate_rule | Validate custom Semgrep YAML rule syntax and structure |
| semgrep_supply_chain | Scan for supply chain vulnerabilities in dependencies |
| semgrep_secrets | Scan for exposed secrets, API keys, and credentials |
| semgrep_ci_report | Generate CI-ready report with diff-aware scanning |
1. Semgrep Scan
Scan files or directories for security issues, bugs, and code quality problems using Semgrep's extensive rule registry.
Input Parameters:
{
path: string // Absolute path to file or directory to scan
config: string // Config: 'auto', registry rule (r/python.lang.security), or local path (optional, default: 'auto')
severity: string // Minimum severity: 'INFO', 'WARNING', or 'ERROR' (optional)
exclude_patterns: string[] // Patterns to exclude (e.g., ['*.test.js', 'vendor/*']) (optional)
max_target_bytes: number // Maximum file size to scan in bytes (optional, default: 1000000)
timeout: number // Max scan duration in seconds (30-600, default: 120)
}Example Request:
{
"path": "/Users/dev/myproject/src",
"config": "auto",
"severity": "WARNING",
"exclude_patterns": ["*.test.ts", "node_modules/*"],
"timeout": 180
}Example Output:
{
"findings_count": 3,
"findings": [
{
"rule_id": "python.lang.security.audit.dangerous-system-call",
"path": "/Users/dev/myproject/src/utils.py",
"start_line": 42,
"end_line": 42,
"start_col": 5,
"end_col": 28,
"message": "Detected use of os.system(). This is dangerous if user input can reach this function. Consider using subprocess.run() instead.",
"severity": "WARNING",
"metadata": {
"cwe": "CWE-78: OS Command Injection",
"owasp": "A1: Injection"
}
},
{
"rule_id": "python.lang.security.audit.hardcoded-password",
"path": "/Users/dev/myproject/src/config.py",
"start_line": 15,
"end_line": 15,
"start_col": 10,
"end_col": 45,
"message": "Hardcoded password detected. Store secrets in environment variables or secure vaults.",
"severity": "ERROR",
"metadata": {
"cwe": "CWE-798: Use of Hard-coded Credentials"
}
}
],
"errors": [],
"scan_info": {
"config": "auto",
"path": "/Users/dev/myproject/src",
"duration_seconds": 12.4
}
}2. Semgrep Scan Code
Scan source code snippets directly without needing to write files to disk. Useful for analyzing code on-the-fly.
Input Parameters:
{
code: string // Source code to scan (max 50KB)
language: string // Language: 'python', 'javascript', 'typescript', 'java', 'go', 'ruby', 'php', 'c', 'cpp', 'csharp', 'rust', 'swift', 'kotlin', 'scala', 'ocaml'
config: string // Config: 'auto', registry rule, or local path (optional, default: 'auto')
timeout: number // Max scan duration in seconds (30-600, default: 120)
}Example Request:
{
"code": "import os\n\ndef run_command(user_input):\n os.system(user_input)\n",
"language": "python",
"config": "r/python.lang.security"
}Example Output:
{
"findings_count": 1,
"findings": [
{
"rule_id": "python.lang.security.audit.dangerous-system-call",
"line_start": 4,
"line_end": 4,
"message": "Detected use of os.system(). This is dangerous if user input can reach this function.",
"severity": "WARNING",
"code_snippet": " os.system(user_input)"
}
],
"errors": [],
"language": "python"
}3. Semgrep List Rules
List available Semgrep rules from a configuration or the registry.
Input Parameters:
{
config: string // Config to list rules from (optional, default: 'auto')
language: string // Filter rules by language (optional)
}Example Request:
{
"config": "r/python.lang.security",
"language": "python"
}Example Output:
{
"rules": [
{
"id": "python.lang.security.audit.dangerous-system-call",
"languages": ["python"],
"severity": "WARNING",
"message": "Avoid os.system() with user input"
},
{
"id": "python.lang.security.audit.sql-injection",
"languages": ["python"],
"severity": "ERROR",
"message": "Potential SQL injection vulnerability"
}
],
"total_count": 2
}4. Semgrep Validate Rule
Validate custom Semgrep YAML rule syntax and structure before deployment.
Input Parameters:
{
rule_content: string // YAML rule content to validate (max 500KB)
}Example Request:
{
"rule_content": "rules:\n - id: my-custom-rule\n pattern: os.system(...)\n message: Dangerous system call\n languages: [python]\n severity: WARNING\n"
}Example Output:
{
"valid": true,
"errors": [],
"warnings": []
}5. Semgrep Supply Chain
Scan for supply chain vulnerabilities in project dependencies using Semgrep's supply-chain ruleset.
Input Parameters:
{
path: string // Absolute path to project directory
timeout: number // Max scan duration in seconds (30-600, default: 120)
}Example Request:
{
"path": "/Users/dev/myproject",
"timeout": 120
}Example Output:
{
"vulnerabilities": [
{
"package": "lodash",
"version": "4.17.15",
"vulnerability": "CVE-2020-8203",
"severity": "ERROR",
"fix_version": "4.17.21",
"description": "Prototype pollution vulnerability in lodash"
},
{
"package": "axios",
"version": "0.21.0",
"vulnerability": "CVE-2021-3749",
"severity": "WARNING",
"fix_version": "0.21.2",
"description": "Regular expression denial of service in axios"
}
],
"total": 2,
"scan_info": {
"path": "/Users/dev/myproject",
"duration_seconds": 8.3
}
}6. Semgrep Secrets
Scan for exposed secrets, API keys, credentials, and other sensitive data in code.
Input Parameters:
{
path: string // Absolute path to file or directory
timeout: number // Max scan duration in seconds (30-600, default: 120)
}Example Request:
{
"path": "/Users/dev/myproject/src",
"timeout": 120
}Example Output:
{
"secrets_found": 2,
"findings": [
{
"rule_id": "secrets.generic.api-key",
"path": "/Users/dev/myproject/src/config.py",
"line": 10,
"secret_type": "API Key",
"secret_value_redacted": "sk_l...x9zA",
"message": "Hardcoded API key detected",
"severity": "ERROR"
},
{
"rule_id": "secrets.aws.access-key",
"path": "/Users/dev/myproject/src/aws.py",
"line": 5,
"secret_type": "AWS Access Key",
"secret_value_redacted": "AKIA...JK2L",
"message": "AWS access key exposed in code",
"severity": "ERROR"
}
],
"errors": [],
"scan_info": {
"path": "/Users/dev/myproject/src",
"duration_seconds": 5.2
}
}7. Semgrep CI Report
Generate a CI-ready report with diff-aware scanning and baseline comparison. Shows new findings and fixed issues.
Input Parameters:
{
path: string // Absolute path to project directory
config: string // Config: 'auto', registry rule, or local path (optional, default: 'auto')
baseline_ref: string // Git ref for diff-aware scanning (e.g., 'main', 'HEAD~1', commit SHA) (optional)
timeout: number // Max scan duration in seconds (30-600, default: 120)
}Example Request:
{
"path": "/Users/dev/myproject",
"config": "auto",
"baseline_ref": "main",
"timeout": 180
}Example Output:
{
"new_findings": [
{
"rule_id": "python.lang.security.audit.dangerous-system-call",
"path": "src/utils.py",
"line": 42,
"message": "Detected use of os.system()",
"severity": "WARNING"
}
],
"fixed_findings": [
{
"rule_id": "python.lang.security.audit.sql-injection",
"path": "src/database.py",
"line": 28,
"message": "SQL injection vulnerability",
"severity": "ERROR"
}
],
"summary": {
"new_count": 1,
"fixed_count": 1,
"baseline_ref": "main",
"total_findings": 1
},
"scan_info": {
"path": "/Users/dev/myproject",
"config": "auto",
"duration_seconds": 15.7
}
}Configuration
Environment Variables
This server requires the Semgrep command-line tool to be installed. No API keys are required for basic usage (registry rules require free Semgrep account).
export PATH="/usr/local/bin:$PATH"Prerequisites
Semgrep - Static analysis tool
- Installation:
pip install semgreporbrew install semgrep(macOS) - Website: https://semgrep.dev/
- Documentation: https://semgrep.dev/docs/
- Installation:
Supported Languages (30+)
- Python, JavaScript, TypeScript, Java, Go, Ruby, PHP
- C, C++, C#, Rust, Swift, Kotlin, Scala, OCaml
- And many more
Installation
Prerequisites
- Bun runtime (version 1.x or later)
- Node.js 18+ (alternative runtime)
- Semgrep installed and accessible
Steps
- Clone or download this repository:
git clone <repo-url>
cd semgrep- Install dependencies:
bun install- Build the project:
bun run build- Verify Semgrep is installed:
which semgrep
semgrep --version- Run the server:
bun run startThe server will start listening on stdio transport.
Usage
Running the Server
Start the server with Bun:
bun run src/index.tsThe server implements the Model Context Protocol (MCP) and communicates via stdio transport. It can be integrated with Claude or other MCP clients.
Claude Desktop Configuration
Add the server to your Claude Desktop configuration at ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"semgrep": {
"command": "bun",
"args": [
"run",
"/path/to/semgrep/src/index.ts"
]
}
}
}Claude Code MCP Settings
Configure the server in Claude Code's MCP settings:
{
"servers": {
"semgrep": {
"transport": "stdio",
"command": "bun",
"args": ["run", "/path/to/semgrep/src/index.ts"]
}
}
}Example Usage in Claude
Once configured, you can use the tools directly in conversations with Claude:
Request: "Scan my Python project for security vulnerabilities"
Claude will call:
{
"tool": "semgrep_scan",
"input": {
"path": "/Users/dev/myproject",
"config": "r/python.lang.security",
"severity": "WARNING"
}
}Request: "Check this code snippet for SQL injection vulnerabilities"
Claude will call:
{
"tool": "semgrep_scan_code",
"input": {
"code": "query = 'SELECT * FROM users WHERE id=' + user_id",
"language": "python",
"config": "r/python.lang.security"
}
}Request: "Scan for exposed secrets in my repository"
Claude will call:
{
"tool": "semgrep_secrets",
"input": {
"path": "/Users/dev/myproject"
}
}Request: "Check for vulnerable dependencies in my project"
Claude will call:
{
"tool": "semgrep_supply_chain",
"input": {
"path": "/Users/dev/myproject"
}
}Security
This server implements comprehensive input validation and security measures to prevent injection attacks and misuse:
Input Validation
Path Validation
- Must be absolute paths (starting with
/) - No path traversal (
../or~) allowed - No null bytes allowed
- Blocked system paths:
/etc,/proc,/sys,/dev - Valid characters: alphanumeric, dots, hyphens, underscores, slashes, colons, spaces
- Prevents command injection via special characters
Config Validation
- Remote URLs (http://, https://, ftp://) are blocked
- Only allows:
- Registry rules (r/..., p/...)
- Local file paths (validated)
- "auto" keyword
- Prevents loading malicious remote configs
Rule Content Validation
- Maximum size: 500KB
- Must contain "rules:" or "patterns:" keywords
- Blocks potentially dangerous code (exec, eval)
- Prevents code injection through custom rules
Language Validation
- Only alphabetic characters allowed
- Prevents injection through language parameter
Blocked Flags
--dangerously-allow-arbitrary-code-execution- Prevents running arbitrary code--metrics=on- Prevents data exfiltration
What Gets Blocked
The server rejects:
- Relative paths and path traversal attempts
- Remote URLs in config parameters
- System directory access (/etc, /proc, /sys, /dev)
- Oversized rule content (>500KB)
- Shell metacharacters in inputs (
;,&,|, backticks,$,(),{}) - Dangerous Semgrep flags
- Invalid language specifications
- Malformed code snippets
Secret Redaction
- Secret values are automatically redacted in output
- Only first 4 and last 4 characters shown (e.g.,
sk_l...x9zA) - Prevents accidental exposure of discovered secrets
Error Handling
- Invalid inputs return descriptive error messages
- Validation failures provide clear guidance
- Command execution errors are caught and reported
- Timeouts are handled gracefully
- Parse failures provide diagnostic information
Common Semgrep Configs
Registry Rules
auto- Automatically detect and run relevant rulesr/python.lang.security- Python security rulesr/javascript.lang.security- JavaScript security rulesr/java.lang.security- Java security rulesp/security-audit- Multi-language security auditp/owasp-top-ten- OWASP Top 10 vulnerabilitiesp/ci- Rules suitable for CI/CDsecrets- Secret detection rulessupply-chain- Dependency vulnerability detection
Custom Rules
You can validate and use custom YAML rules:
rules:
- id: my-custom-rule
pattern: dangerous_function(...)
message: Avoid using dangerous_function
languages: [python]
severity: WARNINGUse semgrep_validate_rule to check syntax before deployment.
License
ISC License - see LICENSE file for details
