Est.
MCP SecurityLong read

MCP Architecture and Attack Surface Overview

MCP's convenience creates security gaps most deployments have yet to close.

Senior Writer · · 10 min read
Cover illustration for “MCP Architecture and Attack Surface Overview”
MCP Security · September 23, 2026 · 10 min read · 2,303 words

The Model Context Protocol solves a specific integration problem, and in solving it, it opens a specific set of doors that most deployments have not yet learned to lock. Anthropic published MCP in November 2024 as a way to stop every AI application from needing its own custom adapter for every tool. On December 9, 2025, the spec was handed off to the Agentic AI Foundation under the Linux Foundation, with platinum members including AWS, Anthropic, Block, Bloomberg, Cloudflare, Google, Microsoft, and OpenAI signing on to steward it. That roster alone tells you the protocol has moved past experiment and into infrastructure.

The problem it fixes is the N×M problem: N AI front ends (ChatGPT, Gemini, Claude) each needing a bespoke connector to M tools (Slack, GitHub, a database instance). Multiplying those integrations out across a growing ecosystem produces a combinatorial mess of one-off integrations, each maintained separately, each a little different from the last. MCP collapses N×M into N+M. A tool vendor builds one MCP server. Any MCP-aware host can talk to it with no extra glue code. That decoupling is the whole pitch, and it's also, as it turns out, the whole risk. Every architectural layer that makes this convenient also gives an attacker a new place to stand.

The three-role architecture: host, client, and server

MCP defines three roles, and most of the security story traces back to where trust does and doesn't cross a boundary between them.

The Host is the user-facing application: Claude Desktop, an IDE like Cursor, or an autonomous agent running unattended. It orchestrates the LLM's interactions, enforces access control, and manages the lifecycle of whatever clients it spins up. It is the gatekeeper.

The Client is an intermediary living inside the host, and each client keeps a dedicated, stateful, one-to-one session with a single server. It handles capability discovery, dispatches tool invocations, and listens for server notifications. One client, one server, one conversation.

The Server is an independent process, often written and run by a third party, that exposes three kinds of capability to whatever client connects to it: tools (functions the model can call), resources (data the model can read), and prompts (reusable templates). The architecture also defines client-side primitives: roots and sampling. Roots restrict a server's access to specific resources, which is the mechanism meant to enforce least privilege. Sampling lets a server request a completion from the LLM itself, which enables multi-step workflows and, ideally, human review at the right checkpoint. Elicitation, added in 2025, lets a server ask the user for more information mid-task without losing the user's control over what gets shared.

On paper, this is a clean separation of concerns. In practice, the separation only holds if every party behaves. MCP's threat model largely assumes they will.

Discovery and dynamic tool registration: runtime extension of the architecture and the attack surface

The mechanism that makes MCP genuinely useful is discovery. When a host connects to a server, the server hands back metadata: tool names, natural-language descriptions of what each tool does, and the schema for calling it. That metadata gets loaded straight into the LLM's context or system prompt. No developer writes a new integration. No code ships. The agent just reads what the server tells it and, from that point forward, knows how to use it.

This is the feature that lets an agent connect to a server it has never seen before and immediately act competently with it. The protocol carries all the semantics needed, so the burden of "teaching" the model a new tool disappears.

It's also the feature that quietly redefines what counts as trusted input. Tool descriptions arrive before the user has typed a single word, and the model treats them as operational configuration, not as content that might be adversarial. That distinction, configuration versus input, is exactly the distinction that later sections will show attackers exploiting. Discovery is supposed to be a convenience. It doubles as an unguarded loading dock.

The transport layer: stdio, Streamable HTTP, and the deprecated SSE mechanism

MCP currently defines two transports, and which one a deployment uses says a lot about how exposed it actually is.

stdio, standard input and output, is the dominant choice in practice. A 2025 study (arXiv 2509.25292) found 339 of 341 measured clients supported it. That dominance reflects MCP's early design center: local, synchronous, one process talking to another on the same machine. It's also, not coincidentally, the safer of the two transports by default, because its exposure is bounded by the host process itself.

