# Microsoft Teams as an AI Agent Channel > How to build a production-grade AI agent inside Microsoft Teams — architecture, auth, Adaptive Cards, and the gotchas nobody warns you about **Source:** [know.imbila.ai/teams-agent-channel-explainer](https://know.imbila.ai/teams-agent-channel-explainer) **Validated:** March 2026 | **Author:** [Imbila.AI](https://imbila.ai) | **License:** CC-BY-SA-4.0 **Structured data:** [teams-agent-channel.json](https://raw.githubusercontent.com/imbilawork/know.agent/main/agentapi/data/teams-agent-channel.json) --- ## What Is an Agent Channel in Teams Microsoft Teams is where most enterprise workers already spend their day. An agent channel turns a Teams conversation — DM, group chat, or channel thread — into a direct interface to your AI agent. Users type natural language, the agent processes it through whatever LLM you choose, and replies appear in the same conversation thread. The underlying technology is the Azure Bot Framework. Your agent registers as a bot in Azure, exposes an HTTPS webhook endpoint, and receives messages via Bot Framework's Activity protocol. Replies go back through the same protocol, landing in the exact conversation they came from. On top of this, Adaptive Cards give you rich interactive UI — buttons, forms, polls, images — inside the chat window. This is not Microsoft Copilot. You control the model (Claude, GPT, Gemini, local Ollama), you control the prompts, you control the data. The tradeoff: you need to set up Azure Bot registration and maintain a publicly accessible HTTPS endpoint. **Key stats:** 320M+ monthly Teams users · Bot Framework Activity protocol · Adaptive Card v1.5 schema · Single-tenant registration required since July 2025 --- ## Why Teams for Agents Teams is the default workplace for most enterprises. Building your agent here means zero adoption friction — users don't download a new app, learn a new interface, or switch contexts. They message the bot like they'd message a colleague. The alternative is Microsoft Copilot at $30/user/month, locked to Microsoft's models, with no control over prompts, data residency, or non-Microsoft integrations. A self-hosted agent on Bot Framework is free to register, model-agnostic, and fully under your control. You pay only for the LLM API tokens you consume. For a small team, expect $6–50/month in API usage. Enterprise deployments with heavy traffic scale linearly with token consumption — still dramatically cheaper than Copilot licensing at scale. --- ## Architecture ### Message Flow ``` Teams Message → Azure Bot Framework (JWT validation) → Your Webhook Endpoint (HTTPS, typically port 3978) → Agent Logic (routing, context, memory) → LLM Processing (Claude, GPT, Gemini, Ollama, etc.) → Teams Reply (back to exact conversation thread) ``` Every Teams message arrives as a Bot Framework Activity — a JSON payload containing the message text, sender identity, conversation reference, and channel data. Your webhook validates the JWT token from Azure, processes the message through your agent, and sends the reply back using the conversation reference. This ensures replies always land in the right place — the same DM, group chat, or channel thread. ### Core Components **1. Azure Bot Registration (Identity Layer)** Your agent needs an identity in Azure AD. You register a bot, which gives you an App ID and App Password (client secret). Since July 2025, Microsoft requires single-tenant registration — multi-tenant bots are deprecated for new registrations. You also need a Tenant ID. **2. Webhook Gateway (Transport Layer)** A publicly accessible HTTPS endpoint that receives Bot Framework activities. Most frameworks default to port 3978 at `/api/messages`. This can run anywhere — a cloud VM, a container, a serverless function — as long as it's reachable from Azure's Bot Framework service. **3. Agent Logic (Processing Layer)** The code that receives messages, manages conversation context, calls your LLM, and formats replies. This is where you choose your framework — Microsoft Bot Framework SDK (Node.js/Python/C#/.NET), OpenClaw, Botpress, or a custom implementation. **4. Adaptive Cards (UI Layer)** Rich interactive cards rendered natively in Teams. Text blocks, images, action buttons, input fields, polls, and data tables — all defined in a JSON schema (v1.5 current). Cards can collect user input via postback events, enabling multi-step workflows inside the chat. --- ## How to Build It ### Step 1: Register the Bot in Azure Go to Azure Portal → Bot Services → Create. Choose single-tenant. You'll get: - **App ID** — identifies your bot to Microsoft - **App Password** — client secret for outbound API calls - **Tenant ID** — your Azure AD tenant Configure the messaging endpoint to point at your webhook URL (e.g., `https://your-domain.com/api/messages`). ### Step 2: Set Up the Webhook Your endpoint needs to: 1. Validate the JWT token on every inbound request (Azure's Bot Framework Connector handles this) 2. Parse the Activity payload to extract the message, sender, and conversation reference 3. Route the message to your agent logic 4. Send the reply back using the Bot Framework REST API or SDK ```javascript // Minimal Node.js example using Bot Framework SDK const { BotFrameworkAdapter } = require('botbuilder'); const adapter = new BotFrameworkAdapter({ appId: process.env.MICROSOFT_APP_ID, appPassword: process.env.MICROSOFT_APP_PASSWORD }); adapter.onTurnError = async (context, error) => { console.error(error); await context.sendActivity('Something went wrong.'); }; // POST /api/messages app.post('/api/messages', (req, res) => { adapter.processActivity(req, res, async (context) => { if (context.activity.type === 'message') { const userMessage = context.activity.text; const reply = await callYourAgent(userMessage, context); await context.sendActivity(reply); } }); }); ``` ### Step 3: Handle Conversation Types Teams has three conversation types, and they behave differently: | Type | Behaviour | Key Gotcha | |------|-----------|------------| | **Personal DM** | 1:1 with the bot. Messages route directly. | Simplest path — start here. | | **Group Chat** | Bot is added to a group. Must be @mentioned to receive messages. | Filter for `@mention` in the activity to avoid noise. | | **Channel** | Bot posts in a team channel. Must be @mentioned. | Channels can be "Posts" or "Threads" mode — the API doesn't tell you which. Configure reply style manually or replies land in the wrong place. | ### Step 4: Implement Access Control Don't expose your agent to everyone by default. Recommended patterns: - **DMs**: Use a pairing/allowlist model. Unknown senders are ignored until explicitly approved. Prevents accidental exposure. - **Group Chats**: Allowlist by user or group. Block by default. - **Channels**: Restrict which channels the bot responds in. Use channel ID allowlists. ### Step 5: Add Adaptive Cards Adaptive Cards turn plain text replies into rich interactive UI. Use the [Adaptive Cards Designer](https://adaptivecards.io/designer/) to build cards visually, then send them as attachments. ```javascript // Sending an Adaptive Card const card = { type: "AdaptiveCard", version: "1.5", body: [ { type: "TextBlock", text: "Deployment Status", weight: "Bolder", size: "Medium" }, { type: "TextBlock", text: "Build #1234 deployed to production", wrap: true }, { type: "FactSet", facts: [ { title: "Status", value: "Success" }, { title: "Duration", value: "2m 34s" }, { title: "Commit", value: "a1b2c3d" } ]} ], actions: [ { type: "Action.OpenUrl", title: "View Logs", url: "https://..." }, { type: "Action.Submit", title: "Rollback", data: { action: "rollback", build: "1234" } } ] }; await context.sendActivity({ attachments: [{ contentType: 'application/vnd.microsoft.card.adaptive', content: card }] }); ``` ### Step 6: File Handling - **DM attachments**: Work natively — files arrive as attachment URLs in the activity payload. - **Channel/group files**: Require SharePoint integration. You need a `sharePointSiteId` and `Sites.ReadWrite.All` Graph permissions. Files are stored in a SharePoint document library. - **Inbound images in channels**: The webhook payload only includes an HTML stub, not the actual file bytes. You must use Graph API with additional permissions to retrieve the content. --- ## Framework Options You don't need to build from scratch. Several frameworks handle the Bot Framework plumbing: | Framework | Language | Strengths | Best For | |-----------|----------|-----------|----------| | **Microsoft Bot Framework SDK** | Node.js, Python, C#, Java | First-party, full API coverage, best docs | Teams-first bots, enterprise compliance | | **OpenClaw** | Node.js | 23-channel support, plugin architecture, model-agnostic | Multi-channel agents (Teams + WhatsApp + Slack) | | **Botpress** | TypeScript | Visual flow builder, built-in NLU, cloud hosting | Non-developer teams, rapid prototyping | | **Custom (direct REST)** | Any | Maximum control, no framework overhead | Teams with unique integration requirements | ### MCP Integration The Model Context Protocol (MCP) is emerging as the standard for giving agents tool access. For Teams-specific operations — scheduling meetings, managing team memberships, archiving channels — MCP servers like Composio provide pre-built toolkits that your agent can call via natural language. --- ## Use Cases - **Deployment Notifications (DevOps)** — Adaptive Cards with build status, rollback buttons, and log links posted to a #deployments channel. One-click rollback from inside Teams. - **Helpdesk Triage (IT Support)** — Employees DM the bot with issues. The agent classifies, routes to the right queue, and auto-creates tickets — without a separate helpdesk portal. - **Onboarding Assistant (HR)** — New hires get a personal DM bot that walks them through policy docs, benefits enrolment, and team introductions — answering questions in natural language. - **CRM Query Bot (Sales)** — Via MCP connectors, sales reps ask the bot for deal status, contact history, or pipeline numbers directly in their Teams channel — no tab-switching to Salesforce. - **Daily Standup Polls (Engineering)** — Automated Adaptive Card polls at 9am. Responses collected automatically. Summary posted at end-of-day. No meeting required for status updates. - **Policy Q&A (Compliance)** — Trained on internal policy documents with RAG. Employees ask compliance questions in Teams and get source-attributed answers — audit-friendly. --- ## Decision Guide ### Build a Teams agent channel when - Your workforce already lives in Teams and you want AI embedded in existing workflows, not bolted on as a separate app. - You need control over model choice, prompts, data residency, and cost — not locked into Copilot's pricing or model. - You want a multi-channel agent that works across Teams, Slack, WhatsApp, and others from the same codebase. - You have (or can get) Azure AD admin consent for bot registration and someone who can maintain the gateway. ### Skip this when - Your org blocks third-party bots in Teams or has a strict no-custom-app policy. Check with IT first. - You don't have access to Azure Portal to create a Bot registration — this is a hard requirement. - You need full message history search. RSC only covers live events; Graph API with admin consent is needed for historical access. - You want zero maintenance. This requires a running gateway on a publicly accessible HTTPS endpoint. If that sounds like a burden, Copilot might be simpler. --- ## Required Permissions **Bot Framework (baseline):** Receive messages in DMs, group chats, and channels. Send replies to conversations. **RSC — Resource-Specific Consent (recommended):** Read channel message text and send messages without broad admin scopes. Enables real-time channel listening. **Graph API (optional, for advanced features):** - `Sites.ReadWrite.All` — SharePoint file uploads in channels - `Chat.Read.All` — Restricted file sharing link access - `ChannelMessage.Read.All` — Historical message access (requires admin consent) All Graph permissions require admin consent from your M365 administrator. --- ## Known Gotchas - **Thread vs Post mode** — Teams channels can be in "Posts" or "Threads" mode. The Bot Framework API does not tell you which mode is active. You must configure reply style manually per channel, or replies appear in the wrong place. - **Multi-tenant deprecation** — Microsoft deprecated new multi-tenant bot registrations in July 2025. Use single-tenant. Existing multi-tenant bots still work but won't receive new feature support. - **Channel images** — Webhook payloads for images in channels only include an HTML stub, not actual file bytes. Graph API permissions are required to retrieve the content. - **Private channels** — Expanded bot support in private channels is rolling out across tenants as of early 2026 but isn't universally available yet. - **RSC limitations** — Resource-Specific Consent only covers real-time events. For historical message access, you need `ChannelMessage.Read.All` with full admin consent. --- ## Timeline | Date | Milestone | |------|-----------| | 2020 | Bot Framework v4 GA — Microsoft stabilises the Activity protocol and SDK for Teams bots. Adaptive Cards v1.2. | | 2023 | Teams Toolkit & AI Library — Microsoft releases Teams AI Library for LLM-powered bots. Simplified bot scaffolding. | | Jul 2025 | Multi-tenant deprecation — Microsoft deprecates new multi-tenant bot registrations. Single-tenant required for new bots. | | Late 2025 | MCP adoption — MCP servers for Teams operations (Composio, others) enable natural-language admin actions. | | Early 2026 | Adaptive Cards v1.5 + RSC expansion — Rich card interactions, expanded private channel bot support rolling out. | --- ## Resources ### Official Documentation - [Microsoft Teams Platform Docs](https://learn.microsoft.com/en-us/microsoftteams/platform/) — Bot Framework, app manifests, deployment - [Bot Framework SDK (GitHub)](https://github.com/microsoft/botframework-sdk) — Source code, samples, migration guides - [Teams AI Library](https://learn.microsoft.com/en-us/microsoftteams/platform/bots/how-to/teams-conversational-ai/teams-conversation-ai-overview) — LLM-powered bot building - [Adaptive Cards Designer](https://adaptivecards.io/designer/) — Visual card builder and schema reference - [Adaptive Cards Schema Explorer](https://adaptivecards.io/explorer/) — Full v1.5 element reference - [Microsoft Graph API — Teams](https://learn.microsoft.com/en-us/graph/teams-concept-overview) — Programmatic access to Teams data ### Framework Options - [Microsoft Bot Framework SDK](https://github.com/microsoft/botframework-sdk) — First-party, Node.js/Python/C#/Java - [OpenClaw](https://github.com/openclaw) — Multi-channel agent framework with Teams plugin - [Botpress](https://botpress.com/) — Visual bot builder with Teams integration ### Sources - [Microsoft Teams Platform Documentation](https://learn.microsoft.com/en-us/microsoftteams/platform/) - [Bot Framework Activity Protocol](https://learn.microsoft.com/en-us/azure/bot-service/rest-api/bot-framework-rest-activity) - [Adaptive Cards Documentation](https://adaptivecards.io/) - [Microsoft Graph — Teams API](https://learn.microsoft.com/en-us/graph/teams-concept-overview) --- *Content validated March 2026. Microsoft Teams and Azure Bot Framework are trademarks of Microsoft Corporation. Independent educational explainer by [Imbila.AI](https://imbila.ai).*