Skip to content

Chapter 9. Sandbox Execution and MCP as an Integration Contract

Freshness note

Last reviewed: May 17, 2026. Previous review: May 14, 2026. Next scheduled review: June 17, 2026.

What changed since the previous review: MCP security boundaries, tool-poisoning surfaces, A2A trust model, and print-readiness concerns now have concrete contract coverage and docs-surface guards.

How to read this chapter

It helps to keep one concrete transition in mind:

  • the agent has already chosen a capability;
  • the agent is already about to reach an external tool or adapter;
  • the platform now has to decide through which transport that action may execute at all and inside which limits.

If that transition is not explicit, sandboxing and MCP quickly turn into vocabulary rather than execution discipline.

1. Why an Execution Layer Without a Sandbox Quickly Becomes Too Trusting

In the running support case, this is very concrete: the agent has already decided to check the request status or create a ticket through an external system. From this point, the question is no longer "what is the next smart step," but "through which boundary is the system even allowed to execute it."

Once an agent has access to tools, the next danger is almost always the same: system boundaries start to blur.

The agent can now:

  • read data;
  • run operations;
  • call external services;
  • receive responses from unpredictable environments.

If all of that executes "as is", without isolation and contracts, the platform quickly accumulates problems:

  • a tool returns untrusted payloads in unexpected formats;
  • an integration hangs or exceeds a resource budget;
  • a side effect happens outside the expected policy path;
  • one badly designed adapter drags the whole runtime down.

That is why the execution layer is not just a router. It is also a sandbox boundary.

2. A Sandbox Is Not Necessarily a Container, It Is First a Set of Limits

When people say "sandbox", many immediately think of Docker, a VM, or a separate process. Those are possible implementations, but architecturally the important thing is different: a sandbox defines the limits of what a capability is allowed to do.

A good sandbox usually limits:

  • network access;
  • file system access;
  • access to secrets;
  • CPU and memory budgets;
  • allowed syscalls or execution mode;
  • operation lifetime.

In other words, the sandbox answers: "What happens if a tool or adapter behaves worse than we expected?"

This is not only security. It is also blast-radius control.

2.1. It Helps to Distinguish Levels of Isolation

In practice, the word sandbox often hides several different levels:

  • logical isolation: policy checks, capability contracts, allowlists;
  • process isolation: separate process, timeout, resource limits;
  • runtime isolation: separate execution environment, reduced filesystem, constrained network egress, minimal secrets.

That matters because many teams think they "have a sandbox" while in reality they only have the first level. For low-risk reads that can be enough, but for high-risk execution you almost always need a stronger runtime boundary.16

A good practical question here is: if the capability behaves worse than expected, what exactly stops it: logic, process boundaries, or the execution environment itself?

3. You Cannot Treat an External Integration Like a Simple Function

A common mistake looks like this: an external service is wrapped in a function, and the agent sees it as just another call.

But a real integration is almost always:

  • less stable than local code;
  • less cleanly typed;
  • dependent on permissions and environment;
  • capable of returning partial or unsafe results;
  • subject to its own latency and rate limits.

That is why it is more useful to treat integrations as capability endpoints with a contract, not as convenient helper methods.

4. MCP Is Useful Precisely as a Contract Layer

MCP is not useful because it is fashionable. It is useful because it gives you a clear contract boundary between the agent and an external capability.

In a good design, MCP gives you several benefits:

  • a standardized way to describe tools and resources;
  • a separate server boundary;
  • a clearer lifecycle for connected capabilities;
  • the ability to keep adapters outside the core runtime;
  • a natural point for policy checks, logging, and isolation.

That becomes especially valuable once you have not one runtime and one integration, but a set of capabilities you want to connect systematically rather than chaotically.

Sandbox/MCP case-spine note: the sandbox and MCP contract should be tested against all three canonical cases. Support triage needs sandbox limits for helpdesk writes, approval-aware MCP tools, and a reconciliation path after timeout. Internal knowledge assistant needs read-only MCP resources, corpus-scoped network access, source validation, and a ban on hidden side effects. Incident coordination needs isolated escalation adapters, notification scopes, responder-role enforcement, and emergency paths that do not bypass the audit trail.

4.1. MCP Is a Security Boundary, Not Just a Convenient Connector

Once MCP carries access to data, write tools, or execution environments, it becomes a security boundary. Useful tool results can cross that boundary, but so can malicious instructions, poisoned tool descriptions, over-scoped OAuth grants, confused-deputy paths, and supply-chain risk from the server itself.

Microsoft's MCP tool poisoning case sharpens this boundary: tool descriptions as system prompts.24 If a previously approved server silently changes a tool description while keeping the same tool name, the runtime may trust it again without a fresh human review. That is silent re-trust, not a harmless metadata update. Review should therefore inspect the description diff, owner/provenance, imperative language inside documentation fields, new endpoints, expanded parameters, and unusual query patterns. The control is not only least privilege, but least agency: disable Allow all tool access, require approval for high-impact actions, and alert on agent-behavior drift after tool metadata changes.

The practical contract for that boundary should answer at least five questions:

  • who owns the MCP server and its lifecycle;
  • which tools/resources it exposes and which write operations require approval;
  • which scopes, network paths, and sandbox limits the server receives;
  • how the runtime validates tool descriptions and tool return values before giving them to the model;
  • which telemetry proves the agent run, identity, and policy decision behind the call.

If those answers are missing, MCP does not stop being a risk. It becomes an implicit trust boundary inside the platform surface.

4.2. MCP Threat Model Matrix

