Skip to main content
You are building a LiveKit agent server: a program that joins a room and runs a voice conversation. Chert connects that room to FaceTime. This example uses JavaScript and OpenAI Realtime; change its instructions to build a tutor, interview coach, or another voice experience. Use macOS or Linux with Node 22.23.2 or 24.x and npm. Check node --version and npm --version. Install Node from nodejs.org or follow your organizer’s setup instructions. If you already use nvm:

1. Create your accounts and choose a name

  1. Create a LiveKit Cloud account and a project. Obtain its URL, API key and API secret from the project’s settings.
  2. Obtain a model API key with access and credits for OpenAI Realtime. This is separate from your LiveKit and Chert credentials; a ChatGPT subscription is not an API key. See the LiveKit Realtime integration.
  3. Choose a dispatch name, such as team-otter-agent. Use that exact name in the env file and in chert dev --agent team-otter-agent.
  4. Get your Chert project access, UUID and assigned FaceTime address from your organizer. See Projects and lines.
Your LiveKit project could be called Otter Hackathon; your agent can still be team-otter-agent. These labels do not need to match. Give other agents in the same LiveKit project different dispatch names unless you intentionally run interchangeable copies of the same agent.

2. Create the local project

Use a new directory:
Create the following files in your editor. This page includes all required source; you do not need access to a private GitHub repository.

package.json

.gitignore

Create this before adding credentials or committing your project:

.env.local

Paste these placeholders into the file, then replace them privately in your editor:
All three LIVEKIT_* values must come from the same project. Both your agent and Chert will use that project. Keep the file private:
Never commit the file, paste its values into chat, or execute it with source. The startup command uses Node’s env-file parser. Chert reads its LiveKit values; your agent uses the model key. Existing shell variables override env-file values, so avoid stale credentials in your terminal environment.

agent.mjs

Change the instructions text to define your agent’s personality and purpose. Keep replies short enough for a spoken conversation.

3. Install and start

This creates package-lock.json; keep that file with your project and use npm ci for subsequent fresh installs. Wait for successful LiveKit registration and leave this terminal running. This starter does not automatically reload edits. npm start runs your agent and registers the dispatch name with LiveKit. The starter reads AGENT_NAME and explicitly passes it as ServerOptions.agentName. There is no separate manual registration command for this local flow.

4. Connect it to FaceTime

Open a second terminal, select the same Node version, and follow Connect and test to install Chert, sign in, and check your connection. CLI beta.3 reads the LiveKit keys from this folder automatically; separate setup is optional. Your everyday Chert command will be:
The agent program and Chert must both remain running. After the waiting-room message, call your assigned line using FaceTime Audio and say hello first.

Why the starter waits

Chert may dispatch a job before a caller exists, for prewarming or diagnostics. The agent joins promptly, waits for a participant, and then opens the model session. It does not automatically greet when a job starts: participant arrival alone does not prove FaceTime audio is ready. Letting the caller speak first avoids losing the greeting during connection. The starter listens to the caller’s audio, leaves room deletion to Chert, and closes the model session on shutdown. Generic rooms allow two participants; adding an avatar or sidecar participant needs a separate integration.

Already have a TypeScript agent?

Keep your existing build/start commands. Set LiveKit’s ServerOptions.agentName to your chosen dispatch name, use the same LiveKit project credentials as Chert, and allow jobs to connect promptly even when a caller has not arrived yet. Avoid an unconditional greeting on job startup. Then follow the same CLI steps. The official LiveKit Node starter provides a TypeScript project structure if you prefer one.
This is an audio starter. Installation, syntax and SDK compatibility checks do not establish working FaceTime media. Complete the two-call test on your assigned line before presenting it or building additional features.