Agent MessengerAgent Messenger
Platform Guides

Teams

Complete reference for the agent-teams CLI.

Tip: agent-teams is a shortcut for agent-messenger teams.

Quick Start

# 1. Sign in with Microsoft device code (required for channels and search)
agent-teams auth login --account-type work

# 2. Get team snapshot
agent-teams snapshot

# 3. Send a message
agent-teams message send <team-id> <channel-id> "Hello from AI agent!"

Authentication

Use auth login for work/school channel, directory, search and Graph-backed file operations; accounts set up with auth extract fall back to the older Teams CSA routes for channel, member and file commands. These use Microsoft bearer tokens from the saved device-code account. auth extract supplies a Skype token for chats, legacy discovery and trusted Teams-hosted inline downloads. Your tenant policies and delegated permissions still apply.

An expired device-code login is refreshed for the same account. If refresh fails, the CLI does not replace it with a different desktop/browser identity. Run auth login explicitly to reconnect.

Seamless Token Extraction

agent-teams automatically extracts your Microsoft Teams credentials from the desktop app or Chromium browser:

agent-teams auth extract

# Use --debug for troubleshooting
agent-teams auth extract --debug

# Scan custom Chromium profile/user-data dirs (repeatable or comma-separated)
agent-teams auth extract --browser-profile ~/browser-data
agent-teams auth extract --browser-profile "$HOME/work-profile,$HOME/personal-profile"

This command:

  • Auto-detects your platform (macOS/Linux/Windows)
  • Extracts Teams access token from the desktop app (with browser fallback)
  • Validates token against Teams API
  • Discovers ALL joined teams
  • Stores credentials securely in ~/.config/agent-messenger/
  • Supports --browser-profile <path> for agent-browser profiles, custom Chrome user data dirs, or portable browser profiles

Refresh and expiry

Extracted Skype tokens commonly expire in 60-90 minutes and only support chat routes. Device-code accounts refresh silently for the selected identity. If this fails, run auth login explicitly for the same account. Do not wrap channel/search operations with auth extract, which can discard the AAD refresh credential.

agent-teams auth status
# Explicit reconnect when silent device-code refresh fails:
agent-teams auth login --account-type work

Any stored device-code account prevents automatic extraction, including when another account type is selected. Explicit auth extract remains available for deliberate Skype-only authentication.

Authentication Commands

# Check auth status (shows expiry time!)
agent-teams auth status

# Logout (clear stored credentials)
agent-teams auth logout

Supported Teams Versions

agent-teams supports both New Teams (WebView2-based, com.microsoft.teams2) and Classic Teams:

VersionmacOSWindowsLinux
New Teams✅✅N/A
Classic Teams✅✅✅

Manual Token Input (Last Resort)

If automatic extraction fails, you can manually provide a token:

agent-teams auth extract --token <your-skype-token>

