Agent security · Analysis

MCP security architecture: five production boundaries

MCP security architecture for production: secure server installation, tool approval, HTTP sessions, OAuth tokens, downstream access, and audit evidence.

An MCP request crosses five controlled boundaries from server installation and host approval through session, token, and downstream tool enforcement
The short answer

A production MCP security architecture needs five separate boundaries. Verify and sandbox every server before installation. Keep tool selection behind host policy and human approval for sensitive actions. Protect each HTTP or stdio connection as its own trust channel. Bind OAuth tokens to the intended MCP server and never pass client tokens through to downstream APIs. Finally, validate tool inputs and outputs, give each tool minimal downstream authority, and record enough evidence to reconstruct every action. TLS and OAuth protect only part of this path; they do not make server code, tool descriptions, model decisions, or returned content trustworthy.

MCP security architecture is the set of controls around the Model Context Protocol, not a feature switched on by using OAuth or TLS. An MCP host lets a model discover tools and exchange data with local processes or remote services. That short path joins software installation, model judgment, network identity, delegated authority, and business-system access. Each step has a different owner and a different failure mode.

The protocol provides useful seams. The host creates an isolated client for each server. Streamable HTTP defines Origin checks and optional session identifiers. The authorization specification binds tokens to an MCP server. Tool schemas describe inputs and outputs. None of those mechanisms proves that a server package is safe, a model chose the right tool, a user approved the exact side effect, or returned text is free of prompt injection.

MCP security best practices work when controls follow the request across five trust boundaries. A control that protects one boundary must not be credited to another. A valid access token cannot sanitize a tool result, and a sandboxed local process does not authorize a database write.

Start with the MCP security model

The MCP architecture specification assigns most coordination and security responsibility to the host application. The host manages client permissions and connection lifecycles, enforces policy and consent, handles user authorization decisions, and aggregates context. Each client maintains a one-to-one connection with one server and preserves isolation from other server connections.

This topology limits what each server can observe. A filesystem server should not automatically see the full conversation or the messages sent to a ticketing server. The host decides what context crosses each connection. If a host merges every server's instructions, results, and credentials into one undifferentiated model context, it has discarded the isolation the architecture was meant to preserve.

MCP capabilities are negotiated during initialization. Negotiation says which protocol features both parties support. It is compatibility information, not authorization. A server advertising tools can participate in tools/list and tools/call; it has not earned permission to execute every listed operation for every user.

Three security layers are easy to confuse:

Layer Question it answers What it does not prove
Protocol capability Can this connection speak the feature? Whether the caller may use a particular tool
Authentication and authorization Which principal may access this server and scope? Whether a model-selected action matches the user's intent
Application policy May this exact operation run with these arguments now? Whether returned content is safe to trust downstream

The protocol also supports local stdio servers and remote Streamable HTTP servers. Their risks overlap, but their controls differ. A local server is code running with operating-system privileges. A remote server is a network resource with transport, OAuth, multitenancy, and service identity concerns. Treating both as generic "MCP endpoints" hides the controls that matter most.

MCP sits inside a larger agent system. The A2A vs MCP guide explains why the host still owns orchestration even when a server wraps agent-like behavior. The AI agent ecosystem guide places MCP alongside identity, policy, evaluation, and observability rather than treating the protocol as a replacement for them.

The five production boundaries

Draw the deployment before selecting products. Mark every point where code, identity, instructions, data, or authority crosses into a component with a different owner or privilege level.

Boundary Protected asset Main enforcement point Typical failure
1. Server installation Host device, runtime, credentials, approved server inventory Package intake, configuration UI, process launcher, sandbox Malicious package or startup command runs with host privileges
2. Model and approval User intent, conversation data, tool catalog, side effects MCP host policy engine and approval UI Prompt injection or misleading metadata causes an unsafe call
3. Transport and session Connection identity, message integrity, session state stdio process channel or Streamable HTTP edge DNS rebinding, exposed localhost service, stolen session handle, version confusion
4. OAuth and token audience User delegation, scopes, access tokens, consent MCP client, authorization server, MCP resource server Wrong-audience token, token passthrough, confused deputy, discovery SSRF
5. Tool and downstream access Files, databases, SaaS accounts, API credentials, returned content MCP server, tool adapter, downstream policy Excess privilege, injection, cross-tenant access, malicious output, missing audit trail

The same component may enforce several boundaries, but the decisions should remain separate. An MCP gateway might authenticate the connection, filter tools, and log calls. It still needs distinct policy inputs for server identity, user identity, tool risk, downstream scope, and content handling. One broad "trusted server" flag is too coarse.

A production design should name the principal and resource on both sides of every boundary. "The agent can use GitHub" is not enough. Record which user or service initiated the request, which host and MCP client sent it, which server identity received it, which repository or organization is in scope, which tool and arguments were approved, and which downstream credential performed the action.

