Vulnerability scanner for Python dependencies using the OSV API.
Supports uv.lock, poetry.lock, pyproject.toml, and requirements.txt — no environment activation needed.
pip install pyvulscan
# or with uv tool
uv tool install pyvulscan
# or with pipx
pipx install pyvulscan# Auto-detect lockfile in current project
pyvulscan pyproject.toml
# Scan a specific lockfile
pyvulscan uv.lock
pyvulscan poetry.lock
# Scan only direct dependencies (not transitive)
pyvulscan pyproject.toml --direct-only
# Include dev dependencies (Poetry only)
pyvulscan pyproject.toml --group main --group dev
# JSON output (for CI/CD integration)
pyvulscan pyproject.toml --json
# Exit with code 1 if vulnerabilities found (CI gate)
pyvulscan pyproject.toml --exit-code
# Add a filtered summary section at the end (HIGH and CRITICAL only)
pyvulscan pyproject.toml --filter HIGH
# Filter from MEDIUM and above
pyvulscan pyproject.toml --filter MEDIUM
# Check if suggested fix versions resolve without conflicts (dry-run, no files modified)
pyvulscan uv.lock --fix-dry-runScan several projects at once from a config file. All projects are scanned in parallel and findings are grouped by project in the report.
pyvulscan multiscan projects.json
pyvulscan multiscan projects.yaml
pyvulscan multiscan projects.py
# JSON output
pyvulscan multiscan projects.json --json
# CI gate: exit 1 if any project has vulnerabilities
pyvulscan multiscan projects.json --exit-code
# Add a filtered summary section grouped by project (HIGH and CRITICAL only)
pyvulscan multiscan projects.json --filter HIGHAll formats accept a simple list of paths or a list of objects with path and an optional name.
JSON (projects.json):
{
"projects": [
{ "path": "~/code/api", "name": "API" },
{ "path": "~/code/workers" }
]
}YAML (projects.yaml) — requires pip install pyyaml:
projects:
- path: ~/code/api
name: API
- path: ~/code/workersPython (projects.py):
projects = [
{"path": "~/code/api", "name": "API"},
{"path": "~/code/workers"},
]Example files are available in the repository root: multiscan.example.json, multiscan.example.yaml, multiscan.example.py.
The --filter LEVEL option appends a dedicated section at the end of the report listing only findings at or above the chosen severity. The full report is always shown — the filter section is additive.
Accepted levels (from lowest to highest): LOW, MEDIUM, HIGH, CRITICAL.
Without --filter, the section is omitted. Works in both single-project and multiscan modes; in multiscan, findings are grouped by project inside the filter section.
The --fix-dry-run flag tests whether the suggested fix versions can be applied without dependency conflicts — no files are modified.
For each vulnerability found, it:
- Selects the lowest fix version higher than the currently installed version
- Runs
uv pip install <package>==<fix_version> --dry-run(orpoetry add/pip installdepending on the project) - Reports whether the resolution succeeds or produces a conflict
════════════════════════════════════════════════════════════
pyau — Fix Dry-run Report
════════════════════════════════════════════════════════════
Packages checked : 1
Resolves cleanly : 1
Conflicts : 0
No fix available : 0
════════════════════════════════════════════════════════════
cryptography → 46.0.7 ✅ resolves cleanly
Applying the fix (editing
pyproject.toml/ lockfile) is planned for a future--fix-applyflag.
- Parses your lockfile to get exact resolved versions
- Sends a single batch request to the OSV API
- Fetches full details (severity, fix version) for each vulnerability found in parallel
- Reports findings with CVSS score, label, and recommended fix version
In multiscan mode, all projects are also scanned in parallel.
pyvulscan includes an MCP (Model Context Protocol) server that lets Claude Code scan for vulnerabilities directly, without leaving the chat.
pip install pyvulscan[mcp]
# or with pipx
pipx install pyvulscan[mcp]
# or with uv
uv tool install pyvulscan[mcp]Project-level — create .mcp.json in your project root (recommended):
{
"mcpServers": {
"pyvulscan": {
"command": "pyvulscan-mcp"
}
}
}Global CLI — add once and use across all projects:
claude mcp add pyvulscan pyvulscan-mcpClaude Desktop — edit ~/.config/claude/claude_desktop_config.json (macOS/Linux) or %APPDATA%\Claude\claude_desktop_config.json (Windows):
{
"mcpServers": {
"pyvulscan": {
"command": "pyvulscan-mcp"
}
}
}Without installing — use uvx:
{
"mcpServers": {
"pyvulscan": {
"command": "uvx",
"args": ["--from", "pyvulscan[mcp]", "pyvulscan-mcp"]
}
}
}Restart Claude Code after any config change.
| Tool | Description |
|---|---|
scan_vulnerabilities |
Scan a specific dependency file (uv.lock, poetry.lock, pyproject.toml, requirements.txt) |
scan_directory |
Auto-detect and scan all dependency files in a directory |
check_package |
Check a specific package by name — auto-detects the version from the project if not provided |
Example prompts:
Scan my current project for vulnerabilities
Check if the requests package has any known vulnerabilities
Scan the file requirements.txt in /path/to/project
All tools return JSON:
{
"success": true,
"packages_scanned": 10,
"vulnerabilities_found": 2,
"findings": [
{
"package": "django",
"version": "3.2.0",
"vuln_id": "GHSA-xxxx-xxxx-xxxx",
"aliases": ["CVE-2023-12345"],
"summary": "Description of the vulnerability",
"severity": { "score": 7.5, "label": "HIGH", "type": "CVSS:3.1" },
"fixed_versions": ["3.2.19", "4.1.8"]
}
]
}- Server not appearing — verify the config file syntax and restart Claude Code completely.
- Command not found — confirm the package is installed (
pip list | grep pyvulscan) or switch to theuvxoption. - Logs — Claude Code stores MCP logs at
~/.config/claude/logs/(macOS/Linux) or%APPDATA%\Claude\logs\(Windows).
# Install with dev dependencies
pip install -e ".[dev]"
# Run tests
pytest tests/
# Lint
ruff check src/