Integration Guide

Six ways to connect Open Face to your agent stack.

1. OpenClaw Plugin

Best for: local coding agents using OpenClaw

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

Best for: Claude Desktop, VS Code, JetBrains integrations

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

Best for: custom stacks, Python, Go, shell scripts, automation

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

Best for: websites, dashboards, kiosks, overlays

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)

Best for: fastest path — no server to run, no deploy, just claim and push

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

Best for: private deployments with your own domain and infrastructure

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