Red-team lab exposes MCP prompt injection before the first tool call

Mike Moore's test harness shows server-written instructions entering trusted context, with public caching able to spread them between callers.

By · Published

Primary source: Web of Mike

Why it matters

MCP clients can accept server-authored prose before tools run. Gateways that cache or trust that text can turn connection metadata into a cross-user security boundary.

A smaller, dark red data stream subtly merges into a larger, bright blue-purple data stream before it enters a crystalline processing node within a data center.

Mike Moore (@themsquared) has published a red-team lab showing how a Model Context Protocol server can place attacker-written instructions into an AI agent's context before the agent makes its first tool call.

Moore, a Portland-based sales engineering and solution architecture leader who works at Solo.io, released the personal research project alongside a September 11th write-up. His open-source test harness focuses on a server-level instructions field that sits outside individual MCP tool definitions, where much of the industry's prompt-injection work has concentrated.

The field is part of MCP's connection and discovery process. Older protocol versions return it during initialize; the July 28th, 2026 specification can return it through server/discover. The current discovery specification describes instructions as optional natural-language guidance for helping an LLM use a server effectively. The same example response marks the discovery result publicly cacheable for one hour.

That combination gives an untrusted server two opportunities. Its prose can reach the model before tool use, and a shared intermediary can potentially retain the prose for another caller.

Four attacks, one controlled environment

Moore's lab runs four scenarios against a simulated hostile server, caching proxy and enforcement layer. One inserts a direct override instruction. Another hides a directive inside a 24,000-character payload. A third changes previously approved instructions after several discovery requests. The fourth marks a poisoned response with cacheScope: "public", allowing the lab's deliberately vulnerable proxy to serve it to a second caller.

All four scenarios reach the lab's trusted prompt region or cross its caller boundary when defenses are disabled. The guarded run blocks all four using isolation, a 4,096-character cap, caller-bound cache keys and a digest that rejects changed instructions. The repository contains eight assertions covering the defended and undefended outcomes.

The cache test carries the clearest infrastructure consequence. In Moore's simulation, client A requests discovery from the hostile server and populates the proxy cache. Client B then receives the same instructions from the proxy without connecting to the hostile server. A gateway that aggregates MCP traffic can therefore become the distribution point for poisoned metadata if its cache key ignores server identity, authorization context or caller identity.

MCP's own Python SDK caching documentation warns that a public scope allows a shared gateway to serve a response across users, including authenticated requests. Its safe default is an immediately stale, private response. The Rust SDK, meanwhile, caches discovery responses carrying a positive lifetime, illustrating why gateway and client behavior must be evaluated implementation by implementation.

The lab does not demonstrate compromise of a named commercial gateway or agent framework. It contains no language model, so it does not establish that a production model would follow the hostile text or convert it into a consequential tool call. It tests whether server-controlled text enters a region the harness labels trusted. Actual impact depends on the client's prompt assembly, the model's behavior and the permissions available to the agent.

At least one major client makes the underlying route concrete. Anthropic's Claude Code documentation says server instructions load at session start to help Claude find deferred MCP tools. Claude Code caps each server's instructions at 2KB, which would truncate Moore's 24,000-character test case and reduce the volume attack. The direct-injection surface remains because shorter server-authored instructions still enter the model context.

A common field, with a narrower cache chain

An August 28th audit of the official MCP registry reported that 5,462 of 8,235 responding servers, or 66%, returned an instructions value. The audit found a median length of 577 characters and a maximum of 68,669 characters. Those figures are self-reported research results backed by a downloadable server-level dataset, rather than measurements reproduced by Moore's red-team lab.

The same audit also narrows the immediate reach of the public-cache scenario. Only 22 responding servers negotiated the July 28th, 2026 protocol version that introduced server/discover; 7,216 used the June 18th, 2025 version. The broad risk is server-authored text entering agent context through legacy initialization. The cross-caller cache chain depends on newer discovery semantics and on a client or intermediary honoring a positive public cache hint without sufficient partitioning.

The protocol concern predates Moore's lab. An open MCP specification issue, filed on August 7th as MCP-2026-015, describes the unrestricted instructions field and its interaction with public discovery caching. The issue proposes isolating server text from trusted system instructions, imposing a length limit and treating the field as untrusted content. It is an issue identifier, not a CVE, and it remained open as of September 18th.

Moore's controls place responsibility at the gateway and host layers. Server instructions are labeled with their source and kept outside the trusted prompt region; instruction-bearing responses are denied public caching; approved content is pinned by hash; and changed text fails closed. His lab also includes a keyword detector, though it cannot block requests because the same phrases trigger in both successful and blocked scenarios.

That distinction matters for agent infrastructure. Phrase scanners can report suspicious text. They cannot guarantee that an agent will refuse it. MCP operators need deterministic policy around what reaches privileged prompt space, which metadata may be shared across callers and what actions an influenced model is authorized to execute.

Reader comments

Conversation for this story loads after sign-in.