AI coding assistants like Claude Code, Cursor, GitHub Copilot — they can reach beyond chat and directly interact with your databases, APIs, filesystems, and cloud services through something called MCP (Model Context Protocol).
MCP servers are the bridge. You write a server, connect it to your AI tool, and suddenly your assistant can query production databases, create Jira tickets, push to GitHub, or read your Slack messages.
This is incredibly powerful. It's also a security nightmare waiting to happen.
The Problem:
I've been reviewing MCP servers — both open-source ones on GitHub and internal ones at companies. Here's what I keep finding:
Hardcoded secrets everywhere. API keys for OpenAI, Anthropic, AWS, and database connection strings sitting right in the source code. Not environment variables. Literal strings.
typescript// Real pattern found in multiple MCP servers
const API_KEY = "sk-ant-api03-actual-key-here";
const DB_URL = "mongodb+srv://admin:password123@cluster.example.net/prod";
eval() on user-controlled input. MCP tools that take a code parameter and pass it straight to eval(). The AI assistant can be tricked into sending malicious code through prompt injection.
server.tool("execute", async ({ code }) => {
const result = eval(code); // Arbitrary code execution
return { content: [{ type: "text", text: String(result) }] };
});
SQL injection via string concatenation. Database query tools that build SQL from template literals without parameterized queries.
server.tool("query_db", async ({ table, filter }) => {
const query = `SELECT * FROM ${table} WHERE ${filter}`;
// Classic SQL injection — filter could be "1=1; DROP TABLE users"
});
Wildcard permissions. Servers configured with root filesystem access or "*" permissions, giving the AI assistant unrestricted access to everything.
No TLS verification. NODE_TLS_REJECT_UNAUTHORIZED = "0" — disabling certificate checks, opening the door to man-in-the-middle attacks.
These aren't edge cases. These are patterns I see repeatedly in MCP servers that people are connecting to production environments.
Why Manual Review Isn't Enough
MCP servers are small — typically 200-500 lines of code. You'd think a quick manual review would catch everything. But:
- Secrets hide in plain sight. A 40-character API key in line 147 of a config file is easy to miss.
- New servers get added constantly. Teams experimenting with AI tools spin up MCP servers weekly. Nobody's reviewing them all.
- Patterns compound. An insecure HTTP endpoint alone is medium risk. Combined with disabled TLS and hardcoded credentials? Critical.
- Copy-paste from examples. Most MCP servers start from tutorial code that prioritizes functionality over security. Those insecure patterns propagate.
Automated Scanning in 10 Seconds
I built mcp-security-auditor to solve this. It's an open-source security scanner specifically designed for MCP servers.
Zero install. One command:
bashnpx mcp-security-auditor scan ./my-mcp-server
That's it. No account, no signup, no cloud dependency. It runs locally and takes about 45ms to scan a typical MCP server.
Here's what actual output looks like:
╔══════════════════════════════════════════════════════╗
║ MCP Security Auditor - Scan Report ║
╚══════════════════════════════════════════════════════╝
Server: my-mcp-server v1.0.0
Language: typescript
Framework: mcp-sdk
Transport: stdio
Tools: 3 detected [query_db, write_file, run_command]
Files: 12 source files scanned
Duration: 45ms
Summary: 8 findings
🔴 Critical: 2
🟠 High: 3
🟡 Medium: 2
🔵 Low: 1
It auto-detects the language (TypeScript, JavaScript, Python), the MCP framework being used, the transport type, and even extracts the tool definitions from your code.
7 Security Analyzers
The scanner runs 7 specialized analyzers:
- Secrets Detection Catches hardcoded API keys, passwords, tokens, private keys, and connection strings. Covers patterns for AWS, GitHub, OpenAI, Anthropic, Slack, MongoDB, PostgreSQL, and more.
- Static Code Analysis Flags dangerous patterns: eval(), exec(), new Function(), child_process, unsafe deserialization (pickle.loads, yaml.unsafe_load), and risky filesystem operations.
- Prompt Injection Detection Identifies where user input flows into prompt construction without sanitization — the #1 attack vector for MCP servers. Catches f-string interpolation, template literals, and string concatenation patterns.
- SQL & Command Injection Detects dynamic SQL queries, NoSQL operator injection, and command execution with user-controlled input.
- Permission Analysis Finds wildcard permissions, root filesystem access, missing authentication on HTTP handlers, and explicitly disabled security features.
- Network Security Scans for insecure HTTP URLs, SSRF vulnerabilities, TLS verification bypass, CORS wildcard origins, and servers binding to all network interfaces.
- Dependency Analysis Checks for wildcard version pins, missing lockfiles, known-compromised packages (like event-stream), and potential typosquatting (e.g., lodahs instead of lodash). You can run specific analyzers if you want:
# Only check for secrets and injection risks
npx mcp-security-auditor scan ./server -a secrets,injection
5 Output Formats
The scanner supports multiple output formats for different workflows:
# Terminal output (default, with colors)
npx mcp-security-auditor scan ./server
# HTML report — great for sharing with security teams
npx mcp-security-auditor scan ./server -f html -o report.html
# JSON — for programmatic use
npx mcp-security-auditor scan ./server -f json -o results.json
# SARIF — for GitHub Security tab and Azure DevOps
npx mcp-security-auditor scan ./server -f sarif -o results.sarif
# Markdown — for docs or PR comments
npx mcp-security-auditor scan ./server -f markdown -o report.md
CI/CD Integration: 3 Lines of YAML
This is where it gets powerful. Add the scanner to your CI pipeline and every PR that touches MCP server code gets automatically scanned.
GitHub Actions
yamlname: MCP Security Scan
on: [push, pull_request]
jobs:
security:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npx mcp-security-auditor ci . --fail-on high -o results.sarif
- uses: github/codeql-action/upload-sarif@v3
if: always()
with:
sarif_file: results.sarif
The ci command defaults to SARIF output and exits with code 1 if findings meet or exceed the severity threshold. The SARIF upload step pushes results into GitHub's Security tab, so findings appear right alongside your CodeQL results.
GitLab CI
yamlmcp-security:
script:
- npx mcp-security-auditor ci . --fail-on high -f json -o mcp-audit.json
artifacts:
reports:
security: mcp-audit.json
Pre-commit Hook
# .git/hooks/pre-commit
npx mcp-security-auditor ci . --fail-on critical
Block commits that introduce critical vulnerabilities. Fast enough (sub-100ms) that it doesn't slow down your workflow.
Programmatic API
If you want to integrate the scanner into your own tooling:
import { scan, generateReport } from "mcp-security-auditor";
const result = scan({ path: "./my-mcp-server", format: "json" });
console.log(`Found ${result.summary.total} issues`);
console.log(`Critical: ${result.summary.critical}`);
// Generate HTML report
const html = generateReport(result, "html");
// Fail the build if critical issues found
if (result.summary.critical > 0) {
process.exit(1);
}
What's Coming Next
This is v1.0. Here's what I'm working on:
GitHub Action on Marketplace — one-click setup for any repo
VS Code extension — scan as you code, inline warnings
MCP config scanning — audit claude_desktop_config.json and Cursor configs for risky server setups
OWASP MCP Top 10 mapping — align findings with emerging MCP security standards
Try It
npm (zero install):
npx mcp-security-auditor scan ./your-mcp-server
pip (Python):
pip install mcp-security-auditor
mcp-audit scan ./your-mcp-server
Links:
- npm: npmjs.com/package/mcp-security-auditor
- PyPI: pypi.org/project/mcp-security-auditor GitHub: (add your repo URL)
MIT licensed. Open source. Contributions welcome.
If you're building or deploying MCP servers, scan them before they reach production. 45ms now could save you a breach later.
Top comments (0)