Ephemora Cell

MCP serverDocs & knowledge

WASM sandbox for MCP tools. WASI-isolated, fuel/memory/I/O capped, attested.

Unavailable. This server has no hosted endpoint yet, so ahel can't serve it.

Add to setup to save this item as a reference. ahel cannot run it, and signing in will not install it.

Getting started

  1. Save this item in Your setup as a reference.
  2. Read the source or reference documentation for its setup requirements. Saving it here does not connect it to your AI.
  3. Check this page for availability before trying to install it through ahel.

From the project's README

As published by michaels1011/ephemora-cell in README.md.

Ephemora Cell is a lightweight security and execution primitive for running untrusted code inside AI agents, MCP tools, plugins, and applications.

Run untrusted code.
Control its capabilities.
Bound its resources.
Record what happened.

Built for AI agents, MCP tools, plugins, code interpreters, and other untrusted workloads.

AI Agent / Application
        │
        ▼
   Tool / Plugin / MCP
        │
        ▼
 ┌───────────────────────┐
 │     Ephemora Cell     │
 │                       │
 │ Capabilities          │
 │ Resource budgets      │
 │ WASI sandbox          │
 │ Execution record      │
 └──────────┬────────────┘
            ▼
       WASM module

~0.5 ms warm · ~3M executions/hour per core (one-liner) up to ~5.5M pooled · deterministic, not "isolated and hoped for"

Status (2026-09-25): latest release v1.0.4.3 (2026-09-25, docs & hardening release — changelog) · full functional audit 2026-09-24, findings fixed and released the same day · latest reproducible evidence: 2026-09-25 (probe classes, benchmarks/results/) · 532 tests passing, 86% coverage (see CI badge — refreshed per release)

What is Ephemora Cell?

Ephemora Cell is an embeddable execution and security primitive for running untrusted WASM code: WASM/WASI isolation, explicit capability control, enforced CPU/fuel, memory, I/O and time limits, bounded output, and structured — optionally signed — execution records. Runtime + security primitive + accounting in one pip install. It uses Wasmtime to implement that boundary — WASM is the mechanism, the controlled execution of untrusted code is the product.

Why Ephemora Cell?

Wasmtime gives you a WASM runtime.

Ephemora Cell builds an application-level execution boundary around it:

Wasmtime:            Ephemora Cell:
    Execute WASM         Execute WASM
                         + define capabilities
                         + enforce budgets (fuel, memory, time, I/O)
                         + bound output
                         + collect execution metadata
                         + produce execution records (sign-ready)
                         + integrate with agents and MCP

The problem this answers: AI agents increasingly need to write and execute code, call tools, and run plugins. The question that decides whether that is safe: how do you let an agent execute untrusted code without giving that code access to your host, your credentials, your network, or unlimited compute — with nothing pre-opened by default? Raw runtimes leave that boundary to you. Cell is that boundary.

Agent-generated code is different from application code: it can be buggy, computationally unbounded, unexpectedly expensive — or hostile. The runtime must enforce boundaries, not document them. Every Cell run does:

  • Enforced, not promised — fuel metering (CPU), memory caps, epoch-based wall-clock timeouts, output caps and I/O budgets run per execution and cannot be switched off by guest or caller; the effective posture is attested in the execution record (RFC 8785 JCS, sign-ready).
  • Deterministic loop-stop — a hostile or buggy module that loops forever is stopped at exactly the budget you set, every time; the run cannot overshoot its fuel budget. The epoch-based wall-clock timeout is the safety net on top — fuel counts CPU, the clock bounds everything else.
  • Measured isolation advantage — of the attack vectors that succeed against a stock Docker container (shell, fork, socket, host filesystem, symlink escape, …), all 8 are blocked here (live-verified, script in the repo).
  • Sub-millisecond warm execution — 0.17 ms guest / 0.51 ms end-to-end (pooled, measured 2026-09-14; benchmarks/results/).

Why now — 2026 evidence that detection and containers are not enough (literature — measured:false for Cell; the measured rows live in the evidence ladder and never mix with these). SABER — the SandboxEscapeBench program (UK AI Security Institute & Oxford, ICML 2026) shows frontier models reliably escaping Docker containers through common misconfigurations — the same benchmark this repo maps to WASM in the Security section. Trail of Bits researchers (Judson & Hess, 2026) bypassed five agent-skill scanners and sandbox defenses in one study, and the DDIPE skill-poisoning attack (arXiv 2604.03081) measures 11.6–33.5% bypass rates against agent skill ecosystems. The pattern across all three: scanning and container defaults fail; the boundary that holds is the one enforced between the code and the host — the layer Cell ships (per-claim provenance: docs/security_posture.md).

