Est.

Model Context Protocol Security Architecture

Reporter · · 11 min read
Cover illustration for “Model Context Protocol Security Architecture”
Running AI-Generated Code Safely · August 9, 2026 · 11 min read · 2,413 words

The host is the intended trust anchor. It is supposed to enforce access control. In practice, it routinely delegates that responsibility to the client, or simply accepts whatever claims the server makes about its own identity and behavior.

Trust in MCP is largely implicit. Clients inherit trust from the servers they connect to without continuous verification. Three structural assumptions underwrite this arrangement, and each is exploitable: that a server's tool metadata was authored by the system developer and accurately reflects the tool's behavior; that a server's behavior at installation time is its behavior at runtime; that credentials presented by a server are valid, not replayed or stolen.

The protocol enforces none of these properties. The original MCP specification did not require servers to sign or attest their tool definitions. Servers can update tool definitions without notifying the client, and most clients do not flag or detect those changes. That gap sits at the root of an entire class of attacks addressed below.

But what if every layer needs to be treated as a potential adversary rather than a trusted peer? Defense concentrated at a single point, at the host, fails when the client and server layers each carry their own attack surfaces. What reads as a clean layered architecture in the specification documents is, in actual deployment, a chain of implicit trust relationships that no single team fully controls. I have watched organizations discover this the hard way, after the fact, because the architecture looked sensible on a whiteboard and the problems only surfaced under adversarial conditions no one anticipated during design.

The Authentication Gap Exposed Across Real-World MCP Deployments

Start with the numbers, because the numbers are the argument. Research published in May 2026 (arXiv:2605.22333) surveyed 7,973 live remote MCP servers. Of those, 40.55% expose tools with no authentication whatsoever. Among the 119 OAuth-enabled servers tested, every single one exhibited at least one flaw; 325 total flaws were catalogued across that population. Dynamic client registration vulnerabilities affected 96.6% of OAuth-enabled servers tested. The documented outcomes include sensitive information leakage and account takeover. Nine CVEs resulted from the study alone.

The November 2025 specification formalized OAuth 2.1. The data above was collected after that. Specification maturation and implementation fidelity are not the same thing. That raises an important question: why does the gap between them persist? It reflects ecosystem incentives, development velocity, and the absence of enforcement mechanisms at the protocol level. A standard that cannot compel adoption is, functionally, a recommendation.

Most deployed servers still rely on static API keys or personal access tokens passed through environment variables, a pattern inherited from the ecosystem's origins in rapid prototyping. CVE-2025-6514 illustrates the cost: critical severity, arbitrary OS command execution triggered when MCP clients connect to untrusted servers, affecting a widely downloaded package before disclosure. The vulnerability was not exotic; the package was.

OAuth 2.1 enforcement for all remote server connections is the baseline posture, not an aspiration. Static API keys warrant a defined rotation policy and should be treated as a temporary compensating control. Dynamic client registration deserves careful validation; server-asserted client metadata should not be accepted without verification. Censys-style scanning is available to defenders as readily as to attackers, which means any organization that has not yet scanned its own surface has already ceded that intelligence to whoever has.

Prompt Injection via Tool Metadata and Why the Model Itself Is the Attack Surface

Tool poisoning's mechanism is counterintuitive, which is part of why it works as reliably as it does. Hidden malicious instructions are embedded in tool metadata: description fields, parameter names, anything the model processes as authoritative context. The model follows them because it treats those fields as originating from the system developer. The payload arrives dressed as trusted system context, not adversarial input. This is structurally closer to a supply-chain attack than to user-side jailbreaking, and that distinction shapes how defenses need to be designed.

OWASP rates prompt injection first in its Top 10 for LLM Applications (2025). Its MCP Top 10 project codified tool poisoning specifically as MCP03:2025. Invariant Labs' April 2025 proof-of-concept made the threat concrete: a single poisoned tool description exfiltrated private repository contents and message histories without user interaction, no network exploit required, no user error involved. A subsequent demonstration involving a WhatsApp MCP server showed a malicious server silently reading and exporting a user's entire message history through tool poisoning alone, by occupying the same agent context as a legitimate server.

The MCPTox benchmark (arXiv:2508.14925) tested 312 attack scenarios across 14 vulnerability classes. Even the strongest commercial agents failed roughly half the prompt-injection-via-tool-output scenarios. It is also worth considering what sits uncomfortably alongside the standard capability narrative: more capable models are frequently more vulnerable to this class of attack, because the attack exploits superior instruction-following rather than circumventing it. Refusal rates were low across all tested models. Better capabilities, worse outcomes on this specific threat vector. Why exactly does this happen? It is not a paradox once you understand the mechanism, but it does complicate the instinct to treat model upgrades as a security improvement.

