Integration Guide
Six ways to connect Open Face to your agent stack.
1. OpenClaw Plugin
The plugin maps OpenClaw lifecycle events directly into face states and emotions. It handles thinking, working, speaking, and idle transitions automatically.
# Install the plugin cp -r packages/plugin ~/.openclaw/plugins/openface # Start the face server bun run dev # Open the dashboard open http://localhost:9999/dashboard
The plugin uses the single-authority model: it owns state transitions, TTS owns audio, the viewer owns amplitude. It never pushes amplitude directly.
2. Claude / MCP Tools
Expose 8 face control tools to any Claude-compatible MCP client. Claude can set states, trigger speech, control gaze, and emote — all through natural language.
# Start MCP bridge
FACE_URL=http://127.0.0.1:9999 bun packages/mcp/src/index.ts
Tools: set_face_state, face_speak, set_face_look, face_wink, set_face_progress, face_emote, get_face_state, face_reset.
3. HTTP / WebSocket
Push state updates from any runtime via REST or WebSocket. Works with any language that can send JSON.
# Push a state update curl -X POST http://127.0.0.1:9999/api/state \ -H "Content-Type: application/json" \ -d '{"state":"speaking","emotion":"happy","text":"Hello!"}' # Or use the TypeScript client import { OpenFaceClient } from "@openface/client"; const face = new OpenFaceClient("http://127.0.0.1:9999"); await face.setState({ state: "thinking", emotion: "happy" }); await face.speaking("Hello world!");
See the API Reference for all endpoints.
4. Web Component
Drop a single script tag and custom element into any HTML page. Works standalone (local animation) or server-backed (live WebSocket).
<!-- Load the component --> <script type="module" src="open-face.js"></script> <!-- Standalone (no server needed) --> <open-face face="default" state="idle" emotion="neutral"></open-face> <!-- Server-backed (live updates) --> <open-face server="ws://localhost:9999/ws/viewer" face="default"></open-face>
Attributes: face, state, emotion, amplitude, server, style-variant, volume, debug-overlay.
5. oface.io (Hosted Faces)
Claim a permanent face URL at oface.io. Get an API key, push state via HTTP, and anyone can view your face at oface.io/username. Each face runs on its own Durable Object with WebSocket Hibernation — idle faces cost nothing.
# 1. Claim a face curl -X POST https://oface.io/api/claim \ -H "Content-Type: application/json" \ -d '{"username":"alice","face":"zen"}' # → { "ok": true, "apiKey": "oface_ak_...", "url": "https://oface.io/alice" } # 2. Push state curl -X POST https://oface.io/alice/api/state \ -H "Authorization: Bearer oface_ak_..." \ -H "Content-Type: application/json" \ -d '{"state":"speaking","emotion":"happy","text":"Hello!"}' # 3. View at oface.io/alice open https://oface.io/alice # 4. Configure via dashboard open https://oface.io/alice/dashboard
Check availability before claiming: GET https://oface.io/api/check/alice. Persistent config (face pack, head, body) via GET/PUT /{username}/api/config. See the oface.io API Reference for full details.
6. Self-Hosted Cloudflare Edge
Deploy the same edge server to your own Cloudflare account. Each room gets an isolated Durable Object with WebSocket connections (up to 50 viewers, 5 agents).
# Deploy to Cloudflare
cd packages/server-edge
wr deploy
Rooms are created on demand: /room/my-room/ws/viewer. Same protocol, same behavior, deployed at the edge.
Quick Reference
# Start everything locally bun install bun run dev # Build + start server on :9999 # Open face viewer open http://localhost:9999 # Open dashboard open http://localhost:9999/dashboard # Run tests bun run test # 330+ tests