A local stdio MCP server that lets a host agent (Claude Code, Cursor, Codex, Windsurf, …) run vulngate and then explain and fix findings on the USER's own subscription. It is a thin wrapper: it shells out to the same CLI and never reimplements scan logic, and it makes NO LLM calls of its own.
Four tools with clear, action-oriented names (scan_repo, explain_finding, suggest_patch, verify_fix) and detailed descriptions (150 - 250 chars each). All tools have input schemas with typed parameters and descriptions. Descriptions are LLM-optimized and include boundary statements (read-only, write behavior, prerequisites). Output schemas are partially documented in code comments but not formally declared in the tool registration. Error handling is present but generic ('no findings.json, run scan_repo first'). No tool annotations (readOnlyHint, destructiveHint, idempotentHint) despite clear risk profiles. Parameter descriptions are strong; enums used appropriately (fail_on: critical|high|medium|low). Missing: formal output schema documentation, tool annotations, and richer error recovery guidance.
Explain a finding to the user in plain English — what the risk is and why it matters for them. Use plain_summary as a starting point. Do not modify code. For secret findings, help the user rotate and remove the secret; do not echo the secret value back.
Run vulngate's deterministic security scanners (SAST via Semgrep, secrets via gitleaks, dependency audit via pip-audit / npm audit) over a local repo and return normalized findings. Writes findings.json to the scanned directory — the ONLY write this server performs; it is otherwise read-only. Makes no LLM calls itself. Call this first, then use the returned finding ids with explain_finding and suggest_patch.
Draft a MINIMAL patch that fixes only this finding, then present the diff to the user for approval before applying it. This tool does not write or apply code — proposing and applying stay with the agent and the human.
Re-scan after a fix and confirm the finding's stable id is actually gone. The stable, line-independent id is what makes this trustworthy: an edit that shifts code around keeps the id, so a disappearance means the *pattern* is gone, not that lines moved. The critical safety check: a finding can also vanish because its scanner didn't run this time (not installed, errored) — that is NOT a fix. We confirm the owning scanner `completed` in the re-scan before ever reporting 'fixed'; otherwise the verdict is 'inconclusive'.
No tool annotations (readOnlyHint, destructiveHint, idempotentHint) despite explicit risk profiles. scan_repo and verify_fix perform writes; explain_finding and suggest_patch are read-only. Annotations enable agents to reason about safety and retry semantics.
Output schemas not formally declared in tool registration. Code comments describe return structure (e.g., 'returns dict[str, Any]'), but LLMs cannot parse comments. Formal schema documentation is missing.
Error messages are generic and lack recovery guidance. 'no findings.json, run scan_repo first' is present, but other errors (e.g., scanner timeout, malformed finding_id) do not suggest next steps or alternatives.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 66 | 2026-07-28+ | v2 |
suggest_patch description states 'This tool does not write or apply code' but does not clarify what it DOES return (e.g., diff format, patch structure). LLMs need to know the output format to plan downstream steps.
verify_fix has complex logic (scanner completion check, inconclusive verdict) but the description does not explain the three possible outcomes (fixed, inconclusive, not-found). LLMs cannot reason about partial success without explicit outcome documentation.