Connect Microsoft Teams to an existing Agent by creating a Microsoft Teams Communication Connection. You create an Azure Bot, bring its credentials to the Connection, point the bot at the Connection's webhook, and install the generated Teams app package.
Microsoft Teams is a shipped Platform Plugin supported by both Hermes and OpenClaw. Platform selection is independent of Runtime selection.
Overview
Microsoft Teams is not selected while creating the Agent. The Agent is created headless, and Teams is added afterward as a Connection.
- An Agent can have zero or many Communication Connections.
- The same Agent may have multiple Microsoft Teams Connections, such as one per tenant.
- Microsoft Teams uses authenticated Bot Framework webhook ingress.
- The Communications Gateway receives Teams activities and delivers normalized messages to the Runtime.
- The Runtime never receives the Teams client secret or other provider credentials.
When you finish this guide, you will have:
- An Azure Bot with the Microsoft Teams channel enabled
- A Microsoft Teams Communication Connection on an existing Agent
- The Connection webhook configured as the bot's messaging endpoint
- The generated Teams app package installed in the intended scopes
- Channel and direct-message policies for the Connection
See Communication Connections for the shared Connection lifecycle, and Compare platform compatibility for how Teams sits beside the other Platforms.
Teams connection model
Teams is the one Platform that calls into Agent Barn rather than being polled or held open:
- Microsoft Teams activity
- Authenticated provider webhook
- Teams Platform Plugin
- Communications Gateway
- Hermes or OpenClaw
Replies return through the same Connection, sent by the Gateway with the Connection's own credentials.
| Value | Where it comes from | Classification |
|---|---|---|
| App (client) ID | Azure Bot → Configuration → Microsoft App ID | Identifier |
| Client secret | Linked app registration → Certificates & secrets → Value | Secret |
| Tenant ID | Microsoft Entra ID → Overview → Directory (tenant) ID | Identifier |
All three belong to the Communication Connection. The public endpoint requirement applies to the Agent Barn Communications service, not to the Agent Runtime, which needs no inbound route.
Before you begin
You need:
- An existing Agent
- Permission to update that Agent and manage its Connection credentials
- Access to the Azure Portal
- Permission to create an Azure Bot and its linked app registration
- Permission to enable the Microsoft Teams channel
- Permission to upload a custom app into the intended Microsoft Teams tenant
- A publicly reachable Agent Barn Communications endpoint
Custom app upload is controlled by Teams administration. Confirm that your tenant permits sideloading before you begin, or arrange for an administrator to complete the installation step.
Prepare a public HTTPS endpoint
Microsoft Teams sends messages to a webhook for your Agent's connection. Microsoft must be able to reach that webhook over HTTPS from the public internet.
If you are using Agent Barn only at http://localhost:3000, complete the networking setup before continuing. Opening the web application on your own computer does not make the webhook reachable by Microsoft.
Choose the next step for your installation:
| Your setup | What to do |
|---|---|
| Your team already has a publicly hosted installation | Ask its administrator to confirm that the Teams webhook route is available through the installation's public HTTPS address. |
| You are preparing a self-hosted installation | Follow Configure production and Deploy to Kubernetes, then arrange the webhook routing described below. |
| You are evaluating Agent Barn only on localhost | Continue local evaluation, and complete Teams setup after a public HTTPS route to the installation has been arranged. A local tunnel setup is not provided by this guide. |
Your installation administrator needs to provide a publicly reachable HTTPS route for /communications/v1/webhooks and configure the external API address used to generate connection webhook URLs. This address is separate from the web application's URL.
The public webhook still authenticates incoming Microsoft requests. Keep that authentication enabled. Internal Agent runtime endpoints, Ingest endpoints, and metrics are not substitutes for this webhook route.
Configure the address used for the webhook
| Installation path | Setting used to generate the webhook address |
|---|---|
| Local source installation | Set API_EXTERNAL_URL to the public HTTPS origin that routes webhook requests to this installation. With Docker Compose, recreate the API container after changing its environment; source-code reload alone does not apply the new value. |
| Supplied Helmfile deployment | Set API_HOST to the public API hostname. Helmfile constructs the external URL using HTTPS and the first hostname when API_HOST contains a comma-separated list. |
The generated connection URL adds /communications/v1/webhooks/<connection-id> to that origin. Copy the complete URL from the saved connection into the Azure Bot Messaging endpoint.
WEB_APP_URL identifies the web application and does not replace this setting. Internal COMMUNICATIONS_BASE_URL is also separate; keep the internal runtime-to-Communications address unchanged when arranging public webhook access.
Local Communications listens on COMMUNICATIONS_PORT, which defaults to 8002. That listener also serves internal communication routes. Any local proxy or tunnel setup must expose the webhook route without exposing the entire listener, preserve the webhook path and Authorization header, and leave Microsoft's webhook authentication enabled.
Create the Azure Bot
Create the bot and collect the three values the Connection needs.
- Create an Azure Bot resource in the Azure Portal.
- Open the Azure Bot's Configuration page.
- Copy the Microsoft App ID.
- Follow Manage passwords to the linked app registration.
- Open Certificates & secrets.
- Create a new client secret.
- Copy the secret Value immediately.
- Open Microsoft Entra ID → Overview.
- Copy the Directory (tenant) ID.
- Open the Azure Bot's Channels page.
- Enable the Microsoft Teams channel.
Note the secret's expiry date. An expired secret breaks the Connection until it is replaced.
Create the Teams Connection
With the three Azure values in hand, create the Connection on the Agent.
- Open the existing Agent.
- Open its Communication Connections section.
- Choose Microsoft Teams.
- Enter a Connection display name.
- Enter the App (client) ID.
- Enter the Client secret.
- Enter the Tenant ID.
- Configure the channel and direct-message policies.
- Create the Connection.
- Use the webhook URL and app-package actions shown on the saved Connection.
Use a display name that identifies the tenant or purpose, such as Teams: Operations tenant.
The combination of Tenant ID and App ID identifies the provider installation and is subject to credential uniqueness protection, so two Connections cannot claim the same bot identity in the same tenant.
Register the Connection's webhook
The saved Connection exposes its own webhook URL. Point the Azure Bot at it.
- Save the Microsoft Teams Connection in Agent Barn using the bot's credentials.
- Copy the webhook URL displayed for that Connection. It includes the Connection's identifier; use the complete URL.
- If the URL contains
localhost, a private-only hostname, or the wrong installation address, ask your installation administrator to correct the external API configuration and public routing before continuing. Do not substitute the web application's home page or an internal service address. - In the Azure Bot configuration, open Configuration, set Messaging endpoint to the complete webhook URL, and apply the change.
- Complete any remaining Teams channel and app installation steps below, including installation in each team or chat where the bot will be used.
The Connection's webhook address and its credentials must belong to the same bot setup. If the installation address changes, obtain the current URL from Agent Barn and update the bot configuration.
The endpoint has this shape:
https://<agent-barn-host>/communications/v1/webhooks/<connection-id>- The endpoint must be reachable from the public internet.
- The webhook belongs to the Communication Connection, not directly to the Agent.
- Inbound requests are authenticated using Microsoft Bot Framework bearer tokens.
- The token audience is checked against the Connection's App ID.
- Authentication is also bound to the activity's Bot Framework service URL.
Only the provider-webhook prefix needs public exposure. Runtime protocol traffic stays internal to the deployment.
Install the Teams app package
Agent Barn generates a sideloadable Microsoft Teams app package for the saved Connection.
- Save the Microsoft Teams Connection.
- Select Download app package from the Connection.
- In Microsoft Teams, open Apps.
- Open Manage your apps.
- Select Upload a custom app.
- Upload the downloaded ZIP package.
- Add the app to every team, group chat, or personal scope the Agent should serve.
About the package:
- It contains the public App ID and Teams manifest assets.
- It does not contain the client secret, tenant credentials, or other private credential material.
- Its manifest identity is stable for the Connection, so a newly downloaded package updates the existing Teams app instead of creating an unrelated installation.
- Installing into a team or group chat requires the app package.
Download and upload the package again after renaming the Agent, so its Teams display information is refreshed.
You do not need to author a Teams manifest by hand. Use the generated package.
Configure the Connection settings
The Microsoft Teams Platform Plugin supplies these settings on the Connection form.
| Setting | Behavior | Underlying setting |
|---|---|---|
| Channel access | open: accept eligible messages from any group or channel conversation where the bot is installed; allowlist: accept eligible messages only from the configured channel conversation IDs | group_policy |
| Allowed channels | Teams conversation IDs, used when Channel access is allowlist | channel_ids |
| Direct messages | off: ignore personal conversations; open: accept personal conversations from any sender; allowlist: accept personal conversations only from configured senders | dm_policy |
| Allowed DM senders | Sender Microsoft Entra object IDs, used when Direct messages is allowlist | dm_user_ids |
A Teams channel conversation ID commonly resembles 19:...@thread.tacv2. Preserve its exact case: Teams conversation IDs are case-sensitive, and a re-cased value will not match.
Direct-message senders are matched by Microsoft Entra object ID rather than by display name or email address.
Start with one allowed channel conversation and direct messages off, then widen after the first successful exchange. See Configure channel access for policy guidance.
Verify the Connection
Confirm the Connection is enabled and shows no provider error, then test from a controlled conversation.
| Test | Expected result |
|---|---|
| Mention the Agent in an allowed channel | The Agent responds |
| Send an unmentioned message in that channel | The Agent does not respond |
| Mention the Agent in a conversation outside the allowlist | The Agent does not respond |
Send a personal message while Direct messages is off | The Agent does not respond |
Send a personal message as an allowed sender while Direct messages is allowlist | The Agent responds |
Then confirm the exchange in Agent Barn:
- Open the Agent.
- Open Conversations.
- Select this Microsoft Teams Connection.
- Confirm the inbound message and outbound response appear under it.
See Verify your Agent for the full layered verification.
Mention behavior
- Microsoft Teams channel and group-chat messages require an explicit mention of the Agent.
- Direct messages do not require a mention, but remain governed by the Direct messages policy.
- Teams does not expose the Slack-specific
every_messageversusstart_onlythread setting.
Mention admission and allowlist checks are Connection policies, not Runtime behavior. Changing them is a Connection update.
Conversation and identity scoping
- Teams conversations are stored under the specific Communication Connection.
- Provider conversation IDs are preserved exactly.
- Sender policy matching uses the Microsoft Entra object ID.
- Available team, channel, group-chat, and sender display names are enriched when provider data permits.
The same Agent can hold additional Teams or non-Teams Connections without sharing provider credentials or conversation histories between them.
Change the Connection later
Teams settings and credentials can be changed at any time without touching the Agent.
- Connection updates increment the Connection revision.
- The Communications Gateway reconciles the Connection independently.
- Updating the Connection does not rebuild or restart the Agent Runtime.
Replace the client secret on the Connection before it expires. Rotating it in Azure without updating the Connection breaks inbound authentication.
Troubleshooting
Start at the saved Connection's diagnostics, then work through these checks:
- The Azure Bot's Microsoft Teams channel is enabled
- The App ID, client secret Value, and Tenant ID belong to the same registration
- The client secret has not expired
- The current Connection webhook is configured as the Azure Bot messaging endpoint
- The webhook is publicly reachable
- The custom Teams app package has been uploaded and installed in the intended scope
- The bot was explicitly mentioned in a group or channel message
- The conversation or sender passes the configured policy
- The Connection is enabled
The Connection journal shows whether the activity was observed, rejected by policy, delivered to the Runtime, retried, or dead-lettered. Use it to decide which layer to investigate.
No activities arrive at all
Confirm the Microsoft Teams channel is enabled on the Azure Bot, that the messaging endpoint matches the current Connection webhook exactly, and that the endpoint is reachable from the public internet.
If the journal shows nothing observed, the request is not reaching Agent Barn; investigate DNS, TLS, ingress, and the Azure Bot configuration before looking at the Agent.
Inbound requests are rejected
Bot Framework token validation failed. Confirm that the App ID on the Connection matches the Azure Bot, that the client secret Value is current and unexpired, and that all three values come from the same app registration.
Authentication is also bound to the activity's Bot Framework service URL, so a mismatched or stale bot registration can cause rejections.
Activities are observed but rejected by policy
Check the channel access policy and the allowed channel conversation IDs, including their exact case. For personal conversations, check the direct-message policy and the allowed sender Entra object IDs.
Confirm the message explicitly mentioned the Agent, which is required in channels and group chats.
The bot cannot be found in Teams
Download the app package from the Connection and upload it through Manage your apps → Upload a custom app, then add it to the intended team, group chat, or personal scope.
If upload is unavailable, your tenant restricts custom app sideloading; ask a Teams administrator to complete the installation.
The activity is delivered but no reply arrives
Ingress and admission succeeded, so the problem is downstream. Review Agent health and logs for the Runtime, then review the Connection's delivery diagnostics for the outbound reply.
Do not restart the Agent for a provider or policy problem.
The Teams app shows an old name
Download the app package again after renaming the Agent, then re-upload it. The manifest identity is stable, so the upload updates the existing Teams app rather than creating a second one.
Next steps
After the Microsoft Teams Connection is working:
- Review the Connection lifecycle
- Configure channel access
- Verify your Agent
- Review Agent health and logs, separately from Connection health
- Compare platform compatibility before adding another Connection
- Set up Slack