Microsoft Teams Integration
Connect Microsoft Teams to capture decisions from your team's conversations.
Features
- Real-time capture -
@Alignto capture decisions instantly - Context extraction - Automatically includes surrounding conversation
- Channel support - Works in team channels
- Discover - Scan historical messages for past decisions
Setup (Cloud)
- Go to Settings → Integrations in Align
- Click Connect Teams
- Sign in with your Microsoft account
- Grant permissions for your tenant
- Add the Align bot to your desired channels
Adding Align to Channels
After connecting:
- Go to the Teams channel
- Click + to add a tab/app
- Search for "Align"
- Add the Align bot to the channel
Capturing Decisions
Basic Capture
Mention @Align with the decision:
@Align We decided to migrate to Azure Kubernetes Service
With Context
Include rationale for richer snapshots:
@Align Moving to AKS for the platform migration.
Key factors:
- Better integration with existing Azure services
- Cost optimization through reserved instances
- Team already has Azure expertise
Commands
| Trigger | Description |
|---|---|
@Align <decision> | Capture a new decision |
@Align help | Show available commands |
| React with 📌 or 🔖 | Capture the message you reacted to |
| Meeting transcript | A decision-relevant Teams meeting transcript is analysed after the meeting |
Ambient suggestions are off by default and enabled per channel. Nothing is stored unless someone confirms. See Capture.
Best Practices
- Use standard channels - Align works best in team channels
- Be descriptive - Teams messages are often shorter, add context
- Capture in threads - Reply to the discussion with the decision
- Include stakeholders - Mention decision makers
Permissions
Align requests these delegated Microsoft Graph permissions when an account connects. Each one is limited to what the connecting account can already see, so connect a dedicated service account that belongs only to the teams you want captured. Historical scans use only these.
| Permission | Purpose |
|---|---|
openid, profile, email, User.Read | Sign the connecting account in |
offline_access | Keep the connection alive after sign-in |
Team.ReadBasic.All, Channel.ReadBasic.All | List the teams and channels the account belongs to |
ChannelMessage.Read.All | Read channel messages and threads |
Chat.Read | Read chats the connecting account is part of |
OnlineMeetings.Read, OnlineMeetingTranscript.Read.All, Calendars.Read | Find meetings the account can access and read their transcripts |
Real-time meeting transcripts use an application permission. Capturing a transcript as soon
as a meeting ends uses the connector's own app identity (a client-credentials token, visible in
your Entra sign-in logs) and the application permission OnlineMeetingTranscript.Read.All,
which covers the tenant's transcripts unless you restrict it with a Teams application access
policy. If you do not grant it, transcripts are still picked up by scheduled scans through the
delegated grant above.
New channel messages are captured by re-scanning or when someone mentions @Align; the Teams
app does not subscribe to every channel message. Replies to @Align go through the Teams bot,
not through the connecting account's token.
Corrected 2026-09-24: this table previously listed ChannelMessage.Send and User.Read.All,
which Align does not request, and omitted the chat, meeting and transcript permissions it does.
Troubleshooting
Align doesn't respond
- Ensure the Align app is installed in your tenant
- Verify the bot is added to the channel
- Check that the bot is not blocked
Permission errors
- Your Teams admin may need to approve the app
- Enterprise tenants may require admin consent
Self-Hosted Setup
On Align cloud, Align's OAuth app is used. Self-hosted, you register your own Microsoft Entra app. See OAuth apps.
Delegated-only installs
If your Azure AD admin granted only delegated permissions (no Application permission for
meeting transcripts), set connectors.teams.disableRealtimeTranscripts: true. This turns off
the tenant-wide real-time transcript subscription, which needs an app-only token the
Application permission provides. Discover scans keep working over your delegated scopes. See
Values reference.
Registering your own Azure Bot and Teams app package
If you register your own Microsoft Entra ID app for Teams, you also need your own Teams app package - the zip a user uploads to install the bot. Align's own package is not usable for this: it names Align's own bot and only allows align.tech domains, so a customer's Teams tenant would try to talk to Align's bot, not yours.
Registering your own app for Teams means setting two sets of credentials from the same -oauth-teams secret: TEAMS_CLIENT_ID/TEAMS_CLIENT_SECRET (the OAuth app, used to read channel messages via Microsoft Graph) and TEAMS_BOT_APP_ID/TEAMS_BOT_APP_PASSWORD/TEAMS_BOT_APP_TENANT_ID (the Bot Framework identity, used to receive @Align mentions and slash commands). A single-tenant Entra app registration can serve as both, and its Application (client) ID is what goes in the manifest as the bot id.
-
Create an Azure Bot resource in the Azure Portal, using the same Entra app registration as your
TEAMS_CLIENT_ID. Note its Microsoft App ID (Application client ID) - this is thebot-idbelow, and alsoTEAMS_BOT_APP_ID. Generate a client secret for it and set that asTEAMS_BOT_APP_PASSWORD; set the app registration's own tenant asTEAMS_BOT_APP_TENANT_ID(for a single-tenant registration - leaving it unset falls back toMultiTenant). Forsecrets.create: true, these aresecrets.oauth.teams.botAppId,botAppPasswordandbotAppTenantId; otherwise set thebot-app-id,bot-app-passwordandtenant-idkeys directly on the-oauth-teamsSecret you pre-create. -
Set the bot's messaging endpoint to
https://{your-api-domain}/webhook/teams(the same domain asgateway.apiBaseUrl- the gateway proxies this route to the connector), then add the Microsoft Teams channel to the bot. -
Generate a Teams app id. This is a separate GUID you choose to identify the app package -
uuidgenon macOS/Linux, or any GUID generator. It does not need to match the bot id, though it may. -
Render the package from
connectors/mcp-teams/teams-app-manifest/render-package.shin the align-stack repository:./render-package.sh <bot-id> <teams-app-id> <your-api-domain> [output-dir]This fills in
manifest.template.json's placeholders (bot id, app id,validDomains) and zips the result with the icons intoalign-teams-app.zip. It refuses to produce a package with an unfilled placeholder or invalid JSON. Optional environment variables (DEVELOPER_NAME,DEVELOPER_WEBSITE_URL,DEVELOPER_PRIVACY_URL,DEVELOPER_TERMS_URL,PACKAGE_NAME) let you set your own developer identity in the package; each has a placeholder default if unset. -
Upload the package. In Teams, go to Apps → Manage your apps → Upload a custom app (or the Teams admin center's equivalent), and select the generated
align-teams-app.zip.
A test asserting the rendered package never carries Align's own bot id or align.tech runs in CI (scripts/__tests__/test-teams-manifest-template.sh).