Skip to main content
@struktoai/mirage-edge runs Mirage on an edge runtime: a host with web Request/Response, no Node and no threads. A workspace runs in the runtime’s own isolate: the shell, the commands built on Rust, and python3 on Monty, all in one thread. The runtime needs:
  • Node’s buffer, crypto, path, process and util modules.
  • A bundler that loads a .wasm import as a compiled WebAssembly.Module. Mirage’s Rust module and Monty both load this way.
The examples below run on Cloudflare Workers.

Install

wrangler.toml

Run a workspace

src/worker.ts
python3 runs on Monty in the isolate’s own thread, where no timer can interrupt it, so Monty’s own clock stops a run: at the line’s time limit, which ends the line with exit 124, or after 30 seconds with TimeoutError if that comes first. A loop that never ends leaves the isolate free for the next line. For anything else from core, import its subpaths (@struktoai/mirage-core/vfs/registry), not its package root: the root also imports optional packages, such as Pyodide, that an edge bundle cannot resolve.

Serve the server API

createApp answers the HTTP routes, MCP and RPC as the server does, over the workspaces the isolate holds:
src/worker.ts
A workspace outlives the request that created it, so a later request finishes work an earlier one started; no_handle_cross_request_promise_resolution above lets it. It checks each request the way the server does, from the same MIRAGE_AUTH_MODE, MIRAGE_AUTH_TOKEN and MIRAGE_JWT_* variables. Without a token or a JWT issuer it serves nothing, since an edge app’s URL is public.
wrangler.toml

Limits

  • An edge isolate has little memory and no disk; a Cloudflare Worker has 128 MB. Set max_memory on each workspace so a large write fails with Disk quota exceeded before the isolate runs out.
  • Workspaces live in the isolate’s memory. A request routed to another isolate does not see them, and they are gone when the isolate is evicted. store.type must be ram.
  • A config’s mounts come from core’s VFS table: ram, github, gdrive, gdocs, gsheets, gslides, gcal, gmail, onedrive, sharepoint, box, airtable, linear, trello, langfuse, wandb, mem0, qdrant and dify. qdrant needs @qdrant/js-client-rest installed; without it the bundle still builds and the mount refuses. chroma loads its package by a name only known at run time, which an edge runtime cannot do.
  • Network rules judge each request by host name: the isolate never sees the address a name reaches, so a denied_domains entry naming an address or a range is refused, and jwt mode’s block on cloud metadata addresses covers only a request made to the address itself.
  • SSH, FUSE, policy and script files read by path, and runtimes or CLIs loaded by a source:Class reference are the Node server’s alone.