mcp-audit GitHub

mcp-audit for security teams

Give every developer the same check, enforce what is allowed, and send the results where your team already works. Everything runs on your own machines and in your own CI; there is no service to buy or connect.

Gate every pull request

The GitHub Action installs mcp-audit, scans the repository's MCP configs and Claude Code settings, uploads SARIF to GitHub code scanning and fails the job at the severity you set. With lock-verify it also fails when the repository drifts from the servers you approved. Exit codes: 0 clean, 1 findings at or above the threshold, 2 an error.

- uses: adudley78/mcp-audit@v0.21.1
  with:
    severity-threshold: high
    lock-verify: true

For developer machines, the pre-commit hooks run the same scan before a commit lands. mcp-audit diff <base> <head> --format pr-comment writes a review comment that lists added servers, tools, credentials and endpoints with a risk level.

Full workflow, every input and the pre-commit configuration

Docs: github-action.md, pre-commit.md

Enforce what is allowed

Write your organisation's rules once in .mcp-audit-policy.yml: which servers are approved, the minimum score a setup must reach, transport requirements, registry membership and how many findings of each severity are tolerated, with overrides per client. Every scan finds the policy on its own (working directory, then repository root, then your user config) and reports violations next to the security findings, in every output format.

mcp-audit policy initmcp-audit policy validate .mcp-audit-policy.ymlmcp-audit policy check

Docs: governance.md, writing-rules.md

Approve once, catch drift

mcp-audit lock writes mcp-lock.json, a committable record of exactly which servers a repository approved: client, server, package, resolved version and integrity hash, and the names (never the values) of environment variables and headers. lock --verify exits 1 on any drift, and lock --accept records a reviewed change. With --connect, the lock also records a digest of every tool each server exposes, so a changed tool description is caught.

mcp-audit lockmcp-audit lock --verifymcp-audit lock --accept

For machines rather than repositories, mcp-audit baseline save and baseline compare do the same against a saved snapshot.

Docs: lock.md, baselines.md

See every machine

mcp-audit shadow lists every MCP server configured on a machine and classifies each one as sanctioned (on your allowlist) or shadow (OWASP MCP09), with a risk level from its capabilities. In --continuous mode it emits an event when a server appears, changes or disappears, as JSON you can send to syslog or a SIEM.

mcp-audit shadow --allowlist .mcp-audit-allowlist.yml --format json

Run scans on a schedule with the standalone binary (no Python needed), tag each machine with --asset-prefix, and combine the results: mcp-audit merge de-duplicates findings across machines into one terminal, JSON or HTML fleet report.

mcp-audit scan --format json --output scan.json --asset-prefix eng-mcp-audit merge --dir ./scans --format html --output fleet.html

Docs: shadow-mcp.md, fleet-scanning.md, enterprise-deployment.md

Keep evidence for audits and incidents

mcp-audit snapshot records every MCP server on a host as a CycloneDX 1.5 AI/ML-BOM, with capabilities, transport and findings, and can sign it with Sigstore. Months later, --rehydrate rebuilds the attack-path graph from that snapshot for incident response, and --stream emits one finding per line for a SIEM. mcp-audit sbom writes a CycloneDX SBOM, and scan --report pdf writes a PDF report.

mcp-audit snapshot --sign --output snapshot.jsonmcp-audit snapshot --rehydrate snapshot.json

Docs: snapshot.md, compliance-report.md, splunk.md, sentinel.md

Feed your vulnerability management program

mcp-audit findings use the formats security programs already ingest. SARIF goes to GitHub code scanning or any SARIF consumer. --format nucleus writes the Nucleus Security FlexConnect schema, and push-nucleus runs a scan and sends it to a Nucleus project directly, so MCP findings get the same de-duplication, ownership and SLA tracking as every other finding. The signed advisory feed is published as OSV records, including a bundle osv-scanner can read, so other tools can consume mcp-audit's findings as advisories.

mcp-audit scan --format sarif --output mcp-audit.sarifmcp-audit push-nucleus --url https://your-instance --project-id 123

Docs: nucleus-integration.md, advisory-feed.md, snyk-integration.md

Map findings to frameworks

Every finding ID is in a machine-readable OWASP MCP Top 10 mapping, covering 10 of 10 categories, and the codes travel with each finding in terminal, JSON and SARIF output. Severities follow a published framework that ties each level to a CVSS range and explains the reasoning, with OWASP Agentic Top 10 references.

Checks by OWASP category

Docs: owasp-mapping.json, owasp-mcp-top-10.md, severity-framework.md

Deploy without a vendor

  • No account, license key or seat count. Every command is in the Apache 2.0 package.
  • A default scan makes no network calls and collects no telemetry, so it needs no network-policy exception.
  • Scanned files are read, never executed.
  • Standalone binaries for macOS (Apple silicon), macOS (Intel), Linux (x86-64) and Windows (x86-64); no Python needed on scanned machines.

Security and quality