Streamable HTTP, introduced in the March 26, 2025 spec update and retained in the November 2025 revision, is the current standard for remote servers. It collapses what used to be a more awkward setup into a single HTTP endpoint handling both POST and GET. What it replaced, HTTP plus Server-Sent Events, is now officially deprecated, though plenty of tooling still supports it out of inertia. As of August 2025, only 95 of the 341 clients measured had actually adopted Streamable HTTP (arXiv 2509.25292). The client ecosystem, in other words, has not caught up to the spec.

The July 28, 2026 revision goes further and removes the handshake and session ID entirely, so every request becomes self-contained and routable to any server instance without needing a sticky session. That's a meaningful simplification for anyone running servers at scale behind a load balancer.

Transport choice maps directly onto threat class. stdio's risk is scoped to whatever can compromise the local host process. Streamable HTTP opens a network endpoint, and network endpoints inherit the usual catalogue: authentication failures, man-in-the-middle interception, DNS rebinding, all documented as attack types in MCPSecBench (arXiv 2508.13220). The gap between 339 stdio adopters and 95 Streamable HTTP adopters suggests most deployments today are local and reasonably contained. But the servers actually wired into production, the ones touching real customer data and real credentials, skew disproportionately toward the remote, network-exposed side. The riskier transport is exactly the one carrying the higher-value traffic.

Evolution of the authentication spec and the long tail of deployments it left behind

Authentication in MCP is a story told through version numbers, and each version reveals something the previous one got wrong.

The initial November 5, 2024 release had no mandatory authentication for remote servers. That wasn't an oversight so much as a reflection of what MCP was built for at the time: a local integration tool, not an internet-facing service. The March 26, 2025 update brought OAuth 2.1 into the spec as a requirement for HTTP-based flows, with the Authorization Code grant plus PKCE (RFC 7636) and Dynamic Client Registration (RFC 7591) brought in for HTTP-based flows. June 18, 2025 added Protected Resource Metadata for auth server discovery and introduced OAuth 2.0 Resource Indicators (RFC 8707) as a requirement. The November 25, 2025 stable release introduced Client ID Metadata Documents as the preferred registration mechanism, keeping Dynamic Client Registration around for backward compatibility.

Read straight through, that's a spec maturing in real time, tightening its own screws every few months. Read against deployment data, it looks different. A measurement study of 7,973 live remote MCP servers (arXiv 2605.22333, Fudan University et al.) A measurement study of 7,973 live remote MCP servers (arXiv 2605.22333, Fudan University et al.) found that 40.55% exposed tools with no authentication whatsoever, two out of every five servers measured running with the door unlocked. It's a widespread pattern, two out of every five servers measured running with the door unlocked. That's two out of every five servers measured, running with the door unlocked.

Trend Micro's research adds a texture to the number: hundreds of MCP servers sitting exposed on the open internet with no auth at all, many of them bound to 0.0.0.0 by default. Any device on the same network can reach them without credentials. Researchers have taken to calling this the "NeighborJack" pattern, and it's a fair name for it. Fewer than a third of servers surveyed implement OAuth-based authorization flows. The spec got stronger. The installed base, largely, did not follow.

Diagram: MCP's Authentication Gap: Spec vs. Reality. Visualizes: Show the contrast between what the MCP authentication spec requires and what live deployments actually implement.

Prompt injection and tool poisoning: how the model's trust in its own context becomes the attack channel

OWASP ranks prompt injection as the number one LLM security risk, and in MCP that risk becomes operational rather than theoretical, because injected instructions get executed as actions. In a chatbot with no tool access, a successful injection produces bad text. In an MCP environment, a successful injection produces an action, because the injected instruction gets routed straight into a tool call.

Two 2025 incidents make the mechanism concrete. A GitHub MCP vulnerability let crafted content sitting inside a repository inject instructions that exfiltrated private data from other users' sessions, the repository content itself functioning as the attack payload once the model read it as context. A WhatsApp MCP exploit followed a similar path, pulling message history out through the same kind of indirect injection.

Tool poisoning is the more targeted variant. Instead of hiding malicious instructions in content the model happens to read, an attacker embeds them directly in a tool's description, its parameter schema, or the text it returns after being called, content the agent has been architecturally conditioned to treat as trusted configuration rather than as something to scrutinize. The timing is what makes this hard to catch: the poisoned instructions load during discovery and initialization, before the user has typed anything. Any security layer built to inspect user messages for injection attempts simply never sees this traffic. It is in the tool's own metadata, loaded before the conversation begins. It's in the tool's own metadata, loaded before the conversation begins.

