Channels
How to Connect OpenClaw to Microsoft Teams
Browse more in Channels.
All channels guides →This guide walks you through connecting OpenClaw to Microsoft Teams using the built-in Microsoft Teams channel. You will create an Azure Bot, wire it to OpenClaw’s `/api/messages` webhook, and install a Teams app so your agents can respond in DMs, group chats, and channels.
By the end, you will have OpenClaw replying to Teams messages with text and DM attachments, with routing and access control configured safely.
Prerequisites
- ✓An existing OpenClaw installation with access to install and configure plugins.
- ✓An Azure subscription where you can create an Azure Bot resource.
- ✓Permissions in Microsoft Teams to upload a custom app package (sideload or via org catalog).
- ✓Ability to expose a public HTTPS URL for OpenClaw (for example a domain or a tunnel) so Azure Bot can reach `/api/messages` on port 3978.
- ✓Basic access to Microsoft Graph and Teams RSC permissions if you plan to use channels, group chats, or member info actions.
Steps
- 1
Ensure the Microsoft Teams plugin is available
First confirm that the Microsoft Teams plugin is present so OpenClaw can speak Bot Framework. Current packaged OpenClaw releases already bundle it, but older or custom builds may not.
If you are on an older build or running from a local checkout, install the plugin explicitly.
bashopenclaw plugins install @openclaw/msteams - 2
Install the Teams plugin from a local checkout when developing from source
If you run OpenClaw from a git repo and are iterating on the Teams plugin itself, point the plugin install at your local path. This keeps your OpenClaw instance in sync with local changes to the plugin code.
bashopenclaw plugins install ./path/to/local/msteams-plugin - 3
Create an Azure Bot for OpenClaw
You need an Azure Bot resource to bridge Teams traffic into OpenClaw. This step gives you the App ID, client secret, and tenant ID that OpenClaw uses to authenticate with Microsoft’s Bot Framework.
Use a Single Tenant bot to match the current recommendations.
textGo to https://portal.azure.com/#create/Microsoft.AzureBot Fill in the Basics tab: | Field | Value | | --- | --- | | Bot handle | Your bot name, e.g., `openclaw-msteams` (must be unique) | | Subscription | Select your Azure subscription | | Resource group | Create new or use existing | | Pricing tier | Free for dev/testing | | Type of App | Single Tenant | | Creation type | Create new Microsoft App ID | - 4
Get the Azure Bot credentials
Once the bot exists, you need to pull out the identifiers OpenClaw will use. These map directly to `appId`, `appPassword`, and `tenantId` in your OpenClaw config.
Keep the client secret safe; you will paste it into your config or environment variables.
text1. Go to your Azure Bot resource → Configuration 2. Copy Microsoft App ID → this is your `appId` 3. Click Manage Password → go to the App Registration 4. Under Certificates & secrets → New client secret → copy the Value → this is your `appPassword` 5. Go to Overview → copy Directory (tenant) ID → this is your `tenantId` - 5
Configure the Azure Bot messaging endpoint
Point the Azure Bot at your OpenClaw webhook so Teams messages actually reach your gateway. In production this is your public domain; for local development you’ll use a tunnel.
Make sure the path and port match what you configure in OpenClaw.
textProduction: https://your-domain.com/api/messages Local dev: Use a tunnel (see Local Development) such as https://abc123.ngrok.io/api/messages - 6
Expose OpenClaw locally with a tunnel for development
Teams cannot call localhost directly, so for local testing you need a tunnel that exposes port 3978 over HTTPS. ngrok and Tailscale Funnel are both supported options.
After starting the tunnel, paste the generated URL into the Azure Bot messaging endpoint.
bashngrok http 3978 # Copy the https URL, e.g., https://abc123.ngrok.io # Set messaging endpoint to: https://abc123.ngrok.io/api/messages - 7
Configure the Microsoft Teams channel in OpenClaw
Now wire the Azure Bot credentials into OpenClaw so the msteams channel can authenticate and listen on `/api/messages`. This minimal config enables the channel, sets the webhook port and path, and is enough to handle text and DM attachments.
You can later tighten access control and group policies.
json{ channels: { msteams: { enabled: true, appId: "<APP_ID>", appPassword: "<APP_PASSWORD>", tenantId: "<TENANT_ID>", webhook: { port: 3978, path: "/api/messages" }, }, }, } - 8
Optionally configure Teams access control and allowlists
Before you roll this out broadly, decide who can trigger the bot in DMs and groups. The default DM policy requires pairing, and group chats are blocked unless you add allowlists.
You can also scope replies to specific teams and channels using stable IDs.
json{ channels: { msteams: { groupPolicy: "allowlist", groupAllowFrom: ["user@org.com"], }, }, } { channels: { msteams: { groupPolicy: "allowlist", teams: { "My Team": { channels: { General: { requireMention: true }, }, }, }, }, }, } - 9
Build a Teams app manifest that references your bot
Teams needs an app package that declares your bot, scopes, and RSC permissions. json` like the example, add icons, and zip them together.
id match your Azure Bot App ID or Teams will reject the app.
json{ $schema: "https://developer.microsoft.com/en-us/json-schemas/teams/v1.23/MicrosoftTeams.schema.json", manifestVersion: "1.23", version: "1.0.0", id: "00000000-0000-0000-0000-000000000000", name: { short: "OpenClaw" }, developer: { name: "Your Org", websiteUrl: "https://example.com", privacyUrl: "https://example.com/privacy", termsOfUseUrl: "https://example.com/terms", }, description: { short: "OpenClaw in Teams", full: "OpenClaw in Teams" }, icons: { outline: "outline.png", color: "color.png" }, accentColor: "#5B6DEF", bots: [ { botId: "11111111-1111-1111-1111-111111111111", scopes: ["personal", "team", "groupChat"], isNotificationOnly: false, supportsCalling: false, supportsVideo: false, supportsFiles: true, }, ], webApplicationInfo: { id: "11111111-1111-1111-1111-111111111111", }, authorization: { permissions: { resourceSpecific: [ { name: "ChannelMessage.Read.Group", type: "Application" }, { name: "ChannelMessage.Send.Group", type: "Application" }, { name: "Member.Read.Group", type: "Application" }, { name: "Owner.Read.Group", type: "Application" }, { name: "ChannelSettings.Read.Group", type: "Application" }, { name: "TeamMember.Read.Group", type: "Application" }, { name: "TeamSettings.Read.Group", type: "Application" }, { name: "ChatMessage.Read.Chat", type: "Application" }, ], }, }, } - 10
Generate and upload the Teams app package
Once the manifest is ready, package it with the required icons and upload it into Teams. You can either hand-zip the files or use the Teams Developer Portal to generate the package for you.
After upload, install the app in personal, team, or group chat scopes where you want OpenClaw to respond.
textZip all three files together: manifest.json, outline.png, color.png. Or use the Teams Developer Portal: 1. Click + New app 2. Fill in basic info (name, description, developer info) 3. Go to App features → Bot 4. Select Enter a bot ID manually and paste your Azure Bot App ID 5. Check scopes: Personal, Team, Group Chat 6. Click Distribute → Download app package 7. In Teams: Apps → Manage your apps → Upload a custom app → select the ZIP - 11
Run the OpenClaw gateway and test the bot
With config and Teams app in place, start your OpenClaw gateway so the msteams channel can bind to the webhook. Use Azure Web Chat first to confirm the endpoint works, then send a DM in Teams and watch the gateway logs.
This helps you distinguish Teams manifest issues from webhook or auth problems.
textIn Azure Portal → your Azure Bot resource → Test in Web Chat 1. Send a message - you should see a response 2. This confirms your webhook endpoint works before Teams setup In Teams (after app installation): 1. Install the Teams app (sideload or org catalog) 2. Find the bot in Teams and send a DM 3. Check gateway logs for incoming activity
Configuration
| Option | Description | Example |
|---|---|---|
| channels.msteams.enabled | Turns the Microsoft Teams channel on so OpenClaw starts the Teams plugin and webhook listener. | |
| channels.msteams.appId | The Microsoft App ID from your Azure Bot resource used to authenticate with Bot Framework. | 11111111-1111-1111-1111-111111111111 |
| channels.msteams.appPassword | The client secret (App password) from your Azure App Registration used as the bot credential. | super-long-client-secret-value |
| channels.msteams.tenantId | The Directory (tenant) ID for your Azure AD tenant, required for single-tenant bots. | 22222222-2222-2222-2222-222222222222 |
| channels.msteams.webhook.port | The local port where OpenClaw listens for Bot Framework webhook traffic. | |
| channels.msteams.webhook.path | The HTTP path that receives Teams webhook requests from Azure Bot. | /api/messages |
| channels.msteams.configWrites | Controls whether Teams messages can update OpenClaw config via `/config set|unset` when commands.config is enabled. | |
| channels.msteams.dmPolicy | Defines how DM access is handled; by default unknown senders are ignored until approved. | pairing |
| channels.msteams.allowFrom | List of allowed sender IDs for DMs, typically stable AAD object IDs. | |
| channels.msteams.dangerouslyAllowNameMatching | Enables matching on UPNs/display names instead of stable IDs, which is disabled by default. | |
| channels.msteams.groupPolicy | Controls whether group chats and channels are open, allowlisted, or disabled. | allowlist |
| channels.msteams.groupAllowFrom | Controls which senders can trigger in group chats and channels, falling back to allowFrom when unset. | |
| channels.msteams.teams | Optional allowlist of teams and channels where the bot can respond, keyed by team and channel identifiers. | |
| channels.msteams.historyLimit | Number of recent channel/group messages to include as context in prompts (default 50, 0 disables). | |
| channels.msteams.dmHistoryLimit | Number of recent user turns in DMs to include as context. | |
| channels.msteams.actions.memberInfo | Enables the Graph-backed member-info action when Graph credentials are available. | |
| MSTEAMS_APP_ID | Environment variable alternative for channels.msteams.appId. | 11111111-1111-1111-1111-111111111111 |
| MSTEAMS_APP_PASSWORD | Environment variable alternative for channels.msteams.appPassword. | super-long-client-secret-value |
| MSTEAMS_TENANT_ID | Environment variable alternative for channels.msteams.tenantId. | 22222222-2222-2222-2222-222222222222 |
Troubleshooting
Teams app upload fails with manifest errors or the bot does not appear in the client.
This usually means required manifest fields do not match your Azure Bot. resourceSpecific` block includes the channel read/send permissions you need.
{
bots: [
{
botId: "11111111-1111-1111-1111-111111111111",
scopes: ["personal", "team", "groupChat"],
supportsFiles: true,
},
],
webApplicationInfo: {
id: "11111111-1111-1111-1111-111111111111",
},
authorization: {
permissions: {
resourceSpecific: [
{ name: "ChannelMessage.Read.Group", type: "Application" },
{ name: "ChannelMessage.Send.Group", type: "Application" },
{ name: "ChatMessage.Read.Chat", type: "Application" },
],
},
},
}The bot installs in Teams but never responds to messages in channels or group chats.
groupPolicy` is `allowlist`, group chats and channels are blocked unless you configure `groupAllowFrom` or a teams allowlist. Add the appropriate users or teams to the allowlist, or set `groupPolicy: "open"` if you want any member to trigger the bot (still mention-gated by default).
{
channels: {
msteams: {
groupPolicy: "allowlist",
groupAllowFrom: ["user@org.com"],
},
},
}DMs to the bot are ignored even though the app is installed.
dmPolicy = "pairing"`, which ignores unknown senders until they are approved. allowFrom` or adjust your DM policy, and avoid relying on display names unless you explicitly enable `dangerouslyAllowNameMatching`.
{
channels: {
msteams: {
dmPolicy: "pairing",
allowFrom: ["user-aad-object-id-1"],
},
},
}Channel or group file uploads do not work, but DM attachments are fine.
Current status is that text and DM attachments are supported, while channel/group file sending requires `sharePointSiteId` and Graph permissions. If you only configured Teams RSC and not the additional Graph permissions and SharePoint settings, channel/group file contents will not be available.
Status: text + DM attachments are supported; channel/group file sending requires `sharePointSiteId` + Graph permissions (see Sending files in group chats).Frequently asked questions
Powered by Mem0
Add persistent memory to OpenClaw
Official Mem0 plugin for OpenClaw keeps context across chats and tools. Smaller prompts, lower cost, better continuity for your agents.