/add-teams
Add Microsoft Teams channel integration via Chat SDK.
Claude Code
$ npx -y skills add nanocoai/nanoclaw --skill add-teams --agent claude-code
Codex
$ npx skills add nanocoai/nanoclaw --skill add-teams -a codex -y
Cursor
$ npx skills add nanocoai/nanoclaw --skill add-teams -a cursor -y
Gemini CLI
$ npx skills add nanocoai/nanoclaw --skill add-teams -a gemini-cli -y
GitHub Copilot
$ npx skills add nanocoai/nanoclaw --skill add-teams -a github-copilot -y
OpenCode
$ npx skills add nanocoai/nanoclaw --skill add-teams -a opencode -y
Windsurf
$ npx skills add nanocoai/nanoclaw --skill add-teams -a windsurf -y
SKILL.md
add-teams.SKILL.mdname: add-teams
description: Add Microsoft Teams channel integration via Chat SDK.
Add Microsoft Teams Channel
Adds Microsoft Teams support via the Chat SDK bridge — interactive chat in team channels, group chats, and direct messages. NanoClaw doesn't ship channels in trunk — this skill copies the Teams adapter in from the `channels` branch.
The mechanical steps under **Apply** carry `nc:` directive fences: an agent reads the prose and applies them, and a parser can apply them deterministically from the same document. Every directive is idempotent, so the whole skill is safe to re-run; anything a parser can't apply falls back to the prose beside it.
Teams has no "paste a token" shortcut — a bot has to exist in Microsoft's cloud before it can receive a message. The Microsoft Teams CLI collapses that into one sign-in and one create command: it registers the Entra app, generates the client secret, registers a Teams-managed bot (through the Teams Developer Portal — **no Azure subscription needed**), uploads the app package, and hands back an install link. The old ~7-step Azure portal walk survives only as a fallback in [Alternatives](#alternatives) for tenants where the Developer Portal is blocked.
Apply
1. Copy the adapter and its registration test
Fetch the `channels` branch and copy the Teams adapter and its registration test into `src/channels/` (overwrite — the branch is canonical):
src/channels/teams.ts
src/channels/teams-registration.test.ts
2. Register the adapter
Append the self-registration import to the channel barrel (skipped if the line is already present). This one line is the skill's only reach-in into core:
import './teams.js';
3. Install the adapter package
Pinned to an exact version — the supply-chain policy rejects ranges and `latest`:
@chat-adapter/teams@4.41.1
4. Build and validate
Build first: it guards the typed `createChatSdkBridge(...)` core call and proves the dependency is installed. Then run the one integration test.
pnpm run build
pnpm exec vitest run src/channels/teams-registration.test.ts
`teams-registration.test.ts` imports the real channel barrel and asserts the registry contains `teams`. It goes red if the import line is deleted or drifts, if the barrel fails to evaluate, or if `@chat-adapter/teams` isn't installed (the import throws) — so it also covers the dependency from step 3. End-to-end delivery against a real Teams workspace is verified manually once the service runs.
Credentials
The adapter is installed and registered, but it can't receive a message until a bot exists, points at this machine, and is installed into Teams. The Teams CLI does all of that below.
Check for existing credentials
Re-running `teams app create` provisions a brand-new app registration and bot each time — it never reuses the first one. So the flow starts with a probe: when `.env` already carries a Teams credential — either key; a partial pair means a half-finished setup that creating ANOTHER app would only corrupt — every step below (prompts included) is skipped and the flow drops straight through to [Restart](#restart). To rotate credentials or finish a partial configuration, see [Troubleshooting](#troubleshooting); if your tunnel URL changed, the fix is `teams app update`, not a re-run (also in Troubleshooting).
( grep -q '^TEAMS_APP_ID=.' .env 2>/dev/null || grep -q '^TEAMS_APP_PASSWORD=.' .env 2>/dev/null ) && echo yes || echo no
Before creating anything, tell the user:
Confirm you have everything Teams setup needs:
1. A Microsoft 365 account that can create Entra app registrations and upload custom apps (sideloading) — free personal Teams does NOT qualify; you need a Microsoft 365 Business / EDU / developer tenant.
2. A way to expose an HTTPS endpoint that forwards to this machine's webhook port 3000 (e.g. a Cloudflare Tunnel, or a reverse-proxied VPS). Start it now if it isn't running — e.g. `cloudflared tunnel --url http://localhost:3000` — the create step needs the URL up front. The next prompt asks for its public base URL: just the https:// origin, no trailing path. NanoClaw's webhook server listens on 127.0.0.1 only, so a tunnel or proxy on this machine works as is. If yours runs on another machine or in Docker on Linux, add `WEBHOOK_HOST=0.0.0.0` to `.env` before the restart step.
Note: the bot is created single-tenant (only your own Microsoft 365 tenant can install it) — the right default for a self-hosted assistant. If you need a bot other tenants can install, set it up manually via the Alternatives section of this skill instead.
Public URL
Microsoft delivers bot messages to an HTTPS endpoint you control; it has to reach this machine's webhook server (port 3000, configurable via `WEBHOOK_PORT`) at `/webhook/teams`.
Paste your tunnel's public https:// URL — e.g. https://your-tunnel.trycloudflare.com
App name
One more choice belongs to the human before anything is created. The name is used everywhere at once: the Entra app registration, the bot, and the Teams app are all created under it. There is no client-secret name to pick on this path — the CLI generates the secret itself (Entra displayName `default`, 2-year expiry); rotating it later is in [Troubleshooting](#troubleshooting).
What should the bot be called? One name covers the Entra app registration, the bot, and the Teams app (letters, digits, spaces, . _ -; max 30 characters) — e.g. NanoClaw.
Install the Teams CLI
Installed globally with npm — not as a workspace dependency — deliberately: the CLI's credential store (keytar) is a native modu
Read more
name: add-teams description: Add Microsoft Teams channel integration via Chat SDK.
Add Microsoft Teams Channel
Adds Microsoft Teams support via the Chat SDK bridge — interactive chat in team channels, group chats, and direct messages. NanoClaw doesn't ship channels in trunk — this skill copies the Teams adapter in from the `channels` branch.
The mechanical steps under **Apply** carry `nc:` directive fences: an agent reads the prose and applies them, and a parser can apply them deterministically from the same document. Every directive is idempotent, so the whole skill is safe to re-run; anything a parser can't apply falls back to the prose beside it.
Teams has no "paste a token" shortcut — a bot has to exist in Microsoft's cloud before it can receive a message. The Microsoft Teams CLI collapses that into one sign-in and one create command: it registers the Entra app, generates the client secret, registers a Teams-managed bot (through the Teams Developer Portal — **no Azure subscription needed**), uploads the app package, and hands back an install link. The old ~7-step Azure portal walk survives only as a fallback in [Alternatives](#alternatives) for tenants where the Developer Portal is blocked.
Apply
1. Copy the adapter and its registration test
Fetch the `channels` branch and copy the Teams adapter and its registration test into `src/channels/` (overwrite — the branch is canonical):
src/channels/teams.ts src/channels/teams-registration.test.ts
2. Register the adapter
Append the self-registration import to the channel barrel (skipped if the line is already present). This one line is the skill's only reach-in into core:
import './teams.js';
3. Install the adapter package
Pinned to an exact version — the supply-chain policy rejects ranges and `latest`:
@chat-adapter/teams@4.41.1
4. Build and validate
Build first: it guards the typed `createChatSdkBridge(...)` core call and proves the dependency is installed. Then run the one integration test.
pnpm run build
pnpm exec vitest run src/channels/teams-registration.test.ts
`teams-registration.test.ts` imports the real channel barrel and asserts the registry contains `teams`. It goes red if the import line is deleted or drifts, if the barrel fails to evaluate, or if `@chat-adapter/teams` isn't installed (the import throws) — so it also covers the dependency from step 3. End-to-end delivery against a real Teams workspace is verified manually once the service runs.
Credentials
The adapter is installed and registered, but it can't receive a message until a bot exists, points at this machine, and is installed into Teams. The Teams CLI does all of that below.
Check for existing credentials
Re-running `teams app create` provisions a brand-new app registration and bot each time — it never reuses the first one. So the flow starts with a probe: when `.env` already carries a Teams credential — either key; a partial pair means a half-finished setup that creating ANOTHER app would only corrupt — every step below (prompts included) is skipped and the flow drops straight through to [Restart](#restart). To rotate credentials or finish a partial configuration, see [Troubleshooting](#troubleshooting); if your tunnel URL changed, the fix is `teams app update`, not a re-run (also in Troubleshooting).
( grep -q '^TEAMS_APP_ID=.' .env 2>/dev/null || grep -q '^TEAMS_APP_PASSWORD=.' .env 2>/dev/null ) && echo yes || echo no
Before creating anything, tell the user:
Confirm you have everything Teams setup needs: 1. A Microsoft 365 account that can create Entra app registrations and upload custom apps (sideloading) — free personal Teams does NOT qualify; you need a Microsoft 365 Business / EDU / developer tenant. 2. A way to expose an HTTPS endpoint that forwards to this machine's webhook port 3000 (e.g. a Cloudflare Tunnel, or a reverse-proxied VPS). Start it now if it isn't running — e.g. `cloudflared tunnel --url http://localhost:3000` — the create step needs the URL up front. The next prompt asks for its public base URL: just the https:// origin, no trailing path. NanoClaw's webhook server listens on 127.0.0.1 only, so a tunnel or proxy on this machine works as is. If yours runs on another machine or in Docker on Linux, add `WEBHOOK_HOST=0.0.0.0` to `.env` before the restart step. Note: the bot is created single-tenant (only your own Microsoft 365 tenant can install it) — the right default for a self-hosted assistant. If you need a bot other tenants can install, set it up manually via the Alternatives section of this skill instead.
Public URL
Microsoft delivers bot messages to an HTTPS endpoint you control; it has to reach this machine's webhook server (port 3000, configurable via `WEBHOOK_PORT`) at `/webhook/teams`.
Paste your tunnel's public https:// URL — e.g. https://your-tunnel.trycloudflare.com
App name
One more choice belongs to the human before anything is created. The name is used everywhere at once: the Entra app registration, the bot, and the Teams app are all created under it. There is no client-secret name to pick on this path — the CLI generates the secret itself (Entra displayName `default`, 2-year expiry); rotating it later is in [Troubleshooting](#troubleshooting).
What should the bot be called? One name covers the Entra app registration, the bot, and the Teams app (letters, digits, spaces, . _ -; max 30 characters) — e.g. NanoClaw.
Install the Teams CLI
Installed globally with npm — not as a workspace dependency — deliberately: the CLI's credential store (keytar) is a native modu
A lightweight alternative to OpenClaw that runs in containers for security. Connects to WhatsApp, Telegram, Slack, Discord, Gmail and other messaging apps,, has memory, scheduled jobs, and runs directly on Anthropic's Agents SDK
Other skills on nanoclaw.
More skills from other plugins.
browser-use
Direct browser control via CDP for web interaction: automation, scraping, testing, screenshots, and site/app work. Also covers…
agent-browser
Browser automation CLI for AI agents. Use when the user needs to interact with websites, including navigating pages, filling…
opencli-adapter-author
Build or improve an OpenCLI JS adapter using observed site behavior, existing adapters and browser API evidence. For ad-hoc…
Questions about add-teams.
- Which coding agents can use add-teams?
- add-teams installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.