For MCP, the MCP threat model should not stay as a vague fear of integrations. It should become a review matrix for every connected capability. The MCP security and authorization material explicitly calls out token passthrough, scope selection, HTTPS/SSRF limits, and protection of application-state handles; that makes the matrix part of the authorization and runtime contract, not decorative security prose.2021 A minimal version looks like this:

  • tool poisoning — a tool description or tool result tries to steer the model; control it by validating tool descriptions, separating tool output from instructions, and allowing only known contracts.
  • rug pull attack — a previously approved MCP server changes tools, scopes, or behavior after review; control it with version pinning, re-attestation, diff review, and a fast quarantine path.
  • tool shadowing — a new tool mimics an approved tool and captures the model's intent; control it with unique capability names, registry ownership, and semantic review before publication.
  • confused deputy — the agent performs an action with the wrong or overly broad delegated authority; control it by checking principal, purpose binding, approval state, and policy decision immediately before the side effect.
  • over-scoped tokens — the MCP server receives broader OAuth scopes than the operation needs; control it with short-lived scoped tokens, per-tool scopes, and no broad standing secrets.
  • data exfiltration through legitimate channels — data leaves through an allowed tool result, notification, or ticket comment; control it with DLP checks, output classification, tenant boundaries, and review for risky writes.
  • supply-chain attack — a compromised server, package, or adapter becomes a trusted capability; control it with provenance, signed artifacts, dependency review, and owner accountability.
  • replay/tampering — requests, responses, or application-state handles are replayed or changed between steps; control it with request signing, nonce/idempotency keys, trace correlation, and handle expiry.
  • sandbox escape — a tool or adapter crosses the network, filesystem, or process boundary; control it with ephemeral sandboxes, minimal egress rules, secret isolation, and runtime-level containment.

The matrix is not there to forbid MCP. It is there so every MCP endpoint has an explicit answer to three questions: which threat class it adds, which control limits it, and which telemetry will still be available after an incident.

Minimum acceptance criteria for an MCP connection:

  1. The server is in the approved registry, and owner plus contract version are visible.
  2. The token is issued for the MCP server or its resource audience, not blindly passed through from another layer.
  3. Scopes are limited to the concrete operation and do not require a broad persistent secret.
  4. Any tool schema, description, or scope change triggers re-review.
  5. Tool output is treated as untrusted content until filtered and classified.
  6. The trace preserves mcp_server_id, tool_contract_version, scope_review, quarantine_state, and evidence links.

4.3. Minimal MCP Server Contract

A threat model becomes useful only when it turns into a reviewable server artifact. A minimal MCP server record should travel with every approved endpoint:

mcp_server:
  owner: platform-integrations
  approved_registry_id: mcp.support.ticketing.v3
  schema_hash: sha256:...
  tool_definition_hash: sha256:...
  allowed_origins:
    - agent-runtime-prod
  auth_mode: delegated_oauth
  token_scope:
    - ticket.read
    - ticket.write_limited
  token_ttl: 15m
  user_delegation_required: true
  server_isolation_profile: remote_ephemeral_sandbox
  return_value_filtering: strip_instructions_and_classify_data
  replay_protection: nonce_and_trace_bound_signature
  schema_change_requires_review: true

The important fields are not bureaucracy. schema_hash and tool_definition_hash catch tool schema injection and post-approval rug pulls. token_scope, token_ttl, and user_delegation_required limit confused-deputy paths. return_value_filtering treats tool results as untrusted content, including prompt injection via tool return values. server_isolation_profile and replay_protection make sandbox escapes, replay, and tampering visible enough to contain.

The short rule is: tool output is an attack surface. A remote tool can change after approval: the server owner changes schema, result, redirect, resource body, or hidden instruction, while the host still treats the integration as already approved. Onboarding remote tools should therefore begin with fake data first: connect a synthetic tenant, synthetic secrets, and safe fixtures, record real traces, and only after validation grant live credentials or production data.

Another useful pattern from Google ADK is metadata registry + runtime schema injection.26 The anti-pattern is explicit: Static Prompting, where all JSON schemas, Pydantic classes, and tool definitions are preloaded into the system prompt. In high-cardinality domains this creates context bloat and Attention Diffusion: the model starts mixing fields from dormant schemas into the active payload.

In a portable runtime contract, structural rules should live in a registry entry, not in the prompt. That entry should carry schema_descriptor_id, schema_version, field metadata, mapping rules, and a validation_hook. The agent first performs lightweight discovery; then the runtime loads the right descriptor, calls the Polymorphic Validator at the boundary before the tool/API call, and records the chosen schema source of truth, runtime validation boundary, validation result, and failure mode in the trace. One reasoning agent can then handle multiple domain forms without carrying every structural rule at once.

4.4. Localhost Is Not a Trust Boundary for Browser Agents

AutoJack, described by Microsoft Defender Security Research, is a compact maturity test for this chapter: untrusted web content opened by a browsing agent could cross the loopback boundary, reach a local MCP WebSocket, and turn connection parameters into process execution on the host.22 The concrete issue was fixed before the affected MCP surface shipped in a PyPI release, but the pattern matters more than the bug.

The architectural conclusion is simple: localhost, 127.0.0.1, and origin allowlists are not sufficient controls when the same machine runs an agent with a browser tool, Playwright-backed surfer, code execution tool, or any mechanism that can open a WebSocket/HTTP request from a local process. For that system, external HTML/JavaScript is no longer merely “somewhere on the internet”; it can become a confused deputy that uses the agent's local network position.

