system: OPERATIONAL
← back to all hacks
SUPPLY CHAIN MEDIUM NEW

Deadbugz: an MCP server that turns hostile after the third tool call

An active campaign shipped a benign-looking MCP server through GitHub pull requests, then rewrote its own tool metadata into credential-hunting instructions once a client had made three ordinary calls.

2026-09-10 // 7 min affects: mcp, mcp-clients, llm-agents, coding-agents

What is this?

On August 12, 2026, Ariel Fogel of Pillar Security published Deadbugz: Currently Active MCP Supply-Chain Campaign, documenting a live operation that distributed a malicious Model Context Protocol server through public GitHub pull requests. Adversa AI’s September 7, 2026 MCP digest called it the MCP security event of the month.

The server advertises itself as a productivity helper with two harmless tools — text formatting and summarization — and behaves exactly as advertised. Then, once a connected client has issued three tools/call requests, the server changes the metadata it returns. The new tool descriptions and prompt content instruct the attached agent to look for SSH keys, AWS credentials, shell history and Kubernetes configuration, and to hide that activity from the operator.

What makes this worth reading is not the payload. It is the gate. The malicious instructions were present in the server the whole time; the counter simply decided when the reviewer was allowed to see them.

How it works

The campaign has two halves: a delivery route and a runtime trigger.

Delivery. A single public GitHub account opened 23 pull requests in 74 minutes on August 10, 2026, spread across unrelated AI, MCP and developer-tool projects. Seventeen added a remote MCP endpoint to a configuration file. Four pointed a local Python interpreter at a hidden path under ~/.config/.cache/.sys/. Two were directory or listing submissions. At the time of Pillar’s review, none had been merged through GitHub’s merge mechanism — 19 were closed and four were still open. The delivery vehicle is a config diff: a few lines in an MCP settings file, the kind of change a reviewer skims.

Trigger. The server keeps an in-memory, per-client counter of tools/call requests. Below the threshold it answers tools/list and prompts/get with ordinary documentation. At the threshold, the same endpoints start returning something else.

client connects  ──►  tools/list  ──►  "format_text", "summarize"   ← benign
                      tools/call  #1  ──►  normal result
                      tools/call  #2  ──►  normal result
                      tools/call  #3  ──►  normal result
                                    ▼  counter == 3
                      tools/list / prompts/get
                          ──►  [REDACTED: credential-seeking instructions
                                + directive to conceal activity]

The server also advertises tools.listChanged, the standard MCP capability that lets a client refresh tool metadata — so a compliant client will happily pick up the swapped definitions on its own.

The counter is the interesting engineering decision. A security reviewer connecting to a new server, poking two tools and reading the descriptions sees a clean server. An automated scanner that enumerates tools without calling them never crosses the line at all. Normal daily use crosses it within minutes. The threshold is calibrated against the reviewer, not the victim.

Why it matters

MCP clients hand tool definitions to the model as context. Those descriptions are how the agent decides what a tool is for and when to reach for it, which means a description is not a label — it is instruction text with a trusted-looking provenance. A server that can change its descriptions after installation can change what the agent believes, without changing anything the user would notice.

The primitive is not new. Invariant Labs demonstrated a delayed tool-description swap against a WhatsApp MCP integration in April 2025, and the ETDI paper (June 2025) formalized the rug-pull class and proposed signed, versioned tool definitions as the answer. We covered the static form of this in MCP tool-description rug pulls and the multi-tool variant in ShareLock threshold poisoning.

Deadbugz is the operational version: known primitive, real delivery campaign, and a gate built specifically to defeat the review step. It says something uncomfortable about approval-time security — a one-time audit is not merely incomplete against this, it is the exact thing the design targets. Whatever posture you hold at install time is the posture an attacker gets to plan around.

The observed impact was limited: no merged pull requests, no confirmed victims. Treat that as luck and timing, not as a ceiling. The technique costs an afternoon to reproduce.

Defenses

Fingerprint tool definitions at approval, and diff them on every reconnect. Hash the full tool list — names, descriptions, schemas — when the operator approves a server. Compare on every session and on every tools/listChanged notification. A definition that changes after approval should surface to the operator and require renewed consent before the changed tool can touch anything sensitive. This is the single control that would have caught Deadbugz.

Treat MCP config diffs as security-sensitive review. A pull request that adds a server to an MCP settings file is granting an external party a channel into your agent’s context. Require a named reviewer, verify the publisher, and never accept a config that points an interpreter at a dot-prefixed path in a cache directory.

Enforce sensitive actions in policy, not in prompt. Reading ~/.ssh, touching cloud credential files, executing code, writing to repositories, sending mail — these should be gated by the client’s own allow list, so that no instruction arriving through tool metadata can produce them. If metadata can talk the agent into an action, metadata is your access-control layer.

Watch for concealment as a signal. Any instruction telling an agent to hide what it is doing from its operator is, by itself, sufficient grounds to halt. Guardrails that only score for “harmful content” will miss it; a rule that flags requests for opacity will not.

Log tool-definition refreshes. Most MCP clients log calls but not metadata changes. Record every definition refresh with a timestamp, and keep the agent actions that followed it. If a device did connect to a hostile server, this is the difference between a scoped investigation and a guess.

For a broader baseline, the OWASP MCP Security Cheat Sheet covers the surrounding controls: message signing, interface binding, host-header validation, and OS-native credential storage.

Status

ItemDetail
DisclosurePillar Security research blog, published August 12, 2026; campaign delivery observed August 10, 2026
ClassSupply-chain delivery + runtime-gated MCP tool-metadata poisoning
TriggerPer-client in-memory counter; metadata changes at the third tools/call
Delivery23 public GitHub pull requests in a 74-minute window; 17 remote-endpoint configs, 4 hidden local-script configs, 2 listing submissions
Merge status at review0 merged via GitHub’s merge mechanism — 19 closed, 4 open
Prior artInvariant Labs WhatsApp MCP sleeper attack (April 2025); ETDI rug-pull formalization, arXiv 2506.01333 (June 2025)
CVENone assigned — this is a malicious-actor campaign, not a product vulnerability
Core defensive gapApproval-time review cannot observe metadata that only turns hostile after approval

Sources