AI Agent ──▶ Tool / MCP ──▶ Ephemora Cell ──▶ WASM ──▶ bounded result

Every execution answers three questions at once — attached to the result as _meta.execution, canonicalized (RFC 8785 JCS) and signable:

AnswerExample fields
RESULTwhat came backstatus, stdout, exit_code
COSTwhat it costfuel_consumed, elapsed_ms
POLICYunder which rules it ranmemory limit, preopens, network policy, wasmtime_version

"Verifying. Not claimed." is data, not a slogan: any record can be re-checked — rewrite one field and verify() fails. Runnable demo: python examples/signed_record_demo.py.

Security Model

Cell assumes that guest code is untrusted. The host explicitly decides what the guest can access — and the runtime enforces that decision per execution.

HOST
────────────────────────────
       Cell Boundary
────────────────────────────
GUEST / UNTRUSTED CODE

By default: no network · no arbitrary filesystem access · no process spawning · no unrestricted environment access — and bounded CPU/fuel, memory, execution time and output.

Security is never opt-in. Every execution — in-process or isolated — runs under enforced limits (CPU fuel, memory, wall-clock time, output caps — always on, neither the guest nor the caller can switch them off). The one thing you choose is the process boundary: add --isolated (or call run_isolated()) when the module comes from outside your own build — agent output, third-party plugins, PR-contributed code. The in-process path stays for modules you build and trust. The enforced defaults:

ResourceDefault
WASM memory128 MB (Store.set_limits)
Fuel / CPU budget1,000,000 (~13 fuel/iteration, R² = 1.000 up to 1M iterations; re-measured 2026-09-14, benchmarks/results/2026-09-14/fuel_boundary.json — fuel is per-platform, see docs/performance.md)
Wall-clock timeout30 s (epoch interruption)
Captured stdout/stderr10 KB
Networkdisabled — Preview1: no socket APIs; WASI 0.2: linked, denied at call time (measured)
Host filesystemdenied by default; 14 dangerous dirs blocked (/dev, /proc, /sys, …)
Process exec / forkunavailable in WASI
Threadingdisabled (wasm_threads=False)

The same rule governs language features: every WebAssembly proposal Cell's shipped WASI surface does not need is enforced off in the engine config (threads, function-references, exceptions, GC, tail-calls, stack-switching — attested in every security_baseline, compile-probe-tested per release). That is a deliberate structural defense: the 2025/26 record — fuel accounting dropped across call_ref/try_table calls (GHSA-m63x-6p34-q65x), a Cranelift aarch64 heap escape (CVE-2026-34971), and the vm2 escape riding WebAssembly try_table exception handling (CVE-2026-26956, secondary sources) — repeats one pattern: sandboxes diverge exactly where a proposal quietly flipped to default-on. Cell keeps that surface at zero and pays the cost in what guests can't run, not in what the host can't guarantee. Full proposal table: SECURITY.md.

Additional controls: I/O budgets (io_cpu_seconds / io_budget_bytes — walls for host work, not just guest compute), dual-ABI (WASI Preview1 + WASI 0.2 components, opt-in), memory64 opt-in, GC-heap declared cap, named state (64 entries · 256 KiB · 1 MiB per session), and an egress sidecar reference mediator (docs/egress_patterns.md).

Quick Start

Three commands: install Cell, run something untrusted, read its audited receipt.

1 — Install (use a virtualenv; on Ubuntu ≥ 23.04 / Fedora a bare pip install is refused by PEP 668. Windows: use Git Bash or WSL, and python instead of python3):

python3 -m venv .venv && source .venv/bin/activate
python -m pip install ephemora-cell

2 — Run something untrusted (the repo ships examples, or bring any .wasm):

git clone https://github.com/MichaelS1011/ephemora-cell.git && cd ephemora-cell
ephemora-cell run examples/hello.wasm --isolated

(adds OS-level process isolation around the run, a few ms — recommended for code you didn't build)

Hello from Ephemora Cell!

3 — Read the audited receipt — same run, machine-readable. Here a hostile module (examples/fuel_bomb.wasm) is given a 100-unit fuel budget and stopped, exactly as budgeted:

ephemora-cell run examples/fuel_bomb.wasm --fuel 100 --isolated --json
{
  "status": "fuel_exhausted",
  "exit_code": 0,
  "fuel_consumed": 100,
  "fuel_budget": 100,
  "stdout_bytes": 0
}

Same from Python — every result carries status, cost and captured output (see API & CLI):

Time to value: no policy file, no access rules, no container to provision — one pip install and you are running untrusted WASM under a hard fuel + memory boundary at ~0.5 ms warm (the same call took a stock docker run ~186 ms to start; measured macOS M5 n=100, benchmarks/results/2026-09-14/competitive_benchmark.json, DGX numbers in benchmarks/results/2026-09-20/).

Scale check: the one-liner path sustains ~3M executions/hour per core (n=500, hello.wasm, Mac M5 — regenerate with the snippet in docs/recipes.md); the pooled hot-loop path reaches ~5.5M/hour.

Where to next: agent/tool isolation → MCP Integration (3-line setup) · CI gating for untrusted PRs → AI Agent Integration · CLI reference and usage recipes → docs/recipes.md. Something failed? The usual suspects are venv not activated, python3 vs python on Windows, or a wrong .wasm path — docs/recipes.md covers them.

Real CLI session: install, first run, --json report with the security baseline, a fuel bomb stopped at exactly 100/100 units, an attack module blocked at the WASI import layer. Every frame reproducible from a clone.

The devtools loop for agent tools

The same commands are a development loop — edit, run, read the receipt — with no Dockerfile, no image build:

CommandWhat it does in the loop
ephemora-cell build tool.rsCompile Rust, Go, C, AssemblyScript or Zig source straight to WASM
ephemora-cell run tool.wasm --jsonVerdict immediately: status, exit code, fuel_consumed, elapsed_ms
ephemora-cell inspect tool.wasmImports, exports, memory — what a module wants, before you run it
ephemora-cell benchmark tool.wasmCold/warm latency and fuel spread while you iterate

Failures come back graded, not crashing: an infinite loop returns status: "fuel_exhausted" with its receipt, a memory hog memory_exceeded, a crash a non-zero exit code — the same statuses the auto-grader and the CI test-bench job consume. A misbehaving tool never takes your terminal with it.

MCP Integration

Listed in the official MCP Registry (io.github.MichaelS1011/ephemora-cell-mcp, stdio via PyPI) and graded on Glama (license A, quality A, maintenance B — Glama's live classifier; see the hero badges above). The call flow is the hero diagram above: the agent's tool call enters the stdio server, the tool runs inside the Cell, and the result comes back with its execution record.

pip install ephemora-cell
ephemora-cell-mcp          # bundled tools: clock + echo; --tools-dir ./tools replaces the bundled set with your own

# One-line setup for GitHub Copilot in VS Code:
code --add-mcp '{"name":"Ephemora Cell","command":"ephemora-cell-mcp"}'

Ask your agent for the current time: the answer comes from the bundled clock tool — a WASM module reading only the WASI real-time clock — and the call report shows exactly what that answer cost.

Runs entirely on your machine — with any MCP client and any model, including local ones. The MCP server is a plain stdio process installed from PyPI: no API key, no cloud account, and tools execute offline inside the WASM sandbox (no network unless you explicitly allow it host-side). Point Claude Desktop, VS Code/Copilot, Codex, LM Studio or your local-model stack of choice at it — the sandbox side never leaves your hardware. How much the agent gets out of the tools then depends on your client and model's tool-calling ability; the sandbox itself adds no requirements beyond a local machine.

What you get:

  • Run untrusted, agent-built tools locally. Every tool is a WASM module inside a Cell sandbox — no network, fuel- and memory-bounded, output-capped. If a tool misbehaves, it hits a wall, not your machine.

  • Verify every call, not just the install. Each result carries its execution record (_meta.execution), and the native get-policy tool reports the exact sandbox policy per tool — computed from the same code path that enforces it, so report and enforcement cannot drift. Policy reads are tools; policy writes are host decisions (ADR-006): an agent cannot grant itself network or filesystem access, and no socket connect succeeds (Preview1 exposes no socket APIs; in the WASI 0.2 world connect is denied at call time — measured).

  • Stateless by design (2026-07-28 revision). Clients on the current revision skip the initialize handshake entirely; results carry resultType: "complete" and tools/list answers with ttlMs/cacheScope. Handshake-era clients (Claude Desktop, VS Code, Codex, …) keep working unchanged — both eras served from one process and tested side-by-side against the official MCP SDK in CI. Details: docs/mcp.md.

  • Isolation priced for every call — three distinct numbers (comparison):

    PathCost per callWhy
    Library pooled runtime (io_budget_bytes=None)~0.5 mscached engine, trusted workloads
    MCP stdio server, default~12 msfresh sandbox per tools/call — the ADR-002 I/O wall enforced via a per-run engine, measured end-to-end
    MCP stdio server, --pooled~0.5 msverified tools on the pooled engine; the relaxed I/O wall is attested in get-policy
  • The agent cannot rewrite its own security boundary. The agent may only propose a capability; the host verifies signature, module hash and policy out-of-band before anything runs; the runtime enforces per execution and returns evidence. No arrow in that chain points backwards.

vs Microsoft Wassette. Wassette is Microsoft's capability-based runtime for MCP tools, built on the same Wasmtime engine family — its OCI pull model moves the trust decision to install time; Cell adds what a caller can verify per call. Full side-by-side (re-verified 2026-09-18): docs/comparison-mcp-servers.md.

This is an execution boundary, not a claim that guest software is trustworthy. Cell does not evaluate whether a module is malicious or correct — a guest can still misbehave within the budgets it was given.

AI Agent Integration

Untrusted PR code in GitHub Actions. This repository ships a composite action: run a WASM module in the Cell sandbox inside your own workflow — with fuel metering, memory cap, epoch timeout and (default) the --isolated subprocess path (OS-level rlimits, hard kill):

- id: run-tool
  uses: MichaelS1011/ephemora-cell/action@main
  with:
    module: path/to/module.wasm   # e.g. built from a PR-provided recipe
    profile: llm
    # fuel: 500_000
- run: echo "status=${{ steps.run-tool.outputs.status }} fuel=${{ steps.run-tool.outputs.fuel_consumed }}"

Non-success statuses fail the step (fail-on: non-success, default) — a module that burns its budget or trips the memory cap cannot take your workflow with it. This repo dogfoods the action on every push: .github/workflows/action-demo.yml runs a benign module and feeds the same module a 100-unit fuel budget, asserting live that the sandbox stops it and accounts every unit.

Agent-framework integration tests (LangGraph, CrewAI, AutoGen, OpenAI Agents SDK, Semantic Kernel, Hermes, NemoClaw) live in integration/ — verified against real framework SDKs.

Use Cases

What you can build with Cell:

  • AI Code Execution — safely execute code generated by an LLM, with explicit limits:

    result = run_wasm(
        "llm_generated.wasm",
        max_fuel=200_000,
        timeout_seconds=5,
        allow_dirs=("/input", "/output")
    )
    
  • MCP Tool Sandbox — run MCP tools inside a bounded execution environment (see MCP Integration).

  • Plugin Runtime — accept user-uploaded plugins without giving them host-level access (WASIConfig(allow_dirs=("/data",), max_fuel=500_000) — same shape as the snippets above).

  • Agent Tool Runtime — give autonomous agents controlled access to computational tools.

  • Verifiable Execution — produce structured and optionally signed records describing an execution (Execution Records).

Also documented: serverless/edge workloads, air-gapped validation, WASI 0.2 components, FastAPI integration — docs/recipes.md.

Architecture

Cell executes the .wasm — it does not know the source language. One command compiles five languages, and the runtime sits underneath your stack:

The enforcement stack — module → engine → capability surface → budgets → record — is diagrammed in docs/security_posture.md. The primary API is deliberately simple — run_wasm(wasm) → result, with status, exit_code, stdout, stderr, elapsed_ms and fuel_consumed on every result (full surface in API & CLI). That makes execution suitable for auditing, policy enforcement, and resource accounting — not just running code. Full CLI (run, --json with security_baseline, inspect, benchmark, build) in the CLI docs and ephemora-cell --help.

Any language that compiles to WASM. One-command build with actionable error hints:

ephemora-cell build src/main.rs # inside a cargo project → tool.wasm → run it
LanguageCompilerVerified
Rustcargo build --target wasm32-wasip1✅ Compiled + executed (CI)
GoGOOS=wasip1 GOARCH=wasm go build✅ Compiled + executed (CI)
Cwasi-sdk clang --target=wasm32-wasip1✅ Compiled + executed (CI)
AssemblyScriptasc --runtime stub✅ Compiled + executed (CI)
Zigzig build-exe -target wasm32-wasi✅ Compiled + executed (CI)
Python—Guidance: run on a wasi-python interpreter (no AOT exists)

All five compiled-language gates verify on every push (.github/workflows/ci.yml). Platforms: macOS (Apple M5) ✅ · Ubuntu 24.04 ✅ · DGX Spark GB10 ✅

Execution Records

Around the sandbox sits a verifiable trust chain for third-party tools:

TOOL ──▶ SIGNED MANIFEST ──▶ HOST VERIFY ──▶ EPHEMORA CELL ──▶ SIGNED EXECUTION
        (vendor ships)     (fail-closed,      runs inside       RECORD
                           hash + policy      the sandbox       (tamper-evident)
                           check)

Anything failing verification is rejected before a single instruction executes — execution never depends on a happy path.

Shortened here. Read the whole README on GitHub.

Signals

GitHub stars
46
Forks
6
Last commit
Oct 2026
Advanced
Delivery
ephemora-cell-mcp MCP server → your ahel connector (mcp.ahel.ai) → your AI.
Item type
mcp-server
Key
io-github-michaels1011-ephemora-cell-mcp
Source
github.com/michaels1011/ephemora-cell