secscan-mcp
# secscan-mcp
[](https://github.com/openjkai/secscan_mcp/actions/workflows/ci.yml)
[](https://pypi.org/project/secscan-mcp/)
[](https://pypi.org/project/secscan-mcp/)
A portable **MCP server** for security scanning — works with **any AI coding assistant** that supports the [Model Context Protocol](https://modelcontextprotocol.io): Cursor, VS Code, Claude Desktop, Windsurf, Zed, Continue, and more.
Scan codebases for **hardcoded secrets**, **SAST issues**, **vulnerable dependencies**, and **IaC misconfigurations** — one install, one normalized report format.
The built-in **custom** scanner works with no extra tools. Install optional CLIs for broader coverage ([below](#optional-scanners)).
## Quick start
**Requires Python 3.11+.** If `pip install secscan-mcp` says *"No matching distribution found"*, your default `python3` is likely too old — use `python3.11 -m pip install secscan-mcp` or install Python 3.11+ first.
**1. Install** from [PyPI](https://pypi.org/project/secscan-mcp/):
```bash
pip install secscan-mcp
# or explicitly:
python3.11 -m pip install secscan-mcp
```
Or run without installing (requires [uv](https://docs.astral.sh/uv/)):
```bash
uvx secscan-mcp
```
For MCP config with `uvx`, use `"command": "uvx"` and `"args": ["secscan-mcp"]` — see [setup guide](docs/setup.md).
<details>
<summary>Install from source</summary>
```bash
git clone https://github.com/openjkai/secscan_mcp.git
cd secscan_mcp && pip install .
```
</details>
**2. Add to your IDE** — pick your client:
| IDE / client | Config file | Guide |
|--------------|-------------|-------|
| Cursor | `~/.cursor/mcp.json` | [setup →](docs/setup.md#cursor) |
| VS Code | `.vscode/mcp.json` | [setup →](docs/setup.md#vs-code-github-copilot) |
| Claude Desktop | OS-specific (see guide) | [setup →](docs/setup.md#claude-desktop) |
| Claude Code | `~/.claude/settings.json` | [setup →](docs/setup.md#claude-code) |
| Windsurf | `~/.codeium/windsurf/mcp_config.json` | [setup →](docs/setup.md#windsurf) |
| Others | — | [Full setup guide](docs/setup.md) |
Minimal config (works in Cursor, Claude Desktop, Windsurf):
```json
{
"mcpServers": {
"secscan": {
"command": "uvx",
"args": ["secscan-mcp"]
}
}
}
```
If you installed with `pip install secscan-mcp`, you can use `"command": "secscan-mcp"` instead.
**3. Verify** — ask your agent: *"Call `list_available_scanners` and scan_secrets on this project."*
## MCP tools
| Tool | Purpose |
|------|---------|
| `list_available_scanners` | Which engines are installed on this machine |
| `scan_secrets` | Hardcoded credentials and secrets (optionally scan git commit history) |
| `scan_code` | SAST (semgrep, bandit) |
| `scan_dependencies` | Vulnerable packages (osv-scanner) |
| `scan_iac` | IaC misconfigurations (checkov) |
| `scan_all` | All available scanners, one unified report |
| `explain_finding` | Remediation hints for a `rule_id` |
Most scan tools accept `path` (directory to scan) and optional `severity_threshold` (`critical`, `high`, `medium`, `low`, `info`).
`scan_secrets` also accepts `include_git_history` (boolean). When `true`, scans past git commits for secrets removed from the working tree but still present in history — no extra tools required beyond `git`. `scan_all` accepts `include_git_history` too.
## Suppressing false positives
Silence known-good findings without changing scanner behavior. Both mechanisms apply to **every** engine, and each report includes a `suppressed` count so nothing is hidden silently.
**`.secscanignore`** at the project root — gitignore-style path globs:
```
# ignore vendored code and test fixtures
vendor/
tests/fixtures/
*.min.js
```
**Inline `# nosecscan`** on the offending source line — suppress all rules there, or scope to specific rule IDs:
```python
API_TOKEN = get_token() # real code, no marker
LEGACY_KEY = "AKIA..." # nosecscan
DEMO_JWT = "eyJ..." # nosecscan: hardcoded-jwt
```
## Optional scanners
Install any of these to extend coverage. Missing CLIs are skipped — the server still runs.
| Engine | Category | Install (example) |
|--------|----------|-------------------|
| gitleaks | secrets | `brew install gitleaks` |
| semgrep | SAST | `pip install semgrep` |
| bandit | SAST (Python) | `pip install bandit` |
| osv-scanner | dependencies | `brew install osv-scanner` |
| checkov | IaC | `pip install checkov` |
After installing, run `list_available_scanners` again to confirm.
## Example prompts
- *"Call `list_available_scanners` and tell me what's installed."*
- *"Run `scan_secrets` with include_git_history on this repo — check if any secrets were ever committed."*
- *"Run `scan_all` with severity_threshold high and summarize the findings."*
- *"Explain the rule `internal-api-key`."*
- *"Add a `.secscanignore` for the `tests/fixtures` directory and re-run the scan."*
## Configuration
Environment variables (optional):
| Variable | Default | Description |
|----------|---------|-------------|
| `SECSCAN_DEFAULT_TIMEOUT_SECONDS` | `300` | Per-engine scan timeout |
| `SECSCAN_MAX_FINDINGS` | `500` | Max findings per report |
| `SECSCAN_GIT_MAX_COMMITS` | `500` | Max commits scanned in git history mode |
Pass via MCP config `env` block — see [setup guide](docs/setup.md#environment-variables).
## Development
```bash
make install-dev # editable install + dev tools
make check # lint + typecheck + test
```
See [docs/CONTRIBUTING.md](docs/CONTRIBUTING.md) and [PLAN.md](PLAN.md).
## License
MIT
TDQS
Scored across 7 tools
Each tool has a clearly distinct purpose: scan_secrets, scan_code, scan_dependencies, and scan_iac target different security domains; scan_all is a meta-runner; list_available_scanners and explain_finding serve informational and post-scan roles. No overlap or ambiguity.
All tool names follow a consistent verb_noun pattern with a logical prefix: scan_ for scanning actions, list_ for listing, and explain_ for explanation. The naming is predictable and coherent.
Seven tools is an ideal scope for a security scanning MCP server. It covers the major scan types plus utilities for listing available scanners and explaining findings, without unnecessary bloat or missing essentials.
The tool set covers the full lifecycle of security scanning: pre-scan discovery (list_available_scanners), individual scans for all major domains (secrets, code, dependencies, IaC), a combined scan (scan_all), and post-scan remediation (explain_finding). No obvious gaps for typical use cases.