Boundary 1: server installation and runtime

A local MCP server is an executable, not a passive configuration entry. The current MCP Security Best Practices warns that a one-click configuration can contain a malicious startup command or install a malicious payload. Once launched, the process may inherit the MCP client's files, network access, environment variables, and user privileges.

Decide whether the server belongs in the inventory before launching it. Record its source repository or vendor, immutable version or digest, expected command, dependency lock, owner, data classification, required directories, outbound destinations, and update process. A registry entry or package name is discovery evidence, not a security review.

For one-click installation, the official guidance requires the client to show the complete command and arguments before execution, identify the action as code execution, obtain explicit approval, and allow cancellation. Do not truncate the command after the package name. Flags, shell operators, working directories, and environment setup can change what runs.

Launch the server with a deliberately small environment:

  • pass only the credentials and variables required by that server;
  • mount approved directories instead of the user's whole home directory;
  • disable outbound network access unless the capability needs it;
  • run as an unprivileged operating-system identity;
  • restrict CPU, memory, process creation, open files, and execution time;
  • separate servers with different data classifications or trust levels.

Containers can help, but a container is not the policy. A privileged container with the host filesystem mounted and unrestricted egress preserves most of the original risk. The May 2026 NSA MCP security guidance recommends operating-system controls such as AppContainer, seccomp, AppArmor, or SELinux and says tool processes should receive only the paths and networks they need.

Prefer direct stdio for a local server when no other process should reach it. If local HTTP is necessary, the server should bind to loopback, authenticate callers, validate Origin, and preferably use a restricted Unix domain socket or equivalent local IPC where the platform allows it. "Localhost" is a routing choice, not an identity check.

Updates belong to the installation boundary. Pin versions, review changes to tool definitions and permissions, scan dependencies, and keep a rollback path. A previously reviewed server can change its package code, transitive dependencies, tool descriptions, or requested privileges. Re-approval should follow a meaningful security change rather than a calendar reminder alone.

Boundary 2: model choice and human approval

MCP tools are described as model-controlled: a language model may discover and select them from the user's prompt and context. The tools specification also says implementations are free to choose their interaction model and should keep a human able to deny tool invocations.

The host must treat tool names, descriptions, schemas, annotations, icons, and server instructions as untrusted input until the server itself has passed policy. The specification explicitly says tool annotations are untrusted unless they come from trusted servers. Even a trusted server's metadata can be stale, compromised, or overly broad, so trust should determine review depth rather than bypass policy.

Separate model suggestion from action authorization. The model can propose transfer_funds, but application code should decide whether that tool is visible, whether the principal may use it, whether the arguments fit policy, and whether a person must approve. Avoid giving the model an approval token or a tool that can approve its own subsequent calls.

Record the policy decision in a form such as:

principal + server_id + tool_id + normalized_arguments
+ data_class + side_effect + destination + current_context
-> allow | deny | require_approval | require_step_up

MCP does not define this record; application code must. The record makes a decision reproducible. A model explanation can inform the UI, but it should not be the sole policy input.

Approval prompts need the real operation. Show the server, tool, destination, material arguments, data leaving the host, expected side effect, and whether the call is reversible. "Allow this tool?" is too vague for a database deletion or a message sent to an external recipient. Bind an approval to the normalized call so a later argument change cannot reuse it.

Risk tiers reduce consent fatigue. Read-only access to public data may run under standing policy. Reading private records may require a narrower scope and logging. Irreversible changes, financial operations, credential use, or external publication usually deserve transaction-level approval. Repeated prompts for harmless calls train users to accept the one prompt that matters.

Cross-server data flow needs its own check. A malicious server can return instructions that persuade the model to call a trusted server with sensitive data. The host should label content by origin, constrain which server outputs may become arguments to another server, and require approval when data crosses a trust or classification zone. One isolated MCP client per server helps only if the host preserves provenance when it combines results.

Boundary 3: transport, Origin, and session state

For stdio, the client launches the server as a subprocess and exchanges protocol messages over standard input and output. There is no network listener to authenticate, but the process boundary still needs control. Launch an explicit executable without an unnecessary shell, use a fixed working directory, limit the environment, verify the process image, and treat anything written outside the MCP channel as untrusted logs.

For Streamable HTTP, the transport specification requires one endpoint that accepts HTTP POST and GET. Servers must validate the Origin header on incoming connections and return HTTP 403 for an invalid Origin. Local servers should bind to 127.0.0.1 rather than 0.0.0.0, and servers should authenticate connections. These controls prevent a remote website from reaching a local MCP service through DNS rebinding.

