```
███╗   ███╗ ██████╗██████╗      █████╗ ██╗   ██╗██████╗ ██╗████████╗
████╗ ████║██╔════╝██╔══██╗    ██╔══██╗██║   ██║██╔══██╗██║╚══██╔══╝
██╔████╔██║██║     ██████╔╝    ███████║██║   ██║██║  ██║██║   ██║
██║╚██╔╝██║██║     ██╔═══╝     ██╔══██║██║   ██║██║  ██║██║   ██║
██║ ╚═╝ ██║╚██████╗██║         ██║  ██║╚██████╔╝██████╔╝██║   ██║
╚═╝     ╚═╝ ╚═════╝╚═╝         ╚═╝  ╚═╝ ╚═════╝ ╚═════╝ ╚═╝   ╚═╝
        Security Scanner for MCP Servers — Zero Dependencies
```

<p align="center">
  <code>python 3.10+</code> &nbsp;|&nbsp;
  <code>zero dependencies</code> &nbsp;|&nbsp;
  <code>MIT license</code> &nbsp;|&nbsp;
  <code>6430+ tests</code> &nbsp;|&nbsp;
  <code>v2.9.0</code>
</p>

---

> MCP servers are the bridge between LLMs and your system. If they have vulnerabilities, the AI can be manipulated to exploit them. mcpaudit finds those vulnerabilities before an attacker does.

## How it works

```
  Your MCP Server Code
         |
         v
  +--------------+
  |   mcpaudit    |-->  AST parsing (no execution)
  |   scanner     |-->  72+ security rules
  |               |-->  CWE mapping + Trust Score
  +------+-------+
         |
    +----+----+----------+----------+
    v    v    v          v          v
  Text  JSON  HTML     SARIF    History
        (CI)  (report) (GitHub)  (trend)
```

## Quick Start

```bash
pip install -e .

# Scan a file
mcpaudit server.py

# Scan a directory
mcpaudit /path/to/mcp-servers/

# HTML report
mcpaudit server.py --format html -o report.html

# SARIF for GitHub Code Scanning
mcpaudit server.py --format sarif -o results.sarif
```

## Why mcpaudit?

| | AI-Infra-Guard (Tencent) | mcpaudit |
|---|---|---|
| Requirements | Docker + 4GB RAM + LLM API key | Python 3.11+ (stdlib only) |
| Speed | Minutes (API calls) | <200ms (static analysis) |
| Cost | $$$ (LLM API) | $0 (everything local) |
| Dependencies | Docker, LLM SDK | None |
| Languages | Python only | Python + TypeScript + Go |
| CI/CD | Manual | Exit codes + JSON + SARIF |

## Features

| Feature | Command | What it does |
|---------|---------|--------------|
| Static Scan | `mcpaudit scan FILE` | AST-based scanning (Python/TS/Go) |
| Fleet Scan | `mcpaudit scan-all DIR` | Recursive discovery + aggregate report |
| Fleet Report | `mcpaudit scan-all --fleet-report` | Executive HTML with heatmap |
| Fingerprint | `mcpaudit fingerprint PATH` | Detect MCP framework + known vulns |
| Data Flows | `mcpaudit flows FILE` | Toxic source-to-sink analysis |
| Config Guard | `mcpaudit guard CONFIG` | Claude Code settings.json audit |
| Diff Scan | `mcpaudit diff` | Compare scans, find new/resolved |
| Live Scan | `mcpaudit live -- CMD` | Runtime probing (8 probes) |
| Watch Mode | `mcpaudit scan --watch` | Re-scan on file change |
| Auto-Fix | `mcpaudit scan --fix` | Auto-remediation (5 rule types) |
| Policy | `mcpaudit scan --policy FILE` | YAML policy enforcement |
| Compliance | `mcpaudit scan --compliance-report` | OWASP Agentic Top 10 report |
| Trust Score | `mcpaudit scan --min-score N` | 0-100 score for CI/CD gates |
| Baseline | `mcpaudit --create-baseline` | Suppress known findings |
| Plugins | `mcpaudit plugins list` | Custom rule loading |
| Rule Gen | `mcpaudit generate --category` | 30 rule templates from CVE/OWASP |

## Security Rules (72+)

Every finding includes a **CWE reference** and a **confidence level** (HIGH/MEDIUM/LOW).

| Rule | Severity | Detects | CWE |
|------|----------|---------|-----|
| `CMD-001` | CRITICAL | Command injection (`shell=True`) | CWE-78 |
| `CMD-002` | HIGH | Command injection (f-strings) | CWE-78 |
| `SQL-001` | CRITICAL | SQL injection (string interpolation) | CWE-89 |
| `SEC-001` | CRITICAL | Hardcoded secrets (API keys, tokens) | CWE-798 |
| `DESER-001` | CRITICAL | Unsafe deserialization (yaml.load) | CWE-502 |
| `PATH-001` | HIGH | Path traversal (unvalidated file ops) | CWE-22 |
| `SSRF-001` | HIGH | Server-Side Request Forgery | CWE-918 |
| `FILE-001` | HIGH | Unsafe file write (dynamic path) | CWE-73 |
| `PERM-001` | HIGH | Excessive permissions (chmod 777) | CWE-250 |
| `IDOR-001` | HIGH | Insecure Direct Object Reference | CWE-639 |
| `PRIV-001` | HIGH | Privilege escalation in tools | CWE-269 |
| `AUTH-001` | MEDIUM | Missing authentication | CWE-306 |
| `AUTHZ-001` | MEDIUM | Missing authorization in handlers | CWE-862 |
| `CORS-001` | MEDIUM | CORS wildcard | CWE-942 |
| `VAL-001` | MEDIUM | Missing input validation | -- |
| `ERR-001` | MEDIUM | Missing error handling | CWE-755 |
| `LOG-001` | MEDIUM | Sensitive data in logs | CWE-532 |
| `RES-001` | MEDIUM | Resource exhaustion | CWE-400 |
| `REDOS-001` | MEDIUM | ReDoS (nested quantifiers) | -- |
| `MCP-003` | HIGH | Confused deputy attack | -- |
| `MCP-004` | MEDIUM | Prompt injection vector | -- |
| `MCP-006` | MEDIUM | Unbounded tool response | -- |
| `MCP-015` | HIGH | Unauthenticated server | -- |
| `MCP-016` | LOW | Missing audit logging | -- |
| `RATE-001` | LOW | Missing rate limiting | CWE-770 |
| `TEMP-001` | LOW | Insecure temp files | CWE-377 |
| `INFO-001` | LOW | Information disclosure | -- |

