gmi-security-mcp
gmi-security-mcp is a 15-tool security MCP server for coding agents that triages semgrep findings, scans repos, checks OSV advisories, verifies findings with PoCs, manages finding records, and controls cost/safety.
Triage one semgrep/scanner finding with GMI Inference, returning verdict, severity, confidence, reason, fix, cost, and a stored finding ID.
Scan repositories with semgrep and osv-scanner, run two-stage triage, estimate/dry-run costs, and produce JSON reports.
Check one lockfile against OSV advisories without any GMI call.
Explain CVE, GHSA, or OSV IDs from advisories with citations and optional model-written summary.
Draft private-disclosure Markdown from confirmed/real findings; never sends, forks, pushes, opens PRs, or emails.
Estimate run cost before spending, with default and maximum spend caps.
Verify findings using deterministic oracles and runnable PoCs, with safeguards for generated PoCs, host vs Docker execution, regression checks, and patch validation.
List, get, update, mark false-positive, and mark confirmed stored findings; confirmation requires reproduced verification.
List the custom semgrep rules pack and enable/disable per-repo scope policies.
Apply safety controls such as secret redaction, environment-only API key, write/apply gating, and scope warnings.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@gmi-security-mcp Triage this semgrep finding and show me the cost before running it"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
gmi-security-mcp
A security MCP server for coding agents, backed by GMI Inference. Your agent triages semgrep findings, scans repos, checks lockfiles against OSV, and verifies findings with a runnable PoC, all inside the editor, with the cost shown before every run.
PyPI: https://pypi.org/project/gmi-security-mcp/ — MCP Registry: https://registry.modelcontextprotocol.io/v0/servers?search=gmi-security-mcp — Repo: https://github.com/Jayanng/gmi-security-mcp
Install
Requires Python 3.13 or later and a GMI Inference API key. No GitHub token is needed for local repos.
pip install gmi-security-mcp
export GMI_API_KEY="your-gmi-key"
gmi-security-mcp --list-toolsThat prints the 15 tool names. Run the server as a stdio MCP server with gmi-security-mcp, or run the 12 built-in examples with mcp-test, which spends under $0.02 with the default model. pipx install gmi-security-mcp works the same way, in an isolated venv.
Related MCP server: SAST MCP Server
Quick start
Add the server to Claude Code with claude mcp add gmi-security-mcp -e GMI_API_KEY="your-gmi-key" -- gmi-security-mcp, or drop this in .mcp.json:
{
"mcpServers": {
"gmi-security-mcp": {
"command": "gmi-security-mcp",
"env": { "GMI_API_KEY": "your-gmi-key" }
}
}
}Config copies for Claude Code, Codex, and Cursor are in install/. Editor test status: Claude Code and Codex are tested for registration and tools/list only, Cursor is not tested end-to-end. See TUTORIAL.md section 2.
Tools
Tool | What it does |
| Triage one finding. One validated verdict: real or false positive, severity, confidence, reason, fix. |
| Scan a repo with semgrep and osv-scanner, then two-stage triage of each finding. Returns a JSON report. |
| Check one lockfile against OSV. No GMI call. |
| Explain a CVE, GHSA, or OSV id from its advisory, with citations. |
| Draft a private disclosure from a confirmed real finding. Drafts only, never sent. |
| Estimate a run before it spends anything. No GMI call, no spend. |
| Prove a finding with a deterministic oracle and a runnable PoC. |
| List stored findings, summaries only, no code. |
| One stored finding in full: code, evidence, verdict history, verification results. |
| Update a stored finding. A reason is required. |
| Mark a finding false positive, with a reason. |
| Mark a finding confirmed, with a reason. Only with a reproduced verification. |
| List the custom semgrep rules pack: 8 rules, all enabled by default. |
| Enable a scope policy for one repo from a scope file. |
| Disable the scope policy for one repo. |
Cost and safety
Estimate before every run. The default cap is $1.00 per tool call and cannot go above $5.00. A single finding typically costs $0.0001 to $0.001 with Gemini 3.5 Flash Lite. A model verdict alone never confirms a finding: only a deterministic oracle reproducing it does, and a generated PoC never runs on your host until you review and confirm it. Secrets are redacted before anything is sent to GMI, and the key comes from GMI_API_KEY only, never from a file. Drafts are never sent, opened as a PR, forked, pushed, or emailed by this server.
Docs
TUTORIAL.md: full worked tutorial, every command with real output, plus the reference appendix with tool details, cost records, limitations, and repo structure.
CHANGELOG.md: version history, including what is new in 0.5.8.
DECISIONS.md: design decisions and the audit record behind them.
DATA_SOURCES.md: where the model pricing comes from and when it was last re-checked live.
Development
python3 -m venv .venv
.venv/bin/pip install -e ".[dev]"
python3 -m pytest tests/ -qUnit tests need no key and no network. 328 tests pass. Live tests are separate and capped: $1.00 per full run, $5.00 total for the whole build.
License
MIT. See LICENSE.
Available Tools
15 toolscheck_osv_advisoryA
Check one lockfile against OSV with the local osv-scanner.
Parses the lockfile locally, then runs osv-scanner on it and returns advisories as facts: id, package, installed version, fixed version, severity, summary, and link. Packages with only a version range and no exact version are reported unresolved, never given a verdict. No GMI call is made.
Inputs: lockfile_path (required), ecosystem. Returns: result
draft_private_disclosureA
Draft a private disclosure from a confirmed real finding.
Uses the GitHub Security Lab report template, with the ssh-mcp-server host-key draft as the worked example of the format. Refuses when the verdict is not real, or when confidence is below 0.8 without explicit confirmation. When finding_id is given, the finding must be in the store with status confirmed, or triaged with verdict real and confidence at or above 0.8; otherwise the draft is refused and the result says why. Returns the draft as Markdown and writes it only when write_path is given. It is never sent, never opened as a PR, never forked, never pushed, never emailed. sent is always false. Writing the draft to write_path needs --allow-apply on the server command line; without it the call is refused. When --require-scope is set, the write target must sit inside a repo with scope enabled.
Inputs: repo (required), finding (required), db_path, finding_id, +4 more. Returns: result
estimate_costA
Estimate the cost of a run with no API call and no spend.
Returns typical and maximum cost in USD, the prompt token estimate, and the per-token pricing used. An unpriced model returns priced false and null costs.
Inputs: model (required), text_length_chars (required), max_tokens, n_findings. Returns: result
explain_cveA
Explain a CVE, GHSA, or OSV id from its advisory, with citations.
Fetches the advisory from OSV by exact id. When no advisory with that id exists, returns found false and invents nothing. When a model is named, GMI writes one plain-language paragraph from the retrieved advisory only. When no model is named, the explanation is the advisory summary itself.
Inputs: advisory_id (required), package, version, max_tokens, +2 more. Returns: result
get_findingB
Get one stored finding in full: code, evidence, verdict history, pipeline events, verification results, business impact, and matching triage memories.
Inputs: finding_id (required), db_path. Returns: result
list_findingsA
List stored finding summaries, newest first.
Filters: status, check, severity, repo_path. limit defaults to 20 and is capped at 100. cursor pages through results. Summaries only: no code in list output, only in get_finding.
Inputs: check, limit, cursor, status, +3 more. Returns: result
list_rulesA
List the custom semgrep rules pack. No GMI call, no spend.
Returns each rule with id, name, category, severity, description, and whether it is enabled by default. category filters to one of the 7 known checks. The pack ships in src/gmi_security_mcp/rules/; set GMI_SECURITY_MCP_RULES_DIR when it is elsewhere.
Inputs: category. Returns: result
mark_confirmedA
Mark a stored finding confirmed. reason is required.
Only when a verification result with status reproduced exists for the finding. Otherwise the call is refused, and an LLM verdict alone cannot set confirmation.
Inputs: reason (required), finding_id (required), db_path. Returns: result
mark_fpA
Mark a stored finding false_positive. reason is required.
Creates a triage memory with the given scope (global, package, or target, default target). The memory is a hint only: it never auto-rejects a future finding, and the agent must still triage it. Memories are created only by this human call.
Inputs: reason (required), finding_id (required), scope, db_path. Returns: result
repo_scanA
Scan a repo with semgrep and osv-scanner, then two-stage triage.
Returns a JSON report: per-finding verdicts with stage and cost, totals, skipped findings with reasons, the OSV section, and the estimate versus actual cost. A dry run runs the scanners and estimates the cost with no GMI calls. Files over max_file_kb are skipped unless the caller raises the cap. Every triaged finding is stored in the findings store (per-user ~/.gmi-security-mcp/findings.db by default) and the report carries scan_id, with one finding_id per finding. The custom rules pack runs in addition to the default semgrep config, and its findings carry source custom-rule. A clean repo_scan does NOT mean flawless. Writing the report to write_report needs --allow-apply on the server command line; without it the scan still runs but the write is refused.
Inputs: repo_path (required), stage1_model (required), stage2_model (required), db_path, +11 more. Returns: result
scope_disableB
Disable scope for one repo.
Returns disabled with a warning that tools will now refuse if --require-scope is set, because there is no scope policy for the repo.
Inputs: repo_path (required). Returns: result
scope_enableA
Enable scope for one repo from a scope file.
A scope file alone never activates checks; only this call does. Returns the in-scope and out-of-scope lists and a warning that scope is a destination policy, not authorisation to test, and not an OS sandbox.
Inputs: repo_path (required), scope_file (required). Returns: result
triage_semgrep_findingB
Triage one semgrep or scanner finding with GMI Inference.
Returns one validated finding as JSON: verdict, severity, confidence, reason, fix, stage used, latency, tokens, cost, and the estimate made before the call. An unparsed reply returns verdict null and unparsed true. It never returns clean. The verdict is stored in the findings store (per-user ~/.gmi-security-mcp/findings.db by default) and the result carries finding_id. An explicit db_path is allowed, with a warning that the caller is responsible for not committing it.
Inputs: code (required), finding (required), file, line, +8 more. Returns: result
update_findingA
Update a stored finding. reason is required.
business_impact changes business impact only, never technical severity, verification, review gates, or patch permissions. status moves one step at a time and is refused when it skips a state, for example new to confirmed without a reproduced verification. Suppressing a critical/high finding with business impact Urgent/High is refused unless force is true with a reason, and is then recorded with that reason and actor.
Inputs: finding_id (required), force, reason, status, +2 more. Returns: result
verify_findingA
Verify one finding with a deterministic oracle, PoV-is-truth.
A finding stays a candidate until an oracle reproduces it. GMI only writes the PoC, when poc is null; the local oracle decides. code is the audited code and harness description sent with the finding when a PoC is generated. A generated PoC is returned for review and only runs when run_poc is true AND confirm_generated_poc is true: run_poc alone never runs model-generated code on the host in the same call that generated it. A caller-supplied PoC runs when run_poc is true, with no extra flag, because the caller already reviewed it. A false_positive finding is refused unless regression_check is true, and then the result is labelled regression, not confirmation. Categories without an oracle return skipped with "no oracle for this category". test_command runs a PoC file already in the repo, or the written PoC when it names {poc}, for example pytest {poc} -k host_key. The PoC runs on the host by default, with a warning; pass executor docker for a disposable container when Docker is available. verify_finding never applies a fix; a fix_candidate is run through patch validation and then restored. A fix_candidate needs --allow-apply on the server command line; without it the call is refused.
Inputs: poc, code, db_path, finding, +12 more. Returns: result
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 15 tools
Most tools have a clearly distinct resource+action (scan vs. triage single vs. verify vs. mark vs. disclose). The only mild overlaps are triage_semgrep_finding vs. repo_scan (single finding vs. bulk pipeline) and check_osv_advisory vs. repo_scan's OSV section / explain_cve, but the descriptions make the boundaries explicit.
All names are snake_case and readable, and the majority follow verb_noun (triage_*, verify_*, list_*, get_*, update_*, mark_*, estimate_*, explain_*, check_*, draft_*). Three deviate into noun_verb (repo_scan, scope_enable, scope_disable), a minor but noticeable inconsistency.
15 tools is at the top of the well-scoped range but each maps to a real stage of the scan→triage→verify→confirm/disclose lifecycle. Nothing is clearly redundant, though the set is on the heavy side for a single MCP server.
The core lifecycle is well covered: scan, single/bulk triage, verify, list/get/update findings, mark_fp/mark_confirmed, disclosure, scope policy, rules listing, cost estimation, and CVE explanation. Minor gaps exist: no way to retrieve past scan reports by scan_id, no listing/deletion of triage memories created by mark_fp, and no delete_finding operation.
Maintenance
Related MCP Connectors
Security reviews for coding agents: diffs checked against your org policy and live infrastructure.
Lets coding agents check their own code for leaked secrets, risky dependencies and AI-code mistakes
Scores your code across 12 areas, with findings, fix prompts, and re-assessment in your AI agent
AI pentesting: run scans, triage vulnerabilities, review PRs, manage schedules and assets.
Related MCP Servers
- AlicenseAqualityDmaintenanceAgent-native "safe to ship?" security gate for AI-generated code. Uses real parsers and inter-rocedural taint analysis (JS/TS, Python, Go) to flag the classes AI coding agents get wrong — secrets, SQL injection, SS, SSRF, path traversal, command injection, weak JWT/CORS — and ranks findings by confidence. Exposes a scan tool over MCP.18 npm2MIT
- AlicenseAqualityCmaintenanceEnables AI agents to scan code for security vulnerabilities using multiple static analysis tools, with support for filtering, deduplication, and CI/CD integration.2744 PyPI4MIT
- AlicenseNot gradedqualityCmaintenanceEnables AI agents to scan code for security and quality issues and receive machine-readable reports with suggested fixes and verification criteria.83 npm2MIT

shipsafe-mcpofficial
AlicenseAqualityCmaintenanceEnables AI coding assistants to scan projects for security issues such as leaked API keys, missing Supabase RLS, open Firebase rules, unauthenticated routes, and hallucinated packages, then fix and verify the results.81MIT