Skip to content

Microsoft Teams Bridge for LiveKit Agents (Python)

Welcome! livekit-msteams-bridge (PyPI: livekit-msteams-bridge) puts a LiveKit Agent - including avatar agents - on a real Microsoft Teams call.

It is a small asyncio service (and importable Python library) that sits between a WebSocket and a LiveKit room:

flowchart LR
    Teams["Microsoft Teams<br/>call"]
    StandIn["StandIn media bridge<br/>(hosted service)"]
    Bridge["this bridge<br/>(yours)"]
    Room["LiveKit room<br/>(one per call)"]
    Agent["your LiveKit agent<br/>(dispatched worker)"]
    Teams <--> StandIn
    StandIn -- "HMAC WS" --> Bridge
    Bridge -- "publish / subscribe" --> Room
    Agent -- "joins via dispatch" --> Room

The hosted StandIn media bridge (standin.komaa.com) joins the Teams call and dials into your bridge, one authenticated WebSocket per call. The bridge creates a fresh LiveKit room per call, dispatches your agent into it, joins as a participant, and relays audio between the Teams side and the room. The worker speaks 16 kHz mono PCM16 natively; the room side uses the SDK’s resampling AudioSource/AudioStream - the bridge itself never transcodes.

  • Any LiveKit agent, unchanged - your agent needs no Teams-specific code. It is dispatched into a normal room and hears a normal audio track; VAD, turn-taking and interruption run inside your agent session exactly as for WebRTC callers.
  • Explicit dispatch - one room per call, your named agent dispatched into it with per-call metadata (caller name, tenant, direction, AAD id when known) in ctx.job.metadata.
  • Data-topic context - teams.context (participant counts, DTMF, recording state) and teams.goodbye (the governor’s goodbye line for your agent to speak).
  • Avatar-aware - the bridge relays the agent’s voice even when an avatar republishes it, binds “the agent” by participant kind (not first-audio-wins), and survives track republishes.
  • Two call governors - StandIn-side tier cutoffs and a bridge-side MAX_CALL_MINUTES hard cap, both funneling into one agent-spoken goodbye.
  • Hardened transport - replay-proof HMAC handshake, connection and payload caps, duplicate-call rejection, dead-peer detection, graceful SIGTERM drain, Prometheus /metrics.

Use the sidebar to navigate. Start with Getting Started, or run the example to see a full working setup (voice agent + bridge), then jump to Agents and Dispatch or the Configuration Reference.