The minimum hardening for local MCP/debug/control channels:

  • do not treat loopback as an authentication boundary;
  • require authn/authz on MCP/control-plane endpoints, including WebSocket paths;
  • check purpose binding and policy decision before launching any subprocess-backed MCP server;
  • keep launch parameters server-side or in a signed nonce-bound artifact instead of accepting command/args from a query string;
  • allowlist executable MCP servers and argument profiles;
  • run browser tools with a separate process/network identity that cannot reach privileged local services;
  • write a trace event for crossing attempts: external page, local channel, policy result, executable decision, and containment action.

If local MCP is needed only for a prototype, the capability registry should say so explicitly: low privileges, a separate OS user/container, short-lived credentials, and no colocating it with an agent that renders untrusted web content.

4.5. Prompt-to-tool-to-execution Needs Its Own Hardening

Microsoft's “When prompts become shells” case adds the adjacent failure mode: a prompt injection does not need to reach localhost when the agent framework already exposes a tool that can interpret model-controlled parameters as paths, code, templates, or commands.23 The exploit shape is prompt-to-tool-to-execution: untrusted content steers the model, the model emits attacker-controlled input, the framework parses it as tool arguments, and a weak adapter turns it into host execution.

The execution-layer rule is the same one this chapter uses for MCP: model output is not authority. Execution-adjacent tools should be deny-by-default, registered through a capability contract, protected by typed validation, canonical path checks, operation allowlists, and a per-tool sandbox. They also need an audit event before the side effect, not only after it, so an investigator can see the prompt source, redacted arguments, validation result, selected sandbox profile, and policy decision.

4.6. Networked-Agent Threat Model

Microsoft Research makes a separate point about what changes when one agent becomes a network of agents: the vulnerability may sit not in one tool wrapper, but in how agents trust each other's messages.25 The practical rule is: peer message is data, not authority. A message from another agent should not escalate permissions, change the goal, trigger a write, or become a system instruction unless the runtime, policy layer, or human approval explicitly promotes it.

This networked-agent threat model belongs next to MCP and A2A. It adds four failure modes:

  • propagation — a malicious instruction, poisoned summary, or false task moves onward as ordinary context;
  • amplification — one weak signal turns into broad fan-out, repeated tool calls, or cascading notifications;
  • trust capture — agents start endorsing one another even though they all depend on the same untrusted source;
  • invisibility — the operator can see local traces but not the cross-agent path by which risk crossed boundaries.

The minimum controls look like network security applied to agent semantics: Sybil resistance for independent votes, hop and rate limits for task propagation, capability scoping on every graph edge, cross-agent tracing for the message path, provenance logs for the original author, and quarantine for peer-originated instructions that try to become authority. In evals, this should appear as a scenario where a neighboring agent asks for excess privilege, repackages a prompt injection, or triggers too-wide fan-out, while the system proves the instruction remained data.

4.7. It Helps Not to Confuse the MCP Host, Client, and Server

MCP often creates unnecessary confusion because the words sound familiar while the roles are actually quite specific.

It helps to keep this picture in mind:

  • the host is the application or runtime that owns the session and decides which capabilities should be connected at all;
  • the client is the protocol-side component the host creates to talk to one specific MCP server;
  • the server is the boundary that exposes tools, resources, and other capability surfaces, then returns structured results.

Two practical consequences follow from that:

  • one host can hold several clients at the same time;
  • one agent runtime can work with multiple MCP servers without collapsing them into one indistinguishable integration blob.

That may sound like a minor terminology point, but it helps a lot. The MCP client is not the product UI and not “the agent itself.” It is the transport and contract layer between the host and one specific server boundary.

MCP is useful as a contract layer between the runtime and external capabilities

flowchart LR
    A["Agent runtime"] --> B["Execution layer"]
    B --> C["Policy and validation"]
    C --> D["MCP client"]
    D --> E["MCP server"]
    E --> F["Typed adapter"]
    F --> G["External API / system"]
    G --> F
    F --> E
    E --> D
    D --> B

5. Why Move Adapters Out of the Core Runtime

Once MCP adoption grows beyond one or two hand-maintained integrations, another concern appears: who governs the MCP surface as a platform, not just as a local developer convenience? Recent enterprise guidance from Cloudflare is useful here because it shows that the hard part is no longer merely “can the agent speak MCP,” but “how do teams discover, approve, route, and audit MCP endpoints at scale.”1

That shift usually pushes the platform toward an explicit MCP control plane:

  • local ad hoc MCP servers for experimentation;
  • governed remote MCP servers for shared production capabilities;
  • a discovery or portal layer for approved servers;
  • identity enforcement at the access boundary;
  • audit and DLP controls around the MCP path itself.

That gives you several immediate benefits:

  • failures in one integration affect the central runtime less;
  • network, secrets, and filesystem can be constrained per capability;
  • it is easier to swap or upgrade one adapter without rewriting orchestration;
  • contracts become clearer;
  • capabilities are easier to test independently of the agent logic.

That matters especially when some tools are read-only, some write into external systems, and some execute code or shell commands.

5.1. Enterprise MCP Usually Needs a Control Plane, Not Just a Protocol

This is where many teams repeat the same maturity mistake. They standardize on MCP as a protocol, but they keep onboarding servers informally: somebody posts an endpoint in chat, another team copies it into a local config, and soon nobody can explain which MCP servers are approved, which ones are experimental, and which ones quietly bypass normal review.

