I've been building an AI security gateway for the past several months. Yesterday I wrote about how chain analysis stops multi-turn escalation attacks — the kind where each individual request looks benign but the pattern across turns is the attack.
Today I want to talk about where those attacks are happening right now: the Model Context Protocol.
When I started looking at the MCP security landscape, I expected to find a few gaps. What I found was a vacuum.
Let me walk through what's out there, what's missing, and what we built.
The Adoption Numbers
MCP launched in November 2024. As of September 2026:
| Metric | Value |
|---|---|
| GitHub repos tagged "model context protocol" | 30,212 |
| Official MCP servers repo stars | 90,550 |
| Python SDK stars | 24,368 |
| TypeScript SDK stars | 13,442 |
| MCP spec repo stars | 9,277 |
| Spec stable release | 2026-07-28 |
30,000+ implementations. Nine months. That's faster growth than Docker had in its first year.
And every single one of those implementations is running without a security gateway.
What the Spec Actually Says About Security
I read the MCP specification security section. Here's what it says — and what it doesn't.
The spec identifies these attack vectors:
- Tool poisoning — malicious instructions embedded in tool descriptions
- Rug pulls — tools silently redefining themselves after installation
- Credential theft — MCP servers with access to local files exfiltrating secrets
- Line jumping — prompt injection via tool descriptions before tools are ever called
The spec's security guidance uses the word SHOULD 23 times. It uses MUST 4 times. The four MUSTs are:
- Servers MUST validate all tool inputs
- Servers MUST implement proper access controls
- Servers MUST rate limit tool invocations
- Servers MUST sanitize tool outputs
Here's what the spec does not provide:
- No enforcement mechanism. No reference implementation. No audit trail format. No chain analysis. No response scanning. No STDIO command validation. No session management. No anomaly detection.
The spec says servers MUST do these things. It doesn't say how. It doesn't provide a library. It doesn't ship a middleware. It's a document.
Every MCP server implementer is left to build their own security — or skip it entirely.
The Vulnerability Trail
The security research community has been documenting MCP vulnerabilities all year. This isn't theoretical — these are real, exploited, disclosed vulnerabilities:
April 2025 — Trail of Bits: "Jumping the Line"
MCP servers can inject prompts through tool descriptions to manipulate AI behavior before tools are ever invoked. The attacker doesn't need you to call their tool. They just need you to install it. (source)
April 2025 — Simon Willison: "MCP has prompt injection security problems"
Tool poisoning, rug pulls, and tool shadowing. Tools that mutate their own definitions after installation. whatsapp-mCP exfiltrating your entire message history. (source)
April 2025 — Trail of Bits: "How MCP servers can steal your conversation history"
MCP servers have access to the full conversation context. A malicious server can read everything you've typed and send it somewhere else. (source)
May 2025 — Invariant Labs: "GitHub MCP Exploited"
Accessing private repositories via MCP. The attack didn't need a vulnerability in GitHub — it exploited the trust relationship between the MCP server and the client. (source)
May 2025 — CyberArk: "Poison everywhere: No output from your MCP server is safe"
Tool outputs can contain prompt injection. Even if you trust the tool, the data it returns can contain adversarial instructions. (source)
June 2025 — Asana discloses data exposure bug in MCP server
Official MCP server from a major SaaS company had a data exposure vulnerability. (source)
June 2025 — Cato Networks: "Living Off AI" PoC
Attack targeting Atlassian's MCP server. New attack category: using legitimate MCP tools as the attack vector. (source)
July 2025 — Critical mcp-remote vulnerability: RCE, 437,000+ downloads
Remote code execution in a widely-used MCP remote transport library. Nearly half a million downloads before the fix. (source)
July 2025 — Anthropic's own Slack MCP server vulnerable to data exfiltration
The company that created MCP had a data leakage vulnerability in their own MCP server. (source)
August 2025 — Cursor hijacked via Jira MCP by submitting a support ticket
Attackers submitted a malicious Jira support ticket that injected instructions into the MCP-connected Cursor editor. (source)
That's 9 months. 9+ disclosed vulnerabilities. Including the company that invented the protocol.
Who Else Is Securing the MCP Data Plane?
I searched. Here's what I found:
| Project | Stars | What It Does | What It Doesn't Do |
|---|---|---|---|
| ToolHive (Stacklok) | 2,205 | Container isolation for MCP servers, Kubernetes operator, IdP integration | No content scanning, no chain analysis, no response guard, no ML detection |
| Hoop | 818 | Gateway proxy across protocols (MCP, LLM, DB), wire-level policy | No ML detection, no chain analysis, no response scanning |
| mcp-context-protector (Trail of Bits) | 226 | Wrapper server, tool description sanitization, ANSI code stripping | Python-only, no chain analysis, no session management, no rate limiting |
| SecureMCP | 140 | Auditing tool — scans for vulnerabilities | Audit-only, not runtime protection |
| Vault MCP | 101 | Prompt injection scanning for MCP tool responses | Response-only, no request scanning, no chain analysis |
| ToolFence | 100 | Local policy enforcement, human approval for tool calls | No ML, no chain analysis, no response guard |
| MCP-Dandan | 66 | Real-time proxying, behavior analysis, malicious tool detection | Early stage, limited detection |
| Agent Identity Protocol | 37 | Zero-trust layer, HITL approval, DLP scanning, audit logging | No ML, no chain analysis |
| mcp-shark | 178 | Wireshark-like forensic analysis of MCP traffic | Forensic-only, not real-time blocking |
What's missing across every single one of these:
- Multi-turn chain analysis — nobody tracks tool call sequences across sessions to detect escalation patterns. Nobody. The single most important detection for multi-step attacks, and it doesn't exist in any MCP security tool.
- Neural threat detection — no ML-based prompt injection detection. Everyone uses regex or policy rules. No semantic understanding of attack intent.
- Response guard with PII/secret blocking — a few projects scan responses, but none block in real-time with fail-closed mode.
- STDIO command validation — only AegisGate validates MCP STDIO transport commands for shell metacharacter injection. Trail of Bits documented the attack. We built the defense.
- 7-layer defense in depth — every other tool is 1-2 layers. Nobody stacks regex + ATLAS mapping + neural net + chain analysis + risk scoring + anomaly detection + exfiltration scoring.
What We Built
AegisGate Platform has an embedded MCP server (pkg/mcpserver/) with 7 guardrails that enforce the spec's four MUSTs — and go well beyond them. Here's what's in the code:
Guardrail 1: Session Limit Enforcement
func (g *GuardrailMiddleware) OnSessionCreate(sessionID, agentID, clientAddr string) error
Tracks concurrent MCP sessions per tier. Enforces MaxConcurrentMCP — when the limit is hit, returns max_sessions_reached JSON-RPC error. Prevents session exhaustion DoS.
Guardrail 2: Tool Authorization
func (g *GuardrailMiddleware) OnToolCallWithAuth(sessionID, agentID, toolName string) error
Every tool call is checked against a tier-gated risk matrix. shell_command is Critical risk — blocked at Community and Developer tiers. database_query is High risk — blocked at Community. Tools are registered with risk levels and data types, and the authorization check happens before the tool executes.
Guardrail 3: STDIO Command Validation
func (v *STDIOValidator) ValidateCommand(cmd string) error
This is the one nobody else has. MCP's STDIO transport executes arbitrary OS commands by design. We validate every command against an allowlist (^[a-zA-Z0-9/._-]+$) and reject shell metacharacters — pipes, semicolons, command substitution, redirects, wildcards, environment variable expansion, background execution.
This directly addresses the OX Security "Mother of All AI Supply Chains" advisory and the Anthropic MCP SDK STDIO design vulnerability. The attack surface is real. The defense is 200 lines of Go.
Guardrail 4: Chain Analysis (P2)
func (g *GuardrailMiddleware) OnToolCall(sessionID, toolName string) error
This is the killer feature. Every tool call is recorded in a chain analyzer that tracks 20 turns (30-minute TTL). It detects three patterns:
- EscalationChain — risk levels increase across calls (read → write → execute)
- ExfilChain — read operations followed by network calls
- ReconChain — systematic probing followed by high-risk execution
Blocks on the 2nd call of a detected chain. 0% FPR across 8.1M benign requests. Nobody else does this.
Guardrail 5: Rate Limiting
func (g *GuardrailMiddleware) OnRateLimitCheck(clientAddr string) error
Per-client rate limiting with configurable RPM. Tracks in sliding window buckets. Developer tier: 500 RPM. Enterprise: configurable. Prevents abuse without breaking legitimate use.
Guardrail 6: MCP Response Guard
func (rs *MCPResponseScanner) ScanMCPMessage(ctx context.Context, message interface{}, sessionID string) (*responseguard.ResponseScanResult, error)
Scans MCP tool responses for PII, secrets, and XSS before they reach the client. StrictMode = true by default — fail-closed. If a tool response contains an AWS API key, it doesn't reach the LLM. Per-session stats track PIIFound, SecretsFound, BlockedResponses.
This addresses CyberArk's "Poison everywhere" finding — tool outputs can contain prompt injection and sensitive data. We scan them before they hit the context window.
Guardrail 7: Audit Logging + SIEM Export
Every session, every tool call, every block, every alert is logged with timestamp, session ID, agent ID, detection results, and block/allow decision. SIEM-exportable format. If an agent does something at 2 AM on a Tuesday, you'll know exactly what it did.
The Spec Says MUST. We Enforce It.
| Spec MUST | AegisGate Guardrail | Status |
|---|---|---|
| Servers MUST validate all tool inputs | Guardrail 2 + Guardrail 3 (STDIO validation) | ✅ Enforced |
| Servers MUST implement proper access controls | Guardrail 2 (tool authorization + tier gating) | ✅ Enforced |
| Servers MUST rate limit tool invocations | Guardrail 5 (per-client rate limiting) | ✅ Enforced |
| Servers MUST sanitize tool outputs | Guardrail 6 (MCP Response Guard) | ✅ Enforced |
The spec says servers MUST do these things. We built the middleware that does them. Every MCP connection that goes through AegisGate gets all four — plus chain analysis, neural detection, and session management that the spec doesn't even mention.
What the Spec Doesn't Say (And We Built Anyway)
The spec's security section is advisory. It says what servers SHOULD do. It doesn't provide:
- Chain analysis — the spec doesn't mention multi-turn attack detection at all. We built it because the OpenAI hack proved it's the most important detection layer.
- Neural threat detection — the spec doesn't mention ML-based prompt injection detection. We trained a 1.6M parameter CharCNN-BiLSTM model because regex can't catch novel attacks.
- STDIO command validation — the spec doesn't mention shell metacharacter injection in the STDIO transport. We built it because OX Security documented the attack vector.
- Response guard with fail-closed mode — the spec says to sanitize outputs but doesn't define fail-closed behavior. We default to StrictMode = true because "fail open" is not a security posture.
How It Works in Practice
Start the platform with the embedded MCP server:
./aegisgate-platform --embedded-mcp
Connect any MCP client. Every JSON-RPC request passes through the guardrail middleware:
Client → MCP JSON-RPC → GuardrailMiddleware → Tool Execution → Response Guard → Client
↓
Session limit check
Tool authorization
STDIO validation
Chain analysis
Rate limiting
↓
Block or Allow
If a tool call triggers an EscalationChain at Turn 2:
{
"jsonrpc": "2.0",
"id": 4,
"error": {
"code": -32000,
"message": "P2-EscalationChain detected: multi-turn attack pattern blocked",
"data": {
"guardrail": "chain_analysis",
"chain_type": "escalation",
"session_id": "sess-abc123",
"turn": 2
}
}
}
The client gets a structured JSON-RPC error. The SIEM gets an alert. The audit log captures everything. The attacker never gets to Turn 3.
The E2E Test Coverage
We didn't just build the guardrails — we wrote end-to-end tests that start the actual platform binary, connect via raw TCP MCP JSON-RPC, and exercise each guardrail:
//go:build e2e
func TestGuardrailIntegration_Initialize(t *testing.T) // Server starts, guardrails active
func TestGuardrailIntegration_ToolAuth_ShellCommandBlocked // Guard 2b: shell_command blocked
func TestGuardrailIntegration_StdioValidation(t *testing.T) // Guard 6: shell metacharacters blocked
func TestGuardrailIntegration_RateLimit(t *testing.T) // Guard 5: per-client rate limiting
func TestGuardrailIntegration_SessionLimit(t *testing.T) // Guard 1: concurrent session limit
func TestGuardrailIntegration_ResponseGuard_PII(t *testing.T) // PII in response blocked
func TestGuardrailIntegration_ResponseGuard_CleanResponse(t *testing.T) // Clean response passes
Every guardrail has an E2E test that connects to the real server and verifies the block at the protocol level. Not unit tests with mocks — real TCP connections, real JSON-RPC, real enforcement.
The Honest Assessment
I'm not going to claim we've "solved" MCP security. Here's what we haven't done:
We don't have production MCP traffic yet. All validation is synthetic. The 8.5M request stress test used generated payloads, not real MCP sessions from real users. That's the design partner conversation.
P4 and DIST2-5 are alert-only. Anomaly detection and distillation detection are validated for false positives (0% across 8.1M benign requests) but not true positives. They need real traffic variation. We won't flip them to blocking until we have that data.
We haven't been third-party pentested yet. The guardrails are tested via E2E integration tests, but we haven't had an external security firm try to break them. That's SBIR-gated ($15-30K).
The MCP spec is still evolving. The 2026-07-28 stable release is the first "stable" version. The authorization spec was rewritten mid-year. Things will change. We'll adapt.
But here's what I will claim: we built more MCP runtime security than anyone else has. The spec says MUST. We enforce it. The research community documented 9+ vulnerabilities in 9 months. We built defenses for every single one of them. And we added chain analysis — the one detection layer that nobody else has — because multi-turn attacks are the real threat.
References
- MCP Specification (2026-07-28 stable)
- MCP Security Best Practices
- Trail of Bits: Line Jumping Attack
- Trail of Bits: mcp-context-protector
- Simon Willison: MCP prompt injection problems
- CyberArk: Poison everywhere
- Invariant Labs: GitHub MCP exploited
- The Hacker News: mcp-remote RCE (437K downloads)
- Wunderwuzzi: Anthropic Slack MCP data exfiltration
- Awesome MCP Security (curated vulnerability list)
- AegisGate Platform (source code)
- AegisGate MCP guardrails code
Josh Colvin is the solo founder of AegisGate Security, building open-source, self-hosted AI security. Apache 2.0. No telemetry. No data egress. GitHub.
Top comments (0)