Give your OpenClaw agents a body — and talk to them in your room.
Incarna drops your agents into your actual room as talking 3D avatars in mixed reality. You look at one, hold a button, and talk. It remembers the conversation, reacts with its face and hands, and can pull up a report on a floating panel. Open a link on a Meta Quest 3 (or any WebXR browser) — no app, no install.
Made for OpenClaw folks. If you already run OpenClaw agents, Incarna is the fun part: it gives them presence. It plugs into your gateway, uses your agents, and keeps your keys on your machine. New to OpenClaw? Start at openclaw.ai, then come back.
A chat window is a great brain in a box. But an agent that stands in your room, turns to look at you, and answers in its own voice hits differently — it feels present. Incarna is a small, honest, zero-dependency project chasing that feeling: the least amount of tech between you and "there's someone here."
It's homemade and hackable on purpose. One server.js, a handful of plain JS files,
no build step, no framework. Bring a .vrm avatar, point it at an agent, open the
link.
|
Your office — the agents who live in your room. |
The Board — ask for a report, get a panel. |
The interesting bits, for people who know the OpenClaw stack:
- 🧠 You talk straight to the agent. No LLM middleman rewriting your words.
server.jscalls your agent through the gateway's OpenAI-compatible endpoint. - 💾 It remembers. Each avatar uses a stable session (
user: "incarna:<id>"), so the agent keeps its own history across turns — the app stores nothing. - ✍️ Zero agent changes. A short "answer for voice" preamble is stapled onto
each message by the app, so replies stay short and can drive the body with
[action:*]. Talk to the same agent from webchat and it behaves normally. - 🗣️ Voice + lip-sync. ElevenLabs per agent, viseme lip-sync, blink, breathing,
facial emotions — all on the VRM standard, so any
.vrmjust works. - 📋 Show, don't just tell. A
<<<incarna:panel … >>>block (or a reply that just looks like a report) becomes a floating, draggable Markdown panel. - 👀 Look to talk. Several agents in the room? Look at one — a ring + name shows who's listening. Grab and move avatars where you want them.
- 🔒 Keys stay yours. The Node proxy never ships your tokens to the browser.
See ARCHITECTURE.md for the full picture.
Requirements: Node 18+. That's the whole dependency list.
git clone https://github.com/andrewsegas/incarna
cd incarna
cp .env.example .env # your OpenClaw / ElevenLabs / OpenAI keys
node server.js # http://localhost:8080Open http://localhost:8080 and you'll land on a guided setup (no agents yet). Add one in the Studio (below), hit Enter, hold the mic, and talk. Without keys it still boots in a degraded mode so you can look around.
You'll need a
.vrmavatar — none ship with the repo (most VRM licenses forbid redistribution). Grab or make one (seeassets/avatars/README.md); it takes a minute.
/studio.html is where you compose your office and test everything, in three tabs:
- Roster — bind a live OpenClaw agent to an avatar + an ElevenLabs voice (with preview) + a seat, and save. No hand-editing config.
- Avatars — preview/upload
.vrm, test emotions and every animation. - Actions — curate and test the body-action catalog live.
Prefer files? Everything lives in agents.local.json — the Studio just writes it
for you. (Saving/uploading needs the server started with ALLOW_DEV_WRITES=true.)
WebXR needs HTTPS, so expose the local server with any tunnel and open the URL in the Quest browser:
node server.js
# then, in another terminal, an HTTPS tunnel to :8080 (cloudflared, ngrok, tailscale funnel…)Tap Enter → 🥽 VR, grant the mic, and hold a controller trigger (or A/X) to talk. Squeeze grip near an avatar to move it.
The agent expresses itself with inline [action:tag] markers (stripped from speech,
played by the body); the catalog lives in actions.json and only
non-broken actions are offered to the brain. When a report helps, it fills The
Board — a floating Markdown panel. Deep dives:
docs/adding-actions.md · docs/panels.md.
server.js is a proxy: your API keys never reach the browser. To lock a public
link, set SESSION_TOKEN and share https://host/?k=YOUR_SECRET. There's a per-IP
rate limiter on the expensive endpoints. Please read
docs/security.md before exposing a tunnel to the internet.
See the ROADMAP — streaming TTS, richer idle motion, a community action pack, a wall-mounted 3D Board, and more. Ideas and PRs very welcome.
This is meant to be maintained by many hands. Start with CONTRIBUTING.md, ROADMAP.md, and good first issues. Be kind — see CODE_OF_CONDUCT.md. Maintainers & governance: MAINTAINERS.md.
A-Frame · @pixiv/three-vrm · a zero-dependency Node proxy · OpenClaw (brain) · ElevenLabs (voice) · OpenAI (speech-to-text). Full attributions in CREDITS.md.
Created by Andrews Egas — GitHub · LinkedIn.
Source code: MIT. Third-party assets and the avatars you supply carry their own licenses — see CREDITS.md.


