npm package: @modular-intelligence/semgrep
Description: MCP server wrapping semgrep for static analysis and SAST scanning
Latest version: 1.0.2

# 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:**
```typescript
{
  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:**
```json
{
  "path": "/Users/dev/myproject/src",
  "config": "auto",
  "severity": "WARNING",
  "exclude_patterns": ["*.test.ts", "node_modules/*"],
  "timeout": 180
}
```

**Example Output:**
```json
{
  "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:**
```typescript
{
  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:**
```json
{
  "code": "import os\n\ndef run_command(user_input):\n    os.system(user_input)\n",
  "language": "python",
  "config": "r/python.lang.security"
}
```

**Example Output:**
```json
{
  "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:**
```typescript
{
  config: string    // Config to list rules from (optional, default: 'auto')
  language: string  // Filter rules by language (optional)
}
```

**Example Request:**
```json
{
  "config": "r/python.lang.security",
  "language": "python"
}
```

**Example Output:**
```json
{
  "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:**
```typescript
{
  rule_content: string  // YAML rule content to validate (max 500KB)
}
```

**Example Request:**
```json
{
  "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:**
```json
{
  "valid": true,
  "errors": [],
  "warnings": []
}
```

### 5. Semgrep Supply Chain

Scan for supply chain vulnerabilities in project dependencies using Semgrep's supply-chain ruleset.

**Input Parameters:**
```typescript
{
  path: string     // Absolute path to project directory
  timeout: number  // Max scan duration in seconds (30-600, default: 120)
}
```

**Example Request:**
```json
{
  "path": "/Users/dev/myproject",
  "timeout": 120
}
```

**Example Output:**
```json
{
  "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:**
```typescript
{
  path: string     // Absolute path to file or directory
  timeout: number  // Max scan duration in seconds (30-600, default: 120)
}
```

**Example Request:**
```json
{
  "path": "/Users/dev/myproject/src",
  "timeout": 120
}
```

**Example Output:**
```json
{
  "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:**
```typescript
{
  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:**
```json
{
  "path": "/Users/dev/myproject",
  "config": "auto",
  "baseline_ref": "main",
  "timeout": 180
}
```

**Example Output:**
```json
{
  "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).

```bash
export PATH="/usr/local/bin:$PATH"
```

## Prerequisites

- **Semgrep** - Static analysis tool
  - Installation: `pip install semgrep` or `brew install semgrep` (macOS)
  - Website: https://semgrep.dev/
  - Documentation: https://semgrep.dev/docs/

- **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

1. Clone or download this repository:
```bash
git clone <repo-url>
cd semgrep
```

2. Install dependencies:
```bash
bun install
```

3. Build the project:
```bash
bun run build
```

4. Verify Semgrep is installed:
```bash
which semgrep
semgrep --version
```

5. Run the server:
```bash
bun run start
```

The server will start listening on stdio transport.

## Usage

### Running the Server

Start the server with Bun:

```bash
bun run src/index.ts
```

The 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`:

```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:

```json
{
  "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:**
```json
{
  "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:**
```json
{
  "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:**
```json
{
  "tool": "semgrep_secrets",
  "input": {
    "path": "/Users/dev/myproject"
  }
}
```

**Request:**
"Check for vulnerable dependencies in my project"

**Claude will call:**
```json
{
  "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 rules
- `r/python.lang.security` - Python security rules
- `r/javascript.lang.security` - JavaScript security rules
- `r/java.lang.security` - Java security rules
- `p/security-audit` - Multi-language security audit
- `p/owasp-top-ten` - OWASP Top 10 vulnerabilities
- `p/ci` - Rules suitable for CI/CD
- `secrets` - Secret detection rules
- `supply-chain` - Dependency vulnerability detection

### Custom Rules

You can validate and use custom YAML rules:

```yaml
rules:
  - id: my-custom-rule
    pattern: dangerous_function(...)
    message: Avoid using dangerous_function
    languages: [python]
    severity: WARNING
```

Use `semgrep_validate_rule` to check syntax before deployment.

## License

ISC License - see LICENSE file for details