Skip to main content

MCP Security Scan

GitHub Marketplace License: MIT

Security scanner for Model Context Protocol (MCP) servers. Finds hardcoded secrets, unsafe execution patterns, data exfiltration risks, filesystem access issues, code obfuscation, and missing authentication.

Available as a GitHub Action and a CLI tool.


Why?

We statically scanned 7,029 public MCP servers (part of a 35,689-endpoint agent-ecosystem corpus):

  • 9% — nearly 1 in 11 — ship at least one high or critical issue detectable by static analysis alone
  • Most common: hardcoded secrets, unsafe shell/exec with user-controllable input, credential-exfiltration paths, filesystem access far broader than advertised

Full prevalence data + methodology: Agent Tool Supply-Chain Security: Prevalence from 35,689 Scans.

MCP servers run on your machine with access to your files, shell, and API keys — and increasingly get called in a loop by autonomous agents with nobody watching. Recent incidents like GitLost (GitHub's AI agent tricked into leaking private repos) and MCPoison / CVE-2025-54136 (the Cursor mcp.json rug-pull) live on this exact attack surface. Most MCP servers have no security review process.

What it detects

Twelve finding categories, all open source:

Category Examples
secret Hardcoded API keys, tokens, credentials
unsafe_exec shell=True with user input, eval/exec on external data
exfiltration Env vars / secrets piped into network calls
fs_access "Read a file" servers that can walk the entire home directory
obfuscation Base64-packed or dynamically-assembled code
dynamic_remote_load Rug-pulls: fetch-then-exec, curl|sh, unpinned npx/uvx, manifest-exec (the MCPoison / CVE-2025-54136 class)
hidden_unicode Invisible Unicode Tags, bidi controls (Trojan Source), zero-width chars smuggling instructions past review
prompt_injection Instruction-override / hide-from-user / exfil directives in tool descriptions, mcp.json, SKILL.md
insecure_deserialization pickle.loads, unsafe yaml.load, torch.load on untrusted data
install_hook npm preinstall/postinstall scripts that fetch, eval, or pipe to shell
toxic_flow The lethal trifecta (the GitLost class): private-data read + untrusted input + outbound send composing in one tool
Missing auth Tool endpoints with no authentication boundary

The hosted scanner at agentgraph.co/check adds what a local one-shot scan structurally can't: every verdict signed as an offline-verifiable attestation (Ed25519/JWS), tool-definition pinning with drift detection across re-scans (a tool that changes after you vetted it fails verification), and vulnerable-dependency intelligence from a 35,689-endpoint scan corpus.


Quick Start

Add this to .github/workflows/mcp-security.yml:

name: MCP Security Scan
on: [push, pull_request]

jobs:
  security-scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: agentgraph-co/mcp-security-scan@v1
        with:
          fail-on: critical

That's it. The action will:

  • Scan your repository for security issues
  • Post a detailed comment on pull requests
  • Fail the check if critical findings are detected

CLI

pip install git+https://github.com/agentgraph-co/mcp-security-scan.git

# Scan any MCP server repo on GitHub
mcp-security-scan owner/repo

# Scan the current repo (auto-detects from git remote)
mcp-security-scan

# JSON output for programmatic use
mcp-security-scan owner/repo --format json

# Fail CI on critical findings
mcp-security-scan owner/repo --fail-on critical

Advanced Usage

Action Inputs

Input Description Default
repo GitHub repo to scan (owner/repo). Defaults to the current repository. Current repo
token GitHub token for API access ${{ github.token }}
fail-on Fail the check if findings at or above this severity: critical, high, or medium critical
format Output format: text, json, github github

Action Outputs

Output Description
trust-score Trust score from 0-100
findings-count Total number of security findings
critical-count Number of critical-severity findings
report Full scan report as JSON

Using Outputs in Your Workflow

jobs:
  security-scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: agentgraph-co/mcp-security-scan@v1
        id: scan
        with:
          fail-on: high

      - name: Check trust score
        if: steps.scan.outputs.trust-score < 50
        run: echo "Trust score is below 50 — review findings"

Scanning a Different Repository

- uses: agentgraph-co/mcp-security-scan@v1
  with:
    repo: some-org/their-mcp-server
    token: ${{ secrets.GITHUB_TOKEN }}

CLI Flags

Flag Description Default
repo GitHub repo (owner/repo) Auto-detect from git remote
--token GitHub API token $GITHUB_TOKEN env var
--format Output format: text, json, github text
--output, -o Write JSON report to file --
--fail-on Exit code 1 if findings at this severity or above: critical, high, medium --

What It Scans

The scanner checks for 6 categories of security issues:

🔑 Hardcoded Secrets (critical/high)

  • AWS access keys and secret keys
  • OpenAI, Anthropic, Google API keys
  • GitHub tokens, Slack tokens, Stripe keys
  • Private key blocks (RSA, etc.)
  • Generic API key and password assignments

⚠️ Unsafe Execution (critical/high)

  • subprocess.run(), os.system(), os.popen() (Python)
  • shell=True in subprocess calls (Python -- critical)
  • eval(), exec() (Python/JS)
  • child_process, execSync (Node.js)
  • Command::new (Rust), exec.Command (Go)

📁 Filesystem Access (medium/high)

  • Unrestricted file read/write operations
  • Path traversal patterns (../)
  • Recursive delete (shutil.rmtree, rimraf)

📡 Data Exfiltration (high/critical)

  • Outbound HTTP requests with sensitive data
  • Encoded data transmission patterns
  • Suspicious network calls in unexpected contexts

🕵️ Code Obfuscation (high)

  • Base64-encoded code execution
  • Dynamic code generation patterns
  • Obfuscated variable names and control flow

✅ Positive Security Signals (reduce risk)

  • Authentication and authorization checks
  • Input validation (Zod, Pydantic, JSON Schema)
  • Rate limiting
  • CORS configuration
  • Security headers (Helmet, CSP)

Example PR Comment

When the action runs on a pull request, it posts a comment like this:

MCP Security Scan Results

✅ Trust Score: 85/100 (Good)

  • ✅ Credential Theft -- Clear
  • ✅ Data Exfiltration -- Clear
  • ⚠️ Unsafe Execution -- 2 findings
  • ✅ Filesystem Access -- Clear
  • ✅ Code Obfuscation -- Clear
Metric Value
Files scanned 45
Language Python
Positive signals Input validation, Rate limiting
Findings (2)
Severity Category Name File Line
high unsafe_exec subprocess.run src/tools.py 42
medium unsafe_exec os.popen src/utils.py 18

Trust Score

Each scanned repo receives a score from 0 to 100:

Factor Impact
Base score 70
Critical finding -15 each
High finding -8 each
Medium finding -3 each
Positive security signal +5 each
Has README +5
Has LICENSE +5
Has tests +5

Contributing

Found a false positive? Missing a detection pattern? PRs welcome.

Good first issues:

  • Add detection for more secret patterns (Twilio, SendGrid, etc.)
  • Reduce false positives on path traversal in test files
  • Add support for local directory scanning (not just GitHub repos)
  • Add SARIF output format for GitHub Code Scanning integration

License

MIT -- see LICENSE.


Built by AgentGraph -- trust infrastructure for AI agents.

Metadata

Release files for mcp-security-scan 1.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for mcp-security-scan 1.1.0
File Size Uploaded
mcp_security_scan-1.1.0.tar.gz 25.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for mcp-security-scan 1.1.0
File Interpreter ABI Platform
mcp_security_scan-1.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 48.4 kB

Release files / mcp_security_scan-1.1.0.tar.gz

Download URL mcp_security_scan-1.1.0.tar.gz
Size 25.7 kB
Tags Source
SHA-256 checksum
How to use checksums
233c85299f675afbb188c7ca32cdb2a7863e101c0240fdf6ac589660692dca62
BLAKE2b-256 checksum
How to use checksums
5ffe4df5547db8148eb707e6fce9f42ae5fc33c4a0c9fed65668e71720f73e6f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.6

Release files / mcp_security_scan-1.1.0-py3-none-any.whl

Download URL mcp_security_scan-1.1.0-py3-none-any.whl
Size 22.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a1ed471cf4c295dcffdd256a6a79cdda8f79d2f8b625f846fb30153d93b1157b
BLAKE2b-256 checksum
How to use checksums
c557ae8f29dd77898881ce9d9fdf0ddd95d57d4c854103f5f55af73336ce51f6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.6

Release history Release notifications | RSS feed

This release

1.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page