The Model Context Protocol: A Revolution… and an Attack Surface
The Model Context Protocol (MCP) is rapidly establishing itself as the open standard enabling AI agents — GitHub Copilot, Claude, Cursor, and many others — to access external tools, databases, and APIs. In practice, an mcp.json file declared in your project allows your IDE to interact with remote or local servers that expose additional capabilities to the AI.
It’s powerful. It’s also dangerous if these servers aren’t audited.
Security Risks Associated with MCP Servers
The security community has already identified several attack vectors specific to MCP servers:
Prompt Injection
A malicious MCP server can inject content into its tool descriptions to manipulate AI agent behavior. The agent then performs actions not intended by the user, in complete transparency.
Tool Poisoning
A tool exposed by an MCP server can be compromised: instead of executing the expected action, it runs malicious code — reading sensitive files, executing system commands, exfiltrating tokens.
Toxic Flows (WhatsApp-style Data Exfiltration)
When an AI agent uses multiple MCP tools in a chain, a compromised tool can transmit data collected by a legitimate tool to a malicious server. This is the principle behind toxic tool-call flows.
Rug Pull Attacks
An MCP server can silently modify the behavior of its tools after the user has approved them. The visible description remains unchanged, but the executed code is different — a particularly insidious scenario.
The Reality: Nobody Is Auditing MCP Servers
During an engagement with a client, we noticed that development teams were adding MCP servers to their VS Code configurations without any validation process. Each developer could declare their own servers, with zero visibility for the security team.
The questions that arose:
- Which MCP servers are being used across the organization?
- Are they trustworthy? Could a third-party HTTP server be compromised between deployments?
- How can we detect silent changes in the tools exposed by a server?
The Solution: An Automated MCP Scanner in GitHub Actions
We developed a GitHub Actions workflow that:
- Automatically discovers all
mcp.jsonfiles in the repository - Runs mcp-scan (Snyk’s open-source tool) on each configuration
- Analyzes every tool, prompt, and resource exposed by the declared MCP servers
- Generates a JUnit XML test report displayed directly in the Pull Request Checks tab
- Publishes a Markdown summary in the Job Summary of each run
Pipeline Architecture
mcp.json → mcp-scan (analysis) → JSON → JUnit XML + Markdown → GitHub Actions (Test Report + Summary)
Automatic Triggers
| Event | Condition |
|---|---|
Push to main |
Modification of an mcp.json file |
Pull Request to main |
Same |
| Weekly schedule | Every Monday at 08:00 UTC |
| Manual | Via the Actions tab |
The weekly scan is essential: it detects rug pull attacks, i.e., silent server-side modifications that occur between commits.
GitHub Actions Workflow Example
name: MCP Security Scan
on:
push:
branches: [main]
paths:
- '**/*mcp*.json'
pull_request:
branches: [main]
paths:
- '**/*mcp*.json'
schedule:
- cron: '0 8 * * 1'
workflow_dispatch:
permissions:
contents: read
checks: write
pull-requests: write
jobs:
mcp-scan:
name: Scan MCP Configurations
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install uv
uses: astral-sh/setup-uv@v4
- name: Run mcp-scan
run: |
MCP_FILES=$(find . -name "mcp.json" -o -name "mcp*.json" \
| grep -v node_modules | grep -v .git/)
uvx mcp-scan@latest --json --server-timeout 30 $MCP_FILES \
> mcp-scan-results.json 2>mcp-scan-stderr.log || true
- name: Convert results to JUnit XML
run: |
python .github/scripts/mcp-scan-to-junit.py \
mcp-scan-results.json \
mcp-scan-results.xml \
mcp-scan-summary.md
cat mcp-scan-summary.md >> "$GITHUB_STEP_SUMMARY"
- name: Publish Test Report
uses: dorny/test-reporter@v1
if: always()
with:
name: MCP Security Scan Results
path: mcp-scan-results.xml
reporter: java-junit
fail-on-error: false
Reading the Results
Results appear directly in the GitHub interface:
- Checks tab on the PR: each MCP server is a test suite, each tool is a test case
- ✅ Passed — no issues detected
- ❌ Failed — vulnerability detected (prompt injection, tool poisoning, etc.)
- ⚠️ Error — server unreachable or timeout
- Job Summary: summary table per server with the number of tools analyzed and alerts
Result Conversion: The Python Script
The core of the system relies on a Python script that converts the JSON output from mcp-scan into a JUnit XML report consumable by dorny/test-reporter. Each tool exposed by an MCP server is evaluated against a risk score:
- Tools with a score above the threshold (0.5) are marked as failed
- Unreachable servers are marked as error
- Healthy tools are marked as passed
This JUnit format leverages the existing ecosystem: native integration with GitHub, Azure DevOps, Jenkins, etc.
Value Proposition
| Benefit | Detail |
|---|---|
| Visibility | Centralized, versioned inventory of all authorized MCP servers |
| Proactive detection | Identify vulnerabilities before they impact developers |
| Continuous monitoring | Detect silent server-side changes (rug pulls) |
| Zero cost | mcp-scan is open-source, no license required |
| Audit & compliance | Archived reports (JUnit XML, JSON, Markdown) for every run |
Going Further
MCP Security Resources
- Model Context Protocol — Official Specification
- Snyk agent-scan (mcp-scan) — GitHub
- Invariant Labs — MCP Security Notifications
- OWASP Top 10 for LLM Applications
- Trail of Bits — The Model Context Protocol and its Security Implications
- Pillar Security — The Security Risks of MCP
- Snyk — Securing AI Agents: Understanding MCP Tool Poisoning
GitHub Actions Used
- dorny/test-reporter — Display test reports in GitHub
- astral-sh/setup-uv — Install
uvto runmcp-scan - actions/upload-artifact — Archive results
Conclusion
The massive adoption of MCP in AI-assisted development tools creates a new attack surface that most organizations have not yet addressed. A compromised MCP server can exfiltrate source code, secrets, or silently manipulate an AI agent’s behavior.
Setting up an automated scanner, integrated into your CI/CD pipeline, is an essential first step to regain control over this emerging supply chain. All at zero cost, with no additional infrastructure, and native GitHub Actions integration.
Don’t wait for an incident to audit your MCP servers.
Comments