Production remote servers should terminate TLS at a controlled edge, authenticate every request, set request and body limits, enforce timeouts, and apply rate limits by principal as well as source. If a proxy terminates TLS or rewrites Origin, document which hop performs each check and prevent direct access to the backend that would bypass it.

Streamable HTTP servers may create a cryptographically secure MCP-Session-Id during initialization. Clients then send it on later requests. The identifier correlates a protocol session; it is not a substitute for user or client authorization. The authorization specification requires the access token on every protected HTTP request, even within one logical session.

Bind session state to the authenticated principal, selected server tenant, negotiated protocol version, and applicable authorization context. Reject a session ID presented by another principal. Expire idle sessions, support explicit deletion, rotate server-side state when privilege changes, and avoid putting secrets or raw authorization data inside a session identifier.

Clients must send the negotiated MCP-Protocol-Version header on later HTTP requests. Servers should reject unsupported versions instead of silently interpreting a new client with old semantics. Capability negotiation and version checks also belong in logs because a security incident may depend on which feature set was active.

Streaming and retries add execution risk. An interrupted response does not prove that the server did not perform the tool call. Define idempotency at the tool or business-operation layer, use operation identifiers for side effects, and reconcile ambiguous outcomes before retrying. A new JSON-RPC request ID alone does not prevent duplicate transfers, messages, or file changes.

Boundary 4: OAuth, token audience, and consent

Authorization in MCP is optional at the protocol level because local stdio and remote HTTP deployments need different mechanisms. When an HTTP MCP server uses the standard flow, the server is an OAuth resource server, the MCP client is an OAuth client, and an authorization server issues access tokens.

The MCP authorization specification requires clients to send a resource parameter in authorization and token requests. The value identifies the intended MCP server according to RFC 8707. The MCP server must validate that an access token was issued for its audience and must reject invalid or expired tokens.

Token passthrough is forbidden. An MCP server must not accept a token issued for another resource and forward that token unchanged to a downstream API. The server needs its own downstream authorization relationship, token exchange, delegated credential, or service identity. This preserves audience boundaries and lets both the MCP server and downstream service enforce policy and produce accurate audit records.

Scope design should follow the operations, not the size of the product. Start with low-risk discovery or read scopes, then use precise WWW-Authenticate challenges and step-up authorization when a tool needs more authority. Avoid *, all, full-access, and one scope that bundles unrelated business systems. A token compromise should expose one narrow capability, not the complete MCP catalog.

An MCP proxy that fronts a third-party API can become a confused deputy. If it uses one static third-party OAuth client while accepting many dynamically registered MCP clients, prior consent at the third party can be mistaken for consent to a new MCP client. The current official security guidance requires per-client consent, exact redirect URI validation, secure and single-use OAuth state, CSRF protection, and a consent screen that identifies the requesting MCP client and requested third-party scopes.

OAuth discovery also opens outbound requests. MCP clients fetch protected-resource and authorization-server metadata; authorization servers may fetch Client ID Metadata Documents. An attacker-controlled URL can target internal services or cloud metadata endpoints. Require HTTPS outside explicit loopback development, block private and link-local address ranges, validate every redirect target, constrain egress, and account for DNS rebinding between validation and use. Do not build the defense from string checks around hostnames.

Apply current OAuth protections from RFC 9700, including authorization-code binding and redirect validation. Record the authorization server issuer before redirect and validate the response issuer where supported to reduce mix-up attacks. PKCE protects an intercepted authorization code, but it does not solve every authorization-server confusion case.

The agent identity and attestation guide covers a related limit: authentication and token scopes identify an actor and delegated resource, but they do not prove that a model's planned action matches current user intent. Keep OAuth enforcement and transaction policy connected without treating them as the same decision.

Boundary 5: tool execution and downstream systems

At the MCP server, protocol arguments become database queries, filesystem operations, API requests, or code execution. Server-side enforcement can still stop a model mistake or malicious client before either reaches a business system.

MCP server security best practices start with the requirements in the tools specification: servers validate all tool inputs, implement access controls, rate limit invocations, and sanitize outputs. Clients should show inputs before sensitive calls, validate tool results before passing them to a model, use timeouts, and log tool usage. These requirements apply even when the tool schema is valid.

JSON Schema checks types and shapes. Business validation checks meaning. A file tool must resolve and normalize a path before comparing it with approved roots. A SQL tool needs query and tenant policy beyond a string field. An email tool should validate recipients against the approval and prevent hidden extra recipients. A payment tool needs currency, amount, beneficiary, duplicate, and authorization checks at the service boundary.

Give each tool adapter a separate downstream identity when practical. A read-only search tool should not share the administrator credential used by a maintenance tool. Restrict database roles, repository scopes, cloud resources, filesystem mounts, network destinations, and allowed methods. If several tools share one broad credential, the MCP scope shown to the user overstates the isolation that actually exists.

