The state of Python MCP server security.
We scanned 39 public Python MCP servers, from the most widely used down to single-purpose ones, 1,939 tools in total, with static taint analysis. Contrary to the headlines that paint Model Context Protocol as a security dumpster fire, the popular Python ecosystem is careful: zero command injection, zero SQL injection in real servers, and 34 of 39 servers clean of any injection finding.
That is the good news, and we are publishing it even though it is the less sensational story. It is also not the whole story. The risks that actually break agents, prompt injection, tool poisoning, and excessive agency, are the ones a code scanner cannot count.
Download the full report (PDF), 5 pages, no signup.
What we found
Injection-class findings across the 38 real servers, with the Pinaka rule that detects each:
- Command injection (RCE), rule AS-TS-004: 0. No real server let a tool input reach a shell, eval, or exec sink.
- SQL injection, rule AS-TS-005: 0. No database tool let a tool input reach a SQL query through unsafe string building.
- Path traversal, rule AS-TS-006: 3 servers, all read-only, by-design for a file tool, or off by default. None a clean exploit.
- Server-side request, rule AS-TS-003: 1 server fetched a user-supplied URL behind an explicit flag, a legitimate feature that doubles as an SSRF primitive.
- The lethal trifecta, rule AS-DL-001: 0. No single server combined a private-data reader and an external-send tool unsafely.
Five servers in the full set of 39 tripped an injection rule. One is the deliberately vulnerable benchmark. The other four each carried a single lower-severity finding. We report these in aggregate rather than naming the projects, because the right next step for a real finding is responsible disclosure, not a blog callout.
Does this mean MCP is safe? No.
A low injection rate is a real, useful finding, but it is not a clean bill of health. Popular is not the same as the server your team wrote last sprint. Injection is only the part a static scanner can see: prompt injection, tool poisoning, rug pulls, and excessive agency do not show up as a tainted parameter reaching a sink. And 7 of the 46 repositories still returned zero tools (non-MCP repos, frameworks, or a tool-name indirection the scanner does not yet resolve), so unmeasured is not the same as safe.
When the bugs are real, the scanner finds them
We ran the same engine against the open-source damn-vulnerable-mcp-server benchmark. Across its 49 tools the engine flagged 15 injection sinks: 8 command and code-injection sinks and 7 path-traversal sinks. The benchmark also includes behavioral attacks like rug pulls that no static scanner can see by reading code, and we do not claim to catch those.
How we measured this
We cloned 46 public Python MCP server repositories as of June 2026, spanning the most widely used servers (AWS, Kubernetes, Telegram, Google Workspace, Atlassian, ElevenLabs, Home Assistant, Jupyter) down to single-purpose ones, a representative sample rather than a ranked top 46. Each was scanned with Pinaka static taint engine, an AST-based intra-procedural pass that traces every tool parameter to shell, eval, SQL, file, and network sinks. The engine is precision-first: a clean codebase produces zero findings, which is what makes a non-zero finding worth acting on.
Pinaka Agent Surface runs this same scan on your own repository, locally, against the OWASP MCP Top 10.
Related: MCP security guide, agentic security, and AI security.