Skip to content

iweb · open-source personal application node

A personal application node. Operated by your AI agent.

You don't need to learn containers, databases, or network operations. Hand your MCP endpoint and one owner key to an AI coding agent (Codex, Claude Code, …) — it deploys and operates applications on your own node. You manage everything from a browser console with a single key.

Single-port Rust kernel MCP operations Two-tier trust runtime ≤ 240 MB idle
Quick start GitHub ↗
quick-start — zsh

$docker compose up -d --build

iweb-kernel listening :8080 — the only published port

health: curl -H "Host: $IWEB_BASE_HOST" http://127.0.0.1:9010/_iweb/health

console: https://admin.<base>/ — log in with an owner key

What’s inside

Ingress · 01

Single-port Rust kernel

kernel-rs is a ~4MB static Rust binary and the node's only published port. It owns host routing, the recovery authority, owner-key auth, and a per-app proxy with WebSocket upgrade tunnels. Everything else — RustFS, the control API, every celld listener — stays on container-internal loopback.

Operations · 02

MCP is the operator

mcp.<base>/mcp is a protected system application: every JSON-RPC request — including initialize and tools/list — must carry an owner key as a Bearer token. Tools cover workspace read/write/delete and domain listing/registration. The worker forwards the credential per request and never stores it.

Trust · 03

Two-tier runtime trust

celld v0.3 (Cloudflare Workers API) is the trusted tier: image-seeded fleet apps, one process per app, watchdog soft limits. iweb-wasmd is the untrusted tier and the only runtime admission path: arbitrary or AI-generated packages execute as wasi:http 0.2 components under Wasmtime — engine-enforced isolation, host services, no socket capability.

Storage · 04

Built-in RustFS

S3-compatible object storage (MinIO lineage), single-node friendly with a low memory envelope, loopback-only with no console. Buckets: iweb-workspace, iweb-cells-<app>, iweb-apps, iweb-system.

Identity · 05

Revocable owner keys

One identity, many revocable tokens (the GitHub PAT model). Issue delegated keys (iwb_<id>_<secret>) with absolute expiry, copy a ready-to-paste deployment prompt for an AI agent, ban a key instantly, and read an append-only, per-key-attributed audit trail of every control-plane operation. The bootstrap IWEB_API_TOKEN cannot be banned — it is the credential face of the recovery law.

Console · 06

Static console, tight envelope

A SvelteKit + shadcn-svelte static app served as celld native assets — replaceable like any app, never a secret configuration screen. The whole node idles within ≤ 240 MB RssAnon (spec: openspec/specs/node-boundary/).

Ingress

One published port routes the whole node

iweb-kernel :8080 is the only published port (a single Rust binary). Everything except the Kernel ingress — RustFS, the control API, every celld listener — stays on container-internal loopback and is never published. One installation is one owner's personal node.

RouteServes
api.<base>Kernel control API (same router/auth as loopback)
admin.<base>per-app celld :8787 (Admin console)
mcp.<base>/mcpper-app celld :8797 (MCP endpoint)
<app>.<base>per-app celld (IWEB_CELLD_PORTS)
<base>/<app>/apppath alias for the same application

Behind the proxy: RustFS (S3-compatible, loopback-only, no console) backing the iweb-workspace / iweb-cells-<app> / iweb-apps / iweb-system buckets.

Demo apps

Three reference applications ship in the image

They exercise the runtime end-to-end. Open collab on both of its domains in two browser windows — a message sent on one side jumps live on the other: the Durable Object cross-instance consistency demo.

AppHostDemonstrates
hellohello.<base>Pure static site via celld's wrangler assets interface — no worker code.
searchsearch.<base>D1 (SQLite) database search with parameterized SQL.
collabcollab.<base>, collab-b.<base>Frontend/backend split; two celld instances share one Durable Object for cross-instance realtime collaboration over WebSocket.

Quick start

One compose command, one health check

IWEB_BASE_HOST is a hostname suffix only (no scheme/port/path). The container publishes one port (8080 — map it however you like); TLS is terminated in front of the node (1Panel, Caddy, nginx, …) and the kernel routes by HTTP Host header only.

$shell
cp .env.example .env
# Set a unique CELLD_NODE, IWEB_BASE_HOST, a long random IWEB_API_TOKEN,
# and the MinIO-compatible root + celld S3 secrets.
docker compose up -d --build
curl -H "Host: $IWEB_BASE_HOST" http://127.0.0.1:9010/_iweb/health

Open the console at https://admin.<base>/ and log in with any valid owner key — the bootstrap IWEB_API_TOKEN, or a delegated key issued in the console. From the Keys & Audit view you can copy a ready-to-paste deployment prompt containing the MCP endpoint and key for an AI agent.

MCP

Point an agent at your node

Every JSON-RPC request — including initialize and tools/list — must carry Authorization: Bearer <owner-key> (bootstrap or delegated). Tools cover workspace read/write/delete and domain listing/registration.

mcp.json
{ "mcpServers": { "iweb": { "url": "https://mcp.<base>/mcp",
  "headers": { "Authorization": "Bearer <owner-key>" } } } }

Security boundary

Untrusted by default, isolated by design

Applications may be copied from the internet or generated by AI, so they are untrusted by default — isolating every application from the node control plane and from each other is the product's security bottom line.

  • celld is the trusted tier. Fleet applications (admin, mcp, notes, hello, search, collab) enter the node only through node images you build, run one process per app, and are bounded by a userspace resource watchdog (soft-limit SIGKILL plus per-app restart). There is no celld runtime admission; celld is never a hostile multi-tenant boundary.
  • wasm is the untrusted tier and the only runtime admission path. Arbitrary, network-sourced, or AI-generated packages execute as wasi:http 0.2 components under Wasmtime with engine-enforced limits (no socket/TLS/fs capability, host-mediated egress, fuel/epoch/store caps) and host services (KV/SQL/Logging) as the data plane.
  • Never place secrets in the workspace. Credentials live only in node environment or Kernel-issued keys. The law lives in openspec/specs/application-sandbox.

Honesty

Current limitations

  • TLS/wildcard certificates are a deployment concern (the kernel is HTTP Host-routing inside the container).
  • Monitor metrics are per-Kernel-lifecycle, not durable history.
  • notes is deployed but not routed (user routes target the wasm tier only).
  • wasm publication stays fail-closed behind its acceptance record and switch; celld publication does not exist (image-only supply).