A more mature model treats remote MCP as part of the platform control plane:

  • the platform publishes approved MCP endpoints through a registry or portal;
  • capability owners are explicit;
  • authentication is mediated by a central identity layer rather than hidden inside each desktop client;
  • policy and DLP checks can observe MCP traffic as a governed surface;
  • retirement of an MCP endpoint is handled like any other lifecycle event.

Once identity becomes central, another design question appears: who is actually authorizing the MCP call, and with whose user context? A managed OAuth boundary is useful here because it prevents each MCP server from inventing its own ad hoc credential story.

That usually means:

  • user delegation is issued through a governed identity layer;
  • tokens are short-lived and attributable to a concrete principal;
  • the MCP server receives scoped access rather than broad standing secrets;
  • the platform can revoke or rotate access without rewriting every adapter.

That same model also clarifies when local MCP is still appropriate: prototyping, isolated experiments, or narrow team-local workflows. But the default for shared business capabilities should usually be: remote, governed, discoverable, and auditable.

Google Cloud's Gemini Enterprise Agent Platform remote MCP server shows the same boundary in a more managed form.9 An external agent or IDE client does not receive an arbitrary bundle of cloud secrets; it connects to a standardized remote MCP endpoint inside Google Cloud, sees toolsets such as generation, prediction, notebooks, endpoints, models, tuning, evaluation, and prompts, and discovers assets through Agent Registry. The architectural lesson is that a managed remote MCP endpoint can be a capability boundary if discovery, IAM Deny policies, tenant/data boundaries, observability, and lifecycle ownership live on the platform side rather than in the client's local config.

The AWS MCP Gateway and Registry frame makes that control-plane shape more concrete.8 It treats MCP servers, AI agents, skills, workflows, and other AI assets as cataloged entities rather than scattered endpoints. The useful lesson for this chapter is not the specific implementation stack, but the split of responsibilities: the registry governs discovery, ownership, security scanning, fine-grained access control, and federation; the gateway routes MCP tool calls and records an audit log. That is a cleaner platform contract than letting every agent or desktop client maintain its own private list of servers.

5.2. Shadow MCP Is the New Shadow API Problem

Once MCP becomes easy to attach, teams can accidentally create a new variant of shadow IT: unregistered MCP servers that expose real business actions without clear ownership or review.1

That anti-pattern usually has recognizable warning signs:

  • capabilities are consumed from private config snippets rather than an approved catalog;
  • nobody can name the owner of the MCP server;
  • auth is handled with long-lived local secrets;
  • no common audit trail exists for which agent used which MCP endpoint;
  • the platform team discovers the server only after an incident.

A useful platform checklist is simple:

  • Is this MCP server in the approved registry?
  • Who owns its lifecycle and incident response?
  • Which identity boundary protects access?
  • Which policy bundle governs write actions and approvals?
  • What telemetry proves which agent called it and with what decision context?

If those answers are missing, the issue is not just “an integration is undocumented.” The issue is that the platform has created a shadow capability path outside its own control model.

A good follow-up question is also: can the platform explain the authorization chain for this MCP action? In a governed setup, operators should be able to reconstruct:

  • which user or service principal delegated access;
  • which identity layer minted or brokered the token;
  • which MCP server accepted the delegated scope;
  • which agent run used that authorization to perform the action.

If that chain is missing, auditability is weaker than the protocol surface suggests.

5.3. MCP as a Governed Access Path to Cloud APIs

A recent AWS Security Blog recommendation is useful because it frames MCP not just as an integration convenience, but as a governed access path to cloud resources.7 The important detail is that AI coding assistants and agents can often reach cloud APIs directly through shell, SDK, or arbitrary code execution. If that path remains open, an MCP server with good IAM policies is only one route, not the real control boundary.

So production agents should distinguish:

  • mcp_brokered_action: the action flows through a registered MCP/tool gateway, receives scoped credentials, writes an audit event, and carries a policy decision;
  • direct_cloud_api_action: the agent calls an SDK, CLI, or HTTP API directly from a shell/code environment;
  • human_initiated_action: a human runs the action, while the agent only prepares the plan, diff, or evidence packet;
  • delegated_agent_action: a human or policy layer delegates a bounded action scope to the agent with TTL, scope, and trace correlation.

The architectural conclusion is strict: direct cloud API access should be treated as a bypass path unless it flows through the same catalog, identity, policy, and audit layer. For the runtime, that adds several required fields to the trace/control record: actor_type, delegation_source, credential_scope, credential_ttl, access_path, mcp_server_id, policy_decision_id, and called_via_gateway. Then the organization can distinguish human-initiated action from AI-driven action and apply least privilege, organizational role governance, and separate approval rules to the agent path, not only to human IAM.

If the team cannot fully prohibit shell/SDK access, the minimum fallback is explicit bypass control: a restricted shell profile, denylist/allowlist rules for cloud CLIs, network egress through a proxy, detection for direct cloud API calls, and a release gate that blocks the agent capability until critical writes flow through the brokered gateway.

5.4. Cloudflare AI Traffic Controls Show That Web Access Is Also a Policy Surface

Cloudflare AI traffic controls add a neighboring but important boundary to this chapter: not only how an agent calls MCP or a cloud API, but how an external site decides which AI traffic is allowed to use its content at all.3 The Search / Agent / Training split is useful precisely as a governance signal. A search crawler, an interactive Agent, and a Training crawler carry different purposes, different expectations from the resource owner, and different audit requirements.

The runtime lesson is practical: outbound identity cannot be reduced to a user-agent string or an IP allowlist. A web-capable agent should declare a declared purpose, preserve an audit trail, and distinguish at least:

  • search/indexing, where the site owner expects discoverability;
  • interactive agent access, where the agent acts on behalf of a user;
  • training or dataset collection, where content use changes the economics of consent.

Cloudflare also shows an important detail for future access contracts: Content-Signal can carry finer-grained terms such as use=reference, while Verified and Forwarded statuses separate verified identity from transitive trust passed through a downstream service. For agent architecture, that means transitive trust has to be modeled explicitly: if a browser or retrieval agent receives access through an intermediary, the trace should show the original identity, forwarded identity, declared purpose, and policy decision, not only the final HTTP request.

A minimal policy matrix for a web-capable agent should therefore carry at least four decisions: allow, block, monetize, or audit-only. Each decision should be bound to the access purpose: Search / Agent / Training. Otherwise web access policy collapses into a fragile list of strings rather than a contract among the resource owner, the user, and the agent platform.

Cloudflare Monetization Gateway makes the monetize branch concrete, especially for an agent-facing resource: a web page, dataset, API, or MCP tool can become a payment-gated resource with an x402-style payment flow.4 For agent architecture, this is not only a billing feature. Before making an MCP tool call or retrieval request to a paid resource, the runtime needs a policy decision before the tool call: whether spend is allowed, who the payer is, which spending cap applies, where the payment proof is stored, and which metering record enters the audit trail. Otherwise agent web/tool access quietly becomes unreviewed spend without business context.

5.5. Browser as an action surface

GitHub Copilot browser tools in VS Code show the next step: a live browser is becoming a normal action environment for agents, not only an external way to check work manually.5 If an agent can open pages, click/type/hover/drag, read page content, collect console errors, take a screenshot, and run scripted flows, the browser has to be treated as its own execution surface.

The practical contract for that surface should account for stale DOM refs, auth/session state, non-deterministic UI, and evidence snapshot. The agent should not merely say "the page works"; it should leave verifiable evidence such as a screenshot, DOM assertion, console errors, network trace, or another artifact bound to the run/trace id. Otherwise browser automation becomes just another opaque tool call.

The control layer should also be explicit. User-owned tabs need share/revoke semantics, agent-owned tabs need an isolated session without normal browser cookies/storage, sensitive permission prompts need human approval, and enterprise environments need network domain controls and workspace trust. Then a browser tool is a governed capability rather than direct agent-process access to all web state.

5.6. Secure MCP Tunnel Makes Private Reachability Explicit

OpenAI's Secure MCP Tunnel adds a useful deployment pattern for private MCP servers: the private side initiates an outbound-only connection instead of accepting inbound traffic from the public internet.10 A tunnel-client runs inside the network that can already reach the private MCP server, long-polls an OpenAI-hosted endpoint for queued MCP work, forwards JSON-RPC requests locally, and returns responses through the same path. The design also creates a natural backpressure point, because the client asks only for work it is ready to process.

The architectural lesson is narrower than "tunnels make private systems safe." A tunnel should be a governed reachability mechanism, not a general-purpose network bridge. The private MCP server still needs owner records, schema hashes, scoped authorization, output filtering, request correlation, and audit events. The tunnel record should say which product surface may call it, which private MCP server it reaches, which identity authenticated the tunnel-client, and which policy decides whether a request is allowed. In other words, Secure MCP Tunnel is useful when it keeps a narrow path: product endpoint -> tunnel service -> authenticated tunnel-client -> private MCP server -> filtered response.

5.7. Code Mode Turns the MCP Portal into Progressive Disclosure

Cloudflare also shows a useful pattern for a large MCP estate: do not give the model every tool schema upfront; put the broad API surface behind a portal with two narrow operations for search and execution.2 In that pattern, Code Mode lets the model first write code to search for the endpoint definitions it needs, then write code to call the selected operations. That code runs inside a sandbox on the MCP server portal side, not inside the main agent session.

Architecturally, this matters for more than token cost. It changes tool visibility:

  • the model receives a search mechanism rather than the whole capability catalog upfront;
  • the portal becomes a point for audit, DLP, and identity enforcement;
  • the agent context is not bloated by thousands of schema tokens;
  • discovery becomes a governed action rather than an implicit load of the whole world;
  • the portal-side sandbox constrains what generated code can do.

The pattern still has to remain governed. A search/execute portal should not become a bypass around capability governance. It needs the same fields as any other MCP endpoint: owner, allowed upstream servers, scope policy, sandbox profile, output filtering, trace correlation, and review rules for risky writes. Otherwise the team only replaces "too many tools in the prompt" with "too broad a programmable portal."

GitHub's Agent Finder points in the same direction from the client side: capability discovery becomes a runtime operation instead of a prompt assembly habit.6 An agent should be able to search an approved registry of MCP servers, skills, canvases, agents, and tools, receive ranked task-specific matches, and load only the resource it actually needs. The safety detail is that discovery is scoped by managed settings and does not silently install or connect new resources. In a production architecture, that means the trace should preserve capability_search_query, registry_scope, ranked candidates, selected resource, policy decision, and human or platform approval state.

5.8. Tool Surface Design Is Part of the Safety Contract

AWS's practical guidance on MCP tool design adds another layer to the Cloudflare Code Mode pattern: the problem is not only where the gateway sits, but which tool surface the agent sees at all.13 If a prompt receives dozens of similar tools, broad schemas, and ambiguous names upfront, the platform gets two failures at once: context bloat and tool confusion. The model may choose the wrong operation, mix fields from neighboring schemas, or use a generic tool as a path around a riskier action.

A good tool-surface contract should therefore record:

  • tool_taxonomy: read, write, execution, orchestration, introspection;
  • tool_visibility_mode: eager, lazy, search_then_execute, or server_side_introspection;
  • max_active_tools: a practical limit on simultaneously visible tools for one step;
  • schema_constraints: required fields, enums instead of free text, short descriptions, and no hidden policy inside descriptions;
  • argument_budget: how many parameters the model actually has to hold in active context;
  • agent_as_tool_policy: when a complex sub-agent is published as one tool instead of exposing every internal operation;
  • tool_evaluation: tests for wrong-tool selection, schema confusion, unsafe defaults, and noisy catalogs.

The useful heuristic is simple: if a tool cannot be explained as one operation with a narrow schema and a clear risk tier, it may be a workflow, sub-agent, or portal search path rather than a tool. Conversely, if five tools differ only by one non-obvious parameter, the difference probably belongs in an enum, taxonomy, or server-side discovery flow rather than in long descriptions the model has to compare.

For the runtime, this becomes reviewable trace data: which tools were visible, why those tools were disclosed, which taxonomy node or search result activated them, which schema version validated the arguments, and which evaluation pack proves the model does not confuse similar tools. Without that trail, "we have an MCP gateway" still leaves a blind spot: the gateway governs the call, but it does not explain why the model saw that tool surface in the first place.

5.9. Smartsheet remote MCP server on AWS: production remote MCP facade

Smartsheet remote MCP server on AWS is a useful production remote MCP facade case: one MCP layer serves internal and external agents instead of exposing separate surfaces for the in-product Smart Assist experience and external AI clients.14 The architectural lesson is that the MCP server becomes an AI-optimized interface over domain services and an intelligence layer, not a thin proxy to existing APIs.

Four properties matter for that surface. First, capability parity: internal Smart Assist and external clients receive one governed contract. Second, schema-driven tool contracts: strict JSON schemas, column-name validation, and structured errors keep the model away from hallucinated parameters. Third, token cost becomes a production control: progressive disclosure, response budgets, and compact serialization reduce cost and context pressure. Fourth, access tiers, OpenTelemetry, audit events, per-user rate limits, and production canaries turn remote MCP into a governed platform boundary.

The portable contract is: single MCP facade → API gateway and OAuth validation → domain services and intelligence layer → schema-driven tools → token-budgeted responses → access tiers → OpenTelemetry and audit → canary workflow tests. This belongs next to the Cloudflare portal and AWS tool design patterns: the gateway says who may call a tool, the tool-surface contract says what the model can see, and the production facade says how one MCP layer survives real agent bursts, governance, and cost constraints.

5.10. Rules of Durable Objects: Durable Agent Identity

Cloudflare Rules of Durable Objects adds a lower-level runtime pattern that is useful beyond Cloudflare: Durable Agent Identity. If an agent has a stable name, that name should be the atom of coordination, not only a label in logs.15 Requests, timers, wakeups, and recovery paths should converge on one durable instance through deterministic IDs; otherwise the platform can create two "same" agents that independently mutate one state boundary.

Five rules matter for agent architecture. First, deterministic IDs should derive from a stable entity such as tenant/workspace/case/thread, not from a random run. Second, durable state is the source of truth for progress, leases, cursors, and idempotency; process memory is only a cache. Third, input and output gates should protect operation order: new work should not observe half-written state, and an external side effect should not leave before durable commit/evidence. Fourth, idempotent alarms are required for delayed actions because an alarm may fire again after a failure. Fifth, unexpected shutdowns are part of the model; recoverable work should continue from a durable checkpoint, not from in-memory timers, closures, or open fetches.

The portable contract is: request → deterministic agent instance → durable state gate → idempotent alarm/fiber/workflow → recovered execution → audited output gate. This does not replace the MCP gateway: MCP governs the capability boundary, while Durable Agent Identity governs which named agent instance owns state and how it survives restart.

5.11. Ephemeral Sandboxes Are Usually Better Than Permanent Environments

Another useful Google idea is that risky capabilities are often better served by short-lived execution environments.16

Why that is usually better:

  • there is less chance that state leaks across runs;
  • it is easier to constrain the lifetime of secrets and temporary files;
  • cleanup is easier to explain;
  • one dirty adapter is less likely to poison the next task.

Persistent workers sometimes win on latency, but they often lose on isolation and explainability. So the default stance for high-risk execution should usually be: ephemeral first, persistence only by explicit need.

6. The MCP 2026-07-28 core is stateless

The MCP 2026-07-28 specification makes each core protocol request self-contained and negotiates the protocol version per message.1819 The former initialize/initialized handshake and protocol session header are no longer part of the core. This simplifies horizontal scaling and recovery, but it does not eliminate application state.

The architectural point is precise: a stateless protocol does not imply a stateless application. A cart, browser, workspace, or long-running task may still outlive one call, but its state must be explicit, bounded, and auditable.

6.1. Application State Travels Through Explicit Handles

When a tool must continue work on an existing object, it accepts an ordinary argument such as basket_id, browser_id, or workspace_id. That handle:

  • is bound server-side to the principal, tenant, authority scope, and expiry;
  • is validated again on every request;
  • is not proof of authority by itself;
  • can be revoked, deleted, or replaced without reconstructing a hidden transport session;
  • appears in telemetry as a state reference, not as a secret.

This separation prevents transport continuity from quietly becoming authorization. After a pause or approval, the runtime can repeat the call with the same application handle while re-evaluating policy, authority, and action integrity.

6.2. Long-Running Work and Additional Input Have Separate Contracts

For work that cannot finish in one response, the Tasks extension gives the server a task handle and lets the client explicitly query, retrieve, or cancel the work. Telemetry should connect task_id, the original call, tool version, progress, outcome, and cancellation reason; a task handle, like any identifier, does not replace authorization.

When the server needs more input, it returns InputRequiredResult with requestState and input requests. After the user responds, the client resubmits the original call with inputResponses. For a side-effecting operation, that retry must retain the same idempotency key and action digest, while the runtime repeats policy and approval-freshness checks. A broken connection therefore cannot turn human input into an implicit duplicate write.

6.3. A Gateway Routes Messages Instead of Guessing at Hidden Sessions

In the HTTP profile, Mcp-Method and Mcp-Name let a gateway route and observe MCP messages without parsing the whole body. The ttlMs and cacheScope hints describe permissible caching, while W3C Trace Context links the request to the end-to-end trace. These values remain protocol hints: the server still validates identity, arguments, and authority on every request.

AgentCore Gateway extended MCP support remains a useful example of aggregating tools/list, prompts/list, resources/list, and resource templates, carrying outputSchema, dynamic listings, and tool annotations.12 Useful trace fields include listing_mode, listed_under_principal, output_schema_hash, and tool_annotations. However, the AWS behavior published on 2025-11-25 is a vendor-specific contract for that service version, not the universal model of the current MCP core.11 A platform should date that compatibility profile and avoid projecting older session-continuation semantics onto the shared protocol.

7. Not Every Capability Needs the Same Isolation Level

It is useful to split integrations into at least three classes:

  • low-risk read capabilities;
  • medium-risk business actions;
  • high-risk execution capabilities.

Examples:

  • read_kb or search_docs can run with softer controls;
  • create_ticket or update_crm_record need stricter policy and audit;
  • run_shell, exec_sql, or deploy_job need the strongest sandbox and approval.

If every tool gets the same soft execution profile, the platform becomes either unsafe or incident-prone.

8. A Capability Contract Must Include More Than Input/Output

Many teams do a decent job describing input schema, but the operational contract is missing. In practice, that part is often more important.

It helps to define explicitly:

  • authentication mode;
  • whether access is platform-owned or user-delegated;
  • token lifetime and renewal rules;
  • scope boundaries per capability;
  • what gets logged about delegated authorization;
  • what happens when delegated access is revoked mid-session.

  • read or write nature;

  • network policy;
  • secret scope;
  • allowed environments;
  • timeout budget;
  • retry policy;
  • approval requirement;
  • logging and redaction rules.
capabilities:
  search_docs:
    transport: mcp
    mode: read
    network: internal_only
    secrets: none
    timeout_seconds: 8
    approval: none
  create_ticket:
    transport: mcp
    mode: write
    network: internal_only
    secrets: service_account_helpdesk
    timeout_seconds: 15
    approval: manager_for_high_priority
    protocol_profile: mcp-2026-07-28
    state_handle_argument: ticket_draft_id
    long_running_mode: tasks_extension
    additional_input: request_state
  run_shell:
    transport: sandboxed_exec
    mode: high_risk
    network: denied
    filesystem: workspace_only
    secrets: none
    timeout_seconds: 10
    approval: always

This is no longer just a function description. It is a behavioral contract for a capability.

9. Sandbox Execution Should Return Execution Facts, Not Only Output

If the sandbox returns only stdout or a payload, you lose half the value of the isolation layer.

For investigations and control, it is useful to return:

  • exit status;
  • timeout flag;
  • resource usage summary;
  • side effect uncertainty;
  • redacted logs;
  • policy decision id.

Then the execution layer can explain not just "the command failed", but something mature like: "the operation was terminated by timeout after 8 seconds, network was denied, side effect is not confirmed".

9.1. Network Egress Deserves Its Own Rule Set

Many incidents happen not because a capability "broke," but because it was able to reach a destination nobody expected.

That is why network egress should be described not as a footnote of sandboxing, but as its own contract surface:

  • denied;
  • internal_only;
  • allowlisted_external;
  • brokered_via_gateway.

If that is not fixed explicitly, it becomes very hard to explain later why a tool suddenly called out to an external destination while technically "breaking no rule."

For a production-grade platform, a good default is often:

  • read-only internal tools: internal_only;
  • external API adapters: allowlisted_external;
  • code execution and shell-like tools: denied by default.

9.2. The Sandbox Manifest as an Execution Contract

Recent OpenAI Sandbox Agents documentation adds a useful practical shape to this discussion: describe a sandbox not only as a "container" or "isolated environment", but through an explicit Manifest, capabilities, permissions, workspace entries, snapshot, and session state.17

That maps cleanly onto the execution contracts in this chapter. A platform needs to answer at least four questions:

  • which files, repositories, mounts, and environment values are materialized into the starting workspace;
  • which sandbox-native capabilities are available: filesystem, shell, memory, skills, compaction;
  • which permissions and run_as identity apply to commands, edits, and file reads;
  • what happens on continuation: a live sandbox_session, serialized session_state, or a fresh session from a snapshot.

Such a manifest does not replace the policy layer. It makes the execution boundary reviewable: reviewers can see what enters the workspace, what rights the agent receives, and whether the work can be safely resumed or snapshotted.

9.3. Brain / hands / session as an isolation contract

Anthropic's Managed Agents architecture states a useful runtime shape for this chapter: session, harness, and sandbox/tools should be treated as separate interfaces, not as one container with magical internal logic.[^anthropic-managed-agents]

  • session is the append-only log of events, decisions, tool calls, approvals, and results;
  • harness is the replaceable control loop that calls the model and routes capability requests;
  • hands are the sandboxes, tools, and adapters that actually read files, touch networks, and create side effects.

That split is useful for scaling, but it is also a security boundary. If the harness hangs, the session should remain readable. If the sandbox dies, the session should not disappear with it. If an operator needs to debug, they should inspect events, profiles, and snapshots, not open a shell inside an environment that also contains user data.

In this chapter's terms, a capability request should pass through a short chain:

capability request → policy → contained execution → telemetry → incident/eval feedback

The chain makes containment reviewable: policy chooses the execution profile, hands execute inside the restricted environment, telemetry records the boundary, and assurance/eval loops use the result for the next decision.

10. A Simple Capability Dispatch Example

This small skeleton shows the core idea: transport and execution profile are chosen from the capability contract, not invented by the model on the fly.

from dataclasses import dataclass


@dataclass
class CapabilitySpec:
    name: str
    transport: str
    mode: str
    timeout_seconds: int


def dispatch_capability(spec: CapabilitySpec, args: dict) -> dict:
    if spec.mode == "high_risk":
        return {"status": "approval_required", "capability": spec.name}
    if spec.transport == "mcp":
        return {"status": "success", "transport": "mcp", "capability": spec.name}
    if spec.transport == "sandboxed_exec":
        return {
            "status": "success",
            "transport": "sandboxed_exec",
            "capability": spec.name,
        }
    return {"status": "validation_failure", "reason": "unsupported capability profile"}

It is intentionally simple, but it locks in the right idea: the way execution happens is determined by the platform, not improvised by the model every time.

11. Common Mistakes

The same problems now repeat at two levels: at the individual adapter level, and at the MCP estate level.

The same problems repeat over and over:

  • a capability gets more network access than it needs;
  • secrets are visible to too many adapters;
  • tool results drag raw external payloads into prompts;
  • timeouts exist, but side effect uncertainty is not modeled;
  • an MCP server was added, but policy and audit never reached it;
  • a sandbox exists on paper but does not restrict anything important.

That is why sandboxing cannot be a checkbox feature. It has to be part of execution design.

12. What to Do Right Away

Start with this short list and mark every "no" explicitly:

  • Are adapters separated from the core runtime?
  • Is there a per-capability execution profile?
  • Are network, filesystem, and secrets constrained?
  • Is it clear which isolation level is used: logical, process, or runtime?
  • Is transport explicit: direct, MCP, sandboxed exec?
  • Does the system distinguish trustworthy from only partially trusted results?
  • Do you store execution facts beyond business payload?
  • Are ephemeral sandboxes used where high-risk execution exists?
  • Can you explain why a capability was allowed in this specific run?

If those answers are vague, the capability layer is still a pile of useful integrations, not a managed platform.

13. What to Do Next

First lock down execution profiles and isolation boundaries, then move to retries, rate limits, and rollback boundaries.

The next natural topic in this part is idempotency, retries, rate limits, and rollback boundaries. After sandboxing and capability contracts, that is what turns the execution model into a production-grade layer.


  1. Cloudflare, Scaling MCP adoption: Our reference architecture for simpler, safer and cheaper enterprise deployments of MCP 

  2. Cloudflare, Code Mode: give agents an entire API in 1,000 tokens 

  3. Cloudflare Blog, Your site, your rules: new AI traffic options for all customers 

  4. Cloudflare Blog, Announcing the Monetization Gateway 

  5. GitHub Changelog, Browser tools for GitHub Copilot in VS Code are generally available 

  6. GitHub Changelog, Agent finder for GitHub Copilot now available 

  7. AWS Security Blog, Secure AI agent access patterns to AWS resources using Model Context Protocol 

  8. AWS Open Source Blog, Governing AI Assets at Scale with MCP Gateway and Registry 

  9. Google Cloud, Build agents even faster with Gemini Enterprise Agent Platform’s fully-managed, remote MCP server 

  10. OpenAI, Secure MCP Tunnel and Making private MCP servers reachable without making them public 

  11. AWS, Introducing stateful MCP client capabilities on Amazon Bedrock AgentCore Runtime 

  12. AWS, Extending MCP support for Amazon Bedrock AgentCore Gateway 

  13. AWS Machine Learning Blog, MCP tool design: practical approaches and tradeoffs and AWS Prescriptive Guidance, Design tools for AI agents 

  14. AWS Machine Learning Blog, How Smartsheet built a remote MCP server on AWS 

  15. Cloudflare, Rules of Durable Objects 

  16. Google Cloud, Introducing Agent Sandbox 

  17. OpenAI Agents SDK, Sandbox Agents, Sandbox Concepts, Sandbox clients, and Agent memory 

  18. Model Context Protocol, Specification 2026-07-28 

  19. Model Context Protocol Blog, The 2026-07-28 MCP Specification Release Candidate 

  20. Model Context Protocol, Security Best Practices 

  21. Model Context Protocol, Authorization specification 

  22. Microsoft Security Blog, AutoJack: How a single page can RCE the host running your AI agent 

  23. Microsoft Security Blog, When prompts become shells: RCE vulnerabilities in AI agent frameworks 

  24. Microsoft Security Blog, Securing AI agents: When AI tools move from reading to acting 

  25. Microsoft Research, Red-teaming a network of agents: Understanding what breaks when AI agents interact at scale 

  26. Google Cloud, Beyond Static Prompts: Building Scale-Proof, Polymorphic Multi-Agent Systems with Google's ADK