Tool output is also untrusted. It may contain malformed structured data, active content, secrets, or instructions aimed at the next model call. Validate structuredContent against the declared output schema, enforce size and type limits, scan files, escape content for its display context, and preserve the server and tool as provenance. Do not concatenate tool output into privileged system instructions.

Side-effecting tools need replay protection and a clear commit point. Generate or accept a business idempotency key, record the normalized action before execution, and return a stable result for safe retries. Separate a preview or plan operation from commit when a user needs to inspect the effect. If the downstream API cannot provide idempotency, the adapter must reconcile state before repeating an ambiguous request.

The server should not leak raw downstream errors, credentials, stack traces, or internal topology to the model. Return a bounded error code and safe explanation, while keeping diagnostic detail in protected logs. Rate limits and concurrency limits should cover both the MCP method and the downstream resource so a cheap-looking tool call cannot start an unbounded batch.

Evidence, tests, and rollout checklist

Security controls are hard to trust when an incident log cannot connect a user request to the final side effect. Build a trace that crosses all five boundaries without copying secrets or unrestricted conversation content.

For every material tool call, record:

  • initiating principal and host application;
  • approved server identity, package or service version, and tool-schema version or hash;
  • MCP client connection, protocol version, and correlation identifiers;
  • tool name, normalized arguments or protected argument digest, and data classification;
  • policy result, rule version, required scope, and approval actor when present;
  • downstream resource, credential identity, idempotency key, outcome, latency, and result metadata;
  • output validation decision and whether content was sent back to a model.

Redact access tokens, authorization codes, cookies, private keys, and sensitive field values. Security telemetry that becomes a second copy of every prompt, file, and credential creates another high-value target. Keep raw content only when a documented investigation or compliance need justifies it, with access and retention controls.

Test the architecture by crossing boundaries, not only by sending malformed JSON:

  1. Install a server configuration with an unexpected shell operator, new network destination, or expanded filesystem mount. The intake and approval path should stop or escalate it.
  2. Change a trusted server's tool description or schema after approval. The host should detect the change and re-evaluate policy.
  3. Return an indirect prompt injection from one server that asks the model to exfiltrate data through another. Provenance and cross-server policy should block it.
  4. Send Streamable HTTP requests with an invalid Origin, stolen session ID, missing authorization, and unsupported protocol version.
  5. Present a valid token for the wrong audience, an excessive scope set, and a token intended for a downstream API.
  6. Point OAuth metadata and redirects at private, loopback, link-local, encoded, and DNS-rebinding destinations.
  7. Call a tool with schema-valid but unauthorized arguments, such as another tenant's record or a path that resolves outside the approved root.
  8. Drop the response after a side effect completes, then retry. The idempotency and reconciliation design should prevent duplicate work.
  9. Return oversized, malformed, active, or instruction-bearing output. The client should contain it before the next model turn.

Roll out by risk zone. Start with approved read-only servers over public or low-sensitivity data. Add private reads after identity, egress, provenance, and audit controls work. Add reversible writes with transaction-level approval and idempotency. Keep irreversible or high-impact operations out until the same control path has survived adversarial tests and incident-response review.

Ownership should follow the five boundaries. The platform team handles server intake and isolation. The host team handles model context, policy, and approval. Network and identity teams handle transport and OAuth controls. Each MCP server owner remains accountable for downstream authorization, validation, and output handling, even when a shared gateway coordinates policy. Trace Brief's editorial policy explains how this publication separates specification requirements, official guidance, and implementation recommendations as the standards change.

Sources and methodology

This article draws on the primary documentation and research listed below. An editor reviewed the technical claims and wording before publication.

  1. MCP Architecture, revision 2025-11-25 — normative host, client, and server responsibilities, connection isolation, context boundaries, and capability negotiation
  2. MCP Authorization, revision 2025-11-25 — HTTP authorization roles, resource indicators, token audience validation, discovery, registration, and scope handling
  3. MCP Security Best Practices, 2026-07-28 — current official mitigations for confused deputies, token passthrough, SSRF, local servers, authorization URL handling, and scope minimization
  4. MCP Transports, revision 2025-11-25 — stdio and Streamable HTTP requirements, Origin checks, localhost binding, session identifiers, and version headers
  5. MCP Tools, revision 2025-11-25 — tool discovery, untrusted annotations, human approval guidance, input and output validation, rate limits, and audit logging
  6. Model Context Protocol: Security Design Considerations for AI-Driven Automation — May 2026 NSA guidance on access control, tool isolation, parameter validation, output filtering, observability, and inventory
  7. RFC 9700: Best Current Practice for OAuth 2.0 Security — OAuth attack model and current security practices referenced by MCP authorization guidance
  8. RFC 8707: Resource Indicators for OAuth 2.0 — standard for requesting access tokens restricted to an intended resource server