That leaves the security team working in awkward territory. The controls at this layer are semantic, not infrastructural. Metadata invisible to users is the attack vector, which means tool descriptions need to pass in front of human reviewers before permissions are granted. Tool output must be treated as untrusted content rather than system instruction; output sanitization before feeding results back into model context is required, not optional. Anomalous tool invocation patterns, calls that diverge from a tool's stated purpose, warrant monitoring. None of this is simple to operationalize at scale, and the problem does not shrink as agent systems grow more capable.

Rug Pulls and Tool Shadowing as Supply-Chain Attacks on Agent Behavior

A rug pull, in the MCP context, is straightforward in conception and difficult to defend against with conventional controls. A tool behaves legitimately at installation. After permissions are granted, its behavior changes, silently, because MCP servers can update tool definitions without client notification and most clients do not detect the change. The permission model is static; the tool is not.

The Postmark incident from September 2025 is the clearest documented case. The maintainer of the official Postmark MCP server added BCC logic that silently copied every sent email to an attacker-controlled address. Koi Security's incident response confirmed the backdoor had been live across multiple versions. The package signature was valid throughout. Signing proved nothing about runtime behavior.

Tool shadowing works through a different mechanism. A malicious tool in an agent's context overrides or intercepts calls intended for a legitimate tool with the same or similar name. The client, having inherited trust from the server at connection time without ongoing verification, has no basis for detecting the interception. The agent calls what it believes is the right tool; something else answers.

Poisoning, rug pulls, and shadowing are three variants of a single architectural problem: clients trust servers at installation and do not reverify. The exposure scales directly with the number of connected servers, and organizations running dozens of MCP integrations simultaneously carry a cumulative trust liability that almost certainly exceeds what any single server's risk profile suggests in isolation. Rigorous vetting at onboarding matters. But how does this affect our original promise? It does not account for behavior that changes after permissions have already been granted.

Defending against this class means treating tool definitions as software artifacts subject to supply-chain discipline: version-locking and cryptographic verification at install, with any definition change treated as a new install requiring re-review. A tool registry with provenance tracking. Least-privilege scoping at the tool level. Sandboxed execution so a compromised tool cannot reach outside its designated boundary.

Code Execution Vulnerabilities: Injection, Traversal, and SSRF at the Server Layer

MCP servers are software. They carry the same implementation vulnerabilities as any other networked service, compounded by the fact that many were written quickly as the ecosystem outpaced security practice.

CVE-2025-49596 in MCP-Inspector is illustrative: a widely used development tool accepted unverified inputs and allowed remote code execution via crafted messages. Command injection, a well-understood vulnerability class, appearing in broadly adopted AI toolchain software. Across independently audited server populations, command injection, path traversal, and server-side request forgery appear at significant rates. Path traversal is particularly common in servers using file operations, which matters because file-access tools are among the most frequently implemented MCP capabilities. SSRF matters because servers often occupy privileged network positions; an SSRF in an MCP server can reach internal services the client was never intended to access.

Unsandboxed execution compounds all of this. Without isolation, a vulnerable MCP server executing AI-generated code creates a direct path from a prompt to arbitrary code running on the host. Incidents involving Claude Code and Cursor IDE have illustrated the real-world cost of uncontrolled code execution in agentic contexts.

Input validation and output encoding on all tool parameters are non-negotiable: every LLM-supplied argument is effectively untrusted user input, regardless of where it originated in the conversation. Filesystem access should be restricted to declared paths, with traversal denied by default. Outbound network access warrants allowlists rather than blocklists; blocklists are incomplete by definition. MCP server processes should run in isolated sandboxes with strong kernel-level boundaries, a requirement that warrants more scrutiny than it typically receives in initial deployment decisions.

Why Running MCP Tool Calls in Plain Containers Is Not Enough Isolation

Venn diagram: Container vs. MicroVM Isolation for MCP Tool Calls. Compares Plain Containers and MicroVM Sandboxes; overlap: Shared Traits.Table: Isolation Options for MCP Tool Execution. Compares Kernel Boundary, Isolation Strength, Suitable Workloads and Key Limitation by Plain Containers, gVisor and MicroVMs (Firecracker/Kata).

