Teams MCP - Tools — Unique AI Documentation
Teams MCP - Tools
The Teams MCP Server exposes 12 tools in two categories:
- Chat & messaging tools (8) interact with Microsoft Teams chats and channels synchronously through the Microsoft Graph API: list teams/channels/chats, read messages, search across messages, and send messages.
- Transcript & knowledge-base tools (4) manage meeting-transcript ingestion into the Unique knowledge base.
Chat and messaging tools target chats and channels by id: you discover the id with a list_* tool (or search_messages), then pass it to the tool that reads or writes:
list_teams / list_chats / list_channels → id → get_*_messages / send_*_message
The list_* tools return distinguishing metadata (creation dates, last-message timestamps, archived/membership flags, member names) so the agent can pick the right id when several teams, chats, or channels share a display name.
Tool Overview
| Tool | Category | Mutating | Description |
|---|---|---|---|
list_teams |
Teams & Channels | No | List the Teams the signed-in user belongs to |
list_channels |
Teams & Channels | No | List the channels in a team |
list_chats |
Chats | No | List the signed-in user's chats |
get_chat_messages |
Messages | No | Read recent messages from a chat |
get_channel_messages |
Messages | No | Read recent messages from a channel |
send_chat_message |
Messages | Yes | Send a plain-text message to a chat |
send_channel_message |
Messages | Yes | Send a plain-text message to a channel |
search_messages |
Search | No | Search messages across chats and channels |
ingest_meeting |
Transcript & KB | Yes | Ingest a specific meeting's transcript on demand |
verify_kb_integration_status |
Transcript & KB | No | Check transcript-ingestion subscription status |
start_kb_integration |
Transcript & KB | Yes | Start automatic transcript ingestion |
stop_kb_integration |
Transcript & KB | Yes | Stop automatic transcript ingestion |
Chat and channel messages are not ingested
The message tools read and write Teams messages live through Microsoft Graph. Unlike meeting transcripts, chat and channel messages are never copied into the Unique knowledge base — get_*_messages and search_messages query Microsoft Graph on every call. Only meeting transcripts are ingested (via start_kb_integration / ingest_meeting).
Teams & Channels
list_teams
List all Microsoft Teams the signed-in user is a member of. Each team carries an isArchived flag (archived teams are read-only) to distinguish teams that share a display name.
Input parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
includeDescriptions |
boolean | No | false |
Include each team's description. Useful when several teams have similar names. |
Returns: A teams array. Each entry has teamId, displayName, isArchived (true/false/null), and description (only when includeDescriptions is true and a description exists). Pass teamId to list_channels, get_channel_messages, or send_channel_message.
Example:
{
"teams": [
{ "teamId": "19:abc...@thread.tacv2", "displayName": "Engineering", "isArchived": false },
{ "teamId": "19:def...@thread.tacv2", "displayName": "Engineering", "isArchived": true }
]
}
list_channels
List all channels in a team, identified by teamId. Each channel carries its creation date and membership type (standard, private, or shared) to tell apart channels that share a display name.
Input parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
teamId |
string | Yes | — | Exact team id from list_teams. |
includeDescriptions |
boolean | No | false |
Include each channel's description. |
Returns: The teamId and a channels array. Each entry has channelId, displayName, createdDateTime, membershipType, and description (only when includeDescriptions is true). Pass teamId + channelId to get_channel_messages or send_channel_message.
Example:
{
"teamId": "19:abc...@thread.tacv2",
"channels": [
{
"channelId": "19:ch1...@thread.tacv2",
"displayName": "General",
"createdDateTime": "2023-04-01T09:00:00Z",
"membershipType": "standard"
}
]
}
list_chats
List the signed-in user's chats (1:1, group, and meeting chats), most recent first. Each chat carries its creation date and last-message timestamp to tell apart chats that share a topic or members. For chats without a topic (typically 1:1 chats), the member list is returned so the chat can be identified by participant.
Input parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
limit |
integer (1–50) | No | 50 |
Maximum number of chats to return. |
includeMemberEmails |
boolean | No | false |
Include member email addresses (only for topic-less chats). Useful when two members share a display name. |
Returns: A chats array and a truncated flag (true when more chats exist than were returned). Each chat has chatId, chatType, topic (nullable), createdDateTime, lastMessageAt, and — for chats without a topic — a members array (displayName, plus email when includeMemberEmails is true). Pass chatId to get_chat_messages or send_chat_message.
Example:
{
"chats": [
{
"chatId": "19:meeting_xyz@thread.v2",
"chatType": "meeting",
"topic": "Weekly Sync",
"createdDateTime": "2024-01-10T08:00:00Z",
"lastMessageAt": "2024-06-20T14:32:00Z"
},
{
"chatId": "19:1on1@unq.gbl.spaces",
"chatType": "oneOnOne",
"topic": null,
"createdDateTime": "2023-11-02T10:00:00Z",
"lastMessageAt": "2024-06-19T09:15:00Z",
"members": [{ "displayName": "Alice Smith" }]
}
],
"truncated": false
}
get_chat_messages
Retrieve recent messages from a chat, identified by chatId. Call list_chats (or search_messages) first to find the chatId.
Input parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
chatId |
string | Yes | — | Exact chat id from list_chats or search_messages. |
limit |
integer (1–50) | No | 20 |
Maximum number of messages to return (newest first). |
contentFormat |
normalized | raw |
No | normalized |
normalized converts HTML to readable text; raw returns Teams HTML verbatim. |
includeSystemMessages |
boolean | No | false |
Include event notifications (member added, call ended). |
timestampFormat |
full | short | none |
No | short |
full = ISO 8601 with ms; short = YYYY-MM-DD HH:mm; none = omit timestamps. |
detail |
standard | full |
No | standard |
standard returns sender, content, and timestamp; full also adds contentType (the source format from Graph). |
Returns: The chatId and a messages array (newest first). Each message has id, senderDisplayName (nullable), content, createdDateTime (omitted when timestampFormat=none), and contentType (only when detail=full).
Example:
{
"chatId": "19:1on1@unq.gbl.spaces",
"messages": [
{
"id": "1718901120000",
"senderDisplayName": "Alice Smith",
"content": "@Bob Jones can you review the PR? [attachment: design.pdf]",
"createdDateTime": "2024-06-20 14:32"
}
]
}
get_channel_messages
Retrieve recent messages from a channel, identified by teamId + channelId. Call list_teams then list_channels first to find the ids.
Input parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
teamId |
string | Yes | — | Exact team id from list_teams. |
channelId |
string | Yes | — | Exact channel id from list_channels (for that team). |
limit |
integer (1–50) | No | 20 |
Maximum number of messages to return (newest first). |
contentFormat |
normalized | raw |
No | normalized |
normalized converts HTML to readable text; raw returns Teams HTML verbatim. |
includeSystemMessages |
boolean | No | false |
Include event notifications (member added, call ended). |
timestampFormat |
full | short | none |
No | short |
full = ISO 8601 with ms; short = YYYY-MM-DD HH:mm; none = omit timestamps. |
detail |
standard | full |
No | standard |
standard returns sender, content, and timestamp; full also adds contentType. |
Returns: The teamId, channelId, and a messages array (same shape as get_chat_messages).
Example:
{
"teamId": "19:abc...@thread.tacv2",
"channelId": "19:ch1...@thread.tacv2",
"messages": [
{
"id": "1718900000000",
"senderDisplayName": "Carol Lee",
"content": "Deploy is green.",
"createdDateTime": "2024-06-20 13:50"
}
]
}
send_chat_message
Send a plain-text message to a chat (1:1 or group), identified by chatId. Call list_chats first to find the chatId.
Input parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
chatId |
string | Yes | — | Exact chat id from list_chats or search_messages. |
message |
string | Yes | — | Plain-text message content to send. |
Returns: messageId and the chatId the message was posted to.
Example:
{ "messageId": "1718901500000", "chatId": "19:1on1@unq.gbl.spaces" }
send_channel_message
Send a plain-text message to a channel, identified by teamId + channelId. Call list_teams then list_channels first to find the ids.
Input parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
teamId |
string | Yes | — | Exact team id from list_teams. |
channelId |
string | Yes | — | Exact channel id from list_channels (for that team). |
message |
string | Yes | — | Plain-text message content to send. |
includeWebUrl |
boolean | No | false |
Include the Teams web URL of the sent message in the response. |
Returns: messageId, and webUrl when includeWebUrl is true and Graph returned one.
Example:
{ "messageId": "1718901600000", "webUrl": "https://teams.microsoft.com/l/message/..." }
search_messages
Search Microsoft Teams messages by keyword across 1:1 chats, group chats, and channels in a single query, using the Microsoft Search API (POST /search/query on Graph v1.0). Supports identity and scope filters. Results are snippets by default; set detail=full to hydrate message bodies. At least one search criterion (query, from, to, mentions, sentAfter, sentBefore, hasAttachment, isRead, or isMentioned) must be provided.
Input parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
query |
string | No | — | Free-text keywords to match in message content. Multi-word terms are quoted automatically. |
from |
string | No | — | Sender name or email (KQL from:). Matches the message author. |
to |
string | No | — | Recipient name or email (KQL to:). |
mentions |
string (GUID) | No | — | User object id of a mentioned user; dashes are stripped automatically. |
sentAfter |
string (ISO date) | No | — | Only messages sent on or after this date (e.g. 2024-01-15). |
sentBefore |
string (ISO date) | No | — | Only messages sent on or before this date (e.g. 2024-01-31). |
hasAttachment |
boolean | No | — | Restrict to messages with (true) or without (false) attachments. |
isRead |
boolean | No | — | Restrict to read (true) or unread (false) messages. |
isMentioned |
boolean | No | — | Restrict to messages where the signed-in user is (true) or is not (false) mentioned. |
source |
chat | channel | all |
No | all |
Filter results by container. Applied after the search, so a non-all value shrinks the returned page. |
detail |
summary | full |
No | summary |
summary returns the hit snippet only (1 Graph call). full hydrates each hit with its message body (one extra Graph call per hit). |
contentFormat |
normalized | raw |
No | normalized |
Only applies when detail=full. normalized converts HTML to readable text; raw returns Teams HTML verbatim. |
offset |
integer (≥ 0) | No | 0 |
Number of results to skip for pagination (maps to Graph from). |
size |
integer (1–GRAPH_PAGE_SIZE) |
No | 25 |
Maximum number of results per page. |
Returns: A messages array, returnedCount (rows on this page, after the source filter — not total corpus matches), and moreResultsAvailable (paginate with offset until this is false). Each hit has:
| Field | Description |
|---|---|
id |
Message id |
source |
chat or channel (derived from the hit's resource shape) |
chatId |
Chat id (present for chat hits, else null) |
teamId |
Team id (present for channel hits, else null) |
channelId |
Channel id (present for channel hits, else null) |
senderDisplayName |
Sender name (nullable) |
summary |
Search snippet (nullable) |
content |
Hydrated message body — present only when detail=full and hydration succeeded |
createdDateTime |
Message timestamp (nullable) |
webUrl |
Deep link to the message (nullable) |
Example:
{
"messages": [
{
"id": "1718900000000",
"source": "channel",
"chatId": null,
"teamId": "19:abc...@thread.tacv2",
"channelId": "19:ch1...@thread.tacv2",
"senderDisplayName": "Carol Lee",
"summary": "Deploy is <c0>green</c0>.",
"createdDateTime": "2024-06-20T13:50:00Z",
"webUrl": "https://teams.microsoft.com/l/message/..."
}
],
"returnedCount": 1,
"moreResultsAvailable": false
}
Transcript & Knowledge-Base Management
These tools manage the ingestion of meeting transcripts into the Unique knowledge base, where they are then searched and queried from within Unique. This is distinct from the message tools above — chat and channel messages are never ingested.
ingest_meeting
Ingest a specific Teams meeting's transcript on demand, identified by its join URL. Use this to ingest a meeting that predates the knowledge-base integration, or to re-pull a single occurrence. You must be the organizer or an invited attendee. Ingestion runs asynchronously; the tool returns once the transcript is queued.
Input parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
joinUrl |
string (URL) | Yes | — | The Teams meeting join URL (joinWebUrl). You must be the organizer or an invited attendee. |
date |
string (ISO date) | No | — | Day (YYYY-MM-DD, UTC) to pick a transcript when a recurring meeting has several. |
Returns: success, a human-readable message, meeting (id, subject, joinUrl — or null if not found), and queued (array of { transcriptId, createdDate } for each transcript queued for ingestion).
Example:
{
"success": true,
"message": "Queued 1 transcript(s) for ingestion. They will appear in the knowledge base shortly.",
"meeting": { "id": "MSo...", "subject": "Q2 Planning", "joinUrl": "https://teams.microsoft.com/l/meetup-join/..." },
"queued": [{ "transcriptId": "MSMjMCMj...", "createdDate": "2024-06-01T10:05:00.000Z" }]
}
verify_kb_integration_status
Check the status of the transcript-ingestion knowledge-base integration: whether automatic ingestion is active, expiring soon, expired, or not configured.
Returns: status (active | expiring_soon | expired | not_configured), a message, and subscription (id, expiresAt, minutesUntilExpiration, createdAt, updatedAt — or null when not configured).
start_kb_integration
Start automatic ingestion of meeting transcripts into the knowledge base. Creates a Microsoft Graph webhook subscription so new transcripts are ingested as they become available. Safe to call when already active — it returns already_active without creating a duplicate.
Returns: success, a message, and subscription (id, expiresAt, minutesUntilExpiration, status — one of created, already_active, expiring_soon).
stop_kb_integration
Stop automatic ingestion of meeting transcripts. Removes the Microsoft Graph webhook subscription; previously ingested transcripts remain in the knowledge base.
Returns: success, a message, and subscription (id, status — removed or not_found — or null when nothing was active).