Review a pull request

Most security review is spent on the wrong thing: reading unchanged code, or reading changed code without knowing whether the dependency it added is maintained. Scope to the diff, and check the dependencies first.

Start with what was added

Dependency changes carry more risk per line than anything else in a PR, because you are accepting code nobody on the team has read.

For each dependency this PR adds or upgrades, call vulnetix_package_search with the right ecosystem. Report vulnerability count, max severity, KEV membership, EOL status, scorecard, and the recommended safe version.

For an upgrade, the question is narrower: does the new version fix something, or introduce something:

Compare the advisories affecting the old and new versions.

Then the changed code

That part needs your repository, so it is a local prompt:

/mcp__vulnetix__vulnetix_code_review_security --base origin/main

Runs SAST, SCA, secret detection, container and IaC checks against the diff only, plus a license check, and produces a structured review comment. With gh available it can post it.

Individually:

/mcp__vulnetix__vulnetix_sast_scan --paths src/
/mcp__vulnetix__vulnetix_secret_scan --staged-only
/mcp__vulnetix__vulnetix_iac_scan
/mcp__vulnetix__vulnetix_container_scan

Coach rather than only catch

For a PR touching auth, crypto, deserialization, SQL or file handling:

/mcp__vulnetix__vulnetix_secure_code_write authentication

Or the tool, for the weakness class behind a specific advisory:

{ "identifier": "CVE-2021-44228", "cweId": "CWE-502", "language": "java" }

Returns an unsafe example, a safe replacement, and the review checks that would catch the unsafe form. That last one is reusable: it turns one review into a checklist.

A gate that can fail

Reviews that only produce prose get skimmed. Ask for a verdict:

For every dependency added in this diff, call vulnetix_package_search and vulnetix_kev_status. Output ONLY a JSON object: {"verdict":"pass"|"fail","reasons":[...]}. Fail if any added package has a KEV-listed vulnerability with no fixed version.

VERDICT=$(agent --prompt-file gate.md | tail -1)
echo "$VERDICT" | jq -e '.verdict == "pass"' || {
  echo "$VERDICT" | jq -r '.reasons[]'; exit 1
}
Warning

A model deciding your merge gate is a judgement call, and it can be wrong in both directions, blocking a safe upgrade or waving through something it misread. For a hard gate use the CLI, which exits non-zero itself with no model in the path:

vulnetix scan --evaluate-sca --severity high --exploits weaponized

The MCP server is better at explaining and prioritising than at being the last word. Use both: the CLI blocks, the agent explains why.

What good output looks like

A review that says “3 highs, 12 mediums” has told the author nothing about what to do. Aim for:

lodash@4.17.20 → blocking. CVE-2021-23337, command injection, CVSS 7.2. Not in KEV, EPSS 0.004, so it is not being exploited. A fixed version exists and the upgrade is one patch release. Pin 4.17.21. One-line change, no API difference.

left-pad@1.3.0 → question. No known vulnerabilities, but the scorecard is 2.1 and the last commit was 2018. Fine to merge; worth an issue to replace it.

Both lines carry the fact, the exploitation reality, the fix and the effort. That is what makes a review actionable rather than a list.

In CI

The same prompts run unattended. See Agents in CI for secret handling, scoping to the diff, and keeping quota under control.