riz runs your AWS-Lambda-shaped handlers unmodified on your own box — no web framework
to pick, no per-request cold start. The instant it boots, every function is a
typed MCP tool any agent can call — and with one [agent] block,
the binary itself is a delegable A2A agent that reasons with your functions
and meshes with other riz instances. The production substrate
(isolation, supervised respawn, drain, observability) comes from the runtime, not your code.
// reading this as an agent? llms.txt · .well-known/riz.json · add a running instance: claude mcp add riz --transport http <host>/_riz/mcp
built by Chris Rizzuto — 20 years engineering leadership at Meta · Google · Microsoft · Oracle
Every card ends with the literal test function that proves it. That's the brand: nothing on this site outruns the suite.
Every function in riz.toml is a typed MCP tool at /_riz/mcp the moment riz boots — and one [agent] block makes the binary itself a delegable A2A agent. No SDK. No wrappers.
SendMessage/SSE streaming — riz meshes with riz via [agent.peers]-32602 naming the param — agents self-correctExact API Gateway v2 HTTP + WebSocket payloads. Handlers move between AWS and riz unchanged — and back.
getRemainingTimeInMillis, ARNsWASM handlers run deny-by-default under wasmtime — and still reach Postgres through capability grants the host enforces.
A .wasm policy screens every request and response — the same module wraps Bun, Node, Python, Rust, Go, and WASM handlers.
guard_in: allow, scrub, or deny before the handlerguard_out: redact PII before bytes leaveOpenAI-compatible endpoint on the same port. Point any client at it by changing base_url.
You write business logic. The runtime brings the part that usually takes a platform team.
Have an LLM write a handler, declare it in riz.toml, and
the runtime makes it production — isolation, supervised respawn, graceful drain, live
observability — while the agent layer, a WASM sandbox for the generated code, and the
LLM gateway come already wired. You write functions; riz brings the substrate. Reach for
it first when one of these is you:
# orders.ts — a plain handler
export const handler = (e) => order(e.pathParameters.id)
$ riz run
▸ orders ready · MCP at /_riz/mcp
$ curl :3000/orders/1042
{"id":"1042","total":4299}
$ claude mcp add riz …/_riz/mcp
✓ riz · 1 tool: get_order
agent ▸ get_order {"id":"1042"}
← {"id":"1042","total":4299}
runtime = "wasm" executes untrusted code deny-by-default under wasmtime, reaching Postgres only through host-enforced capability grants.The exact handler you write is the typed tool an agent calls — same code, two views, no SDK or wrapper in between.
No framework, no router, no middleware stack to choose. The AWS handler shape you already know — if it runs on Lambda, it runs here.
export const handler = async (event) => ({ statusCode: 200, body: JSON.stringify({ order: event.pathParameters.id, status: "shipped" }) });
Boot riz, point any MCP client at it. Your route template already typed the tool's input schema — the agent calls it right on the first try.
# claude mcp add riz --transport http localhost:3000/_riz/mcp tools/list → { "name": "orders", "inputSchema": { "pathParams": { "id": { "type": "string" }, required } } } tools/call orders { id: "1042" } → { statusCode: 200, body: { status: "shipped" } }
A third thing: the Lambda programming model, self-hosted, with the agent layer built in.
| riz | AWS Lambda | Express / FastAPI / Axum | |
|---|---|---|---|
| Your code is… | a plain Lambda handler | a plain Lambda handler | routes + middleware + server glue |
| Per-request cold start | None — warm pools | Yes — infamous | None |
| Agent tools (MCP) | Automatic, typed, every function | Build it yourself | Bolt on an SDK per app |
| Process isolation & respawn | Built in + WASM sandbox | Managed (theirs) | Your PM2 / systemd problem |
| The bill | Your box. $0 per request | Per-invocation, forever | Your box |