Prerequisites
- A StandIn identity at standin.komaa.com. This is the hosted service that joins the Microsoft Teams call and dials your worker.
-
A Microsoft Teams identity for the bot. This is the choice that decides how much Azure work you do:
- Install StandIn from the Microsoft Teams Store. No Azure app registration, no App ID, no
client secret. Add the app, type
signin, and connect your agent from the StandIn portal. A Microsoft 365 admin approves calling once for the organization. - Bring your own Microsoft Teams bot (an Azure Entra app) and connect it to StandIn. See Microsoft Teams setup. Choose this when the bot must carry your own name and live entirely in your tenant.
- Install StandIn from the Microsoft Teams Store. No Azure app registration, no App ID, no
client secret. Add the app, type
- Python 3.10 or newer, or Node.js 20 or newer, depending on which SDK you use. The OpenClaw plugin follows its host and wants Node 22.19, but that travels with the plugin and nothing else in the TypeScript SDK asks for it.
- A way to publish one local port over HTTPS: a tunnel such as Tailscale Funnel, or an ingress. Expose your agent covers both.
1. Run the echo
The echo plugin sends the caller’s voice back. Run one of these, not both.STANDIN_SECRET is the connection secret from your StandIn identity, and it is what arms the
listener: without it the SDK refuses to start rather than serving an unauthenticated socket.
STANDIN_HOST=127.0.0.1 keeps the listener on loopback so only your tunnel reaches it. The SDK’s
own default is 0.0.0.0, which is right for a container behind an ingress and wrong for a laptop.
The listener now sits on port 9442 at path /msteams/calling.
Prove it before you expose anything. The SDK ships an install check that rings your own handler
on loopback: it binds an ephemeral listener, speaks the real call wire to it, streams a few frames
and reports whether audio came back, with no tunnel, no provider bill and no Microsoft tenant
involved. It is the fastest answer to “is my install working”, and it is worth running before the
first real call rather than after it: Checking the install in
Python, Checking the install in TypeScript.
2. Publish the port
StandIn dials you from the internet, so a loopback-only listener is invisible to it. Publish port9442 at /msteams/calling, and keep the path in the proxy target or the request reaches your
worker stripped. Expose your agent carries the one copy of the mount
command, plus the ngrok, cloudflared and devtunnel equivalents.
Confirm the mount, and probe it, before you register anything. A registered mount is not a working
mount, and a probe sent without --http1.1 never arrives as an upgrade at all, so whatever it
answers proves nothing: Probe it by hand.
3. Register the agent voice URL
In your StandIn identity, set the agent voice URL to the public address of that path:STANDIN_SECRET: a mismatch fails the HMAC
handshake silently, which is the single most common first-call failure.
4. Call it
Call your StandIn identity from Microsoft Teams and talk. You should hear yourself back. If nothing happens, work through Troubleshooting top to bottom: secret, reachability, address. Do not start by suspecting the SDK.Configuration
The SDK reads its settings from the environment and ships no config file of its own. A plugin that runs inside another runtime is configured by that runtime instead, which is why the OpenClaw plugin takes its secret and its port from OpenClaw’s own config block rather than from any of the variables below. These are the variables this page uses:
Those are the ones the echo and the chat lane need, not the whole list: placing a call, vision,
sending a picture and the on-disk state directory each read their own, and the two SDKs do not read
an identical set. Every
STANDIN_ variable each one reads is tabulated in one place, so a
deployment is not configured out of nine pages:
Configuration in Python,
Configuration in TypeScript.
Next
Python SDK
The handler contract, the audio helpers, the chat lane, and the LiveKit and Hermes plugins.
TypeScript SDK
The same contract in TypeScript, and the OpenClaw plugin.
Architecture
What the SDK owns, what you own, and what crosses the wire.
Microsoft Teams setup
The Azure bot, the app package, and the admin consent calling needs.