teams-sdk-project

Scaffold a Microsoft Teams SDK bot project in TypeScript that brings agents into Teams. Use this skill whenever the user wants to create a Teams bot, scaffold a Teams project, build a Teams agent, bring an AI agent into Microsoft Teams, or set up a new bot using the Teams SDK. Also trigger when the user mentions 'teams2', 'teams CLI', 'dev tunnel for Teams', or wants to register a bot with Azure AD for Teams. Even if the user just says something like 'I want to make a bot for Teams' or 'set up a Teams project', this skill should be used.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "teams-sdk-project" with this command: npx skills add heyitsaamir/teams.ts-skills/heyitsaamir-teams-ts-skills-teams-sdk-project

Teams SDK Project Scaffolding

This skill walks developers through the full end-to-end process of creating a Teams bot project in TypeScript — from dev tunnel setup through bot registration to a running, message-handling bot.

Overview

There are three phases to getting a Teams bot running:

  1. Dev Tunnel — Create a public tunnel so Teams can reach your local server
  2. Bot Registration — Use the teams2 CLI to register an Azure AD app, create a bot, and get credentials
  3. Project Scaffolding — Generate the TypeScript project files and wire everything together

Phase 1: Dev Tunnel

The bot needs a publicly accessible HTTPS endpoint. Teams sends messages to this URL. During development, a tunnel forwards traffic from a public URL to localhost:3978.

Ask the user which tunnel provider they prefer, then follow the appropriate section.

Option A: Microsoft Dev Tunnels (devtunnel)

Check if devtunnel is installed by running devtunnel --version. If not installed:

brew install microsoft/dev-tunnels/devtunnel

Check if the user is logged in with devtunnel user show. If not:

devtunnel user login

Create the tunnel — run these commands to create a named, persistent tunnel. Use the project name as the tunnel name:

devtunnel create <tunnel-name> -a
devtunnel port create <tunnel-name> -p 3978

Get the tunnel URL — run this to retrieve the endpoint URL (available immediately after creation, before hosting):

devtunnel show <tunnel-name>

Parse the "Connect via browser" URL from the output. It will look like https://<tunnel-name>-3978.<region>.devtunnels.ms. Save this — it's used as the bot endpoint in Phase 2.

Option B: ngrok

Tell the user to run ngrok in a separate terminal (long-running process):

brew install ngrok   # if not installed
ngrok http 3978

The user needs to share the forwarding URL (e.g., https://abc123.ngrok-free.app) back before proceeding.

Phase 2: Bot Registration with teams2 CLI

Check if teams2 is installed by running teams2 --version. If not installed:

npm install -g https://github.com/heyitsaamir/teamscli/releases/latest/download/teamscli.tgz

Check if the user is logged in with teams2 status. If not, run:

teams2 login

This opens a device-code authentication flow — the user needs to complete the browser authentication step.

Create the bot — run this using the tunnel URL from Phase 1. Write the .env file into the project directory:

teams2 app create -n "<project-name>" -e https://<tunnel-url>/api/messages --env <project-dir>/.env

This command automatically:

  1. Creates an Azure AD app registration
  2. Generates a client secret
  3. Registers the bot in the Teams Developer Portal
  4. Imports the app package with manifest
  5. Writes CLIENT_ID and CLIENT_SECRET to the .env file

After creation, read the CLIENT_ID from the .env file and show the Teams install link:

teams2 app view <CLIENT_ID> --web

Share this install link with the user so they can install the bot in Teams later.

Phase 3: Project Scaffolding

Ask the user which template they want:

  • Echo — Simple bot that echoes back messages. Good starting point.
  • AI — Bot with OpenAI/Azure OpenAI integration, streaming, and conversation memory. For building intelligent agents.

Then scaffold the project by creating the files described in the appropriate reference:

  • Echo template: read references/echo-template.md
  • AI template: read references/ai-template.md

Install dependencies after scaffolding:

cd <project-dir> && npm install

For the AI template, the user also needs to add their OpenAI/Azure OpenAI credentials to .env.

Getting it Running

Once everything is scaffolded, tell the user to run two commands in separate terminals:

  1. Host the tunnel (if using devtunnel):

    devtunnel host <tunnel-name>
    
  2. Start the bot:

    npm run dev
    

The bot is now live. The install link was already shown after bot registration in Phase 2 — remind the user to open it in Teams to start chatting with the bot.

Project Structure

Both templates produce this structure:

<project-name>/
├── src/
│   └── index.ts          # Bot entry point
├── .env                   # Credentials (from teams2)
├── package.json
├── tsconfig.json
└── tsup.config.js

Environment Variables Reference

Echo bot

VariableDescriptionSource
CLIENT_IDAzure AD app client IDteams2 app create
CLIENT_SECRETAzure AD app client secretteams2 app create
PORTServer port (default: 3978)Optional

AI bot (additional)

VariableDescriptionSource
OPENAI_API_KEYOpenAI API keyUser provides
AZURE_OPENAI_API_KEYAzure OpenAI API key (alternative)User provides
AZURE_OPENAI_ENDPOINTAzure OpenAI endpoint URLUser provides
AZURE_OPENAI_API_VERSIONAzure OpenAI API versionUser provides
AZURE_OPENAI_MODEL_DEPLOYMENT_NAMEAzure OpenAI deployment nameUser provides

Key SDK Concepts

The App class

The App from @microsoft/teams.apps is the main entry point. It handles HTTP server setup, authentication, and activity routing.

Event handlers

Register handlers with app.on(eventName, handler):

  • 'message' — User sends a message
  • 'install.add' — Bot is installed
  • 'message.submit.feedback' — User gives feedback on a message

Handler parameters: { send, reply, stream, activity, next, log }

  • send(activity) — Send a new message
  • reply(activity) — Reply to the current message
  • stream.emit(chunk) — Stream a response chunk
  • activity — The incoming activity/message
  • next() — Pass to the next handler (middleware pattern)
  • log — Logger instance

AI capabilities (AI template)

  • ChatPrompt from @microsoft/teams.ai — Manages LLM conversations with system instructions and message history
  • OpenAIChatModel from @microsoft/teams.openai — Connects to OpenAI or Azure OpenAI
  • .addAiGenerated() on MessageActivity — Marks response as AI-generated in Teams UI
  • Streaming via onChunk callback and stream.emit()

Plugins

  • DevtoolsPlugin from @microsoft/teams.dev — Adds development tooling and debugging support

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

openclaw-version-monitor

监控 OpenClaw GitHub 版本更新,获取最新版本发布说明,翻译成中文, 并推送到 Telegram 和 Feishu。用于:(1) 定时检查版本更新 (2) 推送版本更新通知 (3) 生成中文版发布说明

Archived SourceRecently Updated
Coding

ask-claude

Delegate a task to Claude Code CLI and immediately report the result back in chat. Supports persistent sessions with full context memory. Safe execution: no data exfiltration, no external calls, file operations confined to workspace. Use when the user asks to run Claude, delegate a coding task, continue a previous Claude session, or any task benefiting from Claude Code's tools (file editing, code analysis, bash, etc.).

Archived SourceRecently Updated
Coding

ai-dating

This skill enables dating and matchmaking workflows. Use it when a user asks to make friends, find a partner, run matchmaking, or provide dating preferences/profile updates. The skill should execute `dating-cli` commands to complete profile setup, task creation/update, match checking, contact reveal, and review.

Archived SourceRecently Updated
Coding

clawhub-rate-limited-publisher

Queue and publish local skills to ClawHub with a strict 5-per-hour cap using the local clawhub CLI and host scheduler.

Archived SourceRecently Updated