Scan MCP and AI-agent configs for leaked secrets before they reach GitHub.
mcp-guard
mcp-guard is a Python CLI for finding leaked secrets in MCP and AI-agent project files before they reach GitHub.
It recursively scans a file or directory, pays special attention to MCP config files, masks every detected value, assigns severity levels, and exits non-zero when findings meet your configured threshold.
What Is mcp-guard?
AI agents and MCP servers often need API keys in files such as .cursor/mcp.json, .vscode/mcp.json, claude_desktop_config.json, .env, and local config files. Those files are easy to commit by mistake.
mcp-guard gives you a lightweight pre-push or CI check for these leaks. It is designed for developer workflows, open-source projects, and portfolio repos where you want a readable terminal report plus machine-readable JSON for automation.
Install
Install from PyPI with pipx:
pipx install mcp-secrets-guard
Or install the latest version from GitHub:
pipx install git+https://github.com/chiragborse1/mcp-guard.git
From a local checkout:
python -m pip install .
For local development:
python -m pip install -e ".[dev]"
Quick Demo
$ mcp-guard .
mcp-guard scanned 26 file(s) under /path/to/project
Skipped 7 file(s)
No secrets found.
$ mcp-guard examples/unsafe-mcp-config
mcp-guard scanned 3 file(s) under /path/to/project/examples/unsafe-mcp-config
Found 6 possible secret(s):
HIGH .cursor/mcp.json:7:31 Firecrawl API key [MCP config] -> fc_f...7890
MEDIUM .env.example:4:26 Generic secret assignment -> corr...aple
Usage
mcp-guard <path>
Examples:
mcp-guard --version
mcp-guard .
mcp-guard ./mcp.json
mcp-guard . --fail-on high
mcp-guard --json .
mcp-guard . --sarif mcp-guard.sarif
mcp-guard . --staged
Exit codes:
0: no findings at or above the configured failure severity1: findings exist at or above the configured failure severity2: scan could not run, such as a missing path
Severity
Each finding has a severity:
high: known credentials such as OpenAI, Anthropic, GitHub tokens, Postgres URLs, Supabase keys, and most provider API keysmedium: generic secret assignments and lower-confidence sensitive valueslow: reserved for future lower-risk checks
By default, mcp-guard behaves as --fail-on low, so any finding exits 1.
Use --fail-on to control CI strictness:
mcp-guard . --fail-on high
mcp-guard . --fail-on medium
mcp-guard . --fail-on low
For example, --fail-on high still prints medium findings, but exits 0 unless a high-severity finding exists.
Staged Files
Use --staged to scan only files currently staged in Git:
mcp-guard . --staged
This is useful in pre-commit hooks because local untracked files and unstaged work are ignored.
Example pre-commit configuration:
repos:
- repo: local
hooks:
- id: mcp-guard
name: mcp-guard
entry: mcp-guard . --staged --fail-on high
language: system
pass_filenames: false
The same example is available at examples/pre-commit/.pre-commit-config.yaml.
JSON Output
mcp-guard --json .
Example:
{
"root": "/path/to/project",
"files_scanned": 3,
"files_skipped": 0,
"findings": [
{
"path": ".env",
"line": 1,
"column": 16,
"kind": "OpenAI API key",
"severity": "high",
"masked_secret": "sk-p...7890",
"context": "OPENAI_API_KEY=sk-p...7890",
"is_mcp_config": false
}
]
}
Secrets are masked in both text and JSON output.
SARIF Output
Use SARIF when you want to upload findings to GitHub code scanning:
mcp-guard . --sarif mcp-guard.sarif
SARIF output includes rule metadata, severity-mapped levels, file locations, and masked values only. The command still prints normal terminal output and uses the same --fail-on exit-code behavior.
For a permissive code-scanning upload that records medium findings but only fails on high severity:
mcp-guard . --fail-on high --sarif mcp-guard.sarif
Ignoring Files
Create a .mcpguardignore file in the scanned project root to ignore known-safe paths, such as test fixtures or intentionally unsafe examples.
Example:
# Test fixtures intentionally use fake secrets.
tests/
examples/unsafe-mcp-config/
*.snapshot
When you scan a directory directly, mcp-guard reads that directory's own .mcpguardignore. This repo ignores examples/unsafe-mcp-config/ during root scans, but you can still scan that folder directly.
For a single known-safe fake value, add an inline allow comment on the same line or the line immediately before it:
# mcp-guard: allow - fake local fixture
OPENAI_API_KEY=sk-p...7890
ANTHROPIC_API_KEY=sk-a...7890 # mcp-guard: ignore
Use allow comments sparingly. Prefer .mcpguardignore for whole fixture directories.
Example Scan
This repo includes fake unsafe files for testing:
mcp-guard examples/unsafe-mcp-config
Expected output includes masked fake findings:
mcp-guard scanned 3 file(s) under /path/to/mcp-guard/examples/unsafe-mcp-config
Found 6 possible secret(s):
HIGH .cursor/mcp.json:7:31 Firecrawl API key [MCP config] -> fc_f...7890
JSON:
mcp-guard --json examples/unsafe-mcp-config
What It Detects
mcp-guard looks for:
- OpenAI and Anthropic API keys
- GitHub tokens
- Postgres connection URLs
- Supabase URLs and JWT-style keys
- Pinecone, Qdrant, Firecrawl, Brave Search, and Perplexity keys
- Generic
api_key,password,secret, andtokenassignments
It gives special attention to MCP configuration files, including:
mcp.jsonclaude_desktop_config.json.cursor/mcp.json.vscode/mcp.json
The scanner skips .git, node_modules, dist, build, .next, venv, .venv, and __pycache__.
GitHub Actions
Add this workflow to .github/workflows/mcp-guard.yml:
name: mcp-guard
on:
pull_request:
push:
branches: [main]
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install pipx
run: python -m pip install --user pipx
- name: Install mcp-guard
run: pipx install mcp-secrets-guard
- name: Scan repository
run: mcp-guard . --fail-on high
GitHub code scanning with SARIF upload:
name: mcp-guard-sarif
on:
pull_request:
push:
branches: [main]
permissions:
security-events: write
contents: read
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install pipx
run: python -m pip install --user pipx
- name: Install mcp-guard
run: pipx install mcp-secrets-guard
- name: Scan repository
run: mcp-guard . --fail-on high --sarif mcp-guard.sarif
- name: Upload SARIF
if: always()
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: mcp-guard.sarif
You can also use the bundled composite action:
name: mcp-guard-action
on:
pull_request:
permissions:
security-events: write
contents: read
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: chiragborse1/mcp-guard/.github/actions/mcp-guard@v1.0.1
with:
path: "."
fail-on: high
sarif: mcp-guard.sarif
- name: Upload SARIF
if: always()
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: mcp-guard.sarif
For PR-only terminal scanning without SARIF:
name: mcp-guard-pr
on:
pull_request:
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: chiragborse1/mcp-guard/.github/actions/mcp-guard@v1.0.1
with:
path: "."
fail-on: high
Development
Run tests:
uv run --extra dev pytest -q
Run the local CLI:
uv run --extra dev mcp-guard .
See CONTRIBUTING.md for contribution guidelines and docs/RELEASE_CHECKLIST.md for release steps.
Release history is tracked in CHANGELOG.md.
The current roadmap and future ideas are tracked in docs/ROADMAP.md.
License
MIT