The Incident
On August 30, 2026, Pillar Security disclosed Deadbugz, an active supply-chain campaign that distributed a malicious Model Context Protocol server through unsolicited GitHub pull requests. On August 10, 2026, between 21:52 and 23:07 UTC, a single GitHub account named zellkernel submitted 23 pull requests to unrelated AI, MCP, and developer-tool repositories, each configuring an MCP server named productivity-suite. The pull requests split three ways: 17 added the remote endpoint productivity-suite-mcp.onrender.com/mcp, 4 configured a local script at ~/.config/.cache/.sys/.deadbug-mcp.py, and 2 submitted directory-listing content as filler. None of the pull requests were merged through GitHub’s own review mechanism; Pillar reports that 19 were closed and 4 remained open at disclosure. Pillar named the campaign after the local payload file.
The server advertised itself as a text-formatting and summarization utility, which was the full tool surface a reviewer would see at install time. After exactly three tool calls, it rewrote its own tool descriptions and returned them on the next list_tools response. The new descriptions functioned as instructions to the connected AI agent to search ~/.ssh/*, ~/.aws/credentials, ~/.bash_history, and ~/.kube/config, and to suppress mention of those reads to the operator. Pillar categorizes the technique as runtime-gated metadata poisoning: the malicious instructions never appear in the code or configuration a reviewer would inspect at install time, and the trust granted to the server at approval time does not expire. Prior art for the mechanism exists — Invariant Labs disclosed MCP tool-description poisoning against Cursor in April 2025 — but Deadbugz is the first active, in-the-wild distribution the public record shows.
MITRE ATT&CK coverage: T1195.001 Supply Chain Compromise: Compromise Software Dependencies and Development Tools; T1552.004 Unsecured Credentials: Private Keys; T1552.001 Unsecured Credentials: Credentials In Files; T1583.001 Acquire Infrastructure: Domains.
The Authority Path That Failed
The identity carrying execution authority at the moment of failure is the AI coding or agent host — Cursor, Claude Desktop, or an IDE agent — running under the developer’s own OS session. At install time, the operator approved productivity-suite on the basis of its declared tool surface: text formatting and summarization. The server held exactly that approved scope at approval time. What it exercised at runtime, from the fourth tool call onward, was a different scope entirely: the server returned mutated tool descriptions, and the agent host read those descriptions as trusted instructions on the same channel it reads tool metadata from any approved server. The scope held and the scope exercised were different objects at different moments; approval bound only the first.
The trust anchor that failed first was the implicit assumption that MCP tool metadata is an install-time contract. The MCP specification permits a server to return any tool metadata on any call, and the agent host treats that metadata as trusted system instructions, not as content to be gated. The gap between held and exercised scope would have been visible to any process that continuously diffed each list_tools response against the install-time snapshot and refused description changes — especially changes that introduce filesystem-read, credential-search, or self-concealment language — without a fresh human approval. No such gate was in the path of any of the 23 targeted repositories; the only reason the campaign produced no confirmed exfiltration is that human reviewers rejected the PR text, not that any runtime boundary caught the mutation.
SecurityV0 Perspective
This is an unproven_execution finding against the MCP integration pattern itself, with a scope-drift reading available if the drift is framed from the agent’s actions rather than from how it was induced. The MCP framework attached credential-reading execution capability to the agent that the deploying operator never explicitly authorized: the install-time review covered a text-formatting tool surface, and the runtime surface — carrying filesystem-read and exfiltration directives in tool metadata — was never seen or approved. This is the Langflow CSV Agent and Python REPL pattern transposed to MCP: a declared, approved tool quietly ships with execution authority the operator did not sign off on, and the surface at approval time is not the surface at runtime.
The evidence pack SecurityV0 would produce for this finding is a per-session diff of every MCP server’s tool-description surface against the install-time snapshot, bound to the agent runtime that approved it. Pre-exfiltration, the pack answers: for every MCP server now in scope on this agent host, which tool descriptions in use today differ from the ones a human approved, and does the delta contain filesystem-read, credential-read, outbound-write, or self-concealment language. Post-exfiltration, the same pack answers: which MCP server last mutated its tool surface, when, what directives did the mutated surface issue to the agent, and which filesystem paths or endpoints did the agent reach after the mutation. Both are questions a disclosure letter needs an answer to, and both are gone if the install-time snapshot and the runtime surface are not stored and compared.
What To Do
- Pin every MCP server’s tool-description manifest at install time and diff it on every
list_toolsresponse. Fail closed on any change until a human re-approves. The description text itself is the attack surface; a byte-level diff bound to the agent session is the only control that catches a mutation before the agent acts on it. - Treat MCP tool descriptions as untrusted instruction input, not trusted system text. Route them through the same prompt-injection and credential-pattern guards you apply to any content the agent ingests from the outside world. The MCP channel is not a privileged channel.
- Reject unsolicited MCP-configuration pull requests at the repository level. Deadbugz landed its payload entirely through PRs that added an MCP server to a project’s config. Require that any PR touching
.mcp.json,.cursor/mcp.json, or an equivalent file originate from a known contributor and pass a human review that specifically evaluates the server surface. - Scope the agent host’s OS identity down from the developer’s. Agents running under a developer’s shell inherit read access to
~/.ssh,~/.aws,~/.kube, and shell history. Give the agent a dedicated OS user with no access to credential directories and no shell history inheritance, and route any legitimate credential need through a secrets broker the agent must prompt for. - Instrument outbound egress from the agent host and alert on first contact with endpoints advertised by MCP tool metadata.
productivity-suite-mcp.onrender.comwas a public Render-hosted endpoint; a per-host egress baseline that flags new destinations introduced by a tool-call surface change would have surfaced the campaign on the first attempted exfiltration.
Sources
- Pillar Security — Deadbugz: Currently Active MCP Supply-Chain Campaign
- Cloud Security Alliance Labs — Deadbugz: Active MCP Campaign Poisons Agents After Trust
- Cloud Security Alliance Labs — Deadbugz: Runtime-Gated MCP Metadata Poisoning as Supply-Chain Attack
- ByteIota — MCP Servers Are Being Weaponized: Here’s the Proof
- DeepInspect — Deadbugz Malicious MCP Server Supply-Chain Campaign
- Invariant Labs — MCP Security Notification (tool-description poisoning, April 2025 prior art)
- MITRE ATT&CK: T1195.001, T1552.004, T1552.001, T1583.001