## Grading and Trust Score

```
  Grade    Score    Meaning
  -----    -----    ----------------------
   A+        0      No findings
   A        1-2     Minor issues only
   B        3-5     Some medium issues
   C       6-10     High severity findings
   D      11-20     Multiple high severity
   F       21+      Critical issues present

  Trust Score: 0-100 (higher = more secure)
  Use --min-score N as CI/CD quality gate
```

## Output Formats

### Terminal (default)

```
============================================================
  MCP Security Audit -- Results
============================================================
  Files scanned: 1
  Lines scanned: 150
  Total findings: 3
============================================================

  [FILE] server.py
     Grade: C | 3 findings | 12.3ms

     [!!] [CMD-001] Command Injection (shell=True)
       Line 42: subprocess.run() with shell=True.
       Fix: Use argument list without shell=True.

     [!] [PATH-001] Potential Path Traversal
       Line 18: open() without path validation.
       Fix: Use path.resolve() and path.is_relative_to(base_dir).

     [-] [AUTH-001] Missing authentication
       Line 1: Server does not implement authentication.
============================================================
  Trust Score: 35/100 (LOW)
```

### JSON, HTML, SARIF

```bash
mcpaudit server.py --format json            # CI/CD pipelines
mcpaudit server.py --format html -o r.html   # Visual dashboard
mcpaudit server.py --format sarif -o r.sarif # GitHub Code Scanning
```

## CI/CD Integration

### GitHub Actions

```yaml
name: Security Scan
on: [push, pull_request]

jobs:
  scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: '3.11'
      - run: pip install -e path/to/mcpaudit
      - run: mcpaudit . --format sarif -o results.sarif
      - uses: github/codeql-action/upload-sarif@v3
        if: always()
        with:
          sarif_file: results.sarif
```

### Pre-commit Hook

```bash
cp hooks/pre-commit .git/hooks/pre-commit
chmod +x .git/hooks/pre-commit
```

### Baseline (only fail on NEW findings)

```bash
mcpaudit . --create-baseline .mcpaudit-baseline.json
mcpaudit . --baseline .mcpaudit-baseline.json
```

### Exit Codes

| Code | Meaning |
|------|---------|
| `0` | No HIGH or CRITICAL findings |
| `1` | HIGH findings present |
| `2` | CRITICAL findings present |

## Configuration

```bash
mcpaudit --init  # Generate .mcpaudit.yml
```

```yaml
# .mcpaudit.yml
exclude_rules:
  - AUTH-001
  - RATE-001
exclude_paths:
  - "tests/*"
  - "vendor/*"
severity_threshold: medium
output_format: text
```

## Custom Rules

```python
from mcpaudit.rules import Rule
from mcpaudit.models import Finding, Severity

class MyRule(Rule):
    rule_id = "CUSTOM-001"
    name = "My Custom Check"
    severity = Severity.HIGH
    description = "Detects my custom pattern."

    def check(self, tree, source) -> list[Finding]:
        findings = []
        # Detection logic here
        return findings

from mcpaudit.scanner import MCPSecurityScanner
scanner = MCPSecurityScanner(rules=[MyRule()])
```

## Architecture

```
mcpaudit/
+-- scanner.py            # Core Python scanning engine
+-- ts_scanner.py         # TypeScript/JavaScript scanner
+-- go_scanner.py         # Go scanner
+-- models.py             # Finding, ScanResult, Severity
+-- formatters.py         # Text + JSON formatters
+-- config.py             # .mcpaudit.yml loader
+-- rules/                # 27 Python security rules
+-- ts_rules/             # 15 TypeScript rules
+-- go_rules/             # 8 Go rules
+-- reporters/            # HTML + SARIF reporters
+-- flows.py              # Data flow analysis
+-- guard.py              # Config file auditing
+-- live.py               # Runtime MCP probing
+-- watcher.py            # File watch mode
+-- fixer.py              # Auto-remediation engine
+-- policy_engine.py      # YAML policy enforcement
+-- compliance.py         # OWASP Agentic Top 10
+-- trust_score.py        # 0-100 trust scoring
+-- baseline.py           # Finding suppression
+-- plugin_system.py      # External rule loading
+-- ...                   # 159 modules total
tests/
+-- ...                   # 6632 tests
```

## Stats

| Metric | Value |
|--------|-------|
| Tests | 6632 |
| Python rules | 27 |
| TypeScript rules | 15 |
| Go rules | 8 |
| Source modules | 159 |
| OWASP Agentic coverage | 10/10 |
| CWE references | 20+ |
| Output formats | 5 (text, JSON, HTML, SARIF, history) |
| CLI commands | 16 |
| Dependencies | 0 |

## License

MIT License.

---

Built by [@cmiretf](https://github.com/cmiretf)
