Skip to content

Repository files navigation

◐ Incarna

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.

Incarna — an agent standing in your room

CI Release License: MIT PRs welcome Discussions


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.

Why I built this

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.

See it

Your office — the agents who live in your room.

Your office

The Board — ask for a report, get a panel.

The Board

What makes it tick

The interesting bits, for people who know the OpenClaw stack:

  • 🧠 You talk straight to the agent. No LLM middleman rewriting your words. server.js calls 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 .vrm just 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.

Quickstart

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:8080

Open 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 .vrm avatar — none ship with the repo (most VRM licenses forbid redistribution). Grab or make one (see assets/avatars/README.md); it takes a minute.

The Studio — configure without touching JSON

/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.)

On a Meta Quest 3

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.

🙆 Actions & 📋 The Board

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.

🔒 Security

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.

🗺️ Where it's going

See the ROADMAP — streaming TTS, richer idle motion, a community action pack, a wall-mounted 3D Board, and more. Ideas and PRs very welcome.

🤝 Contributing

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.

🧱 Stack & credits

A-Frame · @pixiv/three-vrm · a zero-dependency Node proxy · OpenClaw (brain) · ElevenLabs (voice) · OpenAI (speech-to-text). Full attributions in CREDITS.md.

👤 Author

Created by Andrews EgasGitHub · LinkedIn.

📄 License

Source code: MIT. Third-party assets and the avatars you supply carry their own licenses — see CREDITS.md.

About

◐ Give your AI agents a body. Talk to your OpenClaw agents as 3D avatars in Mixed Reality (WebXR / Meta Quest 3).

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages