{ "title": "Microsoft Teams (plugin)", "content": "> \"Abandon all hope, ye who enter here.\"\n\nStatus: text + DM attachments are supported; channel/group file sending requires `sharePointSiteId` + Graph permissions (see [Sending files in group chats](#sending-files-in-group-chats)). Polls are sent via Adaptive Cards.\n\nMicrosoft Teams ships as a plugin and is not bundled with the core install.\n\n**Breaking change (2026.1.15):** MS Teams moved out of core. If you use it, you must install the plugin.\n\nExplainable: keeps core installs lighter and lets MS Teams dependencies update independently.\n\nInstall via CLI (npm registry):\n\nLocal checkout (when running from a git repo):\n\nIf you choose Teams during configure/onboarding and a git checkout is detected,\nOpenClaw will offer the local install path automatically.\n\nDetails: [Plugins](/plugin)\n\n## Quick setup (beginner)\n\n1. Install the Microsoft Teams plugin.\n2. Create an **Azure Bot** (App ID + client secret + tenant ID).\n3. Configure OpenClaw with those credentials.\n4. Expose `/api/messages` (port 3978 by default) via a public URL or tunnel.\n5. Install the Teams app package and start the gateway.\n\nNote: group chats are blocked by default (`channels.msteams.groupPolicy: \"allowlist\"`). To allow group replies, set `channels.msteams.groupAllowFrom` (or use `groupPolicy: \"open\"` to allow any member, mention-gated).\n\n* Talk to OpenClaw via Teams DMs, group chats, or channels.\n* Keep routing deterministic: replies always go back to the channel they arrived on.\n* Default to safe channel behavior (mentions required unless configured otherwise).\n\nBy default, Microsoft Teams is allowed to write config updates triggered by `/config set|unset` (requires `commands.config: true`).\n\n## Access control (DMs + groups)\n\n* Default: `channels.msteams.dmPolicy = \"pairing\"`. Unknown senders are ignored until approved.\n* `channels.msteams.allowFrom` accepts AAD object IDs, UPNs, or display names. The wizard resolves names to IDs via Microsoft Graph when credentials allow.\n\n* Default: `channels.msteams.groupPolicy = \"allowlist\"` (blocked unless you add `groupAllowFrom`). Use `channels.defaults.groupPolicy` to override the default when unset.\n* `channels.msteams.groupAllowFrom` controls which senders can trigger in group chats/channels (falls back to `channels.msteams.allowFrom`).\n* Set `groupPolicy: \"open\"` to allow any member (still mention‑gated by default).\n* To allow **no channels**, set `channels.msteams.groupPolicy: \"disabled\"`.\n\n**Teams + channel allowlist**\n\n* Scope group/channel replies by listing teams and channels under `channels.msteams.teams`.\n* Keys can be team IDs or names; channel keys can be conversation IDs or names.\n* When `groupPolicy=\"allowlist\"` and a teams allowlist is present, only listed teams/channels are accepted (mention‑gated).\n* The configure wizard accepts `Team/Channel` entries and stores them for you.\n* On startup, OpenClaw resolves team/channel and user allowlist names to IDs (when Graph permissions allow)\n and logs the mapping; unresolved entries are kept as typed.\n\n1. Install the Microsoft Teams plugin.\n2. Create an **Azure Bot** (App ID + secret + tenant ID).\n3. Build a **Teams app package** that references the bot and includes the RSC permissions below.\n4. Upload/install the Teams app into a team (or personal scope for DMs).\n5. Configure `msteams` in `~/.openclaw/openclaw.json` (or env vars) and start the gateway.\n6. The gateway listens for Bot Framework webhook traffic on `/api/messages` by default.\n\n## Azure Bot Setup (Prerequisites)\n\nBefore configuring OpenClaw, you need to create an Azure Bot resource.\n\n### Step 1: Create Azure Bot\n\n1. Go to [Create Azure Bot](https://portal.azure.com/#create/Microsoft.AzureBot)\n2. Fill in the **Basics** tab:\n\n| Field | Value |\n | ------------------ | -------------------------------------------------------- |\n | **Bot handle** | Your bot name, e.g., `openclaw-msteams` (must be unique) |\n | **Subscription** | Select your Azure subscription |\n | **Resource group** | Create new or use existing |\n | **Pricing tier** | **Free** for dev/testing |\n | **Type of App** | **Single Tenant** (recommended - see note below) |\n | **Creation type** | **Create new Microsoft App ID** |\n\n> **Deprecation notice:** Creation of new multi-tenant bots was deprecated after 2025-07-31. Use **Single Tenant** for new bots.\n\n3. Click **Review + create** → **Create** (wait \\~1-2 minutes)\n\n### Step 2: Get Credentials\n\n1. Go to your Azure Bot resource → **Configuration**\n2. Copy **Microsoft App ID** → this is your `appId`\n3. Click **Manage Password** → go to the App Registration\n4. Under **Certificates & secrets** → **New client secret** → copy the **Value** → this is your `appPassword`\n5. Go to **Overview** → copy **Directory (tenant) ID** → this is your `tenantId`\n\n### Step 3: Configure Messaging Endpoint\n\n1. In Azure Bot → **Configuration**\n2. Set **Messaging endpoint** to your webhook URL:\n * Production: `https://your-domain.com/api/messages`\n * Local dev: Use a tunnel (see [Local Development](#local-development-tunneling) below)\n\n### Step 4: Enable Teams Channel\n\n1. In Azure Bot → **Channels**\n2. Click **Microsoft Teams** → Configure → Save\n3. Accept the Terms of Service\n\n## Local Development (Tunneling)\n\nTeams can't reach `localhost`. Use a tunnel for local development:\n\n```bash theme={null}\nngrok http 3978", "code_samples": [ { "code": "Local checkout (when running from a git repo):", "language": "unknown" }, { "code": "If you choose Teams during configure/onboarding and a git checkout is detected,\nOpenClaw will offer the local install path automatically.\n\nDetails: [Plugins](/plugin)\n\n## Quick setup (beginner)\n\n1. Install the Microsoft Teams plugin.\n2. Create an **Azure Bot** (App ID + client secret + tenant ID).\n3. Configure OpenClaw with those credentials.\n4. Expose `/api/messages` (port 3978 by default) via a public URL or tunnel.\n5. Install the Teams app package and start the gateway.\n\nMinimal config:", "language": "unknown" }, { "code": "Note: group chats are blocked by default (`channels.msteams.groupPolicy: \"allowlist\"`). To allow group replies, set `channels.msteams.groupAllowFrom` (or use `groupPolicy: \"open\"` to allow any member, mention-gated).\n\n## Goals\n\n* Talk to OpenClaw via Teams DMs, group chats, or channels.\n* Keep routing deterministic: replies always go back to the channel they arrived on.\n* Default to safe channel behavior (mentions required unless configured otherwise).\n\n## Config writes\n\nBy default, Microsoft Teams is allowed to write config updates triggered by `/config set|unset` (requires `commands.config: true`).\n\nDisable with:", "language": "unknown" }, { "code": "## Access control (DMs + groups)\n\n**DM access**\n\n* Default: `channels.msteams.dmPolicy = \"pairing\"`. Unknown senders are ignored until approved.\n* `channels.msteams.allowFrom` accepts AAD object IDs, UPNs, or display names. The wizard resolves names to IDs via Microsoft Graph when credentials allow.\n\n**Group access**\n\n* Default: `channels.msteams.groupPolicy = \"allowlist\"` (blocked unless you add `groupAllowFrom`). Use `channels.defaults.groupPolicy` to override the default when unset.\n* `channels.msteams.groupAllowFrom` controls which senders can trigger in group chats/channels (falls back to `channels.msteams.allowFrom`).\n* Set `groupPolicy: \"open\"` to allow any member (still mention‑gated by default).\n* To allow **no channels**, set `channels.msteams.groupPolicy: \"disabled\"`.\n\nExample:", "language": "unknown" }, { "code": "**Teams + channel allowlist**\n\n* Scope group/channel replies by listing teams and channels under `channels.msteams.teams`.\n* Keys can be team IDs or names; channel keys can be conversation IDs or names.\n* When `groupPolicy=\"allowlist\"` and a teams allowlist is present, only listed teams/channels are accepted (mention‑gated).\n* The configure wizard accepts `Team/Channel` entries and stores them for you.\n* On startup, OpenClaw resolves team/channel and user allowlist names to IDs (when Graph permissions allow)\n and logs the mapping; unresolved entries are kept as typed.\n\nExample:", "language": "unknown" }, { "code": "## How it works\n\n1. Install the Microsoft Teams plugin.\n2. Create an **Azure Bot** (App ID + secret + tenant ID).\n3. Build a **Teams app package** that references the bot and includes the RSC permissions below.\n4. Upload/install the Teams app into a team (or personal scope for DMs).\n5. Configure `msteams` in `~/.openclaw/openclaw.json` (or env vars) and start the gateway.\n6. The gateway listens for Bot Framework webhook traffic on `/api/messages` by default.\n\n## Azure Bot Setup (Prerequisites)\n\nBefore configuring OpenClaw, you need to create an Azure Bot resource.\n\n### Step 1: Create Azure Bot\n\n1. Go to [Create Azure Bot](https://portal.azure.com/#create/Microsoft.AzureBot)\n2. Fill in the **Basics** tab:\n\n | Field | Value |\n | ------------------ | -------------------------------------------------------- |\n | **Bot handle** | Your bot name, e.g., `openclaw-msteams` (must be unique) |\n | **Subscription** | Select your Azure subscription |\n | **Resource group** | Create new or use existing |\n | **Pricing tier** | **Free** for dev/testing |\n | **Type of App** | **Single Tenant** (recommended - see note below) |\n | **Creation type** | **Create new Microsoft App ID** |\n\n> **Deprecation notice:** Creation of new multi-tenant bots was deprecated after 2025-07-31. Use **Single Tenant** for new bots.\n\n3. Click **Review + create** → **Create** (wait \\~1-2 minutes)\n\n### Step 2: Get Credentials\n\n1. Go to your Azure Bot resource → **Configuration**\n2. Copy **Microsoft App ID** → this is your `appId`\n3. Click **Manage Password** → go to the App Registration\n4. Under **Certificates & secrets** → **New client secret** → copy the **Value** → this is your `appPassword`\n5. Go to **Overview** → copy **Directory (tenant) ID** → this is your `tenantId`\n\n### Step 3: Configure Messaging Endpoint\n\n1. In Azure Bot → **Configuration**\n2. Set **Messaging endpoint** to your webhook URL:\n * Production: `https://your-domain.com/api/messages`\n * Local dev: Use a tunnel (see [Local Development](#local-development-tunneling) below)\n\n### Step 4: Enable Teams Channel\n\n1. In Azure Bot → **Channels**\n2. Click **Microsoft Teams** → Configure → Save\n3. Accept the Terms of Service\n\n## Local Development (Tunneling)\n\nTeams can't reach `localhost`. Use a tunnel for local development:\n\n**Option A: ngrok**", "language": "unknown" } ], "headings": [ { "level": "h2", "text": "Plugin required", "id": "plugin-required" }, { "level": "h2", "text": "Quick setup (beginner)", "id": "quick-setup-(beginner)" }, { "level": "h2", "text": "Goals", "id": "goals" }, { "level": "h2", "text": "Config writes", "id": "config-writes" }, { "level": "h2", "text": "Access control (DMs + groups)", "id": "access-control-(dms-+-groups)" }, { "level": "h2", "text": "How it works", "id": "how-it-works" }, { "level": "h2", "text": "Azure Bot Setup (Prerequisites)", "id": "azure-bot-setup-(prerequisites)" }, { "level": "h3", "text": "Step 1: Create Azure Bot", "id": "step-1:-create-azure-bot" }, { "level": "h3", "text": "Step 2: Get Credentials", "id": "step-2:-get-credentials" }, { "level": "h3", "text": "Step 3: Configure Messaging Endpoint", "id": "step-3:-configure-messaging-endpoint" }, { "level": "h3", "text": "Step 4: Enable Teams Channel", "id": "step-4:-enable-teams-channel" }, { "level": "h2", "text": "Local Development (Tunneling)", "id": "local-development-(tunneling)" } ], "url": "llms-txt#microsoft-teams-(plugin)", "links": [] }