Skip to main content

Scan projects for AI and MCP-related secrets before they leak.

Project description

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]"

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 severity
  • 1: findings exist at or above the configured failure severity
  • 2: 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 keys
  • medium: generic secret assignments and lower-confidence sensitive values
  • low: 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, and token assignments

It gives special attention to MCP configuration files, including:

  • mcp.json
  • claude_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

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mcp_secrets_guard-1.0.1.tar.gz (16.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mcp_secrets_guard-1.0.1-py3-none-any.whl (12.8 kB view details)

Uploaded Python 3

File details

Details for the file mcp_secrets_guard-1.0.1.tar.gz.

File metadata

  • Download URL: mcp_secrets_guard-1.0.1.tar.gz
  • Upload date:
  • Size: 16.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for mcp_secrets_guard-1.0.1.tar.gz
Algorithm Hash digest
SHA256 9585344a1e0ecd60127af92d6a1430c2b74e7ea9ebbf07b3da0b7550159ae399
MD5 14f9c5696e4de46ae1be90a793197ef0
BLAKE2b-256 e74379499c2d30f1c7863dadb491e569db1efaa15b7a1188f195f7399395440c

See more details on using hashes here.

Provenance

The following attestation bundles were made for mcp_secrets_guard-1.0.1.tar.gz:

Publisher: publish.yml on chiragborse1/mcp-guard

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file mcp_secrets_guard-1.0.1-py3-none-any.whl.

File metadata

File hashes

Hashes for mcp_secrets_guard-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 45f7c38be5afc95d6652d44dbdf01cc34fa3130792292abdf2d5551cfedc5f9d
MD5 88590b3121c842ad3e3a065808af9e5f
BLAKE2b-256 d5b0d1c4d582381083cf4dba9a145cb261c0cdc7ea2101109b672a48c5d77a1e

See more details on using hashes here.

Provenance

The following attestation bundles were made for mcp_secrets_guard-1.0.1-py3-none-any.whl:

Publisher: publish.yml on chiragborse1/mcp-guard

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page