Teams MCP Plus
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Teams MCP Plussearch my recent messages mentioning project alpha"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Teams MCP Plus
A Microsoft Teams MCP server with multi-tenant support. Connect multiple organizations in one server, with isolated credentials and explicit tenant selection for chats, channels, users, search, and file operations.
Based on Floris Cornelβs Teams MCP, extended and maintained in this repository.
π¦ Installation
Authenticate each tenant first (replace <tenant-id> with its Microsoft Entra directory GUID):
npx -y teams-mcp-plus@latest authenticate --tenant <tenant-id> --name Work
npx -y teams-mcp-plus@latest tenantsThen add the following configuration in Cursor/Claude/VS Code:
{
"mcpServers": {
"teams-mcp-plus": {
"command": "npx",
"args": ["-y", "teams-mcp-plus@latest"]
}
}
}Related MCP server: Microsoft MCP
π Features
π Authentication
Multiple tenants in one server, with isolated credentials and per-call
tenantIdselectionOAuth 2.0 device code authentication flow with Microsoft Graph
Secure token management, cache persistence, and refresh token renewal
Authentication status checking and logout support
Read-only mode with reduced scopes
Direct
AUTH_TOKENsupport for pre-issued Microsoft Graph access tokens
π₯ User Management
Get current user information
Search users by name or email
Retrieve detailed user profiles
Access organizational directory data
π’ Microsoft Teams Integration
Teams Management
List user's joined teams
Access team details and metadata
Channel Operations
List channels within teams
Retrieve channel messages and replies
Send messages to team channels
Reply to existing channel threads
Edit and soft delete channel messages and replies
Support for message importance levels (
normal,high,urgent)Support for inline image attachments via URL or base64 data
Team Members
List team members and their roles
Access member information
Search users for
@mentions
π¬ Chat & Messaging
1:1 and Group Chats
List user's chats
Create new 1:1 or group conversations
Retrieve chat message history with filtering, ordering, and pagination
Fetch all available messages via
@odata.nextLinkpaginationSend messages to existing chats
Edit previously sent chat messages
Soft delete chat messages
βοΈ Message Management
Edit & Delete
Update (edit) sent messages in chats and channels
Soft delete messages in chats and channels (marks as deleted without permanent removal)
Only message senders can update/delete their own messages
Support for Markdown formatting, mentions, and importance levels on edits
π Media & Attachments
Hosted Content
Download hosted content (images, files) from chat and channel messages
Access inline images and attachments shared in conversations
Optionally save hosted content directly to disk
File Upload
Upload and send any file type (PDF, DOCX, XLSX, ZIP, images, etc.) to channels and chats
Large file support (>4 MB) via resumable upload sessions
Channel uploads go to SharePoint and chat uploads go to OneDrive
Optional message text, custom filename, formatting, and importance levels
π Advanced Search & Discovery
Message Search
Search across all Teams channels and chats using Microsoft Search API
Support for KQL (Keyword Query Language) syntax
Filter by sender, mentions, attachments, read state, and date ranges
Get recent messages with advanced filtering options
Find messages mentioning the current user
Rich Message Formatting Support
The following tools support rich message formatting in Teams channels and chats:
send_channel_messagesend_chat_messagereply_to_channel_messageupdate_channel_messageupdate_chat_messagesend_file_to_channelsend_file_to_chat
Format Options
You can specify the format parameter to control the message formatting:
text(default): Plain textmarkdown: Markdown formatting (bold, italic, lists, links, code, etc.) converted to sanitized HTML
When format is set to markdown, the message content is converted to HTML using a secure markdown parser and sanitized to remove potentially dangerous content before being sent to Teams.
If format is not specified, the message will be sent as plain text.
Example Usage
{
"teamId": "...",
"channelId": "...",
"message": "**Bold text** and _italic text_\n\n- List item 1\n- List item 2\n\n[Link](https://example.com)",
"format": "markdown",
"importance": "high"
}{
"chatId": "...",
"message": "Simple plain text message",
"format": "text"
}Security Features
HTML Sanitization: All markdown content is converted to HTML and sanitized to remove potentially dangerous elements (scripts, event handlers, etc.)
Allowed Tags: Only safe HTML tags are permitted (p, strong, em, a, ul, ol, li, h1-h6, code, pre, etc.)
Safe Attributes: Only safe attributes are allowed
XSS Prevention: Content is automatically sanitized to prevent cross-site scripting attacks
Supported Markdown Features
Text formatting: Bold (
**text**), italic (_text_), strikethrough (~~text~~)Links:
[text](url)Lists: Bulleted (
- item) and numbered (1. item)Code: Inline
`code`and fenced code blocksHeadings:
# H1through###### H6Blockquotes:
> quoted textTables: GitHub-flavored markdown tables
LLM-Friendly Content Format
Messages retrieved from the Microsoft Graph API are returned as raw HTML containing Teams-specific tags. To make this content more consumable by AI assistants, the following tools support automatic HTML-to-Markdown conversion:
get_chat_messagesget_channel_messagesget_channel_message_repliessearch_messagesget_my_mentions
Content Format Options
Use the contentFormat parameter to control how message content is returned:
markdown(default): Converts Teams HTML to clean Markdown, optimized for LLM consumptionraw: Returns the original HTML from the Microsoft Graph API
What Gets Converted
HTML Element | Markdown Output |
|
|
|
|
|
|
|
|
|
|
|
|
| GFM Markdown table |
|
|
| (removed) |
|
|
| Decoded to plain characters |
Attachment Metadata
Messages that contain file attachments or inline images include an attachments array in the response with metadata for each attachment (id, name, contentType, contentUrl, thumbnailUrl). The inline {attachment:id} markers in the markdown content correlate with entries in this array, allowing consumers to identify and download attachments via download_message_hosted_content or download_chat_hosted_content.
Example Usage
{
"chatId": "19:meeting_...",
"limit": 10,
"contentFormat": "markdown"
}To get the original HTML:
{
"chatId": "19:meeting_...",
"limit": 10,
"contentFormat": "raw"
}π¦ Installation
# Use the project's Node.js LTS version
nvm install
nvm use
# Install dependencies
npm install
# Build the project
npm run build
# Set up authentication
npm run auth -- --tenant <tenant-id>π§ Configuration
Prerequisites
Node.js 22.22.2+, 24.15.0+, or 26+ (Node.js 20 is no longer supported)
Microsoft 365 account with appropriate permissions
Microsoft Graph delegated permissions for the scopes below
Required Microsoft Graph Permissions
Full mode (default):
User.Read- Read user profileUser.ReadBasic.All- Read basic user infoTeam.ReadBasic.All- Read team informationChannel.ReadBasic.All- Read channel informationChannelMessage.Read.All- Read channel messagesChannelMessage.Send- Send channel messages and repliesChannelMessage.ReadWrite- Edit and delete channel messagesChat.Read- Read chat messages (included via read-only scopes)Chat.ReadWrite- Create and manage chats, send/edit/delete chat messages (supersedesChat.Read)TeamMember.Read.All- Read team membersFiles.ReadWrite.All- Required for file uploads to channels and chats
Read-only mode (TEAMS_MCP_READ_ONLY=true) β only these scopes are requested:
User.ReadUser.ReadBasic.AllTeam.ReadBasic.AllChannel.ReadBasic.AllChannelMessage.Read.AllTeamMember.Read.AllChat.Read
Multiple Tenants
One MCP server can access several organizations concurrently. Authenticate each target tenant separately, including organizations where you are a guest. Use the Microsoft Entra directory tenant ID (GUID); common, organizations, and tenant domains are not accepted. Each tenant stores one selected account; authenticating again replaces that tenant's active login. Different tenants may use the same home account or entirely different users. --name is a display label, not a routing alias.
For a source checkout, build first, then connect two tenants:
npm ci
npm run build
node dist/index.js authenticate --tenant aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa --name Work
node dist/index.js authenticate --tenant bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb --name Customer --read-only
node dist/index.js tenants
node dist/index.js checkReplace the example IDs with real tenant IDs. The account must belong to or be invited into each tenant, and that tenant must permit the application and required Graph permissions. A login in the home tenant does not automatically authorize guest tenants.
Point your MCP client at the built checkout:
{
"mcpServers": {
"teams": {
"command": "node",
"args": ["/absolute/path/to/teams-mcp/dist/index.js"],
"env": {
"TEAMS_MCP_CONFIG_DIR": "/absolute/path/to/shared/teams-credentials"
}
}
}
}Omit TEAMS_MCP_CONFIG_DIR to use ~/.teams-mcp-plus; if you set it, use the same value when authenticating. For the published package, use npx -y teams-mcp-plus@latest instead of node dist/index.js.
Call list_tenants first. Every other tool accepts an optional tenantId:
{ "name": "list_teams", "arguments": { "tenantId": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa" } }{ "name": "search_messages", "arguments": { "tenantId": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb", "query": "release" } }Selection order is explicit tool tenantId, server --tenant / TEAMS_MCP_TENANT_ID, then the sole connected tenant. With multiple connections and no default, omission returns a selection error. An unknown or logged-out explicit/default tenant always fails; it never falls back to another tenant. Keep resource IDs with the tenant that produced them; results and searches are scoped to one tenant per call, not aggregated across organizations.
# Optional server default; individual tool calls can still target another tenant
node dist/index.js --tenant aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa
# Live check of one tenant; without --tenant/default, check covers all tenants
node dist/index.js check --tenant bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb
# Logout requires an explicit target, even if an environment default is configured
node dist/index.js logout --tenant bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb
node dist/index.js logout --alltenants / list_tenants list local connections; they do not guarantee that consent or refresh tokens are still valid. check and auth_status acquire a token and call Graph /me. check exits nonzero if any checked connection fails. New logins and logout are detected by running servers without a restart; requests already submitted to Graph cannot be recalled. Logout clears local files, not Microsoft account sessions or consent. An injected AUTH_TOKEN remains active until removed from the environment and the server restarted.
Isolation design: tenant-specific authorities are used for both device-code login and silent refresh. Account selection matches the persisted home account ID, local account ID, and tenant ID instead of taking the first cached account. A tool receives an immutable tenant-bound service, also passed to file uploads and user lookups. Each login has a separate cache revision; stale processes cannot overwrite the active login. Previous cache revisions are removed when that tenant is logged out. This follows Microsoft's guidance on MSAL account selection and authority configuration.
Authentication Modes
Full access:
npx teams-mcp-plus@latest authenticate --tenant <tenant-id>Read-only access:
npx teams-mcp-plus@latest authenticate --tenant <tenant-id> --read-onlyDirect token injection with an existing Microsoft Graph JWT:
{
"mcpServers": {
"teams-mcp-plus": {
"command": "npx",
"args": ["-y", "teams-mcp-plus@latest"],
"env": {
"AUTH_TOKEN": "<jwt-for-https://graph.microsoft.com>"
}
}
}
}Token Storage
Each tenant has its own directory:
~/.teams-mcp-plus/<tenant-id>/.profile.jsonrecords the selected account, label, granted scopes, and login revision.<revision>.cache.jsoncontains the MSAL tokens for that login. Files use mode0600, and newly created directories use0700on POSIX systems. Writes are atomic. These files contain credentials in plaintext; protect the directory.TEAMS_MCP_CONFIG_DIRoverrides the storage root. All CLI and MCP processes that share connections must use the same directory.Old single-account files are neither read nor migrated. Re-authenticate each tenant; obsolete legacy files can be removed manually.
π οΈ Usage
Starting the Server
# Development mode with hot reload
npm run dev
# Production mode
npm run build && node dist/index.js
# Start in read-only mode (disables all write tools)
TEAMS_MCP_READ_ONLY=true node dist/index.jsCLI Commands
npx teams-mcp-plus@latest authenticate --tenant <tenant-id> # Authenticate with full scopes
npx teams-mcp-plus@latest authenticate --tenant <tenant-id> --read-only # Authenticate with read-only scopes
npx teams-mcp-plus@latest check # Check authentication status
npx teams-mcp-plus@latest logout --tenant <tenant-id> # Clear authentication
npx teams-mcp-plus@latest auth --tenant <tenant-id> # Alias for authenticate
npx teams-mcp-plus@latest # Start MCP server (default)Environment Variables
TEAMS_MCP_READ_ONLY=true- Start the MCP server in read-only modeTEAMS_MCP_TENANT_ID=<tenant-id>- Default tenant;--tenanttakes precedence. Explicit tooltenantIdoverrides both.TEAMS_MCP_CONFIG_DIR=<path>- Shared credential directory (default:~/.teams-mcp-plus).AUTH_TOKEN=<jwt>- Pre-issued Graph token, used only for the tenant in itstidclaim. Other tenants continue to use their own MSAL credentials. The token must have a valid Graph audience and unexpiredexp; it is never written to disk or refreshed.
Read-Only Mode
The server supports a read-only mode that disables all write operations (sending messages, creating chats, uploading files, editing/deleting messages) and requests only read-permission scopes from Microsoft Graph.
Enable read-only mode using either:
Environment variable:
TEAMS_MCP_READ_ONLY=trueCLI flag:
--read-only
Authenticate with reduced scopes:
npx teams-mcp-plus@latest authenticate --tenant <tenant-id> --read-onlyMCP server configuration (read-only):
{
"mcpServers": {
"teams-mcp-plus": {
"command": "npx",
"args": ["-y", "teams-mcp-plus@latest"],
"env": {
"TEAMS_MCP_READ_ONLY": "true"
}
}
}
}Switching modes: Scope grants are stored per tenant. A full-mode server can expose write tools while a tenant still has read-only grants; that tenant's write requests will fail with a Graph permission error. Re-authenticate that tenant without --read-only to request write permissions:
npx teams-mcp-plus@latest authenticate --tenant <tenant-id>Read-only tools (18):
list_tenants, auth_status, get_current_user, search_users, get_user, list_teams, list_channels, get_channel_messages, get_channel_message_replies, list_team_members, search_users_for_mentions, download_message_hosted_content, list_chats, list_chat_members, get_chat_messages, download_chat_hosted_content, search_messages, get_my_mentions
Write tools disabled in read-only mode (15):
set_chat_read_state, send_channel_message, reply_to_channel_message, update_channel_message, delete_channel_message, send_file_to_channel, send_chat_message, create_chat, update_chat_message, delete_chat_message, send_file_to_chat, set_channel_message_reaction, unset_channel_message_reaction, set_chat_message_reaction, unset_chat_message_reaction
Available MCP Tools
Authentication
list_tenants- List tenant IDs, labels, account names, scopes, and the configured default (no token refresh)auth_status- Check current authentication status
User Operations
get_current_user- Get authenticated user informationsearch_users- Search for users by name or emailget_user- Get detailed user information by ID or email
Teams Operations
list_teams- List user's joined teamslist_channels- List channels in a specific teamget_channel_messages- List channel messages, or passmessageIdto read one; addreplyIdto read a specific replyget_channel_message_replies- Get replies to a specific channel messagesend_channel_message- Send a message to a team channel with optional mentions, importance, and image attachmentsreply_to_channel_message- Reply to an existing channel messageupdate_channel_message- Edit a previously sent channel message or replydelete_channel_message- Soft delete a channel message or replylist_team_members- List members of a specific teamsearch_users_for_mentions- Search for team members to @mention in messagessend_file_to_channel- Upload a local file and send it as a message to a channel
Chat Operations
list_chats- List all user's chats (1:1, group, and meeting), with read status and latest-message previews; useunreadOnly: trueto filter unread chatsget_chat_messages- List chat messages with pagination and filters, or passmessageIdto read onelist_chat_members- List all chat members with membership IDs, user IDs, names, emails, tenant IDs, roles, and visible history start timesset_chat_read_state- Mark a chat read (isRead: true) or unread (isRead: false) for the current usersend_chat_message- Send a message to a chatcreate_chat- Create a new 1:1 or group chatupdate_chat_message- Edit a previously sent chat messagedelete_chat_message- Soft delete a chat messagesend_file_to_chat- Upload a local file and send it as a message to a chat
To find unread chats, call list_chats with:
{
"tenantId": "<tenant-id from list_tenants>",
"unreadOnly": true
}The tool lists chats newest message first ($orderby=lastMessagePreview/createdDateTime desc),
follows all chat pages, and compares lastMessagePreview.createdDateTime with
viewpoint.lastMessageReadDateTime, as described in the
Microsoft Graph documentation.
It does not use the Search API's IsRead filter. Results retain the existing chat-list array
format and include isUnread, isHidden, lastMessageReadDateTime, and lastMessagePreview
(message ID, Markdown content, sender name, and creation time). Hidden chats are included.
Missing or invalid timestamps produce isUnread: null; these chats are excluded when
unreadOnly is true. If none match, the response notes any chats with unknown read status.
Omit unreadOnly (or set it to false) to list all chats, including those with unknown status.
This indicates messages after your read position, not other participants' Seen receipts.
It covers chats, not channels, and does not change read state. To fetch the messages,
use get_chat_messages with the returned chat ID and since: lastMessageReadDateTime.
Single-message reads keep the { totalReturned, hasMore, messages } response envelope and
support contentFormat (markdown or raw). Chat list filters, sorting, and pagination
are ignored when messageId is supplied; channel limit is also ignored for single reads.
A channel replyId requires the parent messageId. Reads do not mark messages read.
{ "name": "get_chat_messages", "arguments": { "chatId": "<chat>", "messageId": "<message>" } }
{ "name": "get_channel_messages", "arguments": { "teamId": "<team>", "channelId": "<channel>", "messageId": "<parent>", "replyId": "<reply>" } }
{ "name": "list_chat_members", "arguments": { "chatId": "<chat>" } }
{ "name": "set_chat_read_state", "arguments": { "chatId": "<chat>", "isRead": true } }set_chat_read_state uses the existing delegated Chat.ReadWrite permission and is disabled
in read-only mode. When marking unread, omit lastMessageReadDateTime to mark the latest
message unread, or supply an ISO timestamp to mark messages after that time unread.
This timestamp is rejected with isRead: true. See Graph's
mark read
and mark unread APIs.
Member id identifies the membership record; use userId for mentions and user lookup.
All calls support the existing optional tenantId selector.
Media Operations
download_message_hosted_content- Download hosted content (images, files) from channel messagesdownload_chat_hosted_content- Download hosted content (images, files) from chat messages
Search Operations
search_messages- Search across all Teams messages using KQL syntaxget_my_mentions- Find recent messages mentioning the current user
π Examples
Authentication
First, authenticate with Microsoft Graph:
# Full access (default)
npx teams-mcp-plus@latest authenticate --tenant <tenant-id>
# Read-only (reduced permission scopes)
npx teams-mcp-plus@latest authenticate --tenant <tenant-id> --read-onlyCheck your authentication status:
npx teams-mcp-plus@latest checkLogout if needed:
npx teams-mcp-plus@latest logout --tenant <tenant-id>Chat Pagination Example
{
"chatId": "19:meeting_...",
"limit": 100,
"fetchAll": true,
"orderBy": "createdDateTime",
"descending": true,
"contentFormat": "markdown"
}Channel Message with Mentions and Image
{
"teamId": "team-id",
"channelId": "channel-id",
"message": "Please review **today's update**",
"format": "markdown",
"importance": "high",
"mentions": [
{
"mention": "alex.chen",
"userId": "00000000-0000-0000-0000-000000000000"
}
],
"imageUrl": "https://example.com/status.png"
}File Upload Example
{
"chatId": "19:meeting_...",
"filePath": "/absolute/path/to/report.pdf",
"message": "Please review the attached report",
"format": "markdown"
}Integrating with Cursor/Claude
This MCP server is designed to work with AI assistants like Claude/Cursor/VS Code through the Model Context Protocol.
{
"mcpServers": {
"teams-mcp-plus": {
"command": "npx",
"args": ["-y", "teams-mcp-plus@latest"]
}
}
}π Security
All authentication is handled through Microsoft's OAuth 2.0 flow or a caller-provided Microsoft Graph token
Refresh token support: Access tokens are automatically renewed using cached refresh tokens, so you don't need to re-authenticate every hour
Credentials are isolated per tenant under
~/.teams-mcp-plus/<tenant-id>/; logout removes all login generations for that tenant.Markdown content is sanitized before sending HTML to Teams
AUTH_TOKENrouting checks its Graph audience, tenant ID, and expiry. Microsoft Graph validates the token signature and permissions.No sensitive data is logged or exposed
Follows Microsoft Graph API security best practices
π License
MIT License - see LICENSE file for details
π€ Contributing
Fork the repository
Create a feature branch
Make your changes
Run build, linting, and tests
Submit a pull request
π Support
For issues and questions:
Check the existing GitHub issues
Review Microsoft Graph API documentation
Ensure proper authentication and permissions are configured
Available Tools
33 toolsauth_statusAuth StatusARead-onlyIdempotent
Check live authentication for the selected tenant. Returns its tenant ID, user profile, token expiration, and any authentication error.
| Name | Required | Description | Default |
|---|---|---|---|
| tenantId | No | Target tenant ID from list_tenants. Omit only when a default is configured or exactly one tenant is connected. Resource IDs belong to this tenant. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and non-destructive behavior. The description adds value by noting the check is 'live' and by listing returned auth-related details such as token expiration and errors, which is useful behavioral context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence with no filler. Every part earns its place: it states the action, the target, and the returned information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple optional-parameter read-only tool, the description covers what the agent needs: the purpose, the target tenant, and the returned fields. It does not detail output formatting, but that is not required here given the tool's simplicity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already fully documents tenantId with 100% description coverage, including when to omit it. The description only refers to 'selected tenant' and adds no new parameter meaning, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb and resource: 'Check live authentication for the selected tenant.' It clearly states what the tool returns (tenant ID, user profile, token expiration, authentication error), which distinguishes it from siblings like get_current_user or list_tenants.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly conveys this is a read-only status check for the selected tenant, so an agent can infer when to use it. It does not explicitly name alternatives or exclusions, but the purpose is specific enough to route usage correctly.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_chatCreate ChatB
Create a new chat conversation. Can be a 1:1 chat (with one other user) or a group chat (with multiple users). Group chats can optionally have a topic.
| Name | Required | Description | Default |
|---|---|---|---|
| topic | No | Chat topic (for group chats) | |
| tenantId | No | Target tenant ID from list_tenants. Omit only when a default is configured or exactly one tenant is connected. Resource IDs belong to this tenant. | |
| userEmails | Yes | Array of user email addresses to add to chat |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already carry the mutation profile (readOnlyHint=false, destructiveHint=false), and the description's 'Create' is consistent with that. It adds the 1:1 vs group mode distinction and topic optionality as useful behavioral context, but does not disclose edge-case behavior such as duplicate-chat handling or what occurs when a chat already exists between the given users.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences with zero waste. The core purpose is front-loaded, and the mode distinction (1:1 vs group) and topic optionality each earn their place without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Moderate complexity with clear schema and annotations, and no output schema, so return-format documentation is not expected. The description covers the primary creation semantics well. The main gaps are edge cases like duplicate-chat behavior, but these are minor given the openWorldHint annotation and non-destructive mutation profile.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so all three parameters (topic, tenantId, userEmails) are already documented in the schema. The description reinforces the relationship between userEmails count and chat type (1:1 requires one other user) and topic's optionality, which adds minor semantic value but does not go beyond the schema baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a clear verb+resource: 'Create a new chat conversation.' It adds a valuable distinction between 1:1 and group chats and notes topic optionality. No competing creation tool exists among siblings, so differentiation is less critical, but the description is specific and unambiguous about what it creates.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is given on when to use this tool versus alternatives, nor any exclusions. The description never mentions how it relates to sibling tools like list_chats, send_chat_message, or get_chat_messages. An agent must infer from context that this is the chat-creation entry point.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
delete_channel_messageDelete Channel MessageADestructiveIdempotent
Soft delete a message in a channel. Only the message sender can delete their own messages. The message will be marked as deleted.
| Name | Required | Description | Default |
|---|---|---|---|
| teamId | Yes | Team ID | |
| replyId | No | Reply ID if deleting a reply to a message (optional) | |
| tenantId | No | Target tenant ID from list_tenants. Omit only when a default is configured or exactly one tenant is connected. Resource IDs belong to this tenant. | |
| channelId | Yes | Channel ID | |
| messageId | Yes | Message ID to delete |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description reveals that the delete is soft ('will be marked as deleted') and imposes a sender-only permission, which goes beyond the annotations' destructiveHint and idempotentHint. This clarifies the actual effect on the message and who is allowed to trigger it. No contradiction with annotations since readOnlyHint=false and destructiveHint=true align with deletion.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences totaling ~30 words, front-loading the core action and then layering the permission and outcome. No filler or redundancy. Every sentence contributes either the primary action or a necessary constraint.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the essential usage and effect, and the annotations handle idempotency and destructiveness. The optional replyId is sufficiently documented in the schema, and no output schema means return values aren't expected. A minor gap is the lack of error behavior when the caller is not the sender, but the ownership rule already prevents misuse.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and all parameters have individual descriptions, so the baseline is 3. The description does not add any parameter-specific semantics, such as how replyId interacts with messageId, leaving that to the schema. The sender-only rule is a behavioral constraint, not a parameter clarification.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states the action ('soft delete'), resource ('message in a channel'), and distinct nature ('marked as deleted'). Differentiates from sibling delete_chat_message via the channel context and soft-delete wording. No ambiguity about what the tool does.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives a clear when-not condition: only the sender can delete their own message, so an agent knows not to invoke this on behalf of other users. It implies use for channel messages rather than chat messages but does not explicitly name alternative tools like delete_chat_message. The context is adequate for most routing decisions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
delete_chat_messageDelete Chat MessageADestructiveIdempotent
Soft delete a chat message that was previously sent. Only the message sender can delete their own messages. The message will be marked as deleted but can still be seen as '[This message has been deleted]'.
| Name | Required | Description | Default |
|---|---|---|---|
| chatId | Yes | Chat ID | |
| tenantId | No | Target tenant ID from list_tenants. Omit only when a default is configured or exactly one tenant is connected. Resource IDs belong to this tenant. | |
| messageId | Yes | Message ID to delete |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds valuable behavioral context beyond the annotations: it explains the soft-delete effect (message marked as deleted but visible as placeholder) and the permission restriction, aligning with destructiveHint=true and readOnlyHint=false.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is conciseβtwo sentencesβfront-loaded with the core action and key constraints, with no redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the action, permission, and visible outcome, which is sufficient for an agent to invoke it correctly. Minor gaps like error handling or return value are not mentioned, but given the simplicity and schema coverage, it is adequately complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already provides descriptions for all three parameters (chatId, messageId, tenantId) at 100% coverage. The tool description adds no extra parameter-specific guidance, so it relies on the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action as a 'soft delete' of a chat message, distinguishing it from hard deletes and from sibling tools like delete_channel_message. The verb and resource are explicit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It specifies a clear usage constraint: only the message sender can delete their own messages. This helps the agent decide when to use the tool, though it does not explicitly contrast with alternatives like delete_channel_message.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
download_chat_hosted_contentDownload Chat Hosted ContentARead-onlyIdempotent
Download hosted content (such as images) from a chat message. Returns the content as base64 encoded data along with metadata. Use this to retrieve images or other inline content embedded in chat messages.
| Name | Required | Description | Default |
|---|---|---|---|
| chatId | Yes | Chat ID | |
| savePath | No | Optional file path to save the content. Supports UNC paths (e.g., \\wsl.localhost\Ubuntu\tmp\file.png). | |
| tenantId | No | Target tenant ID from list_tenants. Omit only when a default is configured or exactly one tenant is connected. Resource IDs belong to this tenant. | |
| messageId | Yes | Message ID containing the hosted content | |
| hostedContentId | No | Specific hosted content ID to download. If not provided, downloads all hosted contents from the message. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already disclose readOnlyHint=true and destructiveHint=false, meaning it's a safe read operation. The description adds that it returns base64 encoded data with metadata, which is useful, but does not mention how downloads work when savePath is provided or whether it still returns data. No contradiction, but limited additional behavioral context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences, front-loaded with the primary action and return format, then a usage hint. It is concise and free of fluff, though it could have been slightly more structured, so a 4.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the descriptions of parameters, annotations, and lack of output schema, the description provides sufficient detail for an agent to use the tool correctly. It mentions the return type (base64) and usage context, but does not cover edge cases like what happens when no hostedContentId is provided or savePath behavior. Minor gaps but overall complete for a read-only download.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so every parameter has a description. The tool description adds no extra meaning beyond the schema. Baseline 3 applies since schema does the heavy lifting and the description doesn't need to compensate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'Download' and the resource 'hosted content (such as images) from a chat message', and mentions it returns base64 data and metadata. It differentiates from sibling download_message_hosted_content by specifying 'chat message', but does not explicitly contrast with that sibling, so not a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description states 'Use this to retrieve images or other inline content embedded in chat messages' which gives some usage context, but it does not explicitly say when not to use it or contrast with the sibling download_message_hosted_content. It implies usage for chat-related content but lacks exclusionary guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
download_message_hosted_contentDownload Message Hosted ContentARead-onlyIdempotent
Download hosted content (such as images) from a Teams channel message. Returns the content as base64 encoded data along with metadata. Use this to retrieve images or other inline content embedded in messages.
| Name | Required | Description | Default |
|---|---|---|---|
| teamId | Yes | Team ID | |
| replyId | No | Reply ID if downloading hosted content from a reply to a message (optional) | |
| savePath | No | Optional file path to save the content. Supports UNC paths (e.g., \\wsl.localhost\Ubuntu\tmp\file.png). | |
| tenantId | No | Target tenant ID from list_tenants. Omit only when a default is configured or exactly one tenant is connected. Resource IDs belong to this tenant. | |
| channelId | Yes | Channel ID | |
| messageId | Yes | Message ID containing the hosted content | |
| hostedContentId | No | Specific hosted content ID to download. If not provided, downloads all hosted contents from the message. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, which reduces the burden on the description. The description adds value by disclosing the return format ('base64 encoded data along with metadata') and clarifying the content type ('images or other inline content'), which complements the annotations. It does not mention the optional savePath side effect, but the schema covers that.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two concise sentences with no wasted words. The first sentence front-loads the core action and return behavior, and the second provides a direct usage pointer. Every phrase earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite having 7 parameters, the required parameters are clear from the schema. The description explains what the tool does and returns, which is sufficient given the schema covers parameter meanings. It could mention the optional savePath behavior or the difference from the chat variant, but those are accessible or inferable, so the description is largely complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all parameters have descriptions and the baseline is 3. The description adds minimal parameter-specific semantics beyond saying the content is 'inline content,' which is a general clarification rather than a detailed parameter explanation. It does not need to compensate for schema gaps.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific action ('Download hosted content') and resource ('from a Teams channel message'), and clarifies the return format ('base64 encoded data along with metadata'). It also explicitly notes the content type ('such as images'), making it distinct from the sibling tool download_chat_hosted_content, which targets chat messages.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context with 'Use this to retrieve images or other inline content embedded in messages,' which tells an agent when to invoke the tool. However, it does not explicitly name the alternative for chat messages (download_chat_hosted_content) or state when not to use it, so it stops short of the 'explicit when/when-not/alternatives' level.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_channel_message_repliesGet Channel Message RepliesARead-onlyIdempotent
Get all replies to a specific message in a channel. Returns reply content, sender information, and timestamps.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Number of replies to retrieve (default: 20) | |
| teamId | Yes | Team ID | |
| tenantId | No | Target tenant ID from list_tenants. Omit only when a default is configured or exactly one tenant is connected. Resource IDs belong to this tenant. | |
| channelId | Yes | Channel ID | |
| messageId | Yes | Message ID to get replies for | |
| contentFormat | No | Format for message content. "markdown" (default) converts Teams HTML to clean Markdown optimized for LLMs. "raw" returns original HTML from Graph API. | markdown |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds that it returns reply content, sender info, and timestamps, which is useful but does not disclose pagination behavior, ordering, or how the limit parameter affects results. With annotations covering the core behavioral traits, a 3 is appropriate.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, efficient sentence that front-loads the core action and result. It is appropriately sized for a read-only retrieval tool and contains no wasted words. It could add a note about pagination or limit behavior, but it is not overly verbose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only list tool with 100% schema coverage and annotations covering safety, the description is mostly complete. However, it does not mention pagination, ordering, or how the limit parameter interacts with the 'all replies' claim. An agent might assume 'all' means unlimited, while the schema shows a default limit of 20 and a maximum of 50. This is a minor but real gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all six parameters. The description adds no parameter-specific meaning beyond what the schema provides, but it does confirm the tool returns replies for a specific message, which aligns with messageId. Baseline 3 is correct when the schema does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Get'), a specific resource ('all replies to a specific message in a channel'), and the returned data ('reply content, sender information, and timestamps'). It clearly distinguishes this from sibling tools like get_channel_messages (which lists messages) and reply_to_channel_message (which creates a reply).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies the tool is for reading replies to a specific message, which is clear from the name and description. However, it does not explicitly state when to use this tool versus alternatives like get_channel_messages or search_messages, nor does it mention any exclusions or prerequisites (e.g., needing the messageId from a prior call).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_channel_messagesGet Channel MessagesBRead-onlyIdempotent
List channel messages or read one message or reply by ID.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Number of messages to retrieve (default: 20) | |
| teamId | Yes | Team ID | |
| replyId | No | Read this reply; requires its parent messageId. | |
| tenantId | No | Target tenant ID from list_tenants. Omit only when a default is configured or exactly one tenant is connected. Resource IDs belong to this tenant. | |
| channelId | Yes | Channel ID | |
| messageId | No | Read one message; ignores limit. | |
| contentFormat | No | Markdown or original message body. | markdown |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds the dual list/single-read behavior, which is useful context, but it does not disclose pagination behavior, output shape, or any access requirements. No contradiction with annotations exists.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single efficient sentence with the action verb front-loaded and no filler words. It is appropriately compact, though it could have been more informative without becoming bloated, which is why it does not reach 5.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has 7 parameters, 32 sibling tools, and no output schema, the description is minimally adequate. The schema covers parameters and annotations cover read-only/idempotent behavior, but the description leaves unclear when each mode applies and how this tool relates to similar ones like get_chat_messages or get_channel_message_replies.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so parameters are fully documented in the input schema. The description only lightly gestures at messageId/replyId ('read one message or reply by ID') without adding format, precedence, or interaction details beyond the schema, so it does not elevate above the baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb ('List'/'read') and resource ('channel messages'), and clarifies three modes: list, read one message, read one reply. It is not a tautology, and the 'reply by ID' clause distinguishes it from a plain listing tool, though it does not explicitly contrast with siblings like get_channel_message_replies or get_chat_messages.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is given on when to use this tool versus alternatives. It does not mention that get_channel_message_replies is better for reply threads, that search_messages is for searching, or that get_chat_messages covers direct messages instead of channels. The only implied guidance is 'read channel messages,' which is weak for a tool with many siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_chat_messagesGet Chat MessagesBRead-onlyIdempotent
List chat messages or read one by ID.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Number of messages to retrieve (default: 20, max: 2000) | |
| since | No | Get messages since this ISO datetime | |
| until | No | Get messages until this ISO datetime | |
| chatId | Yes | Chat ID | |
| orderBy | No | Sort order | createdDateTime |
| fetchAll | No | Follow pages up to limit. | |
| fromUser | No | Filter messages from specific user ID | |
| tenantId | No | Target tenant ID from list_tenants. Omit only when a default is configured or exactly one tenant is connected. Resource IDs belong to this tenant. | |
| messageId | No | Read one message; ignores list filters, sorting and pagination. | |
| descending | No | Sort in descending order (newest first) | |
| contentFormat | No | Markdown or original message body. | markdown |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, so the safety profile is covered. The description adds no extra behavioral context, such as pagination behavior, the meaning of fetchAll, or that messageId bypasses list filters. Given the annotations, a 3 is appropriate β the description doesn't contradict annotations but also doesn't enrich them.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is extremely concise, a single sentence that conveys the core purpose. It's front-loaded with the main actions. However, it is arguably too terse for an 11-parameter tool, but that's a completeness issue, not a conciseness issue. It wastes no words, so it earns a 4.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With 11 parameters, 2 enums, and no output schema, the description is severely underspecified. It doesn't explain the difference between listing and reading by ID, the role of pagination (fetchAll), or the filtering options (since, until, fromUser). An agent needs more context to call this correctly, especially to understand when to use messageId vs the list filters. The description is not sufficient for a tool of this complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% with each parameter having a meaningful description. The description itself adds nothing about parameters. Baseline 3 is correct since the schema does the heavy lifting; the description doesn't need to repeat what's already documented.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool lists chat messages or reads a single one by ID. The verb 'List' and 'read' specify the primary actions, and the resource is 'chat messages'. However, it doesn't explicitly differentiate from sibling tools like get_channel_messages, which also deal with messages, but the chat vs channel distinction is implied. It's clear but could be more specific about scope.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives no guidance on when to use this tool versus alternatives such as get_channel_messages or search_messages. It doesn't mention scenarios where reading a single message via messageId is preferred, nor does it explain the relationship between chat messages and channel messages. An agent has to infer usage from the schema, which is not sufficient.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_current_userGet Current UserARead-onlyIdempotent
Get the current authenticated user's profile information including display name, email, job title, and department.
| Name | Required | Description | Default |
|---|---|---|---|
| tenantId | No | Target tenant ID from list_tenants. Omit only when a default is configured or exactly one tenant is connected. Resource IDs belong to this tenant. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, covering the safety profile. The description adds the list of returned fields, which is useful but does not disclose other behavioral traits such as authentication requirements, error handling, or the exact response structure. Given the annotations, the description provides modest additional context beyond what is structured.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single, tightly written sentence that front-loads the core purpose and lists the returned fields. There is no redundant wording, and every phrase adds value. The description is appropriately brief for a simple read-only operation.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a straightforward read-only profile retrieval with an optional parameter and no output schema, the description covers the main purpose and key fields. It does not describe the full response envelope or error conditions, but given the simplicity and the annotations, it is reasonably complete. An agent can call it correctly based on this description alone.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema provides a complete description for tenantId, including type, pattern, and usage guidance (omit when default or single tenant). Schema description coverage is 100%, so the description does not need to add param details. The tool description adds nothing about the parameter, but the baseline of 3 is appropriate since the schema fully documents it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('Get') and the resource ('current authenticated user's profile information'), and explicitly lists the fields returned (display name, email, job title, department). The qualifier 'current authenticated' distinguishes it from sibling tools like get_user (which likely targets a specific user by ID) and search_users, so an agent can select it correctly without ambiguity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage when the current user's profile is needed, but it does not explicitly mention alternatives or provide exclusion conditions. There is no guidance on when to prefer this over get_user or search_users, though the 'current' qualifier partially signals the intended context. The description leaves the selection logic to inference rather than spelling it out.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_my_mentionsGet My MentionsARead-onlyIdempotent
Find recent messages where the current user was @mentioned across all Teams channels and chats.
| Name | Required | Description | Default |
|---|---|---|---|
| size | No | Maximum number of mentions to return | |
| hours | No | Look back this many hours (max 168 = 1 week) | |
| tenantId | No | Target tenant ID from list_tenants. Omit only when a default is configured or exactly one tenant is connected. Resource IDs belong to this tenant. | |
| contentFormat | No | Format for message content. "markdown" (default) converts Teams HTML to clean Markdown optimized for LLMs. "raw" returns original HTML from Graph API. | markdown |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, covering the safety profile. The description adds the scoping detail of 'across all Teams channels and chats' and the recency filter, but does not disclose behavior like ordering, pagination, or handling of missing tenantId. Since annotations carry the heavy lifting, this is adequate but not rich.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, well-structured sentence that front-loads the purpose and scope. It contains zero fluff and every word earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only tool with strong annotations and full schema coverage, the description is fairly complete. It clearly states what it does and its scope. It could mention the return format or ordering, but given the lack of an output schema and the simple nature of the tool, nothing critical is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all four parameters (size, hours, tenantId, contentFormat) have detailed descriptions in the input schema. The description itself does not add parameter-level detail beyond what the schema provides, so a baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's action (find recent messages) and resource (mentions for the current user) with an explicit scope (across all Teams channels and chats). It is easily distinguishable from siblings like get_channel_messages or search_messages, which target different resources or scopes.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies a clear use caseβretrieving mentions for the current userβbut does not explicitly mention when to prefer this tool over alternatives like search_messages or when not to use it. It lacks exclusions or alternative tool names, leaving the agent to infer the appropriate context from the scope stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_userGet UserARead-onlyIdempotent
Get detailed information about a specific user by their ID or email address. Returns profile information including name, email, job title, and department.
| Name | Required | Description | Default |
|---|---|---|---|
| userId | Yes | User ID or email address | |
| tenantId | No | Target tenant ID from list_tenants. Omit only when a default is configured or exactly one tenant is connected. Resource IDs belong to this tenant. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish this is read-only, idempotent, and non-destructive. The description adds useful behavioral context by listing the type of data returned, which helps an agent know what to expect. It does not describe error cases or tenant behavior, but those are partially covered by the schema and annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two short sentences, each earning its place: the first defines scope and lookup method, the second defines the output. No filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only fetch with one required parameter and full schema coverage, the description covers what the tool does and what it returns. It does not discuss not-found behavior or when tenantId must be supplied, but the schema and annotations already provide the key operational constraints. The absence of an output schema is offset by the explicit return-field list.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description essentially restates that userId can be an ID or email and adds the return fields, but it does not add new meaning beyond the schema for either parameter. It is adequate but not enriching.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('get'), a clear resource ('user'), and the lookup key ('by their ID or email address'). It also summarizes the return payload (profile information: name, email, job title, department), which distinguishes it from siblings like get_current_user and search_users.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly indicates this tool is for retrieving a specific user when an identifier is known. It does not explicitly name alternatives like search_users for unknown identifiers, so it lacks full when-not guidance, but the 'by ID or email' phrasing gives clear contextual direction.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_channelsList ChannelsARead-onlyIdempotent
List all channels in a specific Microsoft Team. Returns channel names, descriptions, types, and IDs for the specified team.
| Name | Required | Description | Default |
|---|---|---|---|
| teamId | Yes | Team ID | |
| tenantId | No | Target tenant ID from list_tenants. Omit only when a default is configured or exactly one tenant is connected. Resource IDs belong to this tenant. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark read-only/idempotent. The description adds the scope ('all channels ... specified team') and the returned fields (names, descriptions, types, IDs), providing behavioral context beyond the annotation flags. It doesn't discuss pagination or error conditions, but those are minor for this simple read tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with purpose, each sentence earns its place. No filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The definition is complete for a read-only list tool: it states what it lists, under what scope, and what the response contains. The schema covers the required teamId and optional tenantId. No output schema exists, so the return-field list is the key missing piece and it is provided.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so parameters already have descriptions. The description only references the team (via 'specified team') without adding new semantic details about teamId or tenantId; baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('List'), resource ('channels'), and scope ('in a specific Microsoft Team'). It also enumerates returned fields, which distinguishes it from sibling list_teams and get_channel_messages.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied rather than explicit: the description implies you need channel info for a given team, but it doesn't name alternatives or state when not to use it (e.g., use list_teams first).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_chat_membersList Chat MembersBRead-onlyIdempotent
List all chat members with user IDs, emails, tenant IDs and roles.
| Name | Required | Description | Default |
|---|---|---|---|
| chatId | Yes | Chat ID | |
| tenantId | No | Target tenant ID from list_tenants. Omit only when a default is configured or exactly one tenant is connected. Resource IDs belong to this tenant. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds the return fields (user IDs, emails, tenant IDs, roles), which is useful but does not disclose pagination, ordering, or whether the result includes the requesting user. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single concise sentence that front-loads the action and resource. It is appropriately sized with no wasted words, though it could add a brief usage note without becoming bloated.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only list tool with full schema coverage and safety annotations, the description is mostly adequate. However, it does not mention pagination, result size limits, or whether the chat must exist, which an agent might need to know for robust invocation. The lack of an output schema increases the burden slightly, but the listed return fields mitigate it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents both parameters. The description does not add meaning beyond the schema; it only restates the resource being listed. Baseline 3 is appropriate since the schema carries the parameter documentation burden.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('List') and resource ('chat members') and enumerates the fields returned (user IDs, emails, tenant IDs, roles). It is clear about what the tool does, though it does not explicitly distinguish it from sibling tools like list_team_members or list_chats. The title and description align well.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for retrieving chat membership but provides no explicit guidance on when to use this tool versus alternatives such as list_team_members or search_users. The schema's tenantId description adds some context about when to omit tenantId, but the main description lacks when/when-not guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_chatsList ChatsARead-onlyIdempotent
List the current user's 1:1, group, and meeting chats with participants, latest-message previews, and read status. Returns all pages, newest message first.
| Name | Required | Description | Default |
|---|---|---|---|
| tenantId | No | Target tenant ID from list_tenants. Omit only when a default is configured or exactly one tenant is connected. Resource IDs belong to this tenant. | |
| unreadOnly | No | Only return chats with confirmed unread messages based on the current user's read position. Chats with unavailable read status are excluded. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the read-only, idempotent, non-destructive profile. The description adds meaningful behavior beyond that: it auto-returns all pages, orders newest message first, and scopes results to the current user's chats.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with no filler. The first sentence states the scope and returned content; the second covers pagination and ordering. Every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only list operation with no output schema, the description covers the essential behavior: scope, chat types, included fields, pagination, and sort order. The annotations and rich parameter schema cover the remaining operational concerns.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and the schema already provides detailed semantic guidance for tenantId and unreadOnly. The description adds no additional parameter-level meaning, so the baseline score of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('List') and resource ('current user's chats'), enumerates the chat types (1:1, group, meeting) and the returned fields (participants, message previews, read status). This clearly distinguishes it from siblings like get_chat_messages or list_chat_members.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description establishes a clear context: this is for listing the current user's chat overview, not for fetching messages within a single chat. It does not explicitly name an alternative or state when not to use it, so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_team_membersList Team MembersARead-onlyIdempotent
List all members of a specific Microsoft Team. Returns member names, email addresses, roles, and IDs.
| Name | Required | Description | Default |
|---|---|---|---|
| teamId | Yes | Team ID | |
| tenantId | No | Target tenant ID from list_tenants. Omit only when a default is configured or exactly one tenant is connected. Resource IDs belong to this tenant. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, covering the safety profile. The description adds value by specifying the output fields, but does not mention pagination, ordering, or permission requirements, which are minor for a simple list operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence with no filler. It states the action, scope, and return values efficiently, earning its place with zero waste.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple listing tool with two parameters and no output schema, the description provides the essential return fields and the scope. Annotations cover the safety profile, so nothing critical is missing for an agent to call this tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% because both parameters have descriptions, with tenantId having a detailed explanation. The tool description does not add extra parameter context beyond what the schema provides, so the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'List' and the resource 'members of a specific Microsoft Team', and enumerates the returned fields (names, emails, roles, IDs). This distinguishes it from siblings like list_teams and list_chat_members without needing to open schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly scopes the tool to a 'specific Microsoft Team', making its use case clear. It doesn't name alternatives such as list_chat_members for chat members, but the context strongly implies it is for team memberships, and no contradictory guidance is given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_teamsList TeamsARead-onlyIdempotent
List all Microsoft Teams that the current user is a member of. Returns team names, descriptions, and IDs.
| Name | Required | Description | Default |
|---|---|---|---|
| tenantId | No | Target tenant ID from list_tenants. Omit only when a default is configured or exactly one tenant is connected. Resource IDs belong to this tenant. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the description does not need to repeat that this is a safe read operation. It adds the return format (names, descriptions, IDs), which is useful but does not go beyond what annotations already convey about behavior. No mention of pagination, locking, or other side effects, but for a simple list operation this is acceptable given the annotation coverage.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two concise sentences: the first states the main action and scope, the second lists the return fields. It is front-loaded with the primary purpose and has zero unnecessary words or repetition of the tool name.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the core purpose, scope, and return format. It doesn't mention pagination or error behavior, but for a simple list tool with one optional parameter and annotations covering safety, these are minor omissions. The lack of an output schema makes the return-value note particularly helpful, so the description is largely complete for an agent to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and the parameter 'tenantId' is fully described in the schema (purpose, pattern, when to omit). The description adds no additional meaning about how tenantId affects the result beyond what the schema provides, so it meets the baseline for a fully documented parameter.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('List all Microsoft Teams'), the resource (Microsoft Teams), and the scope ('that the current user is a member of'), which distinguishes it from siblings like list_channels (channels within teams) and list_tenants (tenants). It also mentions the return fields (names, descriptions, IDs), making the purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage (to list teams the user belongs to) but does not explicitly state when to use this tool versus alternatives like list_channels or list_team_members. It lacks any explicit 'when not to use' or mention of alternative tools, though the scope is clear enough for an agent to infer the primary use case.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_tenantsList TenantsARead-onlyIdempotent
List connected Microsoft Teams tenants, account names, granted scopes, and configured default. Use the tenantId in subsequent tool calls. Saved connections may require re-authentication; use auth_status to check live access.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and non-destructive behavior. The description adds useful behavioral nuance beyond those annotations: saved connections may require re-authentication, and the output includes account names, granted scopes, and the configured default. This is exactly the kind of context an agent needs when deciding whether to trust cached connection state.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences with no filler. The first sentence states the action and the returned data; the second covers the key caveat and points to the relevant sibling tool. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple, zero-parameter, read-only discovery tool, the description is complete: it names the returned fields, explains how to use the result, and flags the authentication caveat. No output schema exists, but the description adequately covers what the agent needs to know to select and use the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With zero parameters and 100% schema coverage, the input schema is already exhaustive and there are no parameters to document. The description orients the agent to the meaningful output fields, which is all that is needed for a no-parameter tool.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'List connected Microsoft Teams tenants', and specifies the exact returned fields (account names, granted scopes, configured default). This differentiates it from sibling tools like list_teams and list_channels, which operate at different levels of the Microsoft Teams hierarchy.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear operational context: use the returned tenantId in subsequent tool calls, and use auth_status to check live access when saved connections may need re-authentication. It provides an explicit alternative for the auth edge case, though it does not explicitly contrast list_tenants with list_teams or list_channels.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
reply_to_channel_messageReply to Channel MessageB
Reply to a specific message in a channel. Supports text and markdown formatting, mentions, and importance levels.
| Name | Required | Description | Default |
|---|---|---|---|
| format | No | Message format (text or markdown) | |
| teamId | Yes | Team ID | |
| message | Yes | Reply content | |
| imageUrl | No | URL of an image to attach to the reply | |
| mentions | No | Array of @mentions to include in the reply | |
| tenantId | No | Target tenant ID from list_tenants. Omit only when a default is configured or exactly one tenant is connected. Resource IDs belong to this tenant. | |
| channelId | Yes | Channel ID | |
| imageData | No | Base64 encoded image data to attach | |
| messageId | Yes | Message ID to reply to | |
| importance | No | Message importance | |
| imageFileName | No | Name for the attached image file | |
| imageContentType | No | MIME type of the image (e.g., 'image/jpeg', 'image/png') |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnlyHint=false, destructiveHint=false, and idempotentHint=false, so the basic behavioral profile is covered. The description adds that text/markdown formatting, mentions, and importance levels are supported, but it does not disclose side effects, send behavior, or what the reply operation produces. There is no contradiction with the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence with no filler. It states the core action first and then summarizes key supported capabilities. It could add more structured guidance, but as written it is appropriately concise.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The full schema and annotations compensate for many gaps, but this is a 12-parameter write operation with image attachment options and no output schema. The description does not explain when to use this tool versus send_channel_message, nor does it clarify workflow-level concerns like reply threading or the expected result. It is adequate but leaves selection-related context to the agent to infer.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all 12 parameters. The description adds a small amount of grouping by mentioning formatting, mentions, and importance levels, but it does not meaningfully extend what the parameter descriptions already provide.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a clear verb and target: 'Reply to a specific message in a channel.' It unambiguously identifies the operation as a reply to an existing message, which distinguishes it from sending, updating, deleting, or reacting to channel messages.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No usage guidance is provided. The description never states when to choose this tool over send_channel_message or get_channel_message_replies, and it does not mention any exclusions, prerequisites, or conditions that would steer an agent toward an alternative.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_messagesSearch MessagesARead-onlyIdempotent
Search for messages across all Microsoft Teams channels and chats using the Microsoft Search API. The query string supports KQL (Keyword Query Language) syntax for advanced filtering: from: β messages sent by a person (e.g. from:bob) to: β messages sent to a person mentions: β messages that mention a specific user ID (without dashes) IsMentioned:true β messages that mention the current user hasAttachment:true|false β filter by attachment presence IsRead:true|false β filter by read status sent>=YYYY-MM-DD β messages sent on or after a date sent<=YYYY-MM-DD β messages sent on or before a date Examples: "quarterly report" from:alice sent>=2025-01-01 hasAttachment:true from:bob project update sent>=2025-02-01 Use get_chat_messages or get_channel_messages for browsing a specific conversation.
| Name | Required | Description | Default |
|---|---|---|---|
| from | No | Offset for pagination (0-based). Use with size to paginate through results | |
| size | No | Number of results to return (max 100) | |
| query | Yes | Search query string. Supports KQL syntax (see tool description) | |
| tenantId | No | Target tenant ID from list_tenants. Omit only when a default is configured or exactly one tenant is connected. Resource IDs belong to this tenant. | |
| contentFormat | No | Format for message content. "markdown" (default) converts Teams HTML to clean Markdown optimized for LLMs. "raw" returns original HTML from Graph API. | markdown |
| enableTopResults | No | When true, results are ranked by relevance. When false, results are unranked |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint false, so the safety profile is covered. The description adds value beyond these by clarifying the global scope across all channels/chats and the KQL filtering behavior. It omits details like rate limits or result shape, but annotations lower the burden here.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but efficiently organized: leading scope statement, KQL reference, examples, and sibling routing. Every section contributes to correct invocation, and the structure makes scanning easy despite the volume of syntax detail.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity, the description covers the query language, pagination semantics, content format, tenant selection, and ranking behavior, either directly or via a well-described schema. There is no output schema, so a brief note about the returned message shape would make it fully complete, but this is a minor gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, but the query parameter in the schema only points to the tool description. The description compensates with a detailed KQL syntax reference, including from:, to:, mentions:, hasAttachment:, IsRead:, and sent date filters, plus multiple examples. This adds substantial meaning beyond the structured input schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening sentence names a specific action, resource, and scope: 'Search for messages across all Microsoft Teams channels and chats using the Microsoft Search API.' This clearly distinguishes it from per-conversation browsing tools and tells the agent exactly what it operates on.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly routes to alternatives with 'Use get_chat_messages or get_channel_messages for browsing a specific conversation.' It also gives representative KQL examples that show the intended use cases, so an agent knows when cross-channel searching is appropriate versus when it is not.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_usersSearch UsersBRead-onlyIdempotent
Search for users in the organization by name or email address. Returns matching users with their basic profile information.
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | Search query (name or email) | |
| tenantId | No | Target tenant ID from list_tenants. Omit only when a default is configured or exactly one tenant is connected. Resource IDs belong to this tenant. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already supply the safety profile (readOnlyHint, idempotentHint, destructiveHint false) and openWorldHint. The description adds that it returns 'basic profile information', which is a modest behavioral detail, but it does not describe limits, pagination, or the exact shape of results. Given the annotations carry most of the burden, this is adequate.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, focused sentence with no wasted words. It communicates the core action and expected return in a compact format.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple search tool, the description covers the basic intent but leaves out practical details such as pagination, result limits, or sorting. The openWorldHint implies variable output, which mitigates the lack of an output schema, but an agent might still need more context about result size or fields.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so both parameters (query, tenantId) are already documented. The description restates that search is by name or email, which adds no new semantics beyond the schema. Baseline 3 is appropriate when the schema fully covers parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('search'), a resource ('users in the organization'), and the search criteria ('by name or email address'). It is clear enough to distinguish from search_users_for_mentions, which targets mention-specific lookups, though it does not explicitly name that sibling.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this tool versus alternatives. The sibling search_users_for_mentions exists for a different use case, but the description does not mention it or any exclusion criteria. An agent would need to infer when this is appropriate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_users_for_mentionsSearch Users for MentionsARead-onlyIdempotent
Search for users to mention in messages. Returns users with their display names, email addresses, and mention IDs.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of results to return | |
| query | Yes | Search query (name or email) | |
| tenantId | No | Target tenant ID from list_tenants. Omit only when a default is configured or exactly one tenant is connected. Resource IDs belong to this tenant. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, covering the safety profile. The description adds the return fields but does not disclose additional behavioral details such as pagination, ordering, or tenant-scoping nuances. It is consistent with annotations and adds modest value beyond them.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two concise sentences with no waste. The purpose is front-loaded, and the return information is immediately useful. Every word earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the simple 3-parameter schema with full coverage and annotations covering safety, the description is largely complete. It explains what the tool does and what it returns. The only minor gap is the lack of explicit differentiation from search_users, but this does not hinder correct invocation when the agent reads the sibling list.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so every parameter (query, limit, tenantId) is already documented in the schema. The description adds no further parameter semantics or usage details, so it meets the baseline of 3 without compensating for any gaps.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: searching for users to mention in messages, and lists the return fields (display names, emails, mention IDs). This distinguishes it from a generic user search, though it does not explicitly name the sibling search_users. It is specific and not a tautology.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies the use case (mentioning users) but does not explicitly state when to use this tool versus search_users or other user-related tools. It gives no exclusions or alternative routing, leaving the agent to infer the appropriate context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
send_channel_messageSend Channel MessageA
Send a message to a specific channel in a Microsoft Team. Supports text and markdown formatting, mentions, and importance levels.
| Name | Required | Description | Default |
|---|---|---|---|
| format | No | Message format (text or markdown) | |
| teamId | Yes | Team ID | |
| message | Yes | Message content | |
| imageUrl | No | URL of an image to attach to the message | |
| mentions | No | Array of @mentions to include in the message | |
| tenantId | No | Target tenant ID from list_tenants. Omit only when a default is configured or exactly one tenant is connected. Resource IDs belong to this tenant. | |
| channelId | Yes | Channel ID | |
| imageData | No | Base64 encoded image data to attach | |
| importance | No | Message importance | |
| imageFileName | No | Name for the attached image file | |
| imageContentType | No | MIME type of the image (e.g., 'image/jpeg', 'image/png') |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnlyHint=false and destructiveHint=false, so 'send' is consistent. The description adds no further behavioral context beyond the fact that it sends a messageβdoes not mention side effects like message visibility, notifications, permission requirements, or rate limits. With the low bar set by annotations, it meets the minimum but adds little.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences with no filler: it front-loads the action and resource, then lists the key capabilities. Every clause earns its place, and it is appropriately sized for the tool's complexity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With 11 parameters and no output schema, the description is somewhat sparse. It captures the core purpose and main formatting features but omits image attachment support, parameter relationships (e.g., imageUrl vs imageData), and guidance on obtaining teamId/channelId. The 100% schema coverage compensates partly, but the description alone is not fully complete for a tool with this many optional features.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description's mention of 'text and markdown formatting, mentions, and importance levels' maps to the format, mentions, and importance parameters, but adds no new meaning beyond the schema's own descriptions. It does not cover image attachment parameters or tenantId semantics, so it barely exceeds the baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Send a message to a specific channel in a Microsoft Team,' which clearly indicates the action. It also lists supported features (text/markdown, mentions, importance) but does not explicitly differentiate from siblings like send_chat_message or reply_to_channel_message, though 'channel' vs 'chat' is implicit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The usage is implied: if you need to send a message to a channel, this tool fits. However, there is no explicit guidance about when not to use it (e.g., for replying, use reply_to_channel_message; for chats, use send_chat_message). The sibling list is rich, but the description does not route the agent to alternatives, leaving the choice to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
send_chat_messageSend Chat MessageB
Send a message to a specific chat conversation. Supports text and markdown formatting, mentions, and importance levels.
| Name | Required | Description | Default |
|---|---|---|---|
| chatId | Yes | Chat ID | |
| format | No | Message format (text or markdown) | |
| message | Yes | Message content | |
| mentions | No | Array of @mentions to include in the message | |
| tenantId | No | Target tenant ID from list_tenants. Omit only when a default is configured or exactly one tenant is connected. Resource IDs belong to this tenant. | |
| importance | No | Message importance |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already convey that this is a non-read-only, non-idempotent, non-destructive operation, so the safety profile is established. The description adds no deeper behavioral context such as delivery behavior or side effects, but it does not contradict the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences with the core action front-loaded and no filler. Every clause either identifies the target or summarizes supported options, making it easy to scan.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple, and the schema covers all parameters, but there is no output schema and the description does not explain what the call returns or how to obtain chatId. It also lacks the usage differentiation needed to guide an agent among similar chat- and channel-message tools.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so every parameter is already documented structurally. The description restates the format, mentions, and importance capabilities at a high level, providing a useful summary but no additional semantics beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Send'), a clear resource ('message'), and a target ('specific chat conversation'). It is unambiguous about the action, though it does not explicitly name or differentiate the sibling tool send_channel_message, leaving distinction somewhat implicit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description does not state when to use this tool versus alternatives like send_channel_message or reply_to_channel_message. It gives no prerequisites, exclusions, or explicit routing guidance for an agent deciding among sibling tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
send_file_to_channelSend File to ChannelA
Upload a local file and send it as a message to a Teams channel. Supports any file type (PDF, DOCX, ZIP, images, etc.). The file is uploaded to the channel's SharePoint folder and sent as a reference attachment. If messageId is provided, the file is sent as a reply to that message (thread).
| Name | Required | Description | Default |
|---|---|---|---|
| format | No | Message format (text or markdown) | |
| teamId | Yes | Team ID | |
| message | No | Optional message text to accompany the file | |
| fileName | No | Optional custom filename (defaults to the original file name) | |
| filePath | Yes | Absolute path to the local file to upload | |
| tenantId | No | Target tenant ID from list_tenants. Omit only when a default is configured or exactly one tenant is connected. Resource IDs belong to this tenant. | |
| channelId | Yes | Channel ID | |
| messageId | No | Optional message ID to reply to. When provided, the file is sent as a reply in the message thread instead of a new message. | |
| importance | No | Message importance |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations, it discloses a key side effect: the file is uploaded to the channel's SharePoint folder and attached as a reference. It also clarifies that providing messageId turns the action into a reply in the thread. It does not mention permission requirements or duplicate-file behavior, but the annotations already signal mutation and non-idempotency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences with no filler: the first states the action, the second covers file-type support, and the third explains the upload mechanism and reply behavior. The key purpose is front-loaded, and every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 9-parameter file-send operation with no output schema, the description covers the core behavior, supported file types, the SharePoint attachment mechanism, and reply semanticsβenough for an agent to select and invoke it. It omits caveats like file size limits or permission requirements, but those are not essential for correct invocation given the detailed schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so every parameter is already documented with descriptions, types, and constraints. The natural-language description adds little beyond reiterating messageId's reply behavior, which is already present in the schema. This meets the baseline for high schema coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Upload a local file and send it as a message to a Teams channel.' It immediately differentiates from send_file_to_chat and send_channel_message by naming the channel context and adds helpful scoping about the SharePoint upload and optional reply behavior.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage context: use it for attaching files to a channel, optionally in reply to a message. However, it never explicitly names alternatives like send_channel_message for text-only posts or send_file_to_chat for chats, so the agent must infer when this tool is preferred over siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
send_file_to_chatSend File to ChatA
Upload a local file and send it as a message to a Teams chat. Supports any file type (PDF, DOCX, ZIP, images, etc.). The file is uploaded to OneDrive and sent as a reference attachment.
| Name | Required | Description | Default |
|---|---|---|---|
| chatId | Yes | Chat ID | |
| format | No | Message format (text or markdown) | |
| message | No | Optional message text to accompany the file | |
| fileName | No | Optional custom filename (defaults to the original file name) | |
| filePath | Yes | Absolute path to the local file to upload | |
| tenantId | No | Target tenant ID from list_tenants. Omit only when a default is configured or exactly one tenant is connected. Resource IDs belong to this tenant. | |
| importance | No | Message importance |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already flag non-read-only and non-idempotent behavior, so the bar is lower. The description adds meaningful behavior: the file is uploaded to OneDrive and sent as a reference attachment. This goes beyond the schema and annotations, though it does not cover permissions or failure behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two succinct sentences with no filler. The main action is front-loaded, and the file-type support and OneDrive behavior are presented efficiently.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the schema already documents all 7 parameters and the description covers purpose and mechanism, the definition is largely complete. There is no output schema, but the success outcome is implied by 'sent as a reference attachment'. It could mention response/confirmation but is not critically lacking.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description adds general context about the file upload and reference attachment, but it does not add specific parameter-level detail beyond what the schema already provides for filePath, chatId, or optional fields.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb-resource pairing ('Upload a local file and send it as a message to a Teams chat') and clarifies the action as a reference attachment. It also distinguishes itself from sibling send_file_to_channel by explicitly targeting a chat rather than a channel.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly establishes the context: sending a file to a Teams chat. It also broadens applicability with 'Supports any file type (PDF, DOCX, ZIP, images, etc.)'. It does not explicitly mention when not to use it or point to send_file_to_channel, but the chat-vs-channel distinction is strongly implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_channel_message_reactionSet Channel Message ReactionAIdempotent
Add a reaction to a message in a Teams channel. Supports Unicode emoji characters and named reactions (like, angry, sad, laugh, heart, surprised). Can also react to replies.
| Name | Required | Description | Default |
|---|---|---|---|
| teamId | Yes | Team ID | |
| replyId | No | Reply ID if reacting to a reply (optional) | |
| tenantId | No | Target tenant ID from list_tenants. Omit only when a default is configured or exactly one tenant is connected. Resource IDs belong to this tenant. | |
| channelId | Yes | Channel ID | |
| messageId | Yes | Message ID to react to | |
| reactionType | Yes | Reaction type - Unicode emoji (e.g., "π") or named reaction (e.g., "like", "heart") |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover idempotency, non-destructiveness, and mutating behavior. The description adds useful behavioral context by specifying supported Unicode emoji and named reactions, and by calling out that replies can be reacted to. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with no fluff. The main action is front-loaded, and the additional reaction-type and reply details are placed efficiently.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a mutation tool with six parameters, the description covers the key behavioral aspects: channel targeting, reply support, and acceptable reaction formats. With full schema coverage and annotations, little critical information is missing, though it does not mention return behavior or explicit error cases.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, providing baseline 3. The description adds meaning beyond the schema by giving concrete named reactions and confirming replyId is used for replying, which enriches understanding of reactionType and replyId.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb and resource: 'Add a reaction to a message in a Teams channel.' The mention of 'Teams channel' and 'replies' clearly distinguishes this from sibling tools like set_chat_message_reaction and set_chat_read_state, and the supported reaction types are enumerated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It provides clear context: this tool is for channel messages and can also react to replies. However, it does not explicitly mention when not to use it or name alternatives such as unset_channel_message_reaction for removing reactions or set_chat_message_reaction for chat messages.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_chat_message_reactionSet Chat Message ReactionA
Add a reaction to a message in a chat conversation. Supports Unicode emoji characters and named reactions (like, angry, sad, laugh, heart, surprised).
| Name | Required | Description | Default |
|---|---|---|---|
| chatId | Yes | Chat ID | |
| tenantId | No | Target tenant ID from list_tenants. Omit only when a default is configured or exactly one tenant is connected. Resource IDs belong to this tenant. | |
| messageId | Yes | Message ID to react to | |
| reactionType | Yes | Reaction type - Unicode emoji (e.g., "π") or named reaction (e.g., "like", "heart") |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate this is a mutating (readOnly=false), non-idempotent operation. The description adds that Unicode emoji and named reactions are supported, but does not disclose behavior such as replacing an existing reaction, duplicate reactions, or errors beyond what annotations convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two concise sentences with no filler. The core action is front-loaded, and the reaction-type detail is presented immediately after, making the definition easy to scan.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple tool with complete schema coverage and relevant annotations, the description covers the core action and reaction format. However, it omits usage boundaries (e.g., removal via unset_chat_message_reaction) and any behavior on repeated reactions, leaving some selection context incomplete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already covers all parameters at 100%, so the baseline is 3. The description adds specific value for reactionType by enumerating supported named reactions and explicitly allowing Unicode emoji, which is not present in the schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly identifies the verb ('Add') and resource ('a reaction to a message in a chat conversation'), and the 'chat conversation' scope distinguishes this tool from channel-reaction siblings. It also clarifies the two supported reaction forms.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this tool rather than set_channel_message_reaction or unset_chat_message_reaction. An agent must infer the scope from the tool name and description; there is no explicit when/when-not guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_chat_read_stateSet Chat Read StateAIdempotent
Mark a chat read or unread for the current user.
| Name | Required | Description | Default |
|---|---|---|---|
| chatId | Yes | Chat ID | |
| isRead | Yes | True: read. False: unread. | |
| tenantId | No | Target tenant ID from list_tenants. Omit only when a default is configured or exactly one tenant is connected. Resource IDs belong to this tenant. | |
| lastMessageReadDateTime | No | Unread only: messages after this time become unread. Omit to mark the latest message unread. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, destructiveHint=false, and idempotentHint=true. The description adds only the scope clarification 'for the current user', which is useful but not a deep behavioral disclosure. It does not contradict the annotations and provides minimal extra context beyond them.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence with zero waste. It states the action and scope immediately, making it easy to parse.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple state-setting tool, the description is adequate. The schema covers parameter details, and annotations cover idempotency and destructiveness. The description clarifies the user scope, leaving no critical information missing for invoking the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema fully documents all four parameters. The description does not add any parameter-specific meaning beyond what the schema provides, keeping the baseline at 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'Mark', the resource 'chat', and the state change ('read or unread') for the current user. It is unambiguous and distinguishes itself from all sibling tools, none of which handle read state.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no explicit guidance on when to use this tool versus alternatives, though no direct alternative exists. It implicitly clarifies the scope (current user) but does not explain when to set read vs unread or how the optional parameters affect behavior.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unset_channel_message_reactionUnset Channel Message ReactionAIdempotent
Remove a reaction from a message in a Teams channel. Can also remove reactions from replies.
| Name | Required | Description | Default |
|---|---|---|---|
| teamId | Yes | Team ID | |
| replyId | No | Reply ID if removing reaction from a reply (optional) | |
| tenantId | No | Target tenant ID from list_tenants. Omit only when a default is configured or exactly one tenant is connected. Resource IDs belong to this tenant. | |
| channelId | Yes | Channel ID | |
| messageId | Yes | Message ID to remove reaction from | |
| reactionType | Yes | Reaction type to remove - Unicode emoji (e.g., "π") or named reaction (e.g., "like", "heart") |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish that the tool is a non-read-only, idempotent, non-destructive mutation. The description restates the action and mentions reply support, but that is also visible in the optional replyId parameter, so it adds little behavioral context beyond the structured data. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two short sentences with no filler, front-loading the core action and then adding the reply capability. It is appropriately sized for the tool's simplicity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple mutation tool with full schema coverage and rich annotations, the description is essentially complete: it identifies the operation and the reply variant, and the schema covers the required identifiers and reactionType. The lack of an output schema is not a gap because return values are not needed for invoking this tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema fully explains teamId, channelId, messageId, reactionType, replyId, and tenantId. The description does not add semantic meaning beyond the schema, so the baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb and resource ('Remove a reaction from a message in a Teams channel') and explicitly extends to replies, which clearly distinguishes this tool from set_channel_message_reaction and unset_chat_message_reaction. The action is unambiguous even without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when to use this tool (whenever a reaction needs removing) but does not explicitly name the inverse tool set_channel_message_reaction or the chat variant, nor when to prefer one over the other. There are no stated exclusions or prerequisites, so guidance is adequate but implicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unset_chat_message_reactionUnset Chat Message ReactionAIdempotent
Remove a reaction from a message in a chat conversation.
| Name | Required | Description | Default |
|---|---|---|---|
| chatId | Yes | Chat ID | |
| tenantId | No | Target tenant ID from list_tenants. Omit only when a default is configured or exactly one tenant is connected. Resource IDs belong to this tenant. | |
| messageId | Yes | Message ID to remove reaction from | |
| reactionType | Yes | Reaction type to remove - Unicode emoji (e.g., "π") or named reaction (e.g., "like", "heart") |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnlyHint=false and idempotentHint=true, so the description need not restate mutation or idempotency. It adds no extra behavioral details such as what happens when the reaction is not present or whether the operation is silently idempotent. The description aligns with the annotations and adds minimal context beyond the obvious.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence with zero filler. It states the action and the object clearly without redundant phrasing.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple, low-complexity operation with full schema coverage and idempotency already declared in annotations, the description is sufficient. It identifies the operation and the domain (chat), and the absence of an output schema places no additional burden on the description. Slightly more detail about no-op behavior would push it higher, but it is complete enough for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and each parameter already has a clear description. The tool description itself does not add parameter-level semantics beyond what the schema provides, so the baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description 'Remove a reaction from a message in a chat conversation' uses a specific verb ('remove') and resource ('reaction from a message'), and the phrase 'chat conversation' distinguishes it from related channel-message tools. It is immediately clear what the tool does and how it differs from set_chat_message_reaction and unset_channel_message_reaction.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage: use this when removing a reaction from a chat message. However, it does not explicitly mention when not to use it or point to alternatives like unset_channel_message_reaction for channel contexts. The naming convention provides a hint but no direct guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_channel_messageUpdate Channel MessageBIdempotent
Update (edit) a message in a channel that was previously sent. Only the message sender can update their own messages.
| Name | Required | Description | Default |
|---|---|---|---|
| format | No | Message format (text or markdown) | |
| teamId | Yes | Team ID | |
| message | Yes | New message content | |
| replyId | No | Reply ID if updating a reply to a message (optional) | |
| mentions | No | Array of @mentions to include in the message | |
| tenantId | No | Target tenant ID from list_tenants. Omit only when a default is configured or exactly one tenant is connected. Resource IDs belong to this tenant. | |
| channelId | Yes | Channel ID | |
| messageId | Yes | Message ID to update | |
| importance | No | Message importance |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations indicate readOnlyHint=false (mutation), destructiveHint=false (not destructive), and idempotentHint=true (idempotent). The description mentions the sender restriction, which is a behavioral constraint not covered by annotations. However, it does not disclose other effects like whether formatting or mentions are replaced entirely, or if there are rate limits. Given that idempotentHint is true, the description could be more transparent about the idempotent behavior, but it adds some value beyond annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise, one sentence that clearly states the action and includes the sender restriction. It is appropriately front-loaded with the action and resource. The sentence has no fluff, though it could be slightly expanded to mention alternatives, but it is efficient and easy to parse.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has 9 parameters and no output schema, the description is somewhat minimal. It covers the essential who (sender) and what (update message), but does not explain return values, error conditions, or how the 'message' parameter interacts with other fields like 'format' or 'mentions'. For a mutation tool with moderate complexity, a bit more context would help, such as noting that the entire message content is replaced or that ID fields are required.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all 9 parameters are documented in the schema. The description itself does not add extra details about the parameters, but it does mention 'message' as the new content. With full schema coverage, the baseline is 3, and the description does not need to repeat parameter definitions. No additional semantics are provided beyond what the schema already offers.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool updates (edits) a previously sent message in a channel, specifying the resource and action. It distinguishes from sibling tools like send_channel_message and delete_channel_message, but does not explicitly name alternatives. The phrase 'Update (edit) a message in a channel that was previously sent' is specific enough, though it could be more explicit about the distinction from updating chat messages.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides the key context that only the sender can update their own messages, which is a critical usage constraint. However, it does not explicitly state when to use this tool versus alternatives such as reply_to_channel_message or update_chat_message. The sibling list includes similar tools for chat messages, so clearer routing would be beneficial, but the sender restriction is a concrete guideline.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_chat_messageUpdate Chat MessageAIdempotent
Update (edit) a chat message that was previously sent. Only the message sender can update their own messages. Supports updating content with text or Markdown formatting, mentions, and importance levels.
| Name | Required | Description | Default |
|---|---|---|---|
| chatId | Yes | Chat ID | |
| format | No | Message format (text or markdown) | |
| message | Yes | New message content | |
| mentions | No | Array of @mentions to include in the message | |
| tenantId | No | Target tenant ID from list_tenants. Omit only when a default is configured or exactly one tenant is connected. Resource IDs belong to this tenant. | |
| messageId | Yes | Message ID to update | |
| importance | No | Message importance |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations, the description adds a meaningful behavioral/permission constraint: only the sender can update. It also clarifies supported content types and fields)Skip the destructive/read-only profile is already covered by annotations, so the added sender restriction is valuable context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with no filler. The action and scope are front-loaded, and the capability list is compact and informative without repeating schema content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description leaves out important invocation details such as whether omitted optional fields preserve existing values or reset to defaults, and there is no output schema to clarify the return value. The sender restriction and supported fields are useful, but for a mutation tool with optional parameters, some update semantics are missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all parameters. The description repeats that format, mentions, and importance are supported, but adds no new semantic details such as default behavior or partial-vs-full update semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action (update/edit) and the resource (chat message), and adds that it applies to previously sent messages. It distinguishes from channel-message tools through the word 'chat', though it doesn't explicitly name the sibling alternative.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives a clear, important usage condition: only the message sender can update their own messages. It implies this tool is for editing existing sent chat messages, but it doesn't explicitly mention alternatives like update_channel_message or send_chat_message.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
33 tool updates
v1.0.1- First observed
auth_status - First observed
create_chat - First observed
delete_channel_message - First observed
delete_chat_message - First observed
download_chat_hosted_content - First observed
download_message_hosted_content - First observed
get_channel_message_replies - First observed
get_channel_messages - First observed
get_chat_messages - First observed
get_current_user - First observed
get_my_mentions - First observed
get_user - First observed
list_channels - First observed
list_chat_members - First observed
list_chats - First observed
list_team_members - First observed
list_teams - First observed
list_tenants - First observed
reply_to_channel_message - First observed
search_messages - First observed
search_users - First observed
search_users_for_mentions - First observed
send_channel_message - First observed
send_chat_message - First observed
send_file_to_channel - First observed
send_file_to_chat - First observed
set_channel_message_reaction - First observed
set_chat_message_reaction - First observed
set_chat_read_state - First observed
unset_channel_message_reaction - First observed
unset_chat_message_reaction - First observed
update_channel_message - First observed
update_chat_message
TDQS
Scored across 33 tools
The channel/chat message tools are neatly paired and contextually distinct, and reactions/read-state/search tools have clear targets. Minor overlap exists between search_users and search_users_for_mentions, and get_channel_messages can also read a reply by ID, which may cause occasional misselection.
Almost all tools follow a clear snake_case verb_noun pattern (list_teams, send_chat_message, set_chat_read_state). auth_status is the main outlier because it is a noun phrase rather than a verb-prefixed command.
33 tools exceeds the 25+ threshold for a heavy surface. The parity between channel and chat operations inflates the count, though each tool does represent a distinct operation in a broad domain.
The set covers the messaging lifecycle well: create/list/send/update/delete/reply/reactions/files/search for both channels and chats. Gaps like team/channel management and chat-level editing are present but secondary to the apparent messaging-focused purpose.
Maintenance
Related MCP Connectors
MCP server unifying ERPs, CRMs, APIs and knowledge base for Claude, ChatGPT and Gemini.
- ZapierOAuthcom.zapier
Hosted MCP server connecting AI assistants to 9,000+ apps and 40,000+ actions via Zapier.
MCP server connecting AI agents to 100+ apps (Gmail, Slack, Notion, GitHub) via one-click OAuth.
MCP server for building and testing AI agents with multi-model experimentation and insights.
Related MCP Servers
- AlicenseAqualityDmaintenanceA Model Context Protocol server that provides AI assistants with access to Microsoft Teams, enabling interaction with teams, channels, chats, and organizational data through Microsoft Graph APIs.19604 npm138MIT
- FlicenseCqualityFmaintenanceA powerful MCP server that enables AI assistants to interact with Microsoft Graph API for managing Outlook emails, Calendar events, OneDrive files, and Contacts through natural language commands.3556-
- AlicenseCqualityNot gradedmaintenanceAn MCP server that enables interaction with Microsoft 365 services like Outlook, OneDrive, Teams, and SharePoint via the Microsoft Graph API. It supports comprehensive operations including email management, file access, and organizational collaboration for personal and work accounts.78-
- AlicenseNot gradedqualityDmaintenanceA secure remote MCP server that integrates Microsoft 365 services with AI assistants, enabling email, calendar, Teams, and contact operations via the Microsoft Graph API.2MIT