Skip to main content

mcpaudit

Security scanner for MCP server Python code. Finds vulnerabilities before they reach production.

pip install mcp-vulnscan
mcp-vulnscan ./my-mcp-server

What it finds

Rule CWE Severity
Shell injection — user input to subprocess/os.system without sanitization CWE-78 high
Code injection — user input to eval()/exec() CWE-95 high
SQL injection — user input in raw cursor.execute() queries CWE-89 high
Path traversal — file operations without path boundary validation CWE-22 high/medium
SSRF — user input as HTTP request URL (including Session().get()) CWE-918 high/medium
Hardcoded secrets — API keys and credentials in source code CWE-798 high
Prompt injection — user-fetched content returned to the LLM CWE-020 medium
Unsafe deserialization — user input to pickle.loads, yaml.load CWE-502 high/medium
Template injection — user input to jinja2.Template() or env.from_string() CWE-94 high/medium
XML injection (XXE) — user input to ET.fromstring() or lxml.etree.fromstring() CWE-611 high/medium
LDAP injection — user input in LDAP search filters without escaping CWE-90 high/medium
Log injection — user input as the log message (enables log forging) CWE-117 high/medium

Severity is high for confirmed MCP tool handlers (@mcp.tool), medium for unknown context.

Usage

# Scan a directory
mcp-vulnscan ./path/to/server

# Output as JSON for CI/CD
mcp-vulnscan ./path/to/server --format json

# Output as SARIF for GitHub Code Scanning
mcp-vulnscan ./path/to/server --format sarif --output-file results.sarif

# Only show high and critical findings
mcp-vulnscan ./path/to/server --min-severity high

# Run only specific rules
mcp-vulnscan ./path/to/server --rules shell_injection,path_traversal

# Exit code 0 even when findings exist (for reporting without blocking)
mcp-vulnscan ./path/to/server --no-exit-code

# Include test files (excluded by default)
mcp-vulnscan ./path/to/server --no-default-excludes

# Exclude generated code
mcp-vulnscan ./path/to/server --exclude '**/generated/**'

# Write output to a file
mcp-vulnscan ./path/to/server --format json --output-file findings.json

Baseline mode (CI onboarding)

Establish a baseline from an existing codebase so CI only fails on new findings:

# First run: saves current findings as baseline, exits 0
mcp-vulnscan ./src --baseline baseline.json

# Subsequent runs: only reports findings NOT in baseline
mcp-vulnscan ./src --baseline baseline.json

Commit baseline.json to your repo. From that point on, the scanner blocks only regressions.

Config file

Generate a project config:

mcp-vulnscan init

This creates .mcpaudit.toml in the current directory:

[mcpaudit]
min_severity = "low"
format = "text"
exclude = [
    "**/generated/**",
    "**/vendor/**",
]
rules = []   # empty = all rules

CLI flags always override the config file.

Suppressing findings

Add a comment to suppress a finding on a specific line:

result = eval(expr)           # mcpaudit: ignore
result = eval(expr)           # mcpaudit: ignore[CWE-95]
cursor.execute(query)         # mcpaudit: ignore[CWE-89]

CWE-specific suppression only silences that CWE on that line; other rules still apply.

GitHub Actions

Run tests in CI

- name: Run mcpaudit
  run: mcp-vulnscan ./src --format sarif --output-file mcpaudit.sarif --no-exit-code

- name: Upload to GitHub Code Scanning
  uses: github/codeql-action/upload-sarif@v3
  with:
    sarif_file: mcpaudit.sarif

Block PRs on new findings

- name: mcpaudit (baseline diff)
  run: mcp-vulnscan ./src --baseline baseline.json

How it works

mcpaudit parses Python source with the ast module and traces data flow from MCP tool parameters to dangerous sinks. It classifies each function as:

  • tool — decorated with @mcp.tool or @server.call_tool → findings reported as high
  • unknown — no classifier signal → findings reported as medium
  • safe — CLI code, @classmethod, utils directories, test functions → not flagged

Import aliases are tracked — import subprocess as sp; sp.run(cmd, shell=True) is detected. Session-based HTTP calls are tracked — requests.Session().get(url) is detected.

No external API calls. Runs fully offline.

License

MIT

Metadata

Release files for mcp-vulnscan 0.2.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for mcp-vulnscan 0.2.1
File Size Uploaded Provenance
mcp_vulnscan-0.2.1.tar.gz 46.1 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for mcp-vulnscan 0.2.1
File Interpreter ABI Platform
mcp_vulnscan-0.2.1-py3-none-any.whl Python 3 none any Details

Total release size: 88.7 kB

Release files / mcp_vulnscan-0.2.1.tar.gz

Download URL mcp_vulnscan-0.2.1.tar.gz
Size 46.1 kB
Tags Source
SHA-256 checksum
How to use checksums
d7786704f17e529cbd98574ad26e7a02a0c7b1405d193be80670fbf4eb726c58
BLAKE2b-256 checksum
How to use checksums
286196ae72c1d49e9b68b5d067cd2808ade4cc74cc6b8d8ebba887a4b5dfcd2a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.10.20

Release files / mcp_vulnscan-0.2.1-py3-none-any.whl

Download URL mcp_vulnscan-0.2.1-py3-none-any.whl
Size 42.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
699dd81731cc36ed22b13866c5ac527aa1b3f15c5b2ad74933f5f23801e62c1f
BLAKE2b-256 checksum
How to use checksums
d901efb5c692bb0729a91590d3a3547e7c96a3aa8fca2368bbc5bb3fe3a80553
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.10.20

Security for mcp-vulnscan 0.2.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.2.1 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page