Rug pulls and tool shadowing: attacks that exploit the gap between approval and execution

MCP has no cryptographic content-addressing and no version pinning for tool descriptions. That absence is the entire mechanism behind the rug pull. A server audited and approved at one point in time can behave completely differently later, because nothing in the protocol ties the approved behavior to a fixed, verifiable artifact. It's a supply chain attack, just operating at the semantic layer instead of the binary one.

CVE-2025-54136, nicknamed MCPoison, shows how this plays out against Cursor IDE. Check Point Research disclosed it to Cursor. An attacker supplies a benign MCP configuration that gets approved, then replaces it with a malicious payload after the fact. Because approval was not re-triggered on the change, every following session silently executed the attacker's commands. The approval happened once, against content that no longer existed by the time it mattered.

Tool shadowing is a quieter variant of the same underlying gap. A malicious server needs only to inject a description that reshapes how the agent calls a different, trusted server's tools. It just needs to inject a description that reshapes how the agent calls a different, trusted server's tools. The attack lives in the instructions, not in the invocation, so it can operate entirely underneath a user-facing log that shows only trusted tool names being called. Combining that with a rug pull produces an attack that hijacks agent behavior while the interaction log looks completely clean. Nothing in the UI tells the user anything went wrong, because nothing in the UI was designed to show semantic drift between t₀ and t₁.

Supply chain risk at registry scale: how attacker-controlled servers enter the ecosystem

The same weakness repeats at the registry level. Vetting and ownership checks across public MCP registries are thin enough that adversarial or hijacked servers get listed alongside legitimate ones, and once a host pulls in that server's metadata, the attacker's tool descriptions start shaping the model's reasoning without any independent check confirming they're honest.

A study covering 67,057 servers across six public registries (arXiv 2510.16558) found conditions that would let an attacker hijack a server or manipulate how its tools get invoked, a pattern widespread across the registries rather than confined to a handful of bad actors slipping through. It's a structural gap in how registries vet what they list. OWASP has since given this its own line item, ASI04, in the Agentic AI Top 10, formal recognition that MCP supply chain risk is now a distinct category tracked on its own. Responsible disclosure of MCP authentication vulnerabilities alone has already yielded multiple CVE IDs, and the broader catalogue of filed vulnerabilities continues to grow. That's an active, catalogued attack surface with a growing paper trail.

The four-surface taxonomy: mapping every architectural layer to its threat class

Putting the preceding sections side by side reveals a pattern: every architectural layer in MCP has a matching threat class, and the two move together. The host, client, and server division of labor creates a trust boundary that only holds if every party is honest, which is precisely what tool poisoning and rug pulls violate. Discovery and dynamic registration create a channel where adversarial content loads as trusted configuration before the user ever engages, which is what indirect prompt injection exploits. The transport layer splits exposure between contained local processes and open network endpoints, and authentication has evolved on paper faster than the installed base has followed, leaving a measured 40.55% of live servers with no authentication. Registries, finally, are the entry point where attacker-controlled servers get distributed at scale in the first place, the precondition all the other attacks depend on.

Frameworks like MCPSecBench have started mapping these categories systematically, treating the protocol's own architecture as the index of where to look for weakness. That's the right instinct. MCP's defining promise, that any host can talk to any server with no bespoke glue code, is not separable from its defining risk. The decoupling that makes the ecosystem move fast is the same decoupling that lets a malicious server sit indistinguishable from a legitimate one until the moment it isn't. Understanding the architecture is the only way to see where that moment can happen.

Sources

  1. MCPSecBench: A Systematic Security Benchmark and Playground for Testing Model Context Protocols
  2. A First Measurement Study on Authentication Security in Real-World Remote MCP Servers
  3. Specification - Model Context Protocol
  4. blog.modelcontextprotocol.io
  5. Architecture overview - Model Context Protocol
  6. owasp.org
  7. arxiv.org
Filed underMCP Security

More in MCP Security