Plain containers share the host OS kernel. That sharing is the problem. A kernel-level exploit in AI-generated code can cross the container boundary, escalate privileges, and compromise the host and internal network. The container provides process isolation. It does not provide kernel isolation. For untrusted AI-generated code in production environments, that gap is where exploits live.

To understand why this works, we must first look at the isolation spectrum. Plain containers such as Docker offer the lowest boundary strength; they are adequate for trusted workloads and inadequate for untrusted AI-generated code in production. gVisor intercepts syscalls in user space, placing a real boundary between the workload and the host kernel without the overhead of a full VM. MicroVMs such as Firecracker and Kata give each workload a dedicated kernel, providing the strongest available boundary with hardware-level separation between workloads and host.

For MCP tool calls involving code execution, the relevant threat model is not a misconfigured application. It is an adversary who has already succeeded in injecting a payload through prompt injection or tool poisoning. The sandbox is the last meaningful line of defense at that point. Veracode's 2025 report found that a substantial share of AI-generated code fails security tests, which means code reaching the sandbox cannot be assumed to have been pre-screened.

There is also a statefulness requirement that most container runtimes do not address. Agent workloads are not stateless HTTP requests. A sandbox that terminates the session when the connection drops loses the agent's progress; purpose-built runtimes must maintain state across disconnects so that long-running tool invocations can complete and resume. This is not a minor operational convenience; it is a prerequisite for reliable agentic workflows.

Daytona is one implementation in this space, offering sub-90-millisecond sandbox provisioning with microVM-grade isolation, stateful sessions, and compliance with SOC 2, HIPAA, and GDPR. The architectural choice it represents, purpose-built microVM isolation over retrofitted container tooling, reflects a threat model that takes seriously what actually happens when untrusted AI-generated code reaches a production execution environment.

Access Control and Least Privilege Across the MCP Server Boundary

Isolation limits blast radius. Access control limits what an attacker can reach if isolation is imperfect. Both are necessary; neither is sufficient alone.

Least privilege applied to MCP has a specific texture that differs from conventional application security. Each server should be granted only the permissions its declared tools require. A weather API server should not have filesystem access. A file-reader should not have outbound network access. That logic needs to operate at the tool level, not just the server level, because individual tools within a server may have different access requirements, and server-level permissions over-provision by default.

Human-in-the-loop approval matters for certain tool categories: email sending, code execution, database writes. One might argue that permissions granted at setup are sufficient — but the question worth asking is not just what permissions were granted at setup, but whether a specific invocation, with these arguments, at this moment, should proceed. The Postmark incident is instructive here. The malicious behavior was introduced after permissions were granted; no static access control would have caught it. When the threat includes post-installation changes, and in MCP deployments that threat is routine, runtime monitoring is required.

Practical controls follow from this: an explicit allowlist of approved MCP servers and tool definitions with pinned versions; network egress controls at the sandbox level; full argument and output capture on all tool invocations. The log is both a security audit trail and the primary incident response resource when something goes wrong.

MCP Gateway Patterns and Centralized Policy Enforcement

A gateway sits between MCP clients and the servers they call. Its value is concentration: authentication, authorization, rate limiting, and logging enforced in one place rather than distributed across servers that may implement those controls inconsistently, or not at all.

What a gateway can enforce is worth being specific about. Token validation and OAuth 2.1 flow management applied uniformly, rather than depending on each server's implementation fidelity. Tool allowlisting, so that only approved tool names and signatures can be called, which constrains both rug-pull and shadowing attacks. Input and output inspection to flag or block payloads containing prompt injection patterns before they reach the model context. Rate limiting per server and per tool, which limits the impact of a compromised or misbehaving server without requiring changes to the server itself.

The gateway pattern does not eliminate the need for server-level controls or sandbox isolation. It adds an enforcement layer that makes inconsistent server implementations less consequential. In a multi-server agent context, where each server is a trust dependency, applying policy uniformly at the gateway is what separates a manageable surface from one that grows uncontrollably with each new integration.

Across eight sections, the picture that emerges is not a list of discrete vulnerabilities to patch. It is a protocol where the foundational trust model was never designed to resist adversarial conditions, deployed into production environments by teams moving faster than security practice can keep up with. The research is public. The CVEs are documented. What has lagged, consistently, is implementation. Specification revisions will not close that gap; only deliberate, boundary-by-boundary security discipline will.

Sources

  1. arxiv.org

More in Running AI-Generated Code Safely