Prerequisites
- A working OpenClaw or Hermes Agent install (the host).
- A StandIn account (standin.komaa.com) - the hosted media bridge that joins the Teams call and connects to your plugin. No worker to run. A paid plan is not required to start: the free identity gives you one BYO-bot identity with 5 minutes of call time per day included.
-
A Teams identity for the bot. You have two ways to get one, and 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, no endpoint. Add the app, type
signin, and connect your agent from the StandIn portal. A Microsoft 365 admin approves calling once for the organization; chat works before that. - Bring your own Microsoft Teams bot (an Azure AD app) and connect it to StandIn - see Teams setup to create and upload it. 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, no endpoint. Add the app, type
The steps below show the bring-your-own-bot path, because it is the one with setup to describe. If
you installed StandIn from the Store, skip the Teams setup entirely: everything from Connect the
plugin to StandIn onward is identical.To try StandIn with no Teams identity at all (a shared bot joins a public meeting you generate),
use the Sandbox (community tier). It is metered: 5 minutes of bot time per day per room,
up to 5 new rooms per day, one bot per meeting, and a 7-day room link, with the call ending at the daily limit.
- A realtime voice provider key (for realtime mode) - e.g. OpenAI or Azure OpenAI. Streaming mode uses your host’s configured STT/TTS instead.
Install (one line)
The installer detects your OpenClaw or Hermes install, adds the matching plugin, and prompts for the settings (mode, shared secret, provider API key + model, inbound call policy). On a re-run every prompt defaults to your current configuration, so pressing Enter keeps each value. Linux / macOS / WSL--connection, --runtime, --mode, --secret,
--provider, --api-key, --model, --port, --messages-port) or set the matching STANDIN_*
environment variables.
For secrets (
--secret, --api-key), prefer the STANDIN_SECRET / STANDIN_API_KEY environment variables over
CLI flags, so the values do not land in your shell history. The installer never transmits your secrets: they are only
written to your local plugin config.StandIn Managed Bot
The default run sets up a bring-your-own-bot connection and pairs it with the portal. If you created a StandIn Managed Bot connection in the dashboard instead (see Connection modes), pass--connection managed and the
connection secret the dashboard showed you:
Linux / macOS / WSL
--runtime openclaw (or STANDIN_RUNTIME='openclaw') for OpenClaw. Without the flag the
installer asks Connection type interactively.
What is different in managed mode:
- The secret is the connection secret from the dashboard. The installer never generates one for a
managed connection: it is the key StandIn already signs with, so a made-up value would turn both
lanes off silently. Leave
--secretout and the installer prompts for it (masked), which also keeps it out of your shell history. - One secret, two lanes. The installer writes the calling lane (
9442) and the managed messages lane (9444,--messages-portto change it) into the plugin config, plus the StandIn gateway reply endpoint on Hermes. - Two funnel mounts. On Tailscale it mounts
/msteams/calling->127.0.0.1:9442and/msteams/messages->127.0.0.1:9444, then verifies both. The bring-your-own-bot chat lane (/api/messages->3978) is not mounted. On ngrok, cloudflared or devtunnel it prints the two mounts for you to make yourself; see Managed bot chat. - No pairing. The connection already exists, so the installer prints the two values to paste into
it in the dashboard: Agent calling URL = your public host (StandIn appends
/msteams/calling) and Agent chat URL =https://<your-public-host>/msteams/messages. Restart the runtime as the installer says, and calling switches on once your Microsoft 365 admin approves.
Connect your agent by pairing (recommended)
Pairing is the zero-config way to connect a subscribed identity: the installer exposes your voice endpoint, sends StandIn the exactwss://host:<voicePort> URL, and delivers the generated shared secret back
to the installer automatically. There are no ports to configure and nothing to copy by hand, which avoids
the most common first-call issue (a domain saved without its voice port, so StandIn dials the wrong port and
the bot silently never joins).
1
Run the installer and choose Pair
Run the one-line installer on the machine your agent runs on. When it asks
“Pair this agent with StandIn now?”, choose Pair. It prints an 8-character code.
2
Enter the code at standin.komaa.com/pair
Sign in at standin.komaa.com/pair and enter the code. StandIn shows you
the exact voice endpoint and port your agent proposed - confirm it and approve. If you run the official
msteams channel plugin, the installer already collected your Azure bot App ID, client secret, and
tenant from its config and sent them with the pairing, so the credential fields arrive pre-filled (the
secret is consumed server-side and never shown in the browser). Otherwise the installer prompts you for
them, or you type them here.
3
Done
The installer picks up the shared secret on its next poll and finishes. Your identity provisions and
StandIn dials your agent - you never type a voice URL, a port, or a secret.
At the approve step you choose what the pairing becomes: a paid identity (consumes a plan slot), a
free identity (your own Azure bot, 5 minutes/day included, one per account), or the sandbox
(no Azure bot at all - a shared StandIn bot joins a meeting StandIn generates; see the
Sandbox (community tier)).
Which plan am I on?
Four ways to run StandIn. The first two questions are whether you want to own the Teams bot, and whether you need calls to run longer than 5 minutes.
The free identity is the same BYO-bot setup as paid - your own bot, your own tenant, inbound calls
to your own Teams identity - with 5 minutes of call time per day, one per account, held alongside any
paid identities. Production runs on a paid plan, where calls are not time-capped.
The sandbox is the only option that needs no Teams identity of any kind: a shared StandIn bot joins
a public meeting StandIn generates, so anyone can join as a guest. See
Sandbox (community tier).
First chat message ignored? The two runtimes gate DMs differently. OpenClaw drops DMs from
unapproved senders silently by default (
dmPolicy: pairing) - approve yourself once with
openclaw pairing approve msteams <CODE>. Hermes replies to an unknown sender with a
pairing code instead of silence - approve it with hermes pairing approve teams <CODE>; only
when TEAMS_ALLOWED_USERS is set are unlisted senders dropped silently. See
Troubleshooting.Verify (optional)
Prefer not to pipe a script straight into your shell? Download it, review it, then run it:- macOS / Linux
- Windows (PowerShell)
Download:Review it:Run it:
standin.komaa.com. The installer never transmits your secrets; they
are only written to your local plugin config.
Manual install
Prefer to wire it up by hand? Pick your runtime:- OpenClaw (npm)
- Hermes (pip)
1
Install
The two registries carry different names: on npm it is
@komaa/openclaw-msteams-bridge (the
install above), on ClawHub the listing is clawhub:@komaa/msteams-bridge. Both install the
same plugin under the id msteams-bridge, so the config below is the same either way. See the
plugin README.2
Configure
Add a Full reference → OpenClaw configuration.
msteams-bridge entry to your OpenClaw config - secret must match the value you set in StandIn:3
Run + call
Start the gateway (
openclaw gateway run), then in your StandIn dashboard register your
Agent calling URL (wss://<your-public-host>/msteams/calling via a path-mapped funnel; local bind ws://<host>:9442/...) and the matching secret. Place a Teams call to your bot.4
Add the chat lane
Voice and chat are separate endpoints: chat is OpenClaw’s
msteams channel on
127.0.0.1:3978, published as /api/messages. Mount it and register the Agent chat URL
as described in Expose your agent. Voice-only? Skip this step;
nothing else changes.