examples/basic-bridge
loadConfig() + startServer() and nothing else - about 20 lines, because the agent’s brain
(LLM, tools, conversation logic) lives in your Line deployment on Cartesia, not in the bridge.
Env-file config and graceful shutdown are built in.What you need first
- Node.js
>= 20. - A Cartesia API key and a deployed Line agent (its agent id) - docs.cartesia.ai/line.
- A StandIn identity with its shared secret (from pairing or the dashboard). The sandbox works too if you have no Teams bot yet.
1. Clone and install
2. Configure
| Variable | What to put there |
|---|---|
CARTESIA_API_KEY | Your Cartesia API key (server-side only; each call mints a short-lived token, so the key never rides the agent socket). |
CARTESIA_AGENT_ID | The deployed Line agent that should answer calls. |
WORKER_SHARED_SECRET | The shared secret from StandIn pairing - both sides must match exactly. |
3. Run and expose
8080. Expose it with a tunnel (Tailscale Funnel, Cloudflare Tunnel,
ngrok, dev tunnels - see the installation page) and note the public
wss://…/voice/msteams/stream URL.
4. Connect to StandIn and call
Set your identity’s Agent voice URL to thatwss:// URL in the
dashboard (or use the
sandbox), then place a Teams call. In the logs you should see:
Where the interesting parts live
Unlike the other bridges’ examples there is no vision hook or custom tool to study here - those belong in your Line agent code on Cartesia’s platform. What the bridge forwards to it (caller metadata,call_context and goodbye_request custom events, native DTMF) is documented on the
project site:
Your Line Agent - the contract
The start metadata and custom-event shapes your agent code receives, how to detect a Teams call
(
metadata.from == "msteams"), and the transfer_call limitation.Before production: set the governor variables
(
MAX_CALL_MINUTES, CARTESIA_TTS_MODEL + CARTESIA_TTS_VOICE_ID, GOODBYE_TEXT) so time
limits end with a spoken goodbye instead of silence.