OpenClaw on Microsoft Teams
The bundled plugin, the one-command Teams CLI setup, the tunnel, DM pairing and allowlists, the team-id gotcha, reply styles, and why group files need SharePoint
Microsoft Teams is a bundled OpenClaw channel plugin: text and DM attachments work, polls and approval prompts travel as Adaptive Cards, and sending files into channels or group chats needs a SharePoint site id plus Graph permissions. The docs split it across eight pages; this post follows the three that decide whether the bot works at all: setup, access control and message behaviour. Here is the quick setup and the manual path, the tunnel, DM and group policy, the id gotcha, private channels, routing and reply styles, and attachments and file sending.
Setup
- The Teams CLI does registration, manifest and credentials in one go: install it under its preview tag, log in and check status, start a tunnel because Teams cannot reach localhost, a persistent dev tunnel with anonymous access allowed since Teams cannot authenticate to it while each bot request is still validated by the SDK, then create the app with a name and the tunnel endpoint; that creates the Entra application, a client secret, a manifest with icons and a Teams-managed bot with no Azure subscription, and prints the client id, secret, tenant id and Teams app id.
- Configure OpenClaw with the app id, password and tenant id and a webhook port and path, or the matching environment variables; install the app in Teams from the prompt or the install link; and run the CLI doctor, which checks bot registration, the AAD app, the manifest and SSO in one pass. For production the docs point to federated authentication with a certificate or managed identity instead of a client secret.
- The manual path creates an Azure Bot, single-tenant since multi-tenant creation was deprecated after July 2025, copies the app id, a client secret and the tenant id, sets the messaging endpoint, enables the Teams channel, builds an app package with a bot entry, personal, team and group-chat scopes, file support and the RSC permissions, and configures OpenClaw the same way; the Gateway listens for Bot Framework webhook traffic on the messages path and starts the channel as soon as credentials exist.
- Local development keeps a persistent tunnel so the URL survives sessions, and a changed tunnel URL is pushed with the app update command; testing is the doctor command, then a DM to the bot while watching the Gateway logs.
The groupId query parameter in Teams URLs is NOT the team ID used for configuration.
Access control
Teams has one account per channel configuration. DMs default to pairing mode, so unknown senders are ignored until approved, and the allowlist should use stable AAD object ids or static access groups rather than names, since name matching is disabled by default and only opt-in; the wizard can resolve names to ids through Graph. Groups default to allowlist, blocked until a group allow-from list names senders, access groups or conversation ids in the thread formats with their exact casing, and conversation ids never grant DM access; open admits any member, still mention-gated, and disabled blocks all channels. A teams map scopes replies to listed teams and channels keyed by their conversation ids, and when the policy is allowlist and a teams map exists only listed teams and channels are accepted; group senders and delegated Graph reads are different things, so a configuration that only sets senders should keep the allowlist policy and add the target channel under the teams map. The gotcha: the group id query parameter in a Teams URL is the Entra group id, not the Bot Framework conversation id, so the team key is the URL-decoded path segment after the team segment and the channel key the one after the channel segment. Private channels have limited bot support, real-time webhook messages may not arrive, and the workarounds are standard channels, DMs, or Graph history with the channel-message read permission.
Messages and files
- Session keys follow the standard format, DMs sharing the main session and channel and group messages keyed by conversation id. Teams has two channel UI styles over one data model and the API does not say which a channel uses, so a reply style is configured: thread for classic posts, top-level for Slack-like threads channels, resolved per channel, then per team, then globally, then implicitly from the mention requirement, and pinned globally to avoid mentions in posts channels surfacing as top-level posts; proactive sends into group and personal conversations always resolve to top-level. In thread style the original thread root is re-attached so replies land in the same thread, including proactive sends after the turn context expired.
- Outbound mentions use a name-in-brackets-then-id syntax with escaped brackets; DM images and files work through the bot file APIs, while channel and group attachments live in Microsoft 365 storage and arrive as an HTML stub unless Graph permissions allow the download, media is only fetched from Microsoft hosts by default, and authorisation headers only go to Graph and Bot Framework hosts.
- Files in DMs use the file-consent card flow and images embed inline anywhere, but files in group chats and channels upload to a SharePoint site because bots use an application identity that cannot use the signed-in user resource: add the sites read-write and a chat-member read permission, grant admin consent, look up the site id through Graph, and configure it. Channels get an organisation-wide sharing link, group chats a per-user link only for chat members, and a group send without a supported member-read grant fails closed rather than widening access; uploads land in a shared folder in the site’s default library.
OpenClaw on Slack and OpenClaw on Discord are the two workplace channels with the same allowlist and mention model and simpler file handling.
On Diali
Microsoft Teams is not among the channels Diali connects today: WhatsApp, Telegram, Discord, Slack, Mattermost, Matrix, SMS and voice. Connect your first channel in five minutes explains how those are linked, and Diali security the boundary that applies to each.
The other five pages
The remaining Teams pages cover certificate and managed-identity authentication, the manifest and the RSC versus Graph permission split, the configuration keys and history limits, cards and actions from approvals to polls and member info, and troubleshooting from manifest upload errors to webhook timeouts. Hosted OpenClaw on Diali is the assistant and OpenClaw plugins the surface the bundled Teams plugin ships in.
- One CLI command, one tunnel, one doctor.
- Object ids, not names; path segments, not the group id.
- DM files just work; group files need SharePoint.
Stop reading about it, build one
Set up an agent, pick a channel, and have it working inside the app you already keep open.
