A container takes on the order of 90 milliseconds to cold-start. A Firecracker microVM — the isolation model E2B and Daytona both use for AI-agent sandboxes — takes 150 to 500 milliseconds, because it has to boot a minimal Linux kernel before your code runs at all. Microsoft's Wassette, a security-oriented MCP server that runs tools as WebAssembly Components instead of either one, instantiates them in microseconds to low milliseconds — one to two orders of magnitude faster than both, with no shared kernel to escape and no VM to boot. That gap is the whole pitch.
It's also not the whole story: WASI's capability model still can't reach a GPU, still can't fork(), and still doesn't enforce per-tenant resource quotas the way a heavier sandbox does. Wassette is a genuinely different point on the isolation-vs-capability curve, not a strictly-better one — and knowing exactly where that line falls matters if you're deciding what runs your own MCP server's tool calls.
What Wassette Actually Is
Wassette, shipped by Microsoft's Azure Core Upstream team in August 2025, is an MCP server that runs tools as WebAssembly Components inside a Wasmtime sandbox instead of shelling out to a container or a scripting runtime. It's a single Rust binary with zero runtime dependencies, and it works with any MCP-speaking client — GitHub Copilot, Claude Code, Cursor, Gemini CLI.
The architecture is a stack of four layers, each narrowing what the layer above it is allowed to do:
- Wasm Sandbox — memory isolation and type safety at the instruction level, the same guarantee browser engines give untrusted JavaScript.
- Wasmtime Runtime — enforces WASI (WebAssembly System Interface) capabilities; a component can only call the host functions it was explicitly linked against.
- Policy Engine — applies Wassette's own fine-grained permission checks (filesystem paths, network hosts, environment variables) on top of what Wasmtime already restricts.
- Wassette Server — manages component lifecycle and speaks MCP to whatever client is calling it.
Components themselves don't have to be written against Wassette specifically. They're fetched at runtime from OCI registries — the same distribution mechanism as container images — with a syntax like oci://ghcr.io/microsoft/time-server-js:latest. An agent (or a human) can pull a new tool into a running Wassette instance without a rebuild or a restart, the same way docker pull fetches an image, except what lands is a WASM component instead of a filesystem layer.
Deny-by-Default, Not Deny-by-Configuration
The permission model is the part that actually earns the "security-oriented" label, and it's stricter than the default posture of a container: a Wassette component has no access to the filesystem, network, or environment until something explicitly grants it. Not "runs as an unprivileged user" — no access, full stop, enforced at the WASI import boundary rather than by a policy someone has to remember to write.
Grants are scoped narrowly and expressed in a policy.yaml:
permissions:
filesystem:
- uri: "fs:///workspace/data"
access: ["read", "write"]
network:
- host: "api.weather.com"
environment:
- key: "API_KEY"A component with this policy can read and write exactly one path, make outbound requests to exactly one host, and see exactly one environment variable — nothing else on the machine is reachable, because nothing else was imported. The same grants are also available as MCP tools in their own right (grant-storage-permission, grant-network-permission), which means an agent can request access mid-conversation and a human — or a policy — approves or denies it without editing a YAML file by hand.
Compare that to the default posture most MCP tool implementations actually ship with: a Node or Python process running as whatever user invoked it, with the full filesystem and network reachable unless someone remembered to drop privileges or wrap it in a container with its own separately-configured restrictions. Wassette's model inverts the default — the restrictive case is what you get for free, and every capability past that is a line someone had to write.
The Isolation Comparison, With Real Numbers
Here's where WASM components, containers, and Firecracker microVMs actually land against each other on the dimensions that matter for running someone else's tool code:
| Dimension | WASM Component (Wassette) | Container (Daytona-style) | Firecracker microVM (E2B-style) |
|---|---|---|---|
| Cold start | Microseconds–low ms | ~90ms (p99, optimized) | ~150–500ms |
| Kernel | None — shares no kernel, sandboxed at the instruction level | Shared host kernel (namespaces + cgroups) | Own minimal kernel per instance |
| Blast radius of a kernel exploit | N/A — no kernel to exploit from inside | Can reach the host kernel | Contained to that microVM only |
| Memory footprint per instance | KB–low MB | Tens of MB | ~128MB+ (kernel + guest overhead) |
| Price parity reference | N/A (self-hosted, no per-instance metering) | ~$0.0504/vCPU-hour | ~$0.0504/vCPU-hour |
The cold-start numbers are the headline, but the second row is the more interesting one for a self-hosted fleet: a container shares the host kernel, so a kernel-level exploit inside it can, in principle, reach the host. A Firecracker microVM buys a real hardware-virtualization boundary against that — its own kernel means a compromised guest kernel doesn't compromise the host or a sibling microVM. A WASM component sidesteps the question a different way: there's no kernel inside the sandbox to exploit in the first place, because the component was never given syscalls, only whatever WASI imports its policy explicitly wired up.
That said, the cold-start advantage isn't unconditional. As a tool's logic gets heavier — more code to compile and instantiate, more WASI imports to resolve — WASM's initialization time grows, while a microVM's cold start stays roughly flat regardless of what's inside it. The gap is largest exactly where MCP tool calls tend to live: small, single-purpose, short-lived — a weather lookup, a file read, a deploy-status check — not a multi-gigabyte data-processing job.
What This Means for a Self-Hosted Fleet's Own MCP Server
A platform exposing deploy, rollback, or logs access over MCP — the model Bex and platforms like it are built around — is choosing, whether deliberately or by default, an isolation boundary for every tool call an agent makes against production infrastructure. Today that choice is usually a container, because that's what's already sitting in a Cluster API-managed fleet's toolbox.
The case for a WASM-component layer isn't "replace the container fleet." It's sandbox density for the specific slice of tool calls that are narrow, well-defined, and don't need much beyond a scoped filesystem path or a single outbound host: a get-deploy-status tool, a read-app-logs tool, a list-services tool.
Running each of those as a component that instantiates in microseconds and holds no access beyond an explicit grant means a single machine can host far more concurrent tool-call sandboxes than the same machine could host as one warm container — or one microVM — per call. For an MCP server fielding thousands of short tool calls a day rather than one long interactive session, that density difference compounds directly into either lower latency or lower infrastructure cost — the same trade a fleet already makes when choosing between container density and VM density for tenant apps.
Where WASI Still Can't Reach
The honest limits matter as much as the pitch, because they're exactly what tells you which tool calls don't belong in a WASM component:
- No native GPU access. WASI's capability model has no story yet for handing a component direct GPU compute — a tool that needs to run inference or any GPU-bound workload still needs a heavier sandbox underneath it.
- No
fork(), no arbitrary syscalls. The Component Model's boundaries are deliberate — clear component edges, no shared state — andfork()semantics don't map onto that cleanly. A tool that needs to spawn and manage its own subprocesses isn't a good fit. - Multi-tenant resource quotas are still immature. WASI and its extensions don't yet give a host fine-grained control over how much CPU, disk I/O, network bandwidth, or entropy a single component can consume — a compromised or just poorly-written component can still starve its neighbors on shared hardware, a gap a container's cgroups or a microVM's hardware limits close by default.
- Networking is still stabilizing. WASI networking moved from Preview 1 to Preview 2 relatively recently, and the surrounding tooling is still catching up — a tool that needs anything beyond straightforward outbound HTTP to a fixed host is on less-traveled ground.
None of those are reasons to skip WASM components for the tool surface they're actually good at. They're the reason a deploy-authority MCP server should treat this as one more isolation tier to route tool calls into — narrow, high-frequency, low-privilege calls to WASM components; anything needing a GPU, a subprocess, or hard per-tenant resource limits to whatever heavier sandbox already handles that job today. Firecracker microVMs and WASM components aren't competing for the same tool calls; they're answering different questions about how much a tool actually needs to touch.
Bex.co is the open-source, AI-native Render alternative — push a git repo, get a running HTTPS service on machines you own, with agents built in as first-class operators from day one. Star the repo on GitHub or deploy your first app today.



