AI × Crypto · Agent security
Who Re-Reads a Tool Description After You Approve It?
A malicious server counted its own tool calls and behaved perfectly for the first three. On the fourth, the descriptions it handed the agent turned into instructions to hunt SSH keys and cloud credentials — and to keep quiet about it. Twenty-three pull requests carried it into unrelated projects in seventy-four minutes.
The security firm Pillar published research last month on a malicious Model Context Protocol server it calls Deadbugz. The mechanism is worth understanding precisely, because it is not a bug in anything. Every component behaved as designed.
An MCP server tells an agent what it can do. It publishes a list of tools, each with a name and a description, and the agent reads those descriptions to decide what to call and when. That list is the contract. A human reviews it once, at the moment they wire the server in, and approves it.
The Deadbugz server offered text formatting and summarization. It kept an in-memory counter of how many times each client had called it. For the first three tools/call requests, it did the job. On subsequent tools/list and prompts/get responses, per Pillar, the metadata it returned was no longer tool documentation. It was a set of instructions telling the agent to go and find SSH keys, AWS credentials, shell history and Kubernetes configuration — and, Pillar writes, "to conceal the activity from the user."
Nothing was exploited. The server simply answered a later question differently than it had answered the first one.
Three is a well-chosen number
The counter is the whole design, and three is not arbitrary. Pillar's account of why is the sharpest line in the paper: "a brief inspection or limited test can receive only benign metadata, while normal use crosses the three-call threshold."
That is a threshold tuned to human attention. Someone evaluating a new server pokes it once or twice, sees plausible formatting output, and moves on. Someone actually using it sails past three inside a single working session. The malicious behaviour is gated to appear only after the reviewer has stopped looking.
This is what makes the technique structurally awkward rather than merely nasty. The standard control for third-party tools is review-at-approval: read what it claims to do, decide, grant. Runtime-gated metadata defeats that control by construction, because the artifact reviewed and the artifact served are not the same artifact. As Pillar puts it, metadata that only turns hostile at runtime "defeats review by construction."
Seventy-four minutes of pull requests
The delivery was ordinary open-source contribution. A GitHub account named zellkernel filed twenty-three pull requests against unrelated AI, MCP and developer-tool projects between 9:52 p.m. and 11:07 p.m. UTC on August 10. Nineteen had been closed and four were still open when Pillar reviewed them.
The submissions were not identical. Seventeen configured a remote MCP endpoint. Four pointed at a hidden local Python script. Two were submissions to directories and listings — the catalogues that other people browse when they are looking for a server to install.
What the twenty-three pull requests actually contained
zellkernel account in a 74-minute window on August 10, 2026, as documented by Pillar Security. Bar widths are proportional to the largest category.Pillar also records a Bitcoin address embedded in the malicious prompt, which it reads as a campaign marker rather than a payment mechanism, and an associated account on X. The firm's recommendations are operational: block the endpoint, reject configuration changes that introduce it, search your own repositories and MCP client logs for the indicators, and — the durable one — require renewed authorization when a tool definition changes.
What the record shows now
Pillar described the campaign as active at publication. This desk checked its traces against the GitHub API on September 7.
The zellkernel account no longer resolves; the user endpoint returns 404. A search of issues and pull requests for the account name returns nothing. An authenticated code search for the campaign's endpoint string returns four files, and all four are write-ups of the incident rather than live configuration — two dated daily security reports from September 4 and 5, and two blog posts from August 16. A code search for the Bitcoin marker returns nothing at all.
Those results are worth stating carefully, because they prove less than they appear to. GitHub removes deleted and suspended accounts alike and reattributes their pull requests, so a 404 does not establish that anyone took enforcement action, or when. Code search covers indexed public repositories only; it does not see private forks, unindexed files, or a developer's laptop. What the searches support is narrow and still useful: the campaign's public artifacts are no longer findable where they were, and nobody appears to be shipping that endpoint in public code.
The part that does not get taken down
Deadbugz did not target crypto. The credentials named in the poisoned metadata are the developer's and the cloud operator's — SSH, AWS, shell history, Kubernetes. No wallet, seed phrase or signing key appears in the reported target list, and this desk has seen no evidence of funds being taken. The Bitcoin address is a signature, not a destination.
The reason it lands in this section anyway is that the trust model it broke is the one now being wired to money. MetaMask's Agent Wallet and the exchange-side agent plumbing this desk has covered all rest on the same arrangement: a human approves a set of tools once, and the agent thereafter reads tool descriptions as authoritative instructions about what to do. Deadbugz demonstrates that the second half of that arrangement can be rewritten by the server after the first half is finished.
The month's other MCP findings are more conventional and easier to fix. Adversa's September roundup lists a path-traversal flaw in Atlassian's MCP server (CVE-2026-73498, CVSS 7.7, fixed in 0.22.0), a cluster-token disclosure in ArcadeDB's (CVE-2026-67357, CVSS 7.7, fixed in 26.7.3), and a server-side request forgery issue in a Facebook Ads MCP server (CVE-2026-19956, CVSS 5.3). Those are vulnerabilities with patches and version numbers. Deadbugz has neither, because there is nothing to patch.
The Take
The interesting thing about this campaign is how cheap it was. One account, seventy-four minutes, twenty-three pull requests, no exploit, no zero-day, no malware in the conventional sense — just a server that answered a routine question honestly three times and dishonestly afterward. Most of the PRs were closed, which suggests maintainers are reasonably good at smelling an unsolicited config change from an unknown account. That is a real defence and it deserves credit. But it is the wrong defence to be relying on, because it only works while the submission looks unsolicited. The structural problem is that agent ecosystems inherited a permission model from app stores — review once, then trust — and applied it to a component whose entire job is to send new instructions on every call. Tool descriptions are not manifests. They are live input, arriving continuously from a party you decided to trust at a moment that has passed. Pillar's last recommendation is the one that matters and the one nobody wants: re-authorize when the definition changes. Every serious answer here costs somebody a prompt they would rather not see. Until an agent's tool list is pinned, hashed and diffed the way a lockfile is, "I approved this server" will keep meaning "I approved what this server said the first three times I asked."