berm

Nothing survives the call.

The OS for agent harnesses. One WebAssembly module, pinned by hash, compiled once, and instantiated per invocation.

crates.io cargo add berm

Apache-2.0 licensed Compiled by Cranelift Served over MCP

Two results, and they mean different things.

The outer result is the host's — a missing tool, a trap. The inner one is the program reporting failure, which is a result the model should see.

let berm = Berm::load(&engine, &wasm, &[])?;

match berm.call("echo", br#"{"query":"hello"}"#.to_vec())? {
    Ok(result) => println!("{result}"),
    Err(failure) => eprintln!("{failure}"),
}
crab ls
$ crab ls
NAME     DIGEST        TOOLS
fixture  222890c498ed  echo

$ shasum -a256 ./fixture.wasm
222890c498ed28f4bf60670a223141489d9879020bd1890111b8c11ac79fa31d  ./fixture.wasm

A program travels as one OCI layer with no tarball around it, so the digest a registry addresses it by is shasum of the file on your disk.

Pinned by hash

A program is one WebAssembly module. berm compiles it once and instantiates it per invocation — arguments go in through syscalls, the result comes back out of guest memory, and the instance is gone.

The linker is the boundary

A program reaches the world only through the syscalls it was given, and that list is the Linker it was instantiated with. A call to anything else traps because nothing is registered for it, not because a check said no.

berm has no host

berm ships no syscalls at all. What a filesystem is bounded by, and where bytes persist, are decisions about a host — so they belong to whoever is building one.

Read it without running it

Manifest::from_image reads what an image claims to be — its tools, their schemas, when to reach for them — without compiling it and without running it.

Running

bermd serves every deployed program on one MCP endpoint, with tools named {program}.{tool}.

$ bermd &
$ crab deploy
$ crab ls

Moving

A program is one file, so it travels as one OCI layer: deploy pushes it to the image its berm.toml names when the host pulls from a registry.

$ cat berm.toml
name = "example"
image = "ghcr.io/org/example"
$ crab deploy --context cloud