Microsoft Teams Bridge for OpenAI Realtime Agents
Welcome! @komaa/openai-msteams-bridge (npm: @komaa/openai-msteams-bridge) puts an OpenAI Realtime voice agent (gpt-realtime) on a real Microsoft Teams call.
It is a small Node.js service (and importable TypeScript library) that sits between two WebSockets:
flowchart LR
Teams["Microsoft Teams<br/>call"]
StandIn["StandIn media bridge<br/>(hosted service)"]
Bridge["this bridge<br/>(yours)"]
OAI["OpenAI Realtime API<br/>speech-to-speech:<br/>STT + LLM + TTS + VAD"]
Teams <--> StandIn
StandIn -- "HMAC WS, PCM 16k" --> Bridge
Bridge -- "WS, PCM 24k" --> OAI
The hosted StandIn media bridge (standin.komaa.com) joins the Teams call and dials into your bridge, one authenticated WebSocket per call. The bridge opens one OpenAI Realtime session per call and relays between them. The Teams wire is base64 PCM 16 kHz mono; the Realtime API speaks PCM 24 kHz only, so the bridge converts at that one boundary with a built-in anti-aliased resampler - no codecs, no external dependencies, one relay hop plus a linear resample in the latency budget.
What it does
Section titled “What it does”- Realtime voice - the caller talks to a
gpt-realtimeagent and hears it reply. Turn-taking, VAD and interruption are the model’s own (server_vadorsemantic_vad); the bridge maps the caller’s barge-in onto the Teams side and drops stale “ghost” audio so nothing plays after an interruption. - Per-call personalization - caller name, tenant and direction are appended to the session instructions; an optional deterministic opening line (
OPENAI_FIRST_MESSAGE) is spoken as the first response. - Vision on demand - the agent’s
looktool sees the caller’s camera or screen-share: your own vision model (path 2) or native Realtime image input (path 1, recording-gated). - Built-in agent tools -
end_call,express(avatar emotion),show_image(image on the bot’s tile, SSRF-guarded),look. Registered automatically on every session; no per-agent dashboard setup. - Extensible tools - register your own function tools the bridge executes, or pass remote MCP servers the Realtime API executes server-side. See Extending the Agent’s Tools.
- Two call governors - StandIn-side tier cutoffs get a spoken goodbye; a bridge-side
MAX_CALL_MINUTEShard cap protects your OpenAI budget (and beats the Realtime API’s own 60-minute session ceiling to a graceful ending). - Hardened transport - replay-proof HMAC handshake, connection and payload caps, duplicate-call rejection, dead-peer detection, graceful drain, and an OpenAI host allowlist so your API key can never be sent elsewhere.
Use the sidebar to navigate. Start with Getting Started, or jump to the Configuration Reference or Wire Protocol. There is also a runnable example project in the repository showing a custom vision hook and a custom lookup_order tool.