Ingest Microsoft Teams channel messages, chats, and meeting data into CortexDB.

Microsoft Teams Connector

The Microsoft Teams connector ingests channel messages, 1:1 and group chats, threaded replies, meeting transcripts, and file shares from Teams into CortexDB as typed episodes. Uses the Microsoft Graph API v1.0 with Azure AD client-credentials authentication.

Setup

1. Register an Azure AD Application

  1. Go to Azure Portal > App Registrations
  2. Click New registration
  3. Name the app (e.g., CortexDB Teams Connector)
  4. Set Supported account types to "Accounts in this organizational directory only"
  5. Click Register
  6. Note the Application (client) ID and Directory (tenant) ID

2. Add API Permissions

In your app registration, go to API Permissions and add the following Application permissions:

  • ChannelMessage.Read.All -- Read all channel messages
  • Chat.Read.All -- Read all 1:1 and group chat messages
  • User.Read.All -- Read user profiles
  • TeamMember.Read.All -- Read team membership

Click Grant admin consent for your organization.

3. Create a Client Secret

  1. Go to Certificates & secrets
  2. Click New client secret
  3. Set a description and expiry
  4. Copy the secret Value (not the Secret ID)

4. Configure the Connector

# Required
CORTEX_TEAMS_TENANT_ID=your-azure-tenant-id
CORTEX_TEAMS_CLIENT_ID=your-app-client-id
CORTEX_TEAMS_CLIENT_SECRET=your-client-secret
CORTEX_TEAMS_TEAM_IDS=team-id-1,team-id-2

# CortexDB target
CORTEX_TEAMS_CORTEX_TENANT_ID=my-app
CORTEX_TEAMS_NAMESPACE=teams

5. Start the Connector

# As part of CortexDB
docker run -d \
  -e CORTEX_TEAMS_TENANT_ID=your-azure-tenant-id \
  -e CORTEX_TEAMS_CLIENT_ID=your-app-client-id \
  -e CORTEX_TEAMS_CLIENT_SECRET=your-client-secret \
  -e CORTEX_TEAMS_TEAM_IDS="team-id-1,team-id-2" \
  -e CORTEX_TEAMS_CORTEX_TENANT_ID=my-app \
  cortexdb/cortexdb:latest \
  --enable-connector teams

# As a standalone process
cortexdb-connector teams \
  --azure-tenant-id your-azure-tenant-id \
  --client-id your-app-client-id \
  --client-secret your-client-secret \
  --team-ids "team-id-1,team-id-2" \
  --tenant-id my-app

What Gets Ingested

| Teams Event | Episode Type | Content | |---|---|---| | Channel message | message | Message text (HTML stripped) | | Thread reply | message | Reply text (with thread metadata) | | 1:1 chat message | message | Chat message text | | Group chat message | message | Chat message text | | Meeting event | meeting | Meeting call metadata | | File share | document | File attachment metadata |

Episode Metadata

Each ingested message includes:

{
  "type": "message",
  "content": "We need to discuss the Q2 roadmap before the all-hands.",
  "source": "teams",
  "author": "[email protected]",
  "timestamp": "2026-03-15T14:30:00Z",
  "metadata": {
    "context_type": "channel",
    "message_type": "message",
    "importance": "normal",
    "team_id": "19:abc123",
    "channel_id": "19:def456",
    "channel_name": "Engineering",
    "attachment_count": 0,
    "mentions": ["[email protected]"]
  }
}

Configuration

| Variable | Default | Description | |---|---|---| | CORTEX_TEAMS_TENANT_ID | Required | Azure AD tenant (directory) ID | | CORTEX_TEAMS_CLIENT_ID | Required | Azure AD application (client) ID | | CORTEX_TEAMS_CLIENT_SECRET | Required | Azure AD client secret | | CORTEX_TEAMS_TEAM_IDS | Required | Comma-separated team IDs | | CORTEX_TEAMS_CORTEX_TENANT_ID | Required | CortexDB target tenant | | CORTEX_TEAMS_NAMESPACE | teams | CortexDB target namespace | | CORTEX_TEAMS_BACKFILL_DAYS | 30 | Days of history to backfill on first run | | CORTEX_TEAMS_INCLUDE_CHATS | false | Include 1:1 and group chat messages | | CORTEX_TEAMS_POLL_INTERVAL_SEC | 30 | Polling interval in seconds |

Backfill

On first run, the connector backfills the configured number of days of message history from all configured teams and channels. Subsequent runs use incremental sync based on the lastModifiedDateTime filter.

# Backfill 90 days of history
cortexdb-connector teams --backfill-days 90

Finding Team IDs

To find your Team IDs, use the Microsoft Graph Explorer or PowerShell:

# PowerShell (requires Microsoft.Graph module)
Connect-MgGraph -Scopes "Team.ReadBasic.All"
Get-MgTeam | Select-Object DisplayName, Id

Or in the Graph Explorer: GET https://graph.microsoft.com/v1.0/me/joinedTeams