How to get your token manually:

  1. Open Microsoft Teams in your browser (teams.microsoft.com)
  2. Open Developer Tools (F12 or Cmd+Option+I)
  3. Go to Application > Cookies > https://teams.microsoft.com
  4. Find the cookie named skypetoken_asm
  5. Copy the Value (it's a long string starting with eyJ...)
  6. Run: agent-teams auth extract --token "eyJ..."

Note: Browser tokens also expire in 60-90 minutes. For long-running workflows, you may need to refresh periodically.

Team Management

Teams uses "teams" as the top-level organizational unit. You must select a team before using most commands.

# List all teams
agent-teams team list

# Switch to a different team
agent-teams team switch <team-id>

# Show current team
agent-teams team current

# Get team info
agent-teams team info <team-id>

# Remove a stored team
agent-teams team remove <team-id>

Commands

Whoami Command

# Show current authenticated user
agent-teams whoami
agent-teams whoami --pretty

Output includes the authenticated user's identity information.

Message Commands

# Send a message
agent-teams message send <channel-id> <content>
agent-teams message send abc123-def456 "Hello world"

# List messages
agent-teams message list <channel-id>
agent-teams message list abc123-def456 --limit 50

# Get a specific message
agent-teams message get <channel-id> <message-id>

# Delete a message
agent-teams message delete <channel-id> <message-id> --force

# Reply to a message (thread)
agent-teams message reply <channel-id> <message-id> "Reply content"

# Get a single chat message
agent-teams chat get <chat-id> <message-id>

Messages read from chats and channels include content (plain text), with optional html (original HTML for rich-text messages) and files (downloadable URLs: inline images first, in order, then attachments). Both are omitted when a message has none. Pass a files URL to file download; SharePoint/OneDrive URLs require agent-teams auth login (cookie-only auth extract credentials cannot download them).

Channel Commands

# List channels in current team
agent-teams channel list

# Get channel info
agent-teams channel info <channel-id>

# Get channel message history
agent-teams channel history <channel-id>
agent-teams channel history abc123-def456 --limit 100

User Commands

# List team members
agent-teams user list

# Get user info
agent-teams user info <user-id>

# Get current authenticated user
agent-teams user me

Reaction Commands

# Add reaction
agent-teams reaction add <channel-id> <message-id> <emoji>
agent-teams reaction add abc123-def456 msg789 like

# Remove reaction
agent-teams reaction remove <channel-id> <message-id> <emoji>

# List reactions on a message
agent-teams reaction list <channel-id> <message-id>

File Commands

# Upload file to channel
agent-teams file upload <channel-id> <path>
agent-teams file upload abc123-def456 ./report.pdf

# List files in channel
agent-teams file list <channel-id>

# Get file info
agent-teams file info <channel-id> <file-id>

# Download file
agent-teams file download <file-id> <output-path>

# Download a URL from a message's `files` (inline image or attachment)
agent-teams file download <url> [output-path]

Snapshot Command

Get team overview for AI agents (brief by default):

# Brief snapshot (default) — fast, minimal API calls
agent-teams snapshot

# Full snapshot — includes messages and members (slow, large output)
agent-teams snapshot --full

# Filtered full snapshots
agent-teams snapshot --full --channels-only
agent-teams snapshot --full --users-only

# Limit messages per channel (only with --full)
agent-teams snapshot --full --limit 10

Default returns brief JSON with:

  • Team metadata (id, name)
  • Channels (id, name)
  • Hint for next commands

With --full, returns comprehensive JSON with:

  • Team metadata (id, name)
  • Channels (id, name, type, description)
  • Recent messages (id, content, author, timestamp)
  • Members (id, displayName, email)

Global Options

All commands support these options:

--pretty      # Pretty-print JSON output (default is compact JSON)
--team <id>   # Use specific team (overrides current team)

Real-time Events (SDK)

Real-time message streaming is available through the SDK's TeamsListener, which connects to Teams' internal trouter WebSocket as a user — no bot registration and no public HTTP endpoint. There is no CLI watch command; use the SDK:

import { TeamsClient, TeamsListener } from 'agent-messenger/teams'

const client = await new TeamsClient().login()
const listener = new TeamsListener(client)

listener.on('message', async (message) => {
  console.log(`New message in ${message.chatId}: ${message.content}`)

  // Channel messages carry team/channel context and parsed @mentions.
  if (message.conversationType === 'channel') {
    for (const mention of message.mentions) {
      console.log(`Mentioned: ${mention.displayName} (${mention.mri})`)
    }
    await client.sendMessage(message.teamId!, message.channelId!, 'On it 👍')
  }
})

await listener.start()

Each message is a TeamsRealtimeMessage. Alongside chatId/author and content (plain text with paragraph breaks), optional html/files (same as for read commands), it carries conversationType ('chat' or 'channel'), teamId/channelId (set for channel messages, for use with sendMessage), and mentions (always present, empty when there are no @mentions; each is { id, mri?, displayName }).

The listener reuses your extracted credentials, so the Teams desktop app must be logged in. It reconnects automatically and re-authenticates on token expiry.

Key Differences: Teams vs Discord vs Slack

ConceptSlackDiscordTeams
Server/WorkspaceWorkspaceGuildTeam
Channel ID formatAlphanumeric (C01234567)Numeric snowflakeUUID (abc123-def456-...)
Message ID formatTimestamp (1234567890.123456)Numeric snowflakeUUID
User ID formatAlphanumeric (U01234567)Numeric snowflakeUUID (Azure AD Object ID)
Token lifetimeLong-livedLong-lived60-90 minutes
APISlack Web APIDiscord APITeams Messaging API
ThreadsThread timestampsThread channelsReply chains
Rate limitsModerateModerateStrict

Troubleshooting

Token Expired (401 Unauthorized)

Device-code accounts refresh silently. Reconnect with auth login when refresh fails. For Skype-only extraction accounts, re-extract only the intended chat identity. Authentication repair does not establish whether a prior write succeeded; inspect history before resending.

"No teams found"

For device-code work accounts, verify your joined teams live:

agent-teams --account work team list

"Channel not found"

Teams channel IDs are UUIDs. Make sure you're using the full ID:

# Get channel list to find correct IDs
agent-teams channel list --pretty

Rate Limiting (429 Too Many Requests)

GET requests retry transient 429/5xx responses. Writes and search POST run once. After a write error or lost response, reconcile actual history before another attempt. Pace independent operations:

# Add delays between operations in scripts
sleep 2

Desktop App Not Detected

Ensure Teams desktop app is:

  1. Installed (not just web version)
  2. Currently running
  3. Signed in to your account

Alternatively, log in via a Chromium browser (Chrome, Edge, Arc, Brave, etc.) — the CLI will fall back to browser extraction automatically.

# Debug extraction
agent-teams auth extract --debug

Permission Errors

Some operations require specific Microsoft 365 permissions. Check with your IT admin if you encounter persistent 403 errors.

AI Agent Integration

See skills/agent-teams/ for:

  • Complete skill documentation
  • Runnable templates

Example: AI Agent Workflow

Sign in once with auth login before running the automation. CLI reads refresh the same device-code account when needed:

#!/bin/bash
set -euo pipefail
agent-teams --account work snapshot
# Send only after resolving the authorized team and channel.
agent-teams --account work message send "$TEAM_ID" "$CHANNEL_ID" "Standup reminder"

Preserve the server receipt. If a write fails or its response is lost, inspect exact history before attempting another send. Applications that resume jobs need their own durable reservation/receipt/uncertain state; the upstream CLI does not provide a persistent send ledger.

Message fidelity and pagination

History and message commands retain the legacy text fields and additionally return raw_content, content_type, mentions and attachments. Chat history includes media records; pass --include-system to also include membership, call and other system records. Search returns an indexed preview; fetch the exact message for the full body.

Channel history and replies follow Graph pagination up to --limit. Chat history follows message pages by default; resumable single-page output is explicit:

agent-teams chat history <chat-id> --page --limit 50
agent-teams chat history <chat-id> --cursor '<next_cursor>' --limit 50

Single-page output is { messages, next_cursor }. Ordinary history output remains an array.

Writes are attempted once, without automatic retries on HTTP 429 or 5xx. A timeout or server error can mean a message was delivered. Read the target history before deciding on another send; the CLI does not provide server-side idempotency.

Replies, reactions and permissions

Reply get/delete/reaction calls need the parent root ID:

agent-teams message get <team-id> <channel-id> <reply-id> --thread <root-id>
agent-teams reaction add <team-id> <channel-id> <reply-id> '👍' --thread <root-id>
agent-teams reaction remove <team-id> <channel-id> <reply-id> like --thread <root-id>
agent-teams message delete <team-id> <channel-id> <reply-id> --thread <root-id> --force

Reaction input accepts Unicode and like, heart, laugh, surprised, sad, angry aliases. Graph requires Unicode, so names are converted. Channel reactions use ChannelMessage.Send. Deletion resolves the exact Graph message or reply, then calls Chat Service with the existing Skype token. This avoids adding Graph ChannelMessage.ReadWrite consent. Teams ownership and deletion policy still apply. A delete write is attempted once with no fallback write; reread the exact target before deciding what happened.

Device-code work team list uses live Graph display names. Extraction account names and team current are cached; verify ambiguous labels with team info. The send interface does not expose a Graph mentions payload, so raw <at> markup is not a verified notification mention.

On this page