11-scanner SAST/DAST MCP server with closed-loop remediation, SBOM/SARIF, and CI integrations
11-scanner SAST/DAST MCP server with closed-loop remediation, SBOM/SARIF, and CI integrations
SAST MCP Server ยท v0.8.1
by Skyrxin
SAST MCP Server
Static Application Security Testing (SAST) for AI agents. A production-ready MCP server that gives any AI agent the ability to scan code for security vulnerabilities.
Supports 11 industry-standard scanners:
| Scanner | Languages / Scope | Type |
|---|---|---|
| Bandit | Python | Security linter |
| njsscan | JavaScript, Node.js | Static analysis |
| Bearer | Python, JS, Ruby, Java, Go, PHP | Data-flow SAST |
| Semgrep | 30+ languages | Rule-based SAST |
| Trivy | All (CVEs, Secrets, IaC, images) | Multi-scanner |
| CodeQL | Python, JS, Java, Go, C/C++, C#, Ruby, Swift | Semantic SAST |
| Checkov | Terraform, K8s, Docker, CloudFormation | IaC policy scanner |
| Gitleaks | All (.git history) | Deep secret scanning |
| OSV-Scanner | Multiple (lockfiles, sboms) | SCA |
| Grype | Containers, OS packages, lockfiles, SBOMs | SCA / image scanning |
| OWASP ZAP | RUNTIME | Dynamic (DAST) via Docker |
Works with any MCP-compatible agent: Gemini CLI, Claude Desktop, OpenAI Agents, Cursor, Windsurf, and more.
Features
- ๐ 11 SAST/SCA/DAST scanners with a unified output format
- ๐ณ AST-aware context โ shows the full enclosing function, not just a line number
- ๐ Severity & confidence filtering โ focus on what matters
- ๐ Git diff mode โ scan only modified files for incremental reviews
- ๐ Ignore management โ suppress false positives with audit trail
- ๐ Pagination โ handle large codebases without overwhelming the agent
- ๐ Dual transport โ stdio (local) or Streamable HTTP (remote deployments)
- ๐ JWT & API key authentication โ secure remote deployments
- ๐ฆ One command install โ
pip install sast-mcp-server - ๐ Multi-scanner mode โ run all installed scanners in parallel with deduplication
- ๐ SARIF export โ CI/CD integration with GitHub, GitLab, Azure DevOps
- ๐๏ธ IaC scanning โ Terraform, Kubernetes, Docker security policies
- ๐ Secret detection โ find hardcoded API keys, tokens, and passwords in code and git history
- ๐ฆ SCA / dependency CVEs โ scan lock files for known vulnerabilities against the OSV database
- ๐ท๏ธ DAST โ dynamic baseline scans of running apps via OWASP ZAP + Docker
- ๐ Baselines & trend tracking โ cache scans and diff against a saved baseline
- ๐ค MCP Prompts & Resources โ pre-built security workflows and live dashboards for agents
- ๐ค Dashboard integrations โ push SARIF results to DefectDojo or GitHub Code Scanning
- ๐ฉน AI-assisted remediation โ generate fix prompts and apply agent-written patches via
git apply
Quick Start
Install
pip install sast-mcp-server
Or run directly without installing:
uvx sast-mcp-server
Install at least one scanner
# Python projects
pip install bandit
# JavaScript/Node.js projects
pip install njsscan
# Multi-language (recommended)
pip install semgrep
# IaC, secrets, and dependency CVEs (recommended)
# See: https://aquasecurity.github.io/trivy/latest/getting-started/installation/
# IaC policy scanning
pip install checkov
# Deep semantic analysis
# See: https://github.com/github/codeql-cli-binaries/releases
# Data-flow analysis
# See: https://docs.bearer.com/installation/
Usage with AI Agents
Gemini CLI
Install as an extension:
gemini extensions install https://github.com/Skyrxin/sast-mcp-server
Or add to your ~/.gemini/settings.json:
{
"mcpServers": {
"sast": {
"command": "uvx",
"args": ["sast-mcp-server"]
}
}
}
Claude Desktop
Add to your claude_desktop_config.json:
{
"mcpServers": {
"sast": {
"command": "uvx",
"args": ["sast-mcp-server"]
}
}
}
See full Claude Desktop guide.
Cursor IDE
Add to Cursor Settings โ MCP Servers:
{
"mcpServers": {
"sast": {
"command": "uvx",
"args": ["sast-mcp-server"]
}
}
}
See full Cursor guide.
OpenAI Agents SDK
from agents.mcp import MCPServerStdio
sast_server = MCPServerStdio(command="uvx", args=["sast-mcp-server"])
See full OpenAI guide.
Available MCP Tools
scan_vulnerabilities
Scan a directory for security vulnerabilities using a specific scanner.
| Parameter | Type | Default | Description |
|---|---|---|---|
target_path |
string | required | Path to scan |
scanner_name |
string | "bearer" |
Scanner: bandit, njsscan, bearer, semgrep, trivy, codeql, checkov |
min_severity |
string | "LOW" |
Minimum severity: LOW, MEDIUM, HIGH, CRITICAL |
min_confidence |
string | "LOW" |
Minimum confidence: LOW, MEDIUM, HIGH |
git_diff_only |
bool | false |
Only scan git-modified files |
limit |
int | 50 |
Max findings to return |
offset |
int | 0 |
Pagination offset |
scan_all
Run ALL installed scanners in parallel with automatic deduplication. Recommended for comprehensive security scanning.
| Parameter | Type | Default | Description |
|---|---|---|---|
target_path |
string | required | Path to scan |
min_severity |
string | "MEDIUM" |
Minimum severity (higher default to reduce noise) |
min_confidence |
string | "LOW" |
Minimum confidence |
git_diff_only |
bool | false |
Only scan git-modified files |
limit |
int | 50 |
Max findings to return |
offset |
int | 0 |
Pagination offset |
scan_git_history
Scan the entire .git history for leaked secrets and credentials using Gitleaks.
| Parameter | Type | Default | Description |
|---|---|---|---|
target_path |
string | "." |
Path to the repository root (must contain .git) |
min_severity |
string | "LOW" |
Minimum severity to report |
run_active_scan
Run a dynamic (DAST) baseline scan with OWASP ZAP by orchestrating a Docker Compose stack.
| Parameter | Type | Default | Description |
|---|---|---|---|
target_path |
string | required | Directory containing the docker-compose file |
docker_compose_file |
string | required | Name of the docker-compose file (e.g. docker-compose.yml) |
target_url |
string | required | URL of the running app once it's up (e.g. http://localhost:8080) |
export_sarif
Export scan results in SARIF 2.1.0 format for CI/CD integration.
| Parameter | Type | Default | Description |
|---|---|---|---|
target_path |
string | required | Path to scan |
scanner_name |
string | "bearer" |
Scanner to use |
min_severity |
string | "LOW" |
Minimum severity |
min_confidence |
string | "LOW" |
Minimum confidence |
output_path |
string | "" |
File path to write SARIF (empty = return as string) |
list_scanners
List available scanners, their installation status, and supported languages.
ignore_vulnerability
Suppress a finding from future scans (with audit trail).
unignore_vulnerability
Re-enable a previously suppressed finding.
list_ignored_vulnerabilities
Show all currently suppressed findings for a project.
save_baseline
Run a scan and cache the results as a named baseline for future trend comparison.
| Parameter | Type | Default | Description |
|---|---|---|---|
target_path |
string | required | Path to scan |
tag |
string | "latest" |
Name for this baseline (e.g. main, pre-release) |
scanner_name |
string | "bearer" |
Scanner to use |
min_severity |
string | "LOW" |
Minimum severity to include |
min_confidence |
string | "LOW" |
Minimum confidence to include |
compare_baseline
Compare a fresh scan against a saved baseline to highlight new and fixed findings.
| Parameter | Type | Default | Description |
|---|---|---|---|
target_path |
string | required | Path to scan |
tag |
string | "latest" |
Baseline tag to compare against |
scanner_name |
string | "bearer" |
Scanner to use |
min_severity |
string | "LOW" |
Minimum severity to include |
min_confidence |
string | "LOW" |
Minimum confidence to include |
upload_to_defectdojo
Import a SARIF export into a DefectDojo engagement. Requires DEFECTDOJO_URL
and DEFECTDOJO_API_KEY environment variables.
| Parameter | Type | Default | Description |
|---|---|---|---|
sarif_path |
string | required | Path to a SARIF file from export_sarif |
engagement_id |
int | required | Target DefectDojo engagement ID |
active |
bool | true |
Mark imported findings active |
verified |
bool | false |
Mark imported findings verified |
upload_to_github
Upload a SARIF report to GitHub Code Scanning. Requires a GITHUB_TOKEN with
security_events: write scope.
| Parameter | Type | Default | Description |
|---|---|---|---|
sarif_path |
string | required | Path to a SARIF file from export_sarif |
repo |
string | required | Repository in owner/name form |
commit_sha |
string | required | Full commit SHA the results apply to |
ref |
string | required | Fully qualified ref, e.g. refs/heads/main |
generate_fix_prompt
Package a cached finding's vulnerable code and context into an LLM-ready prompt
that asks for a strict unified diff fix.
| Parameter | Type | Default | Description |
|---|---|---|---|
target_path |
string | required | Scanned project root (with .sast-mcp-cache) |
finding_hash |
string | required | Hash of the finding to fix (from scan output) |
context_window |
int | 15 |
Source lines to include before/after the finding |
apply_patch
Apply an agent-generated unified diff to disk via git apply (paths that escape
the target directory are rejected).
| Parameter | Type | Default | Description |
|---|---|---|---|
target_path |
string | required | Directory the patch paths are relative to |
patch |
string | required | The unified diff text to apply |
check_only |
bool | false |
Validate without modifying files |
evaluate_policy
Run all scanners and return an explicit PASS/FAIL verdict for CI gating.
| Parameter | Type | Default | Description |
|---|---|---|---|
target_path |
string | required | Path to scan |
max_critical |
int | 0 |
Max allowed CRITICAL (โ1 = unlimited) |
max_high |
int | -1 |
Max allowed HIGH (โ1 = unlimited) |
max_medium |
int | -1 |
Max allowed MEDIUM (โ1 = unlimited) |
fail_on_new |
bool | false |
Fail if findings are new vs. a scan_all baseline |
baseline_tag |
string | "latest" |
Baseline tag used when fail_on_new |
output_format |
string | "markdown" |
markdown or json |
export_sbom
Run all scanners and export an SBOM / vulnerability report. In CycloneDX mode, if
Syft is installed the component inventory is the
full dependency list (not just vulnerable packages).
| Parameter | Type | Default | Description |
|---|---|---|---|
target_path |
string | required | Path to scan |
output_path |
string | "" |
File to write (empty = return inline) |
min_severity |
string | "LOW" |
Minimum severity to include |
sca_only |
bool | true |
Only dependency (SCA) findings; false = all |
format |
string | "cyclonedx" |
cyclonedx or spdx (SPDX 2.3) |
generate_report
Run all scanners and render an executive security report.
| Parameter | Type | Default | Description |
|---|---|---|---|
target_path |
string | required | Path to scan |
output_path |
string | "" |
File to write (empty = return inline HTML; required for PDF) |
min_severity |
string | "LOW" |
Minimum severity to include |
format |
string | "html" |
html or pdf (needs the [pdf] extra) |
compliance_report
Map findings to a compliance framework and report the posture.
| Parameter | Type | Default | Description |
|---|---|---|---|
target_path |
string | required | Path to scan |
framework |
string | "owasp" |
owasp, sans, pci, or cis |
output_path |
string | "" |
Optional file to write the markdown report |
min_severity |
string | "LOW" |
Minimum severity to include |
scan_image
Scan a container image reference for vulnerabilities and secrets (Trivy or Grype).
| Parameter | Type | Default | Description |
|---|---|---|---|
image_ref |
string | required | Image reference, e.g. nginx:1.25 |
scanner_name |
string | "trivy" |
trivy or grype |
min_severity |
string | "MEDIUM" |
Minimum severity to report |
output_format |
string | "markdown" |
markdown or json |
remediate_and_verify
Closed-loop remediation: dry-run a patch, apply it, re-scan, and confirm the
finding is gone (rolling the patch back on failure).
| Parameter | Type | Default | Description |
|---|---|---|---|
target_path |
string | required | Project root (with a .sast-mcp-cache) |
finding_hash |
string | required | Hash of the finding to fix |
patch |
string | required | Unified diff to apply |
scanner_name |
string | "" |
Re-scan scanner (default: the finding's scanner) |
auto_rollback |
bool | true |
Revert the patch if verification fails |
import_sarif
Ingest an external SARIF file (Snyk, Veracode, CI jobs, โฆ) into the normalized
finding pipeline so it joins dedup / baselines / dashboards.
| Parameter | Type | Default | Description |
|---|---|---|---|
target_path |
string | required | Project root the results belong to |
sarif_path |
string | required | Path to a SARIF 2.1.0 file |
scanner_name |
string | "external" |
Source scanner name to record |
save |
bool | true |
Cache the imported findings |
triage_finding
Get an exploitability/false-positive assessment prompt, or record a CycloneDX VEX
decision (suppressing dispositions also add the finding to the ignore-list).
| Parameter | Type | Default | Description |
|---|---|---|---|
target_path |
string | required | Project root (with a .sast-mcp-cache) |
finding_hash |
string | required | Hash of the finding to triage |
disposition |
string | "" |
exploitable, not_affected, false_positive, resolved, in_triage (empty = return a prompt) |
justification |
string | "" |
Rationale / CycloneDX justification keyword |
comment_on_pr
Post a security summary on a GitHub PR or GitLab merge request. Requires
GITHUB_TOKEN or GITLAB_TOKEN (+ optional GITLAB_URL).
| Parameter | Type | Default | Description |
|---|---|---|---|
provider |
string | required | github or gitlab |
repo |
string | required | owner/name (GitHub) or project ID/path (GitLab) |
pr_number |
int | required | PR number / MR IID |
body |
string | required | Markdown comment body |
notify_slack / notify_teams
Send a notification to a Slack or Microsoft Teams incoming webhook
(SLACK_WEBHOOK_URL / TEAMS_WEBHOOK_URL).
create_jira_issue
Open a Jira issue for a finding. Requires JIRA_URL, JIRA_EMAIL, JIRA_API_TOKEN.
| Parameter | Type | Default | Description |
|---|---|---|---|
project_key |
string | required | Jira project key (e.g. SEC) |
summary |
string | required | Issue title |
description |
string | required | Issue description |
issue_type |
string | "Bug" |
Jira issue type |
Tip:
scan_vulnerabilities,scan_all, andscan_git_historyaccept
output_format="json"for machine-readable results in CI/agent pipelines.
Auth: On HTTP transports every tool is scope-gated โ
scan:read(scans,
reports, exports),scan:write(baselines, patches, uploads, notifications),
config:write(ignore list). SetSAST_MCP_JWT_SECRETand issue scoped JWTs.
SARIF / CI/CD Integration
Export scan results in SARIF 2.1.0 format for integration with CI/CD platforms:
# In your CI pipeline, use the MCP tool:
# export_sarif(target_path=".", scanner_name="semgrep", output_path="results.sarif")
# Then upload to GitHub Code Scanning:
# gh api /repos/{owner}/{repo}/code-scanning/sarifs -f sarif=@results.sarif
Compatible with: GitHub Code Scanning, GitLab SAST, Azure DevOps, VS Code SARIF Viewer.
Remote Deployment (Streamable HTTP)
For remote or cloud-hosted deployments, the 2026 MCP standard uses Streamable HTTP.
You can secure the server with JWT Bearer Authentication by setting a secret. Alternatively, for backward compatibility, you can use a static API key.
# Set JWT secret for secure authentication
export SAST_MCP_JWT_SECRET="your_hmac_sha256_secret"
# Or use the legacy API key method
export SAST_MCP_API_KEY="your_secure_api_key_here"
# Start the server with streamable-http transport
uv run sast-mcp-server --transport streamable-http --port 8080 --host 0.0.0.0
Note: The old
ssetransport is deprecated. Please migrate tostreamable-http.
Core Workflows
1. Unified Vulnerability Scanning
Run any of the installed scanners individually (scan_vulnerabilities(scanner_name="bandit")) or run all of them at once using scan_all.
2. Deep Secret & Dynamic Scanning
Use scan_git_history to find API keys leaked years ago, or run_active_scan to spin up your application with Docker Compose and test it dynamically with OWASP ZAP.
3. Baseline & Trend Tracking
Save a scan as a named baseline and compare future scans against it to track new vulnerabilities, fixed issues, and severity trends over time.
save_baseline(target_path=".", tag="main")compare_baseline(target_path=".", tag="main")
4. CI/CD Integration
Export scan results to SARIF format (export_sarif) to integrate with GitHub Code Scanning, GitLab SAST, or any other SARIF-compatible platform.
5. MCP Prompts (Security Workflows)
Pre-built security workflows that guide AI agents:
security_review: Full codebase assessmentfix_vulnerability: Focused remediation advisorpr_security_check: Scan only git diffs and enforce a severity gatecompliance_report: Generate an OWASP Top 10 or PCI-DSS report
6. MCP Resources (Security Dashboards)
Read-only contextual data for AI agents without running a full scan:
sast://dashboard/{path}: Security posture dashboardsast://config: Server configuration and statussast://scanners: Available scanners and languagessast://cache/{path}/latest: Latest scan results metadata
7. Dashboard Upload & AI-Assisted Remediation
Push SARIF results to external platforms and remediate findings with agent-written patches:
upload_to_defectdojo/upload_to_github: Push a SARIF export to a dashboardgenerate_fix_prompt: Build an LLM-ready prompt for a specific findingapply_patch: Apply the resulting unified diff viagit apply
Docker
# Minimal image (bandit, njsscan, bearer)
docker build -t sast-mcp-server .
# Full image โ bundles all CLI scanners (semgrep, trivy, checkov, gitleaks,
# osv-scanner, โฆ) so scan_all works out of the box
docker build -f Dockerfile.full -t sast-mcp-server:full .
docker run -p 8080:8080 -e SAST_MCP_JWT_SECRET=your-secret \
sast-mcp-server:full --transport streamable-http
CodeQL and OWASP ZAP are not bundled in the image โ CodeQL ships a multi-GB
bundle (mount at runtime) and ZAP'srun_active_scanorchestrates Docker on
the host.
Configuration
Environment Variables
| Variable | Default | Description |
|---|---|---|
SAST_MCP_TIMEOUT |
300 |
Scan timeout in seconds |
SAST_MCP_LOG_LEVEL |
INFO |
Log level: DEBUG, INFO, WARNING, ERROR |
SAST_MCP_CACHE_TTL |
86400 |
Cache time-to-live in seconds (non-tagged scans) |
SAST_MCP_CACHE_MAX_SCANS |
200 |
Max non-tagged cached scans to retain (0 = unlimited) |
SAST_MCP_HTTP_RETRIES |
3 |
Retry attempts for integration HTTP calls |
SAST_MCP_HTTP_TIMEOUT |
60 |
Per-request timeout (s) for integration HTTP calls |
SAST_MCP_MAX_CONCURRENT_SCANS |
8 |
Max subprocess scanners running at once (0 = unlimited) |
SAST_MCP_RATE_LIMIT_PER_MIN |
0 |
Per-client request budget for HTTP transports (0 = disabled) |
SAST_MCP_SCANNER_TIMEOUTS |
(none) | JSON map of per-scanner timeout overrides, e.g. {"trivy":600} |
SAST_MCP_API_KEY |
(none) | API key for remote (HTTP) authentication |
SAST_MCP_JWT_SECRET |
(none) | HMAC-SHA256 secret for JWT bearer auth (scopes enforced per tool) |
DEFECTDOJO_URL |
(none) | Base URL of a DefectDojo instance (for upload_to_defectdojo) |
DEFECTDOJO_API_KEY |
(none) | DefectDojo API v2 token |
GITHUB_TOKEN |
(none) | Token with security_events: write (SARIF upload + PR comments) |
GITLAB_TOKEN |
(none) | GitLab token with api scope (for comment_on_pr) |
GITLAB_URL |
https://gitlab.com |
GitLab base URL (self-managed override) |
SLACK_WEBHOOK_URL |
(none) | Slack incoming webhook (for notify_slack) |
TEAMS_WEBHOOK_URL |
(none) | Microsoft Teams incoming webhook (for notify_teams) |
JIRA_URL / JIRA_EMAIL / JIRA_API_TOKEN |
(none) | Jira Cloud credentials (for create_jira_issue) |
Operational endpoints (HTTP transports)
When running with --transport streamable-http, the server exposes:
| Endpoint | Purpose |
|---|---|
GET /health |
Liveness probe โ 200 with version while the process is up |
GET /ready |
Readiness probe โ lists installed scanners (503 if none) |
GET /metrics |
Prometheus text exposition (tool calls, scan durations, findings) |
Incremental scans
scan_vulnerabilities and scan_all accept use_cache=true: the server
fingerprints the target's files and reuses the previous scan when nothing has
changed, so repeated scans in a session are fast.
Development
# Clone and install with dev dependencies
git clone https://github.com/Skyrxin/sast-mcp-server.git
cd sast-mcp-server
pip install -e ".[dev]"
# Run tests
pytest tests/ -v
# Lint
ruff check sast_mcp_server/
# Run locally
python -m sast_mcp_server
Project Structure
sast_mcp_server/
โโโ __init__.py # Package version
โโโ __main__.py # python -m entry point
โโโ server.py # FastMCP server with all tools + /health /ready /metrics
โโโ models.py # Typed data models (Finding, Severity, etc.)
โโโ config.py # Central validated settings (env-driven)
โโโ sarif.py # SARIF 2.1.0 export and parsing
โโโ aggregator.py # Multi-scanner parallel execution + deduplication
โโโ cache.py # Scan caching, baselines, comparison, fingerprints
โโโ auth.py # JWT / API key authentication for remote transports
โโโ metrics.py # In-process Prometheus metrics
โโโ ratelimit.py # Per-client token-bucket rate limiting
โโโ prompts.py # MCP prompt templates (security workflows)
โโโ resources.py # MCP resources (sast:// dashboards and metadata)
โโโ scanners/
โ โโโ base.py # Abstract scanner base class
โ โโโ factory.py # Scanner registry and factory
โ โโโ bandit.py # Bandit (Python)
โ โโโ njsscan.py # njsscan (JavaScript)
โ โโโ bearer.py # Bearer (multi-language)
โ โโโ semgrep.py # Semgrep (30+ languages)
โ โโโ trivy.py # Trivy (CVEs, secrets, IaC)
โ โโโ codeql.py # CodeQL (deep semantic SAST)
โ โโโ checkov.py # Checkov (IaC policies)
โ โโโ gitleaks.py # Gitleaks (git history secret scanning)
โ โโโ osv_scanner.py # OSV-Scanner (SCA / dependency CVEs)
โ โโโ grype.py # Grype (SCA + container image scanning)
โ โโโ zap.py # OWASP ZAP (DAST via Docker)
โโโ enrichment/
โ โโโ ast_context.py # AST-aware code context extraction
โ โโโ git_diff.py # Git diff for incremental scanning
โ โโโ ignore_manager.py # Finding ignore list management
โ โโโ patch_prompt.py # Builds LLM prompts to fix a cached finding
โ โโโ patch_apply.py # Applies/reverts agent-generated diffs via `git apply`
โโโ reporting/
โ โโโ sbom.py # CycloneDX SBOM/VDR (+ optional Syft inventory)
โ โโโ spdx.py # SPDX 2.3 SBOM
โ โโโ vex.py # CycloneDX VEX statements (triage decisions)
โ โโโ html.py # Standalone HTML executive report
โ โโโ pdf.py # PDF report (optional [pdf] extra)
โ โโโ compliance.py # OWASP / SANS / PCI / CIS mapping
โโโ integrations/
โโโ defectdojo.py # Upload SARIF to DefectDojo
โโโ github.py # GitHub Code Scanning + PR comments
โโโ gitlab.py # GitLab MR comments
โโโ slack.py / teams.py # Webhook notifications
โโโ jira.py # Create Jira issues