Skip to content

How Do I Connect OpenClaw to Microsoft Teams?

The Problem

I spent 3 days trying to connect OpenClaw to Microsoft Teams. The error messages were cryptic, the documentation scattered, and every tutorial I found was either outdated or missing critical steps.

Here’s what I kept seeing:

Error Message
Error: Bot registration failed.
AADSTS50194: Application 'xxx' is not configured as a multi-tenant application.

Or worse - silent failures where the bot just wouldn’t respond in Teams channels.

Why This Is Hard

The integration requires connecting multiple systems:

Integration Architecture
+------------------+ +------------------+ +------------------+
| Microsoft Teams | --> | Azure Bot | --> | OpenClaw Agent |
| | | Framework | | (your AI) |
+------------------+ +------------------+ +------------------+
| | |
v v v
+------------------+ +------------------+ +------------------+
| Azure AD | | OAuth Tokens | | MCP Connector |
| (Entra ID) | | | | |
+------------------+ +------------------+ +------------------+

Each piece has its own configuration, and a mistake in any one breaks the whole chain.

Phase 1: Azure Bot Framework Setup

Step 1: Create the Azure Bot Resource

First, I created an Azure Bot resource in the Azure Portal:

Create Azure Bot
# Using Azure CLI
az bot create \
--resource-group MyResourceGroup \
--name OpenClawBot \
--kind registration \
--location global
# Enable Teams channel
az bot channel create \
--resource-group MyResourceGroup \
--name OpenClawBot \
--channel-type ms-teams

Mistake I made: I initially used --kind webapp instead of --kind registration. Registration is what you need for external bots like OpenClaw.

Step 2: Get Your Credentials

After creating the bot, I needed the App ID and password:

Get Bot Credentials
az bot show \
--resource-group MyResourceGroup \
--name OpenClawBot \
--query "{appId:properties.msaAppId, password:properties.msaAppPassword}"

Store these securely - you’ll need them for the OpenClaw configuration.

Phase 2: Azure AD App Registration

This is where I got stuck for a day. The bot needs OAuth permissions to access Teams, To Do, and other Microsoft services.

Step 1: Register the App

In Azure Portal (Entra ID):

  1. Go to App registrations > New registration
  2. Name it something like “OpenClaw Teams Integration”
  3. Set Supported account types to “Accounts in any organizational directory” (multi-tenant)
  4. Add a redirect URI: https://token.botframework.com/.auth/web/redirect

Step 2: Configure API Permissions

I added these Microsoft Graph permissions:

Required API Permissions
Permission | Type | Why Needed
------------------------------|--------|----------------------------
TeamsAppInstallation.Read.For| Delegated| Install bot in Teams
Channel.ReadBasic.All | Delegated| Read channel info
ChannelMessage.Send | Delegated| Send messages to channels
User.Read | Delegated| User profile access
Tasks.ReadWrite | Delegated| To Do list access
Mail.Send | Delegated| Send emails via agent

Step 3: Generate Client Secret

Go to Certificates & secrets > New client secret. Save the secret value immediately - you can’t see it again.

Phase 3: OpenClaw Configuration

Step 1: Configure the MCP Connector

Create the OpenClaw configuration file:

mcp_config.json
{
"connectors": {
"microsoft-teams": {
"type": "teams",
"app_id": "${AZURE_BOT_APP_ID}",
"app_password": "${AZURE_BOT_PASSWORD}",
"tenant_id": "${AZURE_TENANT_ID}",
"oauth_config": {
"client_id": "${AZURE_CLIENT_ID}",
"client_secret": "${AZURE_CLIENT_SECRET}",
"scopes": [
"https://graph.microsoft.com/.default"
]
}
}
}
}

Step 2: Set Environment Variables

I created a .env file (never commit this!):

.env
AZURE_BOT_APP_ID=your-bot-app-id-here
AZURE_BOT_PASSWORD=your-bot-password-here
AZURE_TENANT_ID=your-tenant-id-here
AZURE_CLIENT_ID=your-ad-app-client-id-here
AZURE_CLIENT_SECRET=your-ad-app-secret-here

Step 3: OAuth Token Setup

For the Python-based OpenClaw agent, I set up token exchange:

oauth_setup.py
from azure.identity import ClientSecretCredential
from msgraph import GraphServiceClient
# Initialize OAuth credentials
credential = ClientSecretCredential(
tenant_id="YOUR_TENANT_ID",
client_id="YOUR_CLIENT_ID",
client_secret="YOUR_CLIENT_SECRET"
)
# Create Graph client for Teams operations
graph_client = GraphServiceClient(credential)
# Test: List Teams channels
async def test_teams_connection():
teams = await graph_client.me.joined_teams.get()
for team in teams.value:
print(f"Team: {team.display_name}")
channels = await graph_client.teams_by_id(team.id).channels.get()
for channel in channels.value:
print(f" Channel: {channel.display_name}")

Phase 4: Teams App Package

Step 1: Create the Manifest

I created a Teams app manifest:

manifest.json
{
"manifestVersion": "1.16",
"version": "1.0.0",
"id": "${MICROSOFT_APP_ID}",
"packageName": "com.openclaw.teams",
"developer": {
"name": "OpenClaw",
"websiteUrl": "https://openclaw.ai",
"privacyUrl": "https://openclaw.ai/privacy",
"termsOfUseUrl": "https://openclaw.ai/terms"
},
"name": {
"short": "OpenClaw",
"full": "OpenClaw AI Assistant"
},
"description": {
"short": "AI assistant for Teams",
"full": "Your AI-powered assistant integrated with Microsoft Teams"
},
"bots": [{
"botId": "${MICROSOFT_APP_ID}",
"scopes": ["personal", "team", "groupchat"],
"isNotificationOnly": false,
"commandLists": [{
"scopes": ["personal", "team"],
"commands": [
{ "title": "Help", "description": "Show available commands" },
{ "title": "Create Task", "description": "Create a new task" },
{ "title": "Send Email", "description": "Compose and send email" }
]
}]
}],
"permissions": ["identity", "messageTeamMembers"],
"validDomains": ["openclaw.ai", "token.botframework.com"]
}

Step 2: Create the App Package

Using the Teams Developer Portal or manually:

  1. Zip manifest.json with icon files (color.png and outline.png)
  2. Upload to Teams via Apps > Manage your apps > Upload an app

Phase 5: Testing the Integration

Verify the Connection

I tested by messaging my OpenClaw bot (named “Elvis”) in Teams:

Teams Chat Test
Me: @Elvis help
Elvis: Available commands:
- Help: Show this message
- Create Task: Create a new To Do item
- Send Email: Compose and send an email
- Update Document: Edit a shared document
Me: @Elvis Create Task "Review Q1 report"
Elvis: Task "Review Q1 report" created in your To Do list.

Test Other Integrations

The beauty of this setup is that my AI agent can now:

Integration Test Results
Integration | Status | Notes
----------------|--------|---------------------------
Teams messaging | OK | Direct and channel messages
To Do list | OK | Create, read, update tasks
Email | OK | Send via Microsoft Graph
Calendar | OK | Read and create events
Documents | OK | Update SharePoint files

Common Mistakes I Made

Mistake 1: Wrong Redirect URI Format

I used https://mybot.com/auth/callback instead of the Bot Framework’s required redirect:

Correct Redirect URI
https://token.botframework.com/.auth/web/redirect

This caused infinite authentication loops.

Mistake 2: Missing API Permissions

I forgot to add Tasks.ReadWrite permission. The bot connected to Teams but couldn’t access To Do lists. The error was silent - it just returned empty task lists.

Mistake 3: Personal vs Organizational Account

I initially tried with my personal Microsoft account. The bot registration requires an organizational Azure AD tenant.

Account Type Check
Personal account -> Will fail with AADSTS errors
Organizational account -> Works correctly

Mistake 4: Forgot to Enable Teams Channel

After creating the bot, I forgot to explicitly enable the Teams channel:

Enable Teams Channel
az bot channel create \
--resource-group MyResourceGroup \
--name OpenClawBot \
--channel-type ms-teams

Without this, the bot existed but wasn’t accessible from Teams.

For some permissions (like ChannelMessage.Send), I needed admin consent. I added this to the OAuth URL:

Admin Consent URL
https://login.microsoftonline.com/{tenant-id}/adminconsent
?client_id={client-id}
&redirect_uri=https://token.botframework.com/.auth/web/redirect

Understanding the flow helped me debug issues:

OAuth Flow for Teams Bot
1. User sends message in Teams
2. Teams forwards to Azure Bot Framework
3. Bot Framework validates bot identity (App ID + Password)
4. Bot Framework calls your webhook with message
5. Your code (OpenClaw) processes message
6. Response goes back through same chain

The OAuth tokens are for Graph API calls (To Do, Email, etc.), separate from the bot identity.

Troubleshooting Checklist

When things don’t work, I check these in order:

Debug Checklist
[ ] Bot App ID and Password are correct
[ ] Teams channel is enabled in Azure Bot
[ ] Azure AD app has correct API permissions
[ ] Admin consent granted for delegated permissions
[ ] Redirect URI matches exactly (including trailing slashes)
[ ] Environment variables loaded in OpenClaw
[ ] MCP connector config has valid JSON syntax
[ ] Client secret hasn't expired (they expire!)

Summary

Connecting OpenClaw to Microsoft Teams took me 3 days of trial and error. The main hurdles were:

  1. Understanding Azure Bot Framework vs Azure AD app registration (they’re separate things)
  2. Getting OAuth redirect URIs exactly right
  3. Requesting all necessary API permissions
  4. Enabling the Teams channel explicitly

The payoff is worth it - my AI assistant now lives in Teams, updating documents, sending emails, and managing tasks through natural language commands.

Final Words + More Resources

My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me

Here are also the most important links from this article along with some further resources that will help you in this scope:

Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!

Comments