Skip to content

The silo contract

A silo is a full-stack app that runs on Umi. The contract is how it plugs in safely. Every decision here is the 2026 industry consensus and clicks into what Umi already has — the umi-security capability boundary is the plugin permission system, so this assembles proven pieces rather than inventing a new sandbox.

1. A silo is defined by a manifest (silo.toml). It declares identity, a frontend entry, a backend entry, and its requested capabilities (required + optional, each scoped). No remote code — everything is bundled. (The Zed extension.toml + WebExtensions-permissions consensus; the manifest is the user’s consent surface.) Shape and rules: see conventions.

2. The contract is one versioned interface (WIT). A single host-interface IDL — scoped store access, event pub/sub, tool exposure, UI contributions — versioned so silos and core evolve independently. WIT is the WebAssembly Component-Model IDL (typed, polyglot), which makes the WASM sandbox a drop-in later instead of a rewrite. Choosing it now costs nothing and buys the future.

3. Backend runtime: OS process + MCP now, WASM component later — same contract. First-party / trusted silos (Email) run as a managed subprocess speaking MCP (JSON-RPC 2.0 over stdio — the universal local-AI standard). Untrusted third-party graduates to a wasm32-wasip2 component in wasmtime behind the same interface, for true sandboxing. This mirrors the inference decision (process-now, sandbox-later, behind a seam) and is the honest read of the tooling: WASM’s heavy-I/O story (sockets) is maturing until WASI 0.3, so we don’t force it on day one.

4. Frontend: sandboxed, bridge-mediated. A silo’s UI never touches core IPC directly — it speaks through a mediated postMessage bridge that enforces the same capabilities. First-party UI may compile in; untrusted renders in a sandboxed iframe/webview. (The standard web-isolation model; the Electron RCE lesson is “never give untrusted UI raw IPC.”)

5. Capabilities (umi-security) are the one permission spine — no new system. Manifest declares → user grants at install (sensitive ones just-in-time via ConsentGate) → core enforces at every host call via decide(). Least privilege is mandatory — it’s both the security model and a trust win (most users reject apps that over-ask). This is the payoff of building umi-security first: the plugin permission model already exists.

6. MCP is the interop bet. Core is an MCP host; a silo backend is (at least) an MCP server. This makes Umi instantly compatible with the entire MCP ecosystem (200+ existing servers), and the agent uses silo tools natively. It’s also the product thesis in one line: a $30/mo email-AI app is just a local model + an Email silo (an MCP server doing IMAP) + the agent, on hardware the user already owns. Every building block ships today; the missing layer is this assembly.

The first silo. Its manifest declares least-privilege capabilities: read_store/write_store scoped to self (its own mail partition), network scoped to the IMAP host (required) and the SMTP host (optional — sending is granted just-in-time). Its tools are MCP tools namespaced email.* (email.search, email.triage, email.send). The frontend (@umi/email) renders through the bridge. See packages/silos/email/silo.toml and the umi-silo crate, which makes the manifest contract real and validated.

The WASM runtime (decision 3’s “later”), the WIT interface bindings, and the actual IMAP/SMTP backend — those need crates that don’t exist yet (the engine, the runtime, MCP host wiring). What is real now: the manifest format, its capability model, and validation (umi-silo). The rest lands as the backend tier is built, against this contract.