Set up the connection
- Choose Add connection → Microsoft Teams on the agent’s Connections page, or pick Microsoft Teams while creating an agent.
- Create a dedicated Teams-managed bot and single-tenant Entra app through Teams Developer Portal or the Teams CLI. Choose HTTP message delivery and generate a client secret. You need a work/school tenant that permits app registration and custom app installation; no Azure subscription is required. This is self-service registration, not Microsoft Store review. See the CLI recipe below.
- Paste the Application (client) ID, Directory (tenant) ID, and client secret value into Formation. Formation checks token issuance and stores the secret encrypted under this agent’s connector. Another agent cannot claim that application’s identity, including through concurrent saves.
- Copy the exact messaging endpoint shown after saving into the bot’s
configuration. It looks like
https://<formation-host>/connectors/teams/events/<application-id>. Configure Formation’sPUBLIC_URLbefore saving. Microsoft must be able to reach the endpoint over public HTTPS without an interactive login; a private tailnet URL is insufficient. - Download the app ZIP from Formation. In Teams, upload it through Apps → Manage your apps → Upload a custom app, then install it for yourself and in the test team or group chat. Your tenant administrator may need to permit custom app uploads or distribute it through the organization’s app catalog. Public marketplace publication and Microsoft Store approval are unnecessary.
- Send a DM and a channel @mention. Then send another @mention in the same thread and confirm the reply stays there. The connection page separately reports a message received and a provider-confirmed reply.
Teams-managed registration with the CLI
Install Microsoft’s Teams CLI and sign in withteams login. Create the agent’s own registration:
CLIENT_ID, TENANT_ID, and CLIENT_SECRET from the result into
Formation’s matching fields. Do not paste credentials into chat or commit them.
Save in Formation, then set the displayed endpoint in Developer Portal, or run:
<teams-app-id> and the Entra
application client ID for <client-id>; do not assume they are interchangeable.
Download and install Formation’s ZIP for the supported scopes and metadata,
rather than installing the CLI’s generated package. Formation uses ordinary bot
credentials, not user OAuth or SSO. Teams-managed registration changes where
Microsoft manages the bot, not where Formation runs.
Optional Azure registration
An existing Single Tenant Azure Bot works too. Create its dedicated Entra app and client secret, enable its Microsoft Teams channel, and configure the same Formation endpoint. This route requires an Azure subscription. Formation itself can be hosted anywhere with a public HTTPS endpoint. See Microsoft’s registration comparison.Participation and permissions
The package declares channel readiness withsupportsChannelFeatures: "tier1"
using manifest v1.25 and app version 1.0.0. It requests the resource-specific
ChannelMember.Read.Group application permission for channel membership access,
as required by Microsoft’s channel readiness guidance. Installation consent is
scoped to the resource; it grants no tenant-wide Graph access or message-read
permission. In group chats and channels it receives explicit bot
@mentions rather than the whole conversation. Select the actual bot from Teams’
mention picker: mention-shaped text alone is not authenticated mention evidence.
Unmentioned follow-ups may not be delivered by Teams. Formation cannot use
messages Microsoft did not deliver as context.
An accepted message follows Formation’s existing addressing and admission rules.
The connector resolves the exact current conversation’s roster when possible;
it never substitutes the entire tenant or parent team’s membership for a room’s
audience. Missing or incomplete evidence stays unknown and restricts private
recall. Private/shared channels, meetings, files, historical backfill, and proactive
messages are outside this release’s supported flow. Teams does not deliver other
bots’ messages through the ordinary bot activity stream.
The package’s webApplicationInfo.id binds resource-specific consent to the
agent’s own registered application. Each agent keeps its own app identity; no
shared acting account is introduced. See Microsoft’s resource-specific consent declaration.
If Developer Portal rejects an older ZIP for a zero-prefixed app version or a
missing channel readiness declaration, update Formation and download the ZIP
again. Reuse the existing bot registration, credentials and messaging endpoint.
The readiness declaration is manifest compatibility, not evidence of live
private/shared-channel verification; begin testing with a DM and a standard
channel. See Microsoft’s channel requirements.
Streaming answers
Open this agent’s Teams connection and enable Stream answers. It is off by default and applies to new turns on this connection only. Slack has the same independent opt-in. Turning either connection on does not enable the other. Show progress updates independently controls Formation’s brief, validated progress messages during longer tasks. Existing installations keep those messages enabled. These use Formation’s existing progress-notice delivery; they are not Teams informative streaming updates or Slack task cards. Live updates in applies to both answer streaming and progress messages: Everywhere, Direct and group chats, or Direct messages only. Completed answers still arrive in every supported conversation. Settings apply to new turns and are scoped to this agent’s connection. Formation streams authorized public answer text in direct messages, group chats and standard-channel threads. Tool work and private reasoning are withheld. It buffers updates for three seconds, sends cumulative Teams content with a durable sequence cursor, and keeps the preview within one reply part. Longer answers continue through ordinary multipart delivery. Final validation can correct the preview: Formation closes the stream and updates the same activity with the canonical first part, rather than posting a duplicate answer. Both providers expire streams after ten minutes. Teams previews stop updating before that deadline; the final answer still reconciles the known activity. A rejected preview disables further updates for that attempt. Ambiguous stream creation or append requests are never automatically replayed. The existing reply journal governs final delivery and recovery. If the setting reports a restart is required, restart Formation before testing a new turn. Protocol references: Teams streaming REST API, Slack streaming.Reliability and repair
The inbound endpoint checks the Connector JWT signature, issuer, audience, expiry, Teams endorsement and service URL binding, plus the configured tenant. It durably enqueues conversational observations before acknowledging delivery. Non-message activities are authenticated and ignored. Ingress errors do not log message bodies or credentials. The credential-free reply address is persisted with the trigger message and restored after worker loss. It includes Microsoft’s exact conversation and activity IDs and validated service URL; no process-local address cache is needed. Outbound extended Markdown is chunked without truncating the canonical response. Durable reply-part recovery resends only never-started or definitely rejected parts. Confirmed parts are not posted again. HTTP 429 uses the provider’s retry minimum; credential rejection waits for connection repair. Timeouts, 5xx, and missing receipts remain uncertain and are not automatically replayed. The existing model/tools are not rerun merely to retry a reply. To rotate the secret, open the connection and verify/save the replacement value. The app identity remains the same. A changedPUBLIC_URL requires updating the
bot messaging endpoint manually; Formation does not request Azure resource
management credentials. If saving reports saved_restart_required, restart the
instance before sending the test message.
Operator API
All routes use the existing agent-access authorization for sessions/API tokens:status and a connector with a non-secret adapter view:
its setup definition, public values, and exact events_url.
GET /api/agents/{slug}/connectors/{connectorID}/app-package downloads the ZIP.
GET /api/agents/{slug}/readiness reports receive/send evidence. Secrets are
write-only. Do not put a secret in a URL, app ZIP, ticket, or chat.
The descriptor catalog, ingress and provisioning routes can serve further
conversation adapters without new vendor cases in shared runtime or UI code.
Sources: Teams-managed registration,
endpoint configuration,
optional Azure registration,
private installation,
Connector authentication.