Microsoft Teams has become the hub for workplace collaboration, with over 300 million monthly active users relying on it every day. The Teams AI Library lets you build intelligent bots and agents that live right inside Teams conversations — combining the Bot Framework with Azure OpenAI to create AI-powered experiences that understand natural language, execute actions, and deliver rich Adaptive Card interfaces without the usual boilerplate.
This guide walks through the library’s architecture, sets up a project from scratch using Teams Toolkit, and builds a working AI bot that handles conversations, triggers actions, and connects to your organization’s data through retrieval-augmented generation.
What is the Teams AI Library?
The Teams AI Library is an SDK that sits on top of the Bot Framework and provides a structured way to build AI-powered bots for Microsoft Teams. While the Bot Framework gives you messaging infrastructure, the Teams AI Library adds a complete AI layer: prompt management, conversation history, action planning, and direct integration with large language models.
Think of it this way: the Bot Framework handles how your bot sends and receives messages. The Teams AI Library handles how your bot thinks about those messages and decides what to do.
Key differences from the plain Bot Framework
- AI Planner — the library includes an
ActionPlannerthat uses LLMs to decide which actions to execute based on user input, instead of manually parsing intents. - Prompt management — define prompts in separate configuration files with templates, system messages, and model parameters.
- Conversation state — automatic tracking of conversation history, user state, and temp state across turns.
- Built-in moderation — integrate Azure Content Safety to filter harmful inputs and outputs before they reach the model or the user.
- Action system — register typed action handlers that the AI planner can invoke, providing structure instead of free-form text generation.
Setting up your project
The fastest way to get started is with Teams Toolkit, Microsoft’s official extension for Visual Studio Code. It scaffolds the project, handles app registration, and provides local debugging with a tunnel to Teams.
- Install Teams Toolkit from the VS Code marketplace.
- Open the command palette and select Teams: Create a New App.
- Choose Custom Engine Agent and then AI Agent or AI Bot as your template.
- Select TypeScript as the language and provide your Azure OpenAI connection details.
Teams Toolkit generates a project with this structure:
my-teams-bot/
├── appPackage/ # Teams app manifest
│ ├── manifest.json
│ ├── color.png
│ └── outline.png
├── env/ # Environment config
├── infra/ # Bicep templates for Azure
├── src/
│ ├── app.ts # Application entry point
│ ├── index.ts # Server setup
│ └── prompts/
│ └── chat/
│ ├── config.json # Model & prompt settings
│ └── skprompt.txt # System prompt
├── teamsapp.yml
└── package.json
Installing dependencies
# Core dependencies for a Teams AI bot
npm install @microsoft/teams-ai botbuilder
# Azure OpenAI for the AI planner
npm install @azure/openai
# Development tools
npm install --save-dev typescript @types/node nodemon
Environment configuration
Create a .env.local file with your Azure OpenAI credentials:
BOT_ID=your-bot-app-id
BOT_PASSWORD=your-bot-app-password
AZURE_OPENAI_KEY=your-azure-openai-key
AZURE_OPENAI_ENDPOINT=https://your-instance.openai.azure.com
AZURE_OPENAI_DEPLOYMENT=gpt-4o
.env.local (gitignored) for local development. Teams Toolkit manages this automatically when you provision Azure resources.
Building an AI-powered bot
The core of every Teams AI bot is the Application object. It wires together the Bot Framework adapter, the AI planner, and your conversation state. Here is the full setup:
Application entry point
import {
Application,
ActionPlanner,
OpenAIModel,
PromptManager,
TurnState
} from "@microsoft/teams-ai";
// Configure the OpenAI model
const model = new OpenAIModel({
azureApiKey: process.env.AZURE_OPENAI_KEY!,
azureDefaultDeployment: process.env.AZURE_OPENAI_DEPLOYMENT!,
azureEndpoint: process.env.AZURE_OPENAI_ENDPOINT!,
useSystemMessages: true,
logRequests: true
});
// Set up prompt management
const prompts = new PromptManager({
promptsFolder: path.join(__dirname, "../src/prompts")
});
// Create the AI planner
const planner = new ActionPlanner({
model,
prompts,
defaultPrompt: "chat"
});
// Initialize the application
const app = new Application<TurnState>({
ai: {
planner
},
storage // MemoryStorage for dev, BlobStorage for prod
});
Prompt configuration
The prompt system uses two files per prompt. First, config.json defines model parameters:
{
"schema": 1.1,
"description": "A helpful assistant for the team",
"type": "completion",
"completion": {
"model": "gpt-4o",
"completion_type": "chat",
"include_history": true,
"include_input": "required",
"max_input_tokens": 4096,
"max_tokens": 1024,
"temperature": 0.7,
"top_p": 0.95
}
}
Then skprompt.txt holds the system message:
You are a helpful assistant working inside Microsoft Teams.
You help team members find information, summarize documents,
and answer questions based on organizational data.
Rules:
- Be concise and professional.
- If unsure, say so instead of guessing.
- Format responses for readability in Teams chat.
- When referencing documents, include the source.
Handling conversation events
// Handle when the bot is installed or added to a conversation
app.conversationUpdate("membersAdded", async (context, state) => {
const membersAdded = context.activity.membersAdded ?? [];
for (const member of membersAdded) {
if (member.id !== context.activity.recipient.id) {
await context.sendActivity(
"Hi! I'm your AI assistant. Ask me anything " +
"about your team's projects and documents."
);
}
}
});
// Handle feedback from users
app.message("/reset", async (context, state) => {
state.deleteConversationState();
await context.sendActivity("Conversation history cleared.");
});
Action handlers and Adaptive Cards
One of the most powerful features of the Teams AI Library is the action system. Instead of generating free-text responses for every request, the AI planner can decide to call specific action handlers that execute business logic and return structured results.
Registering action handlers
// Define actions the AI can invoke
app.ai.action("createTask", async (context, state, parameters) => {
const { title, assignee, dueDate } = parameters;
// Call your task management API
const task = await taskService.create({
title,
assignedTo: assignee,
due: new Date(dueDate)
});
// Return an Adaptive Card with the created task
const card = createTaskCard(task);
await context.sendActivity({
attachments: [CardFactory.adaptiveCard(card)]
});
return `Task "${title}" created and assigned to ${assignee}.`;
});
app.ai.action("lookupEmployee", async (context, state, parameters) => {
const { name } = parameters;
const employee = await graphClient.findUser(name);
if (!employee) {
return `No employee found matching "${name}".`;
}
return `Found: ${employee.displayName}, ${employee.jobTitle}, ` +
`${employee.department}. Email: ${employee.mail}`;
});
Building Adaptive Cards
Adaptive Cards let your bot present structured, interactive content in Teams. Users can fill out forms, click buttons, and interact with data directly in the chat.
function createTaskCard(task: Task) {
return {
type: "AdaptiveCard",
$schema: "http://adaptivecards.io/schemas/adaptive-card.json",
version: "1.5",
body: [
{
type: "TextBlock",
text: task.title,
weight: "Bolder",
size: "Medium"
},
{
type: "FactSet",
facts: [
{ title: "Assigned to", value: task.assignedTo },
{ title: "Due", value: task.due.toLocaleDateString() },
{ title: "Status", value: "Not started" }
]
}
],
actions: [
{
type: "Action.Submit",
title: "Mark Complete",
data: { action: "completeTask", taskId: task.id }
}
]
};
}
Handling Adaptive Card submissions
// Handle when a user clicks an Adaptive Card button
app.adaptiveCards.actionSubmit(
"completeTask",
async (context, state, data) => {
const { taskId } = data;
await taskService.markComplete(taskId);
await context.sendActivity(
"Task marked as complete!"
);
}
);
Message extensions with AI
Message extensions let users interact with your bot from the compose area, command bar, or directly from a message. The Teams AI Library simplifies building both search commands and action commands with AI backing.
Search command with AI-enhanced results
// Register a search-based message extension
app.messageExtensions.query(
"searchDocuments",
async (context, state, query) => {
const searchText = query.parameters?.[0]?.value ?? "";
// Use AI Search for semantic matching
const results = await searchClient.search(searchText, {
queryType: "semantic",
top: 5,
semanticConfiguration: "default"
});
// Convert to message extension results
const attachments = [];
for await (const result of results.results) {
attachments.push({
contentType: "application/vnd.microsoft.card.adaptive",
content: createDocumentCard(result.document),
preview: CardFactory.heroCard(
result.document.title,
result.document.summary
)
});
}
return { composeExtension: { type: "result", attachments } };
}
);
Retrieval-Augmented Generation in Teams
RAG is where Teams AI bots become genuinely useful for organizations. By connecting your bot to internal data sources — SharePoint, Azure AI Search, Microsoft Graph, or databases — the AI can answer questions grounded in your company’s actual information instead of relying on the model’s general training data.
Adding a data source
import { AzureAISearchDataSource } from "@microsoft/teams-ai";
// Register Azure AI Search as a data source
planner.prompts.addDataSource(
new AzureAISearchDataSource({
name: "company-docs",
indexName: "knowledge-base",
azureAISearchApiKey: process.env.SEARCH_API_KEY!,
azureAISearchEndpoint: process.env.SEARCH_ENDPOINT!,
queryType: "semantic",
semanticConfiguration: "default",
fieldsMapping: {
contentFields: ["content"],
titleField: "title",
urlField: "url"
}
})
);
Then reference the data source in your prompt template (skprompt.txt):
You are a helpful assistant for Contoso employees.
Answer questions using information from the following sources.
Always cite the document title when referencing information.
Sources:
{{$data.company-docs}}
Custom data source with Microsoft Graph
import { DataSource, RenderedPromptSection } from "@microsoft/teams-ai";
class GraphDataSource implements DataSource {
public name = "graph";
async renderData(
context: TurnContext,
memory: Memory,
tokenizer: Tokenizer,
maxTokens: number
): Promise<RenderedPromptSection<string>> {
// Search user's emails, files, and chats via Graph
const query = memory.getValue("temp.input");
const results = await graphClient
.api("/search/query")
.post({
requests: [{
entityTypes: ["driveItem", "message", "chatMessage"],
query: { queryString: query },
from: 0,
size: 5
}]
});
const text = formatResults(results);
return { output: text, length: text.length, tooLong: false };
}
}
Files.Read.All, Mail.Read, and Chat.Read. Configure SSO through the Teams app manifest so users authenticate seamlessly.
Capabilities at a glance
AI-Powered Conversations
Natural language understanding backed by Azure OpenAI, with automatic conversation history management.
Action Planning
LLM-driven action planner maps user requests to typed handler functions automatically.
Adaptive Cards
Build rich, interactive card-based UIs with forms, buttons, and data displays embedded in chat.
Message Extensions
Search and action commands accessible from the compose box, command bar, and messages.
RAG Integration
Built-in data source connectors for Azure AI Search, SharePoint, and custom APIs.
Content Moderation
Azure Content Safety integration filters harmful inputs and outputs automatically.
SSO Authentication
Single sign-on with Microsoft Entra ID for seamless user authentication in Teams.
Teams Toolkit
VS Code extension for scaffolding, local debugging, provisioning, and deployment.
Comparison: Teams AI Library vs. alternatives
Choosing the right tool depends on your team’s skills and the complexity of the bot you are building:
| Feature | Teams AI Library | Bot Framework SDK | Power Virtual Agents | Copilot Studio |
|---|---|---|---|---|
| Target audience | Pro developers | Pro developers | Citizen developers | Citizen + pro developers |
| Language support | TypeScript, C# | TypeScript, C#, Python, Java | No code | Low code + pro code |
| AI integration | Built-in (Azure OpenAI) | Manual via SDKs | Limited (topic triggers) | Built-in (GPT models) |
| RAG support | Native data sources | Build your own | Knowledge sources | Knowledge sources + plugins |
| Action planning | LLM-driven planner | Dialog system | Topic routing | Topics + plugins |
| Adaptive Cards | Full support | Full support | Limited | Full support |
| Custom code | Full control | Full control | Cloud flows only | Cloud flows + plugins |
| Deployment | Azure Bot Service | Azure Bot Service | SaaS (managed) | SaaS (managed) |
| Best for | AI-first Teams bots | Complex, non-AI bots | Simple FAQ bots | Enterprise copilots |
Use the Teams AI Library when you need full control over the AI behavior, custom action handlers, and deep integration with your existing codebase. Choose Copilot Studio when citizen developers need to build and maintain the bot without writing code.
Deploying to Teams
Once your bot is ready, deploying it to Teams involves three steps: provisioning Azure resources, deploying the code, and publishing the app to your organization.
Provision and deploy with Teams Toolkit
- Open the Teams Toolkit panel in VS Code and click Provision to create the Azure Bot Service, App Service, and Key Vault resources.
- Click Deploy to push your bot code to the Azure App Service.
- Click Publish to submit the Teams app package to your organization’s app catalog.
- An admin approves the app in the Teams Admin Center, making it available to users across the organization.
CI/CD with GitHub Actions
# .github/workflows/deploy.yml
name: Deploy Teams Bot
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npm ci && npm run build
- uses: azure/webapps-deploy@v3
with:
app-name: "my-teams-bot"
publish-profile: ${{ secrets.AZURE_PUBLISH_PROFILE }}
package: "."
teamsapp.yml lifecycle configuration to define provision, deploy, and publish steps declaratively. This file integrates with both local development and CI/CD pipelines, keeping environment-specific settings separate from your deployment logic.
Next steps
- Clone the samples — explore the official samples repository for complete working bots covering chat, actions, RAG, and message extensions.
- Add authentication — implement SSO with Microsoft Entra ID so your bot can access user-specific data through Microsoft Graph.
- Connect your data — index your SharePoint sites, wikis, or databases into Azure AI Search and wire them as data sources.
- Set up monitoring — integrate Application Insights to track bot usage, latency, failures, and token consumption.
- Read the docs: Teams AI Library overview and Teams Toolkit documentation.
Leave a Reply