This guide explains how to run Teams apps using the Teams AI Library without relying on the ATK VS Code extension, using custom shell functions for a more controlled development experience.
Instead of using the ATK VS Code extension (which recreates devtunnels on every launch), this approach uses a long-living devtunnel and custom functions to streamline the development process.
- Dev Tunnels CLI installed
- Teams Toolkit CLI (
npm install -g @microsoft/teamsapp-cli
) - Teams CLI (
npm i -g @microsoft/teams.cli@preview
) - Custom functions loaded in your shell:
- Bash/Zsh: Source the
teams-dev-functions.sh
script (see Bash/Zsh setup below) - PowerShell: Load the
teams-dev-functions.ps1
module (see PowerShell setup below)
- Bash/Zsh: Source the
Use the tunnel creation function to create a persistent devtunnel:
Bash/Zsh:
create_tunnel <tunnel_name> <port>
# Example:
create_tunnel myteamsapp 3978
PowerShell:
Create-Tunnel -TunnelName "<tunnel_name>" -Port <port>
# Example:
Create-Tunnel -TunnelName "myteamsapp" -Port 3978
This function:
- Creates a new devtunnel with the specified name
- Sets up the port mapping
- Configures anonymous access
Ensure your project has the correct ATK files:
npx @microsoft/teams.cli@preview config add atk.basic
Use the provisioning function to register and provision your bot:
For TypeScript projects: Run from the root directory
Bash/Zsh:
provision_ttk_local
PowerShell:
Invoke-ProvisionTtkLocal
For .NET projects: Run from the TeamsApp directory
Bash/Zsh:
cd TeamsApp
provision_ttk_local
PowerShell:
Set-Location TeamsApp
Invoke-ProvisionTtkLocal
This function:
- Creates
env/.env.local
if it doesn't exist - Prompts for and configures
BOT_ENDPOINT
andBOT_DOMAIN
- Runs
teamsapp provision --env=local
You need two terminals running simultaneously:
devtunnel host <tunnel_name>
Example:
devtunnel host myteamsapp
For TypeScript/Node.js:
npm run dev
For .NET:
dotnet run --project <project-name>
- Persistent Tunnel: No need to update bot endpoints on every launch
- Better Control: Manual control over tunnel lifecycle
- Consistent URLs: Same tunnel URL across development sessions
- Cleaner Workflow: Separation of concerns between tunneling and application hosting
To use the Bash/Zsh functions, source the script in your shell session or profile:
# Load the functions (run this once per session)
source ./teams-dev-functions.sh
# Or add to your shell profile (~/.bashrc, ~/.zshrc, etc.)
echo "source $(pwd)/teams-dev-functions.sh" >> ~/.zshrc
To use the PowerShell functions, load the module in your PowerShell profile or session:
# Load the functions (run this once per session or add to your PowerShell profile)
. .\teams-dev-functions.ps1
# Or import as a module
Import-Module .\teams-dev-functions.ps1
To add to your PowerShell profile permanently:
# Add to your PowerShell profile
Add-Content $PROFILE ". `"$PWD\teams-dev-functions.ps1`""
Bash/Zsh: create_tunnel(tunnel_name, port)
PowerShell: Create-Tunnel -TunnelName <name> -Port <port>
Creates a new devtunnel with the specified name and port, configured for anonymous access.
Bash/Zsh: provision_ttk_local()
PowerShell: Invoke-ProvisionTtkLocal
Provisions a Teams Toolkit project for local development, handling environment configuration and bot registration.
- Ensure your devtunnel is running before starting your application server
- Verify the port in your tunnel matches the port your application is running on
- Check that
BOT_ENDPOINT
inenv/.env.local
matches your tunnel URL - If you encounter issues with bot registration, verify your tunnel is accessible and anonymous access is enabled
Thanks Aamir!
CLI version of powershell script. Can be used from command line: https://gist.github.com/rajan-chari/8b1c4d8c54609a8c89c42bf7cfef3d02