Teams App Developer
MicrosoftOfficialPublished by Microsoft
- Skill
- Tool integration
- Software development
- MIT
- Medium risk
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
The teams-app-developer skill provides a structured framework for managing the lifecycle of Microsoft 365 agents and Teams applications. It leverages the ATK CLI to handle project scaffolding, local testing via the Agents Playground, cloud provisioning on Azure, and troubleshooting. The skill includes specialized guidance for migrating Slack bots to Teams, including converting Block Kit UI to Adaptive Cards, and provides access to an extensive library of micro-expert documentation for cross-platform development.
What it does
- Scaffolds new Microsoft 365 agents and Teams applications from templates.
- Facilitates local testing using the Agents Playground or Teams-specific environments.
- Automates Azure resource provisioning and cloud deployment workflows.
- Provides diagnostic procedures for common authentication and configuration errors.
- Supports migration of Slack bots to the Teams platform.
- Manages project configuration and environment variables for ATK-based projects.
When to use it
- When starting a new Teams app, bot, or Declarative Agent project.
- When you need to test an agent locally before deploying to the cloud.
- When migrating existing Slack bots to the Microsoft Teams ecosystem.
- When troubleshooting deployment or authentication issues in a Teams project.
- When you need to provision Azure infrastructure for a Teams application.
Advantages
- Streamlines the development lifecycle with standardized CLI commands.
- Reduces development time by offering a local testing playground.
- Provides expert-level guidance for complex cross-platform migrations.
- Ensures consistent configuration management across development environments.
- Includes robust error-handling protocols for common platform-specific pitfalls.
Usage examples
- “Create a new Teams bot project using the default template.”
- The agent will initialize a new project folder, configure the necessary YAML files, and guide you through the initial setup using the ATK CLI.
- “How do I migrate my Slack bot to Microsoft Teams?”
- The agent will initiate the slack-to-teams workflow, providing access to cross-platform bridging experts and guidance on converting UI components.
- “My Teams bot is returning a 401 error, how do I fix it?”
- The agent will trigger the troubleshooting workflow, checking your environment variables, tunnel status, and authentication configuration.
Install
Download the skill as a ZIP:
https://mp-staging.autogineer.com/agent-skills/microsoft/teams-app-developer/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip teams-app-developer.zip -d .agents/skills
Documentation by Microsoft
Microsoft 365 Agents Toolkit Skill
Build Microsoft 365 agents and Teams apps using the ATK CLI.
AI Behavior Guidelines
Testing Strategy: Recommend Agents Playground first (faster, no M365 needed). Use Teams workflow only if user explicitly requests it.
Environment Variables: NEVER hardcode secrets or make up placeholder values. Always ask users for real values.
Error Handling: Read error messages carefully. Check
env/.env.local,.localConfigs, andatk auth list. Common pitfalls:AADSTS7000229→aadApp/createmissinggenerateServicePrincipal: truein YAML — add it and re-provisionMissing
TENANT_IDin.localConfigs→ SDK uses wrong token authority → 401 from Bot Connector401 persists after auth fix → devtunnel URL may be blacklisted — create a fresh tunnel
See troubleshoot/troubleshoot.md for full diagnostic steps
Long-Running Commands — WAIT for completion:
atk new,atk provision,atk deploycan take several minutesAlways wait for completion before running the next step (timeout 120000ms+)
Local Service Startup — Hangs terminal (expected):
npm run dev,npm start,python app.py,devtunnel host, etc. will hang — the process keeps running indefinitelyALWAYS run as a background process (
isBackground=true) — NEVER useisBackground=falsefor these commandsDo NOT wait for it to "finish" — verify startup by checking output for "listening on port" or tunnel URL
If errors appear, read logs, diagnose, fix, restart
Use a NEW terminal to launch Agents Playground or open Teams sideloading URL
Monitor App Logs: Periodically check background terminal output for runtime errors. If the app crashes, read the error, fix the root cause, and restart.
Telemetry Tagging: Before running any
atkCLI commands, set the session environment variable so all CLI invocations are tagged as skill-initiated:export ATK_CLI_SKILL=trueRun this once at the start of the session. All subsequent
atkcommands in the same terminal will inherit it.
ATK CLI Setup
atk --version # Must be > 1.1.5-betaIf ATK is not found or version is too old:
npm i -g @microsoft/m365agentstoolkit-cli@betaCLI Global Options
| Option | Meaning | Recommendation |
|---|---|---|
-i | Interactive mode | Always use -i false in automation to avoid hanging |
-f | Project folder | Default to be current directory, used when specifying a custom folder. When scaffolding a new project, this is the parent folder where the project folder will be created under. |
-h | Command help | Use atk <command> -h for quick syntax checks |
Sub-Skills
| Sub-Skill | When to Use | Reference |
|---|---|---|
| create-project | Scaffold new project from template, choose template, atk new | create-project/create-project.md |
| test-playground | Test locally with Agents Playground, agentsplayground, quick testing | test-playground/test-playground.md |
| test-teams | Run on Teams, devtunnel, sideload, Teams testing, test in Copilot | test-teams/test-teams.md |
| provision-deploy | Provision Azure resources, deploy to cloud, atk provision, atk deploy | provision-deploy/provision-deploy.md |
| troubleshoot | Fix errors, 401, port conflicts, YAML errors, stale bots | troubleshoot/troubleshoot.md |
| slack-to-teams | Migrate Slack bot to Teams, cross-platform bridging, Block Kit to Adaptive Cards | slack-to-teams/SKILL.md |
MANDATORY: Before executing any workflow, read the corresponding sub-skill document.
Shared References
manifest-and-yaml.md — Project files, YAML config, env vars, .localConfigs flow
commands.md — ATK CLI commands: package, validate, share, collaborate
templates.md — Complete template catalog with language support
experts/ — 100+ micro-expert files: Teams SDK, Slack SDK, cross-platform bridging, deploy, AI models, security, language conversion
docs/ — Platform comparison guides: UI, messaging, identity, infrastructure, feature gaps
Workflow Chains
Match user intent to the smallest valid workflow.
| User Intent | Workflow (read in order) |
|---|---|
| Build new app from scratch | create-project → test-playground |
| Test existing project locally | test-playground (recommended) or test-teams |
| Deploy to Azure | provision-deploy |
| Fix broken bot | troubleshoot → re-test |
| Migrate Slack bot to Teams | slack-to-teams |
MANDATORY: Before executing any slack-to-teams workflow, read slack-to-teams/SKILL.md first. The sub-skill contains a routed expert system with 100+ micro-expert files for cross-platform bot development.
ATK Project Context Resolution
Resolve config values only when missing. If a value is already known in the session, reuse it.
Step 1: Detect ATK Project
If m365agentstoolkit*.yml exists in the current folder, treat it as an ATK project and parse configuration.
Step 2: Resolve Common Configuration
Resolve variables referenced in m365agentstoolkit*.yml. Common variables:
AZURE_OPENAI_API_KEY
AZURE_OPENAI_ENDPOINT
AZURE_OPENAI_DEPLOYMENT_NAME
Step 3: Collect Missing Values
If required values are missing, ask the user for only the missing ones.
Refer to manifest-and-yaml.md for full config-file details.
Files
- ATTRIBUTION.mdAdded by AutoGineer906 B
- LICENSELicence file added by AutoGineer1.1 KiB
- SKILL.md7.6 KiB
- create-project/create-project.md8.1 KiB
- docs/README.md2.8 KiB
- docs/advanced-features.md7.0 KiB
- docs/feature-gaps.md46.3 KiB
- docs/files-and-links.md4.2 KiB
- docs/identity-and-auth.md4.3 KiB
- docs/infrastructure.md6.7 KiB
- docs/interactive-responses.md4.4 KiB
- docs/messaging-and-commands.md4.5 KiB
- docs/middleware-and-handlers.md4.4 KiB
- docs/ui-components.md6.9 KiB
- docs/workflows.md14.4 KiB
- experts/README.md8.6 KiB
- experts/_expert-ts.md2.2 KiB
- experts/analyzer.md14.0 KiB
- experts/bridge/app-distribution-packaging-ts.md14.2 KiB
- experts/bridge/channel-ops-graph-ts.md15.4 KiB
- experts/bridge/commands-slash-text-ts.md18.5 KiB
- experts/bridge/cross-platform-advisor-ts.md36.4 KiB
- experts/bridge/cross-platform-architecture-ts.md8.3 KiB
- experts/bridge/events-activities-ts.md22.4 KiB
- experts/bridge/files-upload-download-ts.md17.2 KiB
- experts/bridge/identity-oauth-bridge-ts.md19.8 KiB
- experts/bridge/index.md13.0 KiB
- experts/bridge/infra-compute-ts.md14.6 KiB
- experts/bridge/infra-observability-ts.md14.0 KiB
- experts/bridge/infra-secrets-config-ts.md13.2 KiB
- experts/bridge/infra-storage-ts.md14.3 KiB
- experts/bridge/interactive-responses-ts.md19.6 KiB
- experts/bridge/link-unfurl-preview-ts.md17.1 KiB
- experts/bridge/middleware-handlers-ts.md15.4 KiB
- experts/bridge/python-cross-platform.md9.3 KiB
- experts/bridge/rate-limiting-resilience-ts.md17.6 KiB
- experts/bridge/rest-only-integration-ts.md8.4 KiB
- experts/bridge/scheduling-deferred-send-ts.md17.8 KiB
- experts/bridge/shortcuts-extensions-ts.md17.5 KiB
- experts/bridge/transport-socketmode-https-ts.md14.3 KiB
- experts/bridge/ui-app-home-personal-tab-ts.md14.5 KiB
- experts/bridge/ui-block-kit-adaptive-cards-ts.md21.5 KiB
- experts/bridge/ui-legacy-attachments-cards-ts.md11.2 KiB
- experts/bridge/ui-modals-dialogs-ts.md21.4 KiB
- experts/bridge/workflow.composable-platform-ts.md13.7 KiB
- experts/bridge/workflows-automation-ts.md14.3 KiB
- experts/builder.md11.1 KiB
- experts/convert/bulk-conversion-strategy-ts.md12.8 KiB
- experts/convert/dependency-mapping-ts.md8.3 KiB
- experts/convert/index.md3.5 KiB
- experts/convert/java-to-ts-ts.md20.6 KiB
- experts/convert/js-to-ts-ts.md6.2 KiB
- experts/convert/json-serialization-ts.md11.0 KiB
- experts/convert/kotlin-to-ts-ts.md11.2 KiB
- experts/convert/ruby-to-ts-ts.md9.7 KiB
- experts/convert/type-mapping-ts.md10.1 KiB
- experts/deploy/aws-bot-deploy-ts.md14.6 KiB
- experts/deploy/aws-cli-reference-ts.md52.4 KiB
- experts/deploy/azure-bot-deploy-ts.md15.4 KiB
- experts/deploy/azure-cli-reference-ts.md16.9 KiB
- experts/deploy/index.md4.6 KiB
- experts/fallback.md2.1 KiB
- experts/index.md18.9 KiB
- experts/models/anthropic-ts.md7.8 KiB
- experts/models/bedrock-ts.md9.9 KiB
- experts/models/foundry-cloud-ts.md8.1 KiB
- experts/models/foundry-local-ts.md10.6 KiB
- experts/models/index.md5.8 KiB
- experts/models/openai-azure-openai-ts.md8.3 KiB
- experts/models/oss-openai-compatible-ts.md10.7 KiB
- experts/models/transformers-js-ts.md11.6 KiB
- experts/prompt-engineer.md14.7 KiB
- experts/researcher.md2.8 KiB
- experts/security/index.md1.2 KiB
- experts/security/input-validation-ts.md13.8 KiB
- experts/security/secrets-ts.md13.9 KiB
- experts/slack/bolt-assistant-ts.md9.9 KiB
- experts/slack/bolt-events-ts.md9.3 KiB
- experts/slack/bolt-java.md8.9 KiB
- experts/slack/bolt-oauth-distribution-ts.md10.9 KiB
- experts/slack/bolt-python.md9.5 KiB
- experts/slack/cli.app-management.md7.9 KiB
- experts/slack/cli.datastore-env.md8.6 KiB
- experts/slack/cli.getting-started.md8.0 KiB
- experts/slack/cli.local-dev-deploy.md8.4 KiB
- experts/slack/cli.manifest-triggers.md9.9 KiB
- experts/slack/index.md8.9 KiB
- experts/slack/runtime.ack-rules-ts.md9.8 KiB
- experts/slack/runtime.bolt-foundations-ts.md10.7 KiB
- experts/slack/runtime.shortcuts-ts.md11.0 KiB
- experts/slack/runtime.slash-commands-ts.md11.6 KiB
- experts/slack/runtime.socket-mode-ts.md9.5 KiB
- experts/slack/ui.block-kit-ts.md11.5 KiB
- experts/slack/ui.modals-lifecycle-ts.md13.3 KiB
- experts/slack/web-api-proactive-ts.md11.0 KiB
- experts/slack/workflow.slack-automations-ts.md10.2 KiB
- experts/teams/a2a.client-basics-ts.md9.7 KiB
- experts/teams/a2a.orchestrator-patterns-ts.md12.7 KiB
- experts/teams/a2a.server-basics-ts.md11.4 KiB
- experts/teams/ai.chatprompt-basics-ts.md8.1 KiB
- experts/teams/ai.citations-feedback-ts.md6.9 KiB
- experts/teams/ai.conversational-query-ts.md14.2 KiB
- experts/teams/ai.function-calling-design-ts.md9.0 KiB
- experts/teams/ai.function-calling-implementation-ts.md7.7 KiB
- experts/teams/ai.memory-localmemory-ts.md7.3 KiB
- experts/teams/ai.model-setup-ts.md6.6 KiB
- experts/teams/ai.rag-retrieval-ts.md7.4 KiB
- experts/teams/ai.rag-vectorstores-ts.md8.5 KiB
- experts/teams/ai.streaming-ts.md6.9 KiB
- experts/teams/auth.oauth-sso-ts.md10.1 KiB
- experts/teams/compat.botbuilder-interop-ts.md14.6 KiB
- experts/teams/dev.debug-test-ts.md14.1 KiB
- experts/teams/graph.usergraph-appgraph-ts.md9.0 KiB
- experts/teams/index.md9.8 KiB
- experts/teams/mcp.client-basics-ts.md9.5 KiB
- experts/teams/mcp.expose-chatprompt-tools-ts.md9.5 KiB
- experts/teams/mcp.security-ts.md10.4 KiB
- experts/teams/mcp.server-basics-ts.md9.9 KiB
- experts/teams/project.scaffold-files-ts.md12.2 KiB
- experts/teams/runtime.app-init-ts.md10.9 KiB
- experts/teams/runtime.manifest-ts.md12.3 KiB
- experts/teams/runtime.proactive-messaging-ts.md12.6 KiB
- experts/teams/runtime.routing-handlers-ts.md12.3 KiB
- experts/teams/state.storage-patterns-ts.md9.4 KiB
- experts/teams/teams-dotnet.md8.2 KiB
- experts/teams/teams-python.md8.3 KiB
- experts/teams/ui.adaptive-cards-ts.md12.9 KiB
- experts/teams/ui.dialogs-task-modules-ts.md15.1 KiB
- experts/teams/ui.message-extensions-ts.md15.6 KiB
- experts/teams/workflow.approvals-inline-ts.md12.4 KiB
- experts/teams/workflow.message-native-records-ts.md10.6 KiB
- experts/teams/workflow.sharepoint-lists-ts.md9.0 KiB
- experts/teams/workflow.state-driven-events-ts.md12.2 KiB
- experts/teams/workflow.triggers-compose-ts.md10.3 KiB
- experts/update-experts.md10.0 KiB
- provision-deploy/provision-deploy.md4.3 KiB
- test-playground/playground-cli.md4.6 KiB
- test-playground/playground.md4.5 KiB
- test-playground/test-playground.md1.1 KiB
- test-teams/test-teams.md4.9 KiB
- toolkit/README.md4.2 KiB
- toolkit/commands.md2.6 KiB
- toolkit/environments.md12.6 KiB
- toolkit/lifecycle-cli.md17.6 KiB
- toolkit/manifest-and-yaml.md6.0 KiB
- toolkit/playground.md7.6 KiB
- toolkit/publish.md9.3 KiB
- toolkit/templates.md6.7 KiB
- troubleshoot/troubleshoot.md20.2 KiB
experts/teams/dev.debug-test-ts.md
dev.debug-test-ts
purpose
Developer tools, local debugging, DevTools plugin, sideloading, tunneling, ConsoleLogger configuration, and build verification for Teams SDK v2.
rules
Always include
DevtoolsPluginfrom@microsoft/teams.devin thepluginsarray during local development. It provides a web-based DevTools UI, WebSocket-based real-time activity inspection, and message replay capabilities. github.com/microsoft/teams.ts -- devThe DevTools UI runs at
http://localhost:{PORT+1}/devtools(defaulthttp://localhost:3979/devtools). It starts automatically when the app starts withDevtoolsPluginregistered. Open it in a browser to inspect inbound and outbound activities. github.com/microsoft/teams.ts -- devThe bot endpoint is
http://localhost:{PORT}/api/messages(defaulthttp://localhost:3978/api/messages). This is the URL that Teams (or the Bot Framework Emulator) sends activities to. For Azure deployment, update the messaging endpoint tohttps://your-domain/api/messages. github.com/microsoft/teams.tsRun locally with
npm run devwhich executestsx watch -r dotenv/config src/index.ts. This provides TypeScript execution with automatic file watching -- changes to source files trigger an instant restart without a build step. github.com/microsoft/teams.tsConfigure logging with
ConsoleLoggerat the appropriate level:'trace'for deep SDK internals,'debug'for development,'info'for staging,'warn'or'error'for production. Usepattern: '-azure/msal-node'to suppress noisy MSAL authentication logs. Child loggers are created withlogger.child('name'). github.com/microsoft/teams.ts -- commonRun
npx tsc --noEmitas a build verification gate before testing or deploying. This type-checks all TypeScript source without producing output files. The project must compile cleanly -- type errors caught here prevent runtime failures. github.com/microsoft/teams.tsFor testing with real Teams clients locally, use a tunneling solution (ngrok, dev tunnels, Cloudflare Tunnel) to expose your local
localhost:3978endpoint over HTTPS. Update the Azure Bot messaging endpoint to the tunnel URL (e.g.,https://abc123.ngrok.io/api/messages). learn.microsoft.com -- Dev tunnelsSideload the app by opening the Teams sideloading URL after provisioning:
https://teams.microsoft.com/l/app/${{TEAMS_APP_ID}}?installAppPackage=true&webjoin=true&appTenantId=${{TENANT_ID}}&login_hint=${{USER_EMAIL}}UseTEAMS_APP_IDandUSER_EMAILfromenv/.env.local; useTENANT_IDfrom.localConfigs(generated byatk deploy --env local, mapped fromTEAMS_APP_TENANT_IDinenv/.env.local). Alternatively, zip theappPackage/directory (manifest.json + icons) and upload in Teams via Apps > Manage your apps > Upload a custom app. Both paths require admin-enabled custom app upload or a developer tenant. learn.microsoft.com -- Sideload appsUse
skipAuth: trueinAppOptionsfor purely local development against DevTools without Azure Bot credentials. This disables JWT validation. Never use it in production or when testing against real Teams clients. github.com/microsoft/teams.ts -- appsUse Agents Toolkit (ATK) as the recommended provisioning path for local development. First start a devtunnel (
devtunnel host -p 3978 --allow-anonymous) and setBOT_ENDPOINTinenv/.env.localto the tunnel URL. Then runatk provision --env local -i falseto create the Entra ID app registration, Bot Framework registration, and Teams app. Then runatk deploy --env local -i falseto generate.localConfigswith CLIENT_ID, CLIENT_SECRET, TENANT_ID, and PORT. Verify.localConfigshas TENANT_ID — if missing, copy the value ofTEAMS_APP_TENANT_IDfromenv/.env.localintoTENANT_IDin.localConfigs. See →toolkit.lifecycle-cli.mdfor the full m365agents.yml reference. learn.microsoft.com -- Agents ToolkitFor manual bot registration without ATK, create the Entra ID app registration and Azure Bot resource through the Azure Portal or Azure CLI, then copy the credentials into
.env. This path is useful for understanding what ATK automates or when ATK is not available. See →azure-bot-deploy-ts.mdfor the full manual workflow.
patterns
Local development setup with DevTools
import { App } from '@microsoft/teams.apps';
import { ConsoleLogger } from '@microsoft/teams.common';
import { DevtoolsPlugin } from '@microsoft/teams.dev';
const app = new App({
// Use skipAuth for local DevTools-only testing (no Azure credentials needed)
// Remove skipAuth when testing against real Teams clients
skipAuth: true,
logger: new ConsoleLogger('dev-bot', { level: 'debug' }),
plugins: [new DevtoolsPlugin()],
});
app.on('message', async ({ reply, activity }) => {
await reply(`Echo: ${activity.text}`);
});
// Bot endpoint: http://localhost:3978/api/messages
// DevTools UI: http://localhost:3979/devtools
app.start(3978);Production-ready logging configuration
import { App } from '@microsoft/teams.apps';
import { ConsoleLogger } from '@microsoft/teams.common';
import { DevtoolsPlugin } from '@microsoft/teams.dev';
// Development logger: verbose, noisy auth logs suppressed
const devLogger = new ConsoleLogger('my-bot', {
level: 'debug',
pattern: '-azure/msal-node',
});
// Production logger: only warnings and errors
const prodLogger = new ConsoleLogger('my-bot', {
level: 'warn',
});
// Choose based on environment
const isProduction = process.env.NODE_ENV === 'production';
const logger = isProduction ? prodLogger : devLogger;
const app = new App({
clientId: process.env.CLIENT_ID,
clientSecret: process.env.CLIENT_SECRET,
tenantId: process.env.TENANT_ID,
logger,
// Only include DevtoolsPlugin in non-production
plugins: isProduction ? [] : [new DevtoolsPlugin()],
});
// Child loggers for scoped output
app.on('message', async (ctx) => {
const handlerLog = ctx.log; // Scoped to this activity
handlerLog.info(`Message from ${ctx.activity.from.name}`);
// Output: [my-bot] Message from John Doe
await ctx.send('Hello!');
});
app.start(process.env.PORT || 3978).catch(console.error);Build verification and debugging workflow
// === Option A: ATK-provisioned workflow (recommended) ===
// 1. Install dependencies
// npm install
// 2. Start a dev tunnel (must be running BEFORE provisioning)
// devtunnel host -p 3978 --allow-anonymous
// Copy the tunnel URL and set BOT_ENDPOINT in env/.env.local
// 3. Provision bot resources via ATK (creates Entra ID app + Bot Framework + Teams app)
// atk provision --env local -i false
// 4. Generate .localConfigs with credentials
// atk deploy --env local -i false
// Verify .localConfigs contains CLIENT_ID, CLIENT_SECRET, TENANT_ID, PORT.
// If TENANT_ID is missing, copy the value of TEAMS_APP_TENANT_ID from env/.env.local into TENANT_ID in .localConfigs.
// 5. Type-check the project (build gate)
// npx tsc --noEmit
// 6. Start dev server with file watching
// npm run dev
// 7. Open DevTools in browser
// http://localhost:3979/devtools
// 7. For real Teams testing, start a dev tunnel and provision:
// devtunnel host -p 3978 --allow-anonymous
// Set BOT_ENDPOINT in env/.env.local to the tunnel URL
// atk provision --env local -i false
// atk deploy --env local -i false
// Open Teams sideload URL (TEAMS_APP_ID from env/.env.local):
// https://teams.microsoft.com/l/app/$TEAMS_APP_ID?installAppPackage=true&webjoin=true&appTenantId=$TENANT_ID
// (TEAMS_APP_ID from env/.env.local; TENANT_ID from .localConfigs, mapped from TEAMS_APP_TENANT_ID in env/.env.local)
// === Option B: Manual workflow (no ATK) ===
// 1. npm install
// 2. Create .env: CLIENT_ID, CLIENT_SECRET, TENANT_ID, PORT=3978
// (Register bot manually -- see azure-bot-deploy-ts.md)
// 3. npx tsc --noEmit
// 4. npm run dev
// 5. devtunnel host -p 3978 --allow-anonymous → update Azure Bot messaging endpoint
// 6. Sideload: zip appPackage/ → upload in Teams
// === Build for production (both options) ===
// npm run build # Compiles to dist/ via tsup
// npm run start # Runs compiled JS: node -r dotenv/config .
// Common troubleshooting:
// - Bot not responding in Teams?
// Check: tunnel running, messaging endpoint updated, manifest scopes correct
// - DevTools blank?
// Check: DevtoolsPlugin in plugins array, port+1 not blocked
// - Type errors on import?
// Check: tsconfig module is "NodeNext", not "commonjs"
// - .env not loaded?
// Check: dotenv in devDependencies, -r dotenv/config in scripts
// - 401 Unauthorized after atk deploy?
// Check: .localConfigs has TENANT_ID; if missing, copy the value of TEAMS_APP_TENANT_ID from env/.env.local into TENANT_ID in .localConfigspitfalls
Forgetting to start the tunnel: Without ngrok or dev tunnels, the Azure Bot Framework cannot reach your local endpoint. Teams messages never arrive. Always verify the tunnel is running and the messaging endpoint is updated.
DevTools port conflict: DevTools runs on
PORT + 1. If port 3979 is already in use, DevTools fails silently. Check for port conflicts or change the bot'sPORT.Using
skipAuthwith real Teams clients:skipAuth: truedisables JWT validation. Real Teams activities require proper authentication. UseskipAuthonly with DevTools for rapid iteration.Not running
npx tsc --noEmit: Skipping the type-check means errors surface only at runtime. Always run this gate after changes, especially before committing or deploying.Stale tunnel URL in Azure Bot config: Ngrok generates a new URL each time it restarts (unless on a paid plan). Forgetting to update the Azure Bot messaging endpoint after restarting ngrok means the bot stops receiving messages.
Missing sideload permissions: Sideloading requires either admin-enabled custom app upload or a Microsoft 365 developer tenant. Without it, the "Upload a custom app" option does not appear in Teams.
Wrong log level in production: Running with
'debug'or'trace'in production floods logs and can impact performance. Switch to'info'or'warn'for deployed environments.Testing only in DevTools: DevTools simulates a Teams client but does not replicate all Teams behaviors (e.g., @mention stripping, SSO token exchange, card rendering differences). Always test in a real Teams client before shipping.
.localConfigsmissing TENANT_ID: Afteratk deploy --env local, the generated.localConfigsmay omitTENANT_ID. Without it, MSAL defaults to the wrong token authority, causing 401 errors. Copy the value ofTEAMS_APP_TENANT_IDfromenv/.env.localintoTENANT_IDin.localConfigs.Dev tunnel URL blacklisted or expired: Dev tunnel URLs can be flagged by corporate proxies or expire after inactivity. If the bot suddenly stops receiving messages with a working tunnel, create a fresh tunnel and update the messaging endpoint.
references
instructions
This expert covers local development, debugging, and testing workflows for Teams SDK v2 bots. Use it when you need to:
Set up
DevtoolsPluginand access the DevTools UI atlocalhost:3979/devtoolsRun the bot locally with
npm run dev(tsx watch with hot reload)Configure
ConsoleLoggerlevels and noise filtering for different environmentsUse
skipAuth: truefor credential-free local testingProvision bot credentials locally with
atk provision --env localandatk deploy --env localSet up dev tunnels or ngrok for testing with real Teams clients
Sideload the bot via the Teams sideloading URL or by packaging and uploading
appPackage/as a zipRun
npx tsc --noEmitas a build verification gateTroubleshoot common issues (bot not responding, DevTools blank, import errors)
Understand the difference between DevTools testing and real Teams testing
Pair with runtime.app-init-ts.md for App constructor setup and project.scaffold-files-ts.md for npm scripts and project file structure. Pair with project.scaffold-files-ts.md for npm scripts and build verification, and runtime.app-init-ts.md for DevtoolsPlugin configuration.
research
Deep Research prompt:
"Write a micro expert on developing, debugging, and testing Teams SDK v2 bots in TypeScript. Cover DevtoolsPlugin setup from @microsoft/teams.dev, DevTools UI at localhost:3979/devtools with WebSocket activity inspection and message replay, local development with npm run dev (tsx watch), bot endpoint at localhost:3978/api/messages, ConsoleLogger configuration (levels: error/warn/info/debug/trace, pattern filtering, child loggers), skipAuth for local testing, ngrok and dev tunnels for HTTPS exposure, sideloading via zip upload, npx tsc --noEmit build gate, M365 Agents Toolkit VS Code extension, and a troubleshooting flowchart for common issues (bot not responding, port conflicts, stale tunnel URLs, missing sideload permissions). Include a step-by-step local workflow and production logging patterns."
Requirements and compatibility
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Needs: Needs an API key, Needs Python, Needs Node.js
Security
What our scanner noticed· Medium risk
- Possible data-exfiltration endpoints
- Instructions that use the network
- Downloads piped into a shell
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- Published by
- Microsoft
- Publisher
- Microsoft (Official)
- Source
- microsoft/skills · .github/plugins/microsoft-365-agents-toolkit/skills/teams-app-developer · commit 0696600
- Licence
- MIT License (redistribution allowed)
- LICENSE (added by AutoGineer from LICENSE)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
AutoGineer is not affiliated with or endorsed by Microsoft.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download teams-app-developer.zip