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: 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:
+------------------+ +------------------+ +------------------+| 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:
# Using Azure CLIaz bot create \ --resource-group MyResourceGroup \ --name OpenClawBot \ --kind registration \ --location global
# Enable Teams channelaz bot channel create \ --resource-group MyResourceGroup \ --name OpenClawBot \ --channel-type ms-teamsMistake 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:
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):
- Go to App registrations > New registration
- Name it something like “OpenClaw Teams Integration”
- Set Supported account types to “Accounts in any organizational directory” (multi-tenant)
- Add a redirect URI:
https://token.botframework.com/.auth/web/redirect
Step 2: Configure API Permissions
I added these Microsoft Graph permissions:
Permission | Type | Why Needed------------------------------|--------|----------------------------TeamsAppInstallation.Read.For| Delegated| Install bot in TeamsChannel.ReadBasic.All | Delegated| Read channel infoChannelMessage.Send | Delegated| Send messages to channelsUser.Read | Delegated| User profile accessTasks.ReadWrite | Delegated| To Do list accessMail.Send | Delegated| Send emails via agentStep 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:
{ "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!):
AZURE_BOT_APP_ID=your-bot-app-id-hereAZURE_BOT_PASSWORD=your-bot-password-hereAZURE_TENANT_ID=your-tenant-id-hereAZURE_CLIENT_ID=your-ad-app-client-id-hereAZURE_CLIENT_SECRET=your-ad-app-secret-hereStep 3: OAuth Token Setup
For the Python-based OpenClaw agent, I set up token exchange:
from azure.identity import ClientSecretCredentialfrom msgraph import GraphServiceClient
# Initialize OAuth credentialscredential = ClientSecretCredential( tenant_id="YOUR_TENANT_ID", client_id="YOUR_CLIENT_ID", client_secret="YOUR_CLIENT_SECRET")
# Create Graph client for Teams operationsgraph_client = GraphServiceClient(credential)
# Test: List Teams channelsasync 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:
{ "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:
- Zip
manifest.jsonwith icon files (color.png and outline.png) - 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:
Me: @Elvis helpElvis: 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 | Status | Notes----------------|--------|---------------------------Teams messaging | OK | Direct and channel messagesTo Do list | OK | Create, read, update tasksEmail | OK | Send via Microsoft GraphCalendar | OK | Read and create eventsDocuments | OK | Update SharePoint filesCommon Mistakes I Made
Mistake 1: Wrong Redirect URI Format
I used https://mybot.com/auth/callback instead of the Bot Framework’s required redirect:
https://token.botframework.com/.auth/web/redirectThis 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.
Personal account -> Will fail with AADSTS errorsOrganizational account -> Works correctlyMistake 4: Forgot to Enable Teams Channel
After creating the bot, I forgot to explicitly enable the Teams channel:
az bot channel create \ --resource-group MyResourceGroup \ --name OpenClawBot \ --channel-type ms-teamsWithout this, the bot existed but wasn’t accessible from Teams.
Mistake 5: Not Requesting Admin Consent
For some permissions (like ChannelMessage.Send), I needed admin consent. I added this to the OAuth URL:
https://login.microsoftonline.com/{tenant-id}/adminconsent ?client_id={client-id} &redirect_uri=https://token.botframework.com/.auth/web/redirectRelated Knowledge: How Bot Framework Authentication Works
Understanding the flow helped me debug issues:
1. User sends message in Teams2. Teams forwards to Azure Bot Framework3. Bot Framework validates bot identity (App ID + Password)4. Bot Framework calls your webhook with message5. Your code (OpenClaw) processes message6. Response goes back through same chainThe 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:
[ ] 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:
- Understanding Azure Bot Framework vs Azure AD app registration (they’re separate things)
- Getting OAuth redirect URIs exactly right
- Requesting all necessary API permissions
- 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:
- 👨💻 Azure Bot Framework Documentation
- 👨💻 OpenClaw Official Documentation
- 👨💻 Microsoft Graph API Reference
- 👨💻 Reddit r/LocalLLaMA Discussion
Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!
Comments