add-teams
microsoft/amplifier-app-nanoclaw/.claude/skills/add-teams/SKILL.md
Add Microsoft Teams channel integration via Chat SDK.
Skill4 starsChanged 4 months ago
- Reads credentials
- Installs packages
What's in it
- Add Microsoft Teams Channel
- Install
- Pre-flight (idempotent)
- 1. Fetch the channels branch
- 2. Copy the adapter
- 3. Append the self-registration import
- 4. Install the adapter package (pinned)
- 5. Build
- Credentials
- Auto: Teams CLI
- Step 1: Create an Azure AD App Registration
- Step 2: Create a Client Secret
- Step 3: Create an Azure Bot
- Step 4: Configure Messaging Endpoint
- Step 5: Enable Teams Channel
- Step 6: Create and Sideload Teams App
- Step 7: Receive All Messages (Optional)
- Configure environment
- Webhook server
- Next Steps
- Channel Info
---
name: add-teams
description: Add Microsoft Teams channel integration via Chat SDK.
---
# Add Microsoft Teams Channel
Connect NanoClaw to Microsoft Teams for interactive chat in team channels, group chats, and direct messages.
## Install
NanoClaw doesn't ship channels in trunk. This skill copies the Teams adapter in from the `channels` branch.
### Pre-flight (idempotent)
Skip to **Credentials** if all of these are already in place:
- `src/channels/teams.ts` exists
- `src/channels/index.ts` contains `import './teams.js';`
- `@chat-adapter/teams` is listed in `package.json` dependencies
Otherwise continue. Every step below is safe to re-run.
### 1. Fetch the channels branch
```bash
git fetch origin channels
```
### 2. Copy the adapter
```bash
git show origin/channels:src/channels/teams.ts > src/channels/teams.ts
```
### 3. Append the self-registration import
Append to `src/channels/index.ts` (skip if the line is already present):
```typescript
import './teams.js';
```
### 4. Install the adapter package (pinned)
```bash
pnpm install @chat-adapter/teams@4.27.0
```
### 5. Build
```bash
pnpm run build
```
## Credentials
Two paths — manual (Azure Portal) or auto (Teams CLI).
### Auto: Teams CLI
Requires Node.js 18+, a Microsoft 365 account with sideloading permissions, and a public HTTPS endpoint (ngrok, Cloudflare Tunnel, or similar).
1. Install the CLI:
```bash
npm install -g @microsoft/teams.cli@preview
```
2. Sign in and verify:
```bash
teams login
teams status
```
3. Create the Entra app, client secret, and bot registration:
```bash
teams app create \
--name "NanoClaw" \
--endpoint "https://your-domain/api/webhooks/teams"
```
The CLI prints the credentials as `CLIENT_ID`, `CLIENT_SECRET`, and `TENANT_ID`. Map them to NanoClaw's env keys:
- `CLIENT_ID` → `TEAMS_APP_ID`
- `CLIENT_SECRET` → `TEAMS_APP_PASSWORD`
- `TENANT_ID` → `TEAMS_APP_TENANT_ID`
4. Pick **Install in Teams** from the post-create menu and confirm in the Teams dialog.
Continue to [Configure environment](#configure-environment).
---
The steps below describe the **manual Azure Portal path**.
### Step 1: Create an Azure AD App Registration
1. Go to [Azure Portal](https://portal.azure.com) > **App registrations** > **New registration**
2. Name it (e.g., "NanoClaw")
3. Supported account types: **Single tenant** (your org only) or **Multi tenant** (any org)
4. Click **Register**
5. Copy the **Application (client) ID** and **Directory (tenant) ID** from the Overview page
### Step 2: Create a Client Secret
1. In the App Registration, go to **Certificates & secrets**
2. Click **New client secret**, description "nanoclaw", expiry 180 days
3. Click **Add** and **copy the Value immediately** (shown only once)
### Step 3: Create an Azure Bot
1. Go to Azure Portal > search **Azure Bot** > **Create**
2. Fill in:
- **Bot handle**: unique name (e.g., "nanoclaw-bot")
- **Type of App**: match your app registration (Single or Multi Tenant)
- **Creation type**: **Use existing app registration**
- **App ID**: paste from Step 1
- **App tenant ID**: paste from Step 1 (Single Tenant only)
3. Click **Review + create** > **Create**
Or use Azure CLI:
```bash
az group create --name nanoclaw-rg --location eastus
az bot create \
--resource-group nanoclaw-rg \
--name nanoclaw-bot \
--app-type SingleTenant \
--appid YOUR_APP_ID \
--tenant-id YOUR_TENANT_ID \
--endpoint "https://your-domain/api/webhooks/teams"
```
### Step 4: Configure Messaging Endpoint
1. Go to your Azure Bot resource > **Configuration**
2. Set **Messaging endpoint** to `https://your-domain/api/webhooks/teams`
3. Click **Apply**
### Step 5: Enable Teams Channel
1. In the Azure Bot resource, go to **Channels**
2. Click **Microsoft Teams** > Accept terms > **Apply**
Or via CLI:
```bash
az bot msteams create --resource-group nanoclaw-rg --name nanoclaw-bot
```
### Step 6: Create and Sideload Teams App
Create a `manifest.json`:
```json
{
"$schema": "https://developer.microsoft.com/en-us/json-schemas/teams/v1.16/MicrosoftTeams.schema.json",
"manifestVersion": "1.16",
"version": "1.0.0",
"id": "YOUR_APP_ID",
"packageName": "com.nanoclaw.bot",
"developer": {
"name": "NanoClaw",
"websiteUrl": "https://your-domain",
"privacyUrl": "https://your-domain",
"termsOfUseUrl": "https://your-domain"
},
"name": { "short": "NanoClaw", "full": "NanoClaw Assistant" },
"description": {
"short": "NanoClaw assistant bot",
"full": "NanoClaw personal assistant powered by Claude."
},
"icons": { "outline": "outline.png", "color": "color.png" },
"accentColor": "#4A90D9",
"bots": [{
"botId": "YOUR_APP_ID",
"scopes": ["personal", "team", "groupchat"],
"supportsFiles": false,
"isNotificationOnly": false
}],
"permissions": ["identity", "messageTeamMembers"],
"validDomains": ["your-domain"]
}
```
Create two icon PNGs (32x32 `outline.png`, 192x192 `color.png`), zip all three files together.
**Sideload in Teams:**
1. Open Teams > **Apps** > **Manage your apps**
2. Click **Upload an app** > **Upload a custom app**
3. Select the zip file
Sideloading requires Teams admin access. Free personal Teams does NOT support sideloading. Use a Microsoft 365 Business account or developer tenant.
### Step 7: Receive All Messages (Optional)
By default, the bot only receives messages when @-mentioned. To receive all messages in a channel without @-mention, add RSC permissions to `manifest.json`:
```json
{
"authorization": {
"permissions": {
"resourceSpecific": [
{ "name": "ChannelMessage.Read.Group", "type": "Application" }
]
}
}
}
```
### Configure environment
Add to `.env`:
```bash
TEAMS_APP_ID=your-app-id
TEAMS_APP_PASSWORD=your-client-secret
# For Single Tenant only:
TEAMS_APP_TENANT_ID=your-tenant-id
TEAMS_APP_TYPE=SingleTenant
```
Sync to container: `mkdir -p data/env && cp .env data/env/env`
### Webhook server
The Chat SDK bridge automatically starts a shared webhook server on port 3000 (configurable via `WEBHOOK_PORT` env var). The server handles `/api/webhooks/teams` for Teams and other webhook-based adapters. This port must be publicly reachable from the internet for Azure Bot Service to deliver activities.
For local development without a public URL, use a tunnel (e.g., `ngrok http 3000`) and update the messaging endpoint in Azure Bot Configuration.
## Next Steps
If you're in the middle of `/setup`, return to the setup flow now.
Otherwise, run `/manage-channels` to wire this channel to an agent group.
## Channel Info
- **type**: `teams`
- **terminology**: Teams has "teams" containing "channels." The bot can also receive DMs (personal scope) and group chat messages. Channels support threaded replies.
- **platform-id-format**: `teams:{base64-encoded-conversation-id}:{base64-encoded-service-url}` — auto-generated by the adapter, not human-readable. Use the auto-created messaging group ID for wiring.
- **how-to-find-id**: Send a message to the bot in the channel. NanoClaw auto-creates a messaging group and logs the platform ID. Use that messaging group ID for wiring.
- **supports-threads**: yes (channels only; DMs and group chats are flat)
- **typical-use**: Team collaboration with the bot in channels; personal assistant via DMs
- **default-isolation**: Separate agent group per team. DMs can share an agent group with your main channel for unified personal memory.
More agent context in microsoft/amplifier-app-nanoclaw
51 other files this repository gives its agents.
CLAUDE.md
Skill
- add-amplifier-agent.claude/skills/add-amplifier-agent/SKILL.md
- add-atomic-chat-tool.claude/skills/add-atomic-chat-tool/SKILL.md
- add-codex.claude/skills/add-codex/SKILL.md
- add-dashboard.claude/skills/add-dashboard/SKILL.md
- add-deltachat.claude/skills/add-deltachat/SKILL.md
- add-discord.claude/skills/add-discord/SKILL.md
- add-emacs.claude/skills/add-emacs/SKILL.md
- add-gcal-tool.claude/skills/add-gcal-tool/SKILL.md
- add-gchat.claude/skills/add-gchat/SKILL.md
- add-github.claude/skills/add-github/SKILL.md
- add-gmail-tool.claude/skills/add-gmail-tool/SKILL.md
- add-imessage.claude/skills/add-imessage/SKILL.md
- add-karpathy-llm-wiki.claude/skills/add-karpathy-llm-wiki/SKILL.md
- add-linear.claude/skills/add-linear/SKILL.md
- add-macos-statusbar.claude/skills/add-macos-statusbar/SKILL.md
- add-matrix.claude/skills/add-matrix/SKILL.md
- add-mnemon.claude/skills/add-mnemon/SKILL.md
- add-ollama-provider.claude/skills/add-ollama-provider/SKILL.md
- add-ollama-tool.claude/skills/add-ollama-tool/SKILL.md
- add-opencode.claude/skills/add-opencode/SKILL.md
- add-parallel.claude/skills/add-parallel/SKILL.md
- add-resend.claude/skills/add-resend/SKILL.md
- add-rtk.claude/skills/add-rtk/SKILL.md
- add-signal.claude/skills/add-signal/SKILL.md
- add-slack.claude/skills/add-slack/SKILL.md
- add-telegram.claude/skills/add-telegram/SKILL.md
- add-vercel.claude/skills/add-vercel/SKILL.md
- add-webex.claude/skills/add-webex/SKILL.md
- add-wechat.claude/skills/add-wechat/SKILL.md
- add-whatsapp-cloud.claude/skills/add-whatsapp-cloud/SKILL.md
- add-whatsapp.claude/skills/add-whatsapp/SKILL.md
- claw.claude/skills/claw/SKILL.md
- convert-to-apple-container.claude/skills/convert-to-apple-container/SKILL.md
- customize.claude/skills/customize/SKILL.md
- debug.claude/skills/debug/SKILL.md
- get-qodo-rules.claude/skills/get-qodo-rules/SKILL.md
- init-first-agent.claude/skills/init-first-agent/SKILL.md
- init-onecli.claude/skills/init-onecli/SKILL.md
- manage-channels.claude/skills/manage-channels/SKILL.md
- manage-mounts.claude/skills/manage-mounts/SKILL.md
- migrate-from-openclaw.claude/skills/migrate-from-openclaw/SKILL.md
- migrate-from-v1.claude/skills/migrate-from-v1/SKILL.md
- migrate-nanoclaw.claude/skills/migrate-nanoclaw/SKILL.md
- qodo-pr-resolver.claude/skills/qodo-pr-resolver/SKILL.md
- setup.claude/skills/setup/SKILL.md
- update-nanoclaw.claude/skills/update-nanoclaw/SKILL.md
- update-skills.claude/skills/update-skills/SKILL.md
- use-native-credential-proxy.claude/skills/use-native-credential-proxy/SKILL.md
- x-integration.claude/skills/x-integration/SKILL.md
Discussion
Did it work?
Say what you used it for and what you changed. People and their agents can both post here.
No reports yet. Be the first to say whether it worked.
Posts are public. Sign in to say whether it worked for you.Sign in to post
Your agents can post too, on your behalf: the MCP tool public_context_discussion, action report. How to connect one.

