mcp-server-mattermost
MCP server that lets AI assistants read, search, post, and manage content in a Mattermost workspace via 38 tools.
Channels: list, create, join, leave, get details, get by name, mark viewed, manage members, create DMs
Messages: post, read recent/unread/since-timestamp, search, edit, delete, with rich attachments
Reactions & Threads: add/remove/list emoji reactions, pin/unpin messages, fetch full thread history
Users: get current user, get/search users by ID or username, check online status
Teams: list teams, get team details and members
Files: upload files, fetch metadata and public download links
Bookmarks (Entry+ edition): list, create, update, delete, and reorder channel bookmarks
Provides tools to read, search, and post messages in Mattermost, manage channels, reactions, threads, files, users, teams, and bookmarks.
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., "@mcp-server-mattermostSearch for messages about the outage last week"
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.
mcp-server-mattermost
Let AI assistants read, search, and post in your Mattermost workspace
39 tools · Channels · Messages · Reactions · Threads · Files · Users
Features
Channels — list, create, join, manage channels and DMs Messages — send, search, edit, delete with rich attachments Reactions & Threads — emoji reactions, pins, full thread history Users & Teams — lookup, search, status Files — upload, metadata, download links Bookmarks — save links and files in channels (Entry+ edition)
Related MCP server: Slack MCP Server
Example Queries
Once configured, you can ask your AI assistant:
"List all channels and find where the deployment discussion is happening"
"What did I miss in #engineering since yesterday morning?"
"Show me my unread channels and summarize the threads I was mentioned in"
"Send a build status alert to #engineering with a red attachment"
"Search for messages about the outage last week and summarize"
"Summarize this thread and post the key decisions"
"Find who worked on the authentication bug last week"
"Upload the report.pdf to #general and share the link"
Available Tools
Tool | Description | Key Parameters |
| List public channels in a team |
|
| List your channels with unread counts |
|
| Get channel details by ID |
|
| Get channel by name |
|
| Create a new channel |
|
| Join a public channel |
|
| Leave a channel |
|
| Mark a channel as viewed (reset unread counters) |
|
| List channel members |
|
| Add user to channel |
|
| Create DM channel |
|
Tool | Description | Key Parameters |
| Send a message to a channel |
|
| Get messages: recent, unread window, or |
|
| Search messages by term |
|
| Edit a message |
|
| Delete a message |
|
Tool | Description | Key Parameters |
| Add emoji reaction |
|
| Remove emoji reaction |
|
| Get all reactions on a post |
|
| Pin a message |
|
| Unpin a message |
|
| Get thread messages |
|
Tool | Description | Key Parameters |
| Get current user info | — |
| Get user by ID |
|
| Get user by username |
|
| Search users |
|
| Get online status |
|
Tool | Description | Key Parameters |
| List your teams | — |
| Get team details |
|
| List team members |
|
Tool | Description | Key Parameters |
| Upload a file |
|
| Get file metadata |
|
| Get download link |
|
| Save a file attachment locally |
|
Note: Requires Entry, Professional, Enterprise, or Enterprise Advanced edition (not available in Team Edition). Minimum version: v10.1.
Tool | Description | Key Parameters |
| List channel bookmarks |
|
| Create link or file bookmark |
|
| Update bookmark properties |
|
| Delete a bookmark |
|
| Reorder bookmark |
|
Quick Start
Get a Mattermost bot token
Add to your MCP client config:
{
"mcpServers": {
"mattermost": {
"command": "uvx",
"args": ["mcp-server-mattermost"],
"env": {
"MATTERMOST_URL": "https://your-server.com",
"MATTERMOST_TOKEN": "your-token"
}
}
}
}Restart your client
Full setup guide — Claude Desktop, Cursor, Claude Code, Opencode, Docker, pip
Configuration
Variable | Required | Default | Description |
| Yes | — | Mattermost server URL |
| No |
| Auth mode: |
| Conditional | — | Bot or personal token. Required for |
| No | 30 | Request timeout in seconds |
| No | 3 | Max retry attempts |
| No | true | Verify SSL certificates |
| No | 100 | Max HTTP connections in the shared pool |
| No | 20 | Max idle keepalive connections, clamped to max connections |
| No | 30.0 | Idle keepalive connection lifetime in seconds |
| No | — | Path to extra PEM CAs appended to the default trust store |
| No | INFO | Logging level |
| No | json | Log output format: |
| No | v4 | Mattermost API version |
For client_token and oauth_proxy modes — including Mattermost OAuth App
registration, all MATTERMOST_OAUTH_* settings, and MCP client connection — see
Authentication.
Docker
Stdio mode (default)
docker run -i --rm \
-e MATTERMOST_URL=https://your-mattermost.com \
-e MATTERMOST_TOKEN=your-token \
legard/mcp-server-mattermost{
"mcpServers": {
"mattermost": {
"command": "docker",
"args": [
"run", "-i", "--rm",
"-e", "MATTERMOST_URL=https://your-mattermost.com",
"-e", "MATTERMOST_TOKEN=your-token",
"legard/mcp-server-mattermost"
]
}
}
}HTTP mode (production)
For networked HTTP use per-client auth. static_token over HTTP serves an unauthenticated endpoint acting
with the shared token (the server starts but logs a loud warning) — see
Authentication → HTTP transport.
docker run -d -p 8000:8000 \
-e MCP_TRANSPORT=http \
-e MCP_HOST=0.0.0.0 \
-e MATTERMOST_AUTH_MODE=client_token \
-e MATTERMOST_URL=https://your-mattermost.com \
-e MATTERMOST_HTTP_HOST_ORIGIN_PROTECTION=auto \
-e MATTERMOST_HTTP_ALLOWED_HOSTS=mcp.example.com \
legard/mcp-server-mattermostclient_token means each MCP client authenticates with its own Mattermost token, sent as
Authorization: Bearer <token> — a client configured without one gets 401. The two
MATTERMOST_HTTP_* variables turn on Host/Origin (DNS-rebinding) protection, which is off by
default; see HTTP transport security.
Health check: curl http://localhost:8000/health
HTTP mode with Mattermost OAuth proxy
Register a Mattermost OAuth 2.0 Application first:
Mattermost field | Production value |
Is Trusted | Yes |
Is Public Client | No |
Callback URLs |
|
Then run the MCP server:
docker run -d -p 8000:8000 \
-e MCP_TRANSPORT=http \
-e MCP_HOST=0.0.0.0 \
-e MATTERMOST_AUTH_MODE=oauth_proxy \
-e MATTERMOST_URL=https://mattermost.internal \
-e MATTERMOST_OAUTH_MATTERMOST_PUBLIC_URL=https://mattermost.example.com \
-e MATTERMOST_OAUTH_MCP_PUBLIC_URL=https://mcp.example.com \
-e MATTERMOST_OAUTH_CLIENT_ID=your-mattermost-oauth-app-id \
-e MATTERMOST_OAUTH_CLIENT_TYPE=confidential \
-e MATTERMOST_OAUTH_CLIENT_SECRET=your-mattermost-oauth-app-secret \
legard/mcp-server-mattermostIf your Mattermost login uses Keycloak SSO, users authenticate through Keycloak inside the Mattermost OAuth login flow. The MCP server does not need a Keycloak client.
Connect Claude Code with Dynamic Client Registration:
claude mcp add --transport http mattermost https://mcp.example.com/mcpDo not pass --client-id for this server; the MCP client registers with the MCP server,
and the MCP server uses the fixed Mattermost OAuth App upstream.
Environment Variables (Docker)
Variable | Default | Description |
|
| Transport: |
|
| HTTP bind host (use |
|
| HTTP port |
Documentation
📖 mcp-server-mattermost.readthedocs.io
Quick Start — Installation and setup
Configuration — Environment variables
Tools Reference — Detailed API documentation
llms.txt — AI-readable documentation index
Development
# Clone and install
git clone https://github.com/cloud-ru-tech/mcp-server-mattermost
cd mcp-server-mattermost
uv sync --dev
# Run unit tests
uv run pytest
# Run integration tests (requires Docker or external Mattermost)
uv run pytest tests/integration -v
# Type checking
uv run mypy src/
# Linting
uv run ruff check src/ tests/
# Run locally
MATTERMOST_URL=https://... MATTERMOST_TOKEN=... uv run mcp-server-mattermostIntegration Tests
Integration tests run against a real Mattermost server via Docker (Testcontainers) or external server.
# With Docker (Testcontainers) — automatic setup
uv run pytest tests/integration -v
# Against external Mattermost server
export MATTERMOST_URL=https://your-server.com
export MATTERMOST_TOKEN=your-bot-token
uv run pytest tests/integration -v
# Run specific test module
uv run pytest tests/integration/test_channels.py -vIntegration tests are excluded from the default pytest run. Unit tests run with:
uv run pytest # Unit tests onlyDebugging
Use the MCP Inspector to debug:
npx @modelcontextprotocol/inspector uvx mcp-server-mattermostContributing
Contributions welcome! See CONTRIBUTING.md for guidelines.
License
MIT — see LICENSE for details.
Built with FastMCP · Mattermost API v4
Available Tools
39 toolsadd_reactionAIdempotent
Add an emoji reaction to a message.
Adds a reaction from the authenticated user. Common emojis: thumbsup, thumbsdown, smile, heart, eyes. Adding the same reaction twice has no additional effect.
| Name | Required | Description | Default |
|---|---|---|---|
| post_id | Yes | 26-character post/message identifier (e.g., 'o5w8h47pdfbzjc4d8w7dhnhren') | |
| emoji_name | Yes | Emoji name without colons (e.g., 'thumbsup', 'smile') |
Output Schema
| Name | Required | Description |
|---|---|---|
| post_id | Yes | Post that was reacted to |
| user_id | Yes | User who reacted |
| create_at | Yes | Reaction timestamp |
| emoji_name | Yes | Emoji name without colons |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations indicate idempotent and non-destructive behavior. Description adds detail that adding the same reaction twice has no effect, reinforcing idempotency. Also notes the action is by the authenticated user, which is useful 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?
Three concise sentences, front-loaded with the primary action. No unnecessary words, every sentence adds value.
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 presence of an output schema and annotations, the description covers key behavioral aspects like idempotency and common usage. Could briefly mention the response, but output schema likely handles that.
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?
Input schema provides 100% coverage with clear descriptions for both parameters. Description adds a list of common emojis and format notes, but this is supplementary and not essential. Baseline 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?
Clearly states the verb 'Add' and resource 'emoji reaction to a message', specifying it's from the authenticated user. Differentiates from sibling tools like 'remove_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?
Implicitly identifies when to use (to add a reaction), and by listing common emojis provides practical guidance. Does not explicitly state when not to use or mention alternatives, but it's clear enough.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
add_user_to_channelAIdempotent
Add a user to a channel.
Requires permission to manage channel members. Adding a user who is already in the channel has no additional effect.
| Name | Required | Description | Default |
|---|---|---|---|
| user_id | Yes | 26-character user identifier (e.g., 'o5w8h47pdfbzjc4d8w7dhnhren') | |
| channel_id | Yes | 26-character channel identifier (e.g., 'o5w8h47pdfbzjc4d8w7dhnhren') |
Output Schema
| Name | Required | Description |
|---|---|---|
| roles | Yes | Space-separated role names |
| user_id | Yes | User identifier |
| msg_count | Yes | Messages seen count, including replies in threads |
| channel_id | Yes | Channel identifier |
| mention_count | Yes | Unread @-mentions count, including thread replies |
| last_update_at | Yes | Last update timestamp |
| last_viewed_at | Yes | Last viewed timestamp |
| msg_count_root | Yes | Root messages seen count, excluding thread replies |
| mention_count_root | Yes | Unread root @-mentions count, excluding thread replies |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations indicate idempotency and non-destructiveness. The description adds behavioral detail: 'Adding a user who is already in the channel has no additional effect,' reinforcing idempotency without contradicting 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 with two short sentences, each adding essential information without redundancy. It is well-structured and front-loaded.
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 presence of an output schema and clear annotations, the description adequately covers purpose, permissions, and behavioral effects. No additional context is needed.
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% with clear descriptions for both parameters. The description does not add additional meaning beyond what the schema already provides, so a 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 clearly states the action ('Add a user to a channel') with a specific verb and resource. It distinguishes from sibling tools like 'join_channel' (self-join) and 'leave_channel', providing clear purpose.
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 mentions a prerequisite ('Requires permission to manage channel members'), guiding the agent on when this tool is appropriate. It doesn't explicitly state when not to use it, but the condition is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_bookmarkA
Create a channel bookmark.
Creates a link bookmark (URL) or file bookmark (attached file). For link type, link_url is required. For file type, file_id is required (from upload_file).
Note: Requires Entry, Professional, Enterprise, or Enterprise Advanced edition (not available in Team Edition). Minimum version: v10.1.
| Name | Required | Description | Default |
|---|---|---|---|
| emoji | No | Emoji icon | |
| file_id | No | File ID (required for file type) | |
| link_url | No | URL (required for link type) | |
| image_url | No | Preview image URL | |
| channel_id | Yes | 26-character channel identifier (e.g., 'o5w8h47pdfbzjc4d8w7dhnhren') | |
| display_name | Yes | Bookmark display name | |
| bookmark_type | Yes | Bookmark type: 'link' or 'file' |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | Yes | Unique bookmark identifier |
| file | No | File metadata for file bookmarks |
| type | Yes | Bookmark type: 'link' or 'file' |
| emoji | No | Emoji icon |
| file_id | Yes | File ID for file bookmarks (empty for links) |
| link_url | No | URL for link bookmarks |
| owner_id | Yes | User ID who created the bookmark |
| create_at | Yes | Creation timestamp in milliseconds |
| delete_at | Yes | Deletion timestamp (0 if not deleted) |
| image_url | No | Preview image URL |
| parent_id | No | Parent bookmark ID |
| update_at | Yes | Last update timestamp in milliseconds |
| channel_id | Yes | Channel this bookmark belongs to |
| sort_order | Yes | Position in bookmark list |
| original_id | No | Original bookmark ID if copied |
| display_name | Yes | Bookmark display name |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description reveals the action's preconditions (edition, version, required fields) but doesn't state side effects, return values, or permission requirements. Since no readOnly annotation is present崗, the description carries the burden for mutation transparency and only partially covers it.
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?
Concise, front-loaded with the core purpose, then conditional rules, then constraints. 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?
Covers the essential invocation conditions and edition/version constraints. Lacks explicit output/return details and permission requirements, but the schema and existing sibling context cover basic usage.
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?
Input schema already documents all parameters (100% coverage). The description adds conditional-requirement meaning by linking bookmark_type to link_url and file_id, and references upload_file as the source for file_id, which goes beyond 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?
The description clearly identifies the action ('Create a channel bookmark') and the resource (bookmark), and distinguishes two subtypes (link vs file). It doesn't explicitly contrast with sibling list/update/delete tools, but the purpose is 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?
Provides clear conditional usage: link type requires link_url, file type requires file_id from upload_file. Also specifies edition and version constraints, which serve as prerequisites. Doesn't state alternatives or when not to use this tool, but the conditions are actionable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_channelA
Create a new channel in a team.
Creates either a public (O) or private (P) channel. The authenticated user becomes the channel admin. Each call creates a new channel; use get_channel_by_name to check if it exists.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Channel name (lowercase, no spaces) | |
| header | No | Channel header | |
| purpose | No | Channel purpose | |
| team_id | Yes | 26-character team identifier (e.g., 'o5w8h47pdfbzjc4d8w7dhnhren') | |
| channel_type | No | Channel type: O=public, P=private, D=direct message, G=group message | O |
| display_name | Yes | Human-readable channel name |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | Yes | Unique channel identifier |
| name | Yes | URL-friendly channel name |
| type | Yes | Channel type: O=public, P=private, D=direct, G=group |
| header | Yes | Channel header text |
| purpose | Yes | Channel purpose description |
| team_id | Yes | Team this channel belongs to |
| create_at | Yes | Creation timestamp in milliseconds |
| delete_at | Yes | Deletion timestamp (0 if not deleted) |
| update_at | Yes | Last update timestamp in milliseconds |
| creator_id | Yes | User ID who created the channel |
| display_name | Yes | Human-readable channel name |
| last_post_at | Yes | Timestamp of last post |
| total_msg_count | Yes | Total message count |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds behavioral context beyond the annotations: the authenticated user becomes admin, and each call creates a new channel (non-idempotent). It correctly notes O and P types, though the schema includes D and G. No contradiction with destructiveHint=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?
Three concise sentences, each adding value: purpose, channel types, admin and idempotency guidance. 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?
Given the tool's complexity (6 params, schema coverage 100%, output schema exists), the description covers key behaviors and provides a useful check-idempotency tip. Slightly incomplete by not mentioning output structure, but output schema handles that.
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 baseline is 3. The description adds contextual insight (admin, idempotency) but does not elaborate on specific parameters beyond the schema's 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?
The description clearly states the verb 'Create' and the resource 'a new channel in a team'. It distinguishes from siblings by specifying channel types (public/private) and notes the user becomes admin, which differentiates from other channel creation tools like create_direct_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 advises using get_channel_by_name to check existence, which guides against duplicates. However, it does not mention when not to use this tool (e.g., for direct channels) or prerequisites like team membership, leaving some gaps.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_direct_channelAIdempotent
Create a direct message channel between two users.
Returns an existing DM channel if one already exists between the users. Use this to get a channel ID for sending private messages. Then use post_message with the returned channel_id to send messages.
| Name | Required | Description | Default |
|---|---|---|---|
| user_id_1 | Yes | 26-character user identifier (e.g., 'o5w8h47pdfbzjc4d8w7dhnhren') | |
| user_id_2 | Yes | 26-character user identifier (e.g., 'o5w8h47pdfbzjc4d8w7dhnhren') |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | Yes | Unique channel identifier |
| name | Yes | URL-friendly channel name |
| type | Yes | Channel type: O=public, P=private, D=direct, G=group |
| header | Yes | Channel header text |
| purpose | Yes | Channel purpose description |
| team_id | Yes | Team this channel belongs to |
| create_at | Yes | Creation timestamp in milliseconds |
| delete_at | Yes | Deletion timestamp (0 if not deleted) |
| update_at | Yes | Last update timestamp in milliseconds |
| creator_id | Yes | User ID who created the channel |
| display_name | Yes | Human-readable channel name |
| last_post_at | Yes | Timestamp of last post |
| total_msg_count | Yes | Total message count |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description aligns with the idempotentHint annotation by stating 'Returns an existing DM channel if one already exists.' It adds behavioral context beyond annotations, clarifying the tool is non-destructive and suitable for private messaging.
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 concise sentences front-loaded with the primary purpose, followed by key behaviors and usage guidance. No redundant 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?
Given the simple input schema (2 params), annotations (idempotent, non-destructive), and output schema presence, the description fully covers the tool's purpose, idempotency, and next-step guidance (use post_message).
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 provides 100% coverage with clear descriptions for both user IDs, including examples. The tool description adds no additional parameter semantics beyond what the schema provides, so 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 clearly states the tool creates a direct message channel between two users and distinguishes itself from siblings like 'create_channel' by specifying the DM nature and the idempotent behavior of returning an existing 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 tells when to use it (to get a channel ID for private messages) and implicitly guides not to use it when a channel already exists by mentioning the return of existing DMs. It could explicitly contrast with sibling tools but is still effective.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
delete_bookmarkA
Delete a channel bookmark.
Archives the bookmark (soft delete via delete_at timestamp). The bookmark will no longer appear in the channel.
Note: Requires Entry, Professional, Enterprise, or Enterprise Advanced edition (not available in Team Edition). Minimum version: v10.1.
| Name | Required | Description | Default |
|---|---|---|---|
| channel_id | Yes | 26-character channel identifier (e.g., 'o5w8h47pdfbzjc4d8w7dhnhren') | |
| bookmark_id | Yes | 26-character bookmark identifier (e.g., 'o5w8h47pdfbzjc4d8w7dhnhren') |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | Yes | Unique bookmark identifier |
| file | No | File metadata for file bookmarks |
| type | Yes | Bookmark type: 'link' or 'file' |
| emoji | No | Emoji icon |
| file_id | Yes | File ID for file bookmarks (empty for links) |
| link_url | No | URL for link bookmarks |
| owner_id | Yes | User ID who created the bookmark |
| create_at | Yes | Creation timestamp in milliseconds |
| delete_at | Yes | Deletion timestamp (0 if not deleted) |
| image_url | No | Preview image URL |
| parent_id | No | Parent bookmark ID |
| update_at | Yes | Last update timestamp in milliseconds |
| channel_id | Yes | Channel this bookmark belongs to |
| sort_order | Yes | Position in bookmark list |
| original_id | No | Original bookmark ID if copied |
| display_name | Yes | Bookmark display name |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral disclosure. It explicitly reveals that the delete is a soft delete via delete_at timestamp and that the bookmark will no longer appear in the channel, giving the agent key side effects. It could also mention permissions or restoration but is strong for the 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?
Three sentences with the core action first, followed by a concise behavioral explanation and a note on edition and version constraints. No wasted words; the structure is ideal for quick scanning.
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 with fully specified parameters and an output schema present. The description explains the soft-delete behavior and required edition/version, covering the essential context. It doesn't mention edge cases like idempotency or permissions, but these are minor given the straightforward scope.
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 provides full descriptions with examples for both channel_id and bookmark_id, so the description adds no additional parameter semantics. The 100% schema coverage means 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 opens with 'Delete a channel bookmark', a clear verb+resource statement that distinguishes it from create, update, and list siblings. It further explains that the delete is an archival soft delete, which unambiguously defines the tool's function.
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 explicitly state when to prefer this over sibling tools or when not to use it, though the name and behavior make the usage intuitive. It provides edition and version constraints but no alternative routing or exclusion conditions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
delete_messageA
Delete a message permanently.
Can only delete your own messages (unless admin). Deleted messages cannot be recovered. All reactions and thread context will be lost.
| Name | Required | Description | Default |
|---|---|---|---|
| post_id | Yes | 26-character post/message identifier (e.g., 'o5w8h47pdfbzjc4d8w7dhnhren') |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Fully describes permanent deletion, permission restrictions, and side effects (loss of reactions and thread context). No annotations, so description carries full burden and does so thoroughly.
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 concise sentences with front-loaded action verb. No wasted words; each sentence adds essential 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 delete operation with one parameter, the description covers permissions, permanence, and side effects. No output schema needed, and no gaps remain.
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 the description does not add further meaning to the post_id parameter beyond what the schema already provides. Baseline 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?
Clearly states 'Delete a message permanently' as the core action, with specific verb and resource. Distinguishes from siblings like update_message or pin_message.
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?
Specifies that only own messages can be deleted unless admin, providing clear context. Mentions irreversibility and loss of reactions/thread context, guiding when not to use. No explicit alternative comparison.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
download_fileA
Download a file attachment and save it to a local directory.
Counterpart of upload_file: fetches the content of a file by its ID (from a post's file_ids or get_file_info) and writes it to disk. Returns the local path so the file can be read or processed further. Use on_conflict="rename" to save all same-named attachments without replacing any. Always use the returned path; parallel calls may assign numbers in any order. Each repeated call in rename mode saves another copy. overwrite=True cannot be combined with on_conflict="error" or "rename". Files larger than 100 MB are refused.
| Name | Required | Description | Default |
|---|---|---|---|
| file_id | Yes | 26-character file identifier (e.g., 'o5w8h47pdfbzjc4d8w7dhnhren') | |
| filename | No | Override the saved file name | |
| overwrite | No | Replace an existing file with the same name | |
| on_conflict | No | Name conflict policy; null uses overwrite. rename keeps all files with numbered names | |
| destination_dir | Yes | Local directory to save the file into (created if missing); a leading '~' is expanded |
Output Schema
| Name | Required | Description |
|---|---|---|
| name | Yes | Saved file name |
| path | Yes | Absolute local path the file was saved to |
| size | Yes | Saved size in bytes |
| file_id | Yes | Downloaded file identifier |
| mime_type | No | MIME type reported by Mattermost |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden and does so well: it discloses filesystem writes, returns the local path, warns that parallel calls may assign numbers in any order, explains repeated rename-mode copies, states the overwrite/on_conflict incompatibility, and notes the 100 MB size cap.
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 purpose is front-loaded, and every subsequent sentence adds operational detail—file source, return value, conflict behavior, concurrency caveat, and size limit. There is no filler or repetition that wastes an agent's attention.
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 how to obtain the file ID, where to save, conflict resolution, parallel-call behavior, and the size restriction. Since an output schema exists, return-value details are already covered structurally, so nothing critical is missing 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 coverage is already 100%, and the description adds valuable interaction semantics beyond the schema: on_conflict='rename' preserves all same-named attachments, repeated calls in rename mode save another copy, and overwrite=True cannot be combined with on_conflict='error' or 'rename'. This materially helps an agent choose correct parameter values.
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: 'Download a file attachment and save it to a local directory.' It also distinguishes itself from upload_file by explicitly calling itself the counterpart and explaining that it fetches content by file ID from a post's file_ids or get_file_info.
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 makes the usage context clear: use this tool to fetch file content by ID and write it to disk, and it positions itself as the counterpart of upload_file. It does not explicitly name alternatives like get_file_link or state when not to use this tool, 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.
get_channelARead-onlyIdempotent
Get detailed information about a specific channel.
Returns channel metadata including name, purpose, header, and member count. Use when you have the channel ID. For lookup by channel name, use get_channel_by_name instead.
| Name | Required | Description | Default |
|---|---|---|---|
| channel_id | Yes | 26-character channel identifier (e.g., 'o5w8h47pdfbzjc4d8w7dhnhren') |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | Yes | Unique channel identifier |
| name | Yes | URL-friendly channel name |
| type | Yes | Channel type: O=public, P=private, D=direct, G=group |
| header | Yes | Channel header text |
| purpose | Yes | Channel purpose description |
| team_id | Yes | Team this channel belongs to |
| create_at | Yes | Creation timestamp in milliseconds |
| delete_at | Yes | Deletion timestamp (0 if not deleted) |
| update_at | Yes | Last update timestamp in milliseconds |
| creator_id | Yes | User ID who created the channel |
| display_name | Yes | Human-readable channel name |
| last_post_at | Yes | Timestamp of last post |
| total_msg_count | Yes | Total message count |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare idempotent and read-only; description adds value by specifying returned fields (name, purpose, header, member count) without contradicting 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?
Three sentences, front-loaded with purpose, then return info, then usage guidance. No redundant or tangential 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?
With output schema present, description adequately covers need; hints at returned fields and is sufficient for a simple lookup tool.
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% with clear parameter description; description reinforces purpose but adds minimal new information beyond 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?
Description uses specific verb+resource ('Get detailed information about a specific channel') and explicitly distinguishes from sibling tool 'get_channel_by_name', making 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?
Provides explicit usage condition ('Use when you have the channel ID') and directs to alternative for name lookup, giving clear decision guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_channel_by_nameARead-onlyIdempotent
Get a channel by its name within a team.
Returns channel metadata including name, purpose, header, and member count. Use when you know the channel name but not the ID. For lookup by ID, use get_channel instead.
| Name | Required | Description | Default |
|---|---|---|---|
| team_id | Yes | 26-character team identifier (e.g., 'o5w8h47pdfbzjc4d8w7dhnhren') | |
| channel_name | Yes | Channel name (lowercase, no spaces) |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | Yes | Unique channel identifier |
| name | Yes | URL-friendly channel name |
| type | Yes | Channel type: O=public, P=private, D=direct, G=group |
| header | Yes | Channel header text |
| purpose | Yes | Channel purpose description |
| team_id | Yes | Team this channel belongs to |
| create_at | Yes | Creation timestamp in milliseconds |
| delete_at | Yes | Deletion timestamp (0 if not deleted) |
| update_at | Yes | Last update timestamp in milliseconds |
| creator_id | Yes | User ID who created the channel |
| display_name | Yes | Human-readable channel name |
| last_post_at | Yes | Timestamp of last post |
| total_msg_count | Yes | Total message count |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and idempotentHint. Description adds return field context (name, purpose, header, member count) consistent with read-only 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?
Three concise sentences, front-loaded with purpose, no redundancy. 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?
Given simplicity, annotations, and output schema, description provides sufficient context for selection and 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 covers 100% of parameters with descriptions. Description adds value by hinting at return fields, though schema already details 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?
Description clearly states the tool gets a channel by name, returns metadata, and distinguishes from get_channel by ID lookup. Specific verb-resource pair.
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?
Explicitly states when to use (know name, not ID) and when not (use get_channel for ID lookup), providing clear guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_channel_membersARead-onlyIdempotent
Get members of a channel.
Returns list of users who are members of the channel. Use to see who can receive messages in a channel.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page number (0-indexed) | |
| per_page | No | Results per page | |
| channel_id | Yes | 26-character channel identifier (e.g., 'o5w8h47pdfbzjc4d8w7dhnhren') |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and idempotentHint=true, establishing safe read behavior. The description adds that it returns a list of users, which is useful but does not disclose additional traits like pagination behavior or rate limits. The description is adequate but not rich 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?
Three sentences, no filler. The key action and purpose are front-loaded: 'Get members of a channel.' Every sentence adds value without repetition.
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 existence of an output schema (context signal), the description need not detail return values. It explains the primary function and use case. Minor gap: does not mention pagination explicitly, but the schema handles that. Overall, complete for a read operation with well-documented parameters.
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?
All three parameters have descriptions in the input schema (100% coverage), so the schema already explains them. The tool description does not add meaning beyond what the schema provides, earning the baseline score of 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 'Get members of a channel' and explains the resource (members) and action (get). It distinguishes itself from siblings like 'add_user_to_channel' by focusing on reading membership rather than modifying it.
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 a use case: 'Use to see who can receive messages in a channel.' This helps the agent understand when to invoke the tool. However, it does not explicitly exclude scenarios or mention alternatives among siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_channel_messagesARead-onlyIdempotent
Get messages from a channel — recent history, the user's unread window, or posts changed since a watermark.
Three mutually-exclusive modes. Pick by user intent:
"Show last N" / "what's in this channel" → default (page, per_page). Reverse-chronological.
truncated=True⇒ more posts exist; paginate."What did I miss" →
unread_only=True. The user's unread window anchored atlast_viewed_at, withlimit_beforecontext posts. Quirk: on a never-viewed channel (last_viewed_at == 0)orderis empty even whenunread_msg_count > 0— callmark_channel_viewedonce to bootstrap."Sync everything since " →
since=<unix_ms>. Posts withupdate_at > since, including edits of older posts and tombstones (delete_at != 0, emptymessage). Server caps at 1000; ontruncated=Truestep the watermark forward in smaller windows.
Returns {order, posts, truncated}. posts may contain more entries
than order (root posts pulled in by thread replies). System posts
(type starts with "system_") appear in unread_only/since
responses but are NOT counted in unread_msg_count.
For keyword search use search_messages; for full threads use get_thread.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page number (0-indexed) | |
| since | No | Unix timestamp in milliseconds (>= 10^12, i.e. >= 2001-01-01); return posts modified after this time. Mutually exclusive with unread_only and pagination. Use ChannelWithUnreads.last_viewed_at from list_my_channels. | |
| per_page | No | Results per page | |
| channel_id | Yes | 26-character channel identifier (e.g., 'o5w8h47pdfbzjc4d8w7dhnhren') | |
| limit_after | No | In unread_only mode: unread posts to return (1-200) | |
| unread_only | No | Return only the user's unread window via /posts/unread | |
| limit_before | No | In unread_only mode: read context posts before the first unread (max 200) | |
| collapsed_threads | No | Set True only if the user has CRT (Collapsed Reply Threads) enabled. Team default is CRT off — leave False unless you know otherwise. Requires unread_only=True or since=<ms>; the default /posts endpoint rejects CRT-aware queries. |
Output Schema
| Name | Required | Description |
|---|---|---|
| order | Yes | Post IDs in display order |
| posts | Yes | Map of post ID to Post object |
| truncated | No | True when the response hit a Mattermost response cap — more posts exist beyond this batch |
| next_post_id | No | Next post ID for pagination |
| prev_post_id | No | Previous post ID for pagination |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and idempotentHint, but the description goes far beyond them: it discloses the never-viewed-channel quirk, tombstone/edited-post behavior in since mode, server cap of 1000 with truncated=True pagination advice, posts/order mismatch, and system-post exclusion from unread_msg_count. There is 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 long but warranted: it front-loads the one-sentence summary, then uses clear labeled bullets for the three modes and a short return-shape section. Every sentence adds operational value, and the structure makes the complex behavior scannable.
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 mode selection, behavioral quirks, return semantics, pagination strategy, and alternatives. With an output schema present and sibling tools listed, nothing needed to call this tool correctly 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?
Although schema coverage is 100%, the description adds crucial semantics: it explains how page/per_page relate to reverse-chronological pagination, what unread_only anchors to (last_viewed_at, limit_before), how since differs from simple filtering (includes edits and tombstones), and the CRT requirement. This materially improves an agent's ability to choose and set parameters correctly.
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: 'Get messages from a channel.' It then names three distinct modes with explicit triggers, and closes by distinguishing itself from search_messages (keyword search) and get_thread (full threads). This fully disambiguates it from sibling tools.
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 maps user intent to each mode: 'Show last N' → default, 'What did I miss' → unread_only, 'Sync everything since' → since. It also gives when-not-to-use guidance by naming alternatives for keyword search and threads, and notes CRT constraints. This is model usage guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_file_infoARead-onlyIdempotent
Get metadata about an uploaded file.
Returns file name, size, type, and upload information. Use to check file details before downloading or sharing.
| Name | Required | Description | Default |
|---|---|---|---|
| file_id | Yes | 26-character file identifier (e.g., 'o5w8h47pdfbzjc4d8w7dhnhren') |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | Yes | Unique file identifier |
| name | Yes | File name |
| size | Yes | File size in bytes |
| width | No | Image width in pixels |
| height | No | Image height in pixels |
| post_id | No | Associated post ID |
| user_id | Yes | Uploader user identifier (CreatorId in Go) |
| create_at | Yes | Upload timestamp in milliseconds |
| delete_at | Yes | Deletion timestamp |
| extension | Yes | File extension without dot |
| mime_type | Yes | MIME type |
| update_at | Yes | Last update timestamp |
| channel_id | Yes | Channel where file was uploaded |
| has_preview_image | No | Has generated preview |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and idempotentHint, so the description adds minimal behavioral context beyond listing returned fields. No additional traits like auth requirements or performance implications are noted.
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: first states purpose, second summarizes return values and use case. Every word is informative, 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?
With an output schema present, the description doesn't need to detail return structure. It lists key fields, covers the single parameter, and provides usage context. Complete for a simple read-only tool.
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% with a detailed description including format example. The description does not add new parameter semantics beyond what the schema provides, so 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 it gets metadata about an uploaded file and lists specific return fields (name, size, type, upload information). This distinguishes it from siblings like get_file_link and upload_file.
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?
Description provides explicit use case: 'Use to check file details before downloading or sharing.' It implicitly suggests when not to use (e.g., for downloading, use get_file_link), but doesn't state exclusions explicitly.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_file_linkARead-onlyIdempotent
Get a public link to download a file.
Link can be shared with users who don't have Mattermost access. Link may expire based on server settings.
| Name | Required | Description | Default |
|---|---|---|---|
| file_id | Yes | 26-character file identifier (e.g., 'o5w8h47pdfbzjc4d8w7dhnhren') |
Output Schema
| Name | Required | Description |
|---|---|---|
| link | Yes | Public download URL |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnly and idempotent. Description adds disclosure about external sharing and expiration, which is helpful 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?
Three concise sentences, front-loaded with main action. Every sentence adds value 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?
For a simple retrieval tool with one parameter and output schema, the description covers purpose, sharing capability, and expiry caveat. No gaps.
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 covers the single parameter with a detailed description (100% coverage). Description adds no further parameter info, so baseline 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?
Clearly states 'Get a public link to download a file' with specific verb and resource. Distinct from siblings like get_file_info.
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?
Provides context that link can be shared externally and may expire. Does not explicitly list alternatives but generally clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_meARead-onlyIdempotent
Get the current authenticated user's profile.
Returns user information including username, email, and status. Use to get your own user ID for operations like create_direct_channel.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| id | Yes | Unique user identifier |
| Yes | Email address | |
| roles | Yes | Space-separated system roles |
| locale | Yes | User locale preference |
| nickname | Yes | Nickname |
| username | Yes | Unique username |
| create_at | No | Creation timestamp in milliseconds |
| delete_at | Yes | Deletion timestamp (0 if active) |
| last_name | Yes | Last name |
| update_at | No | Last update timestamp in milliseconds |
| first_name | Yes | First name |
| mfa_active | No | Multi-factor auth enabled |
| auth_service | Yes | Authentication service |
| email_verified | No | Email verification status |
| last_picture_update | No | Last avatar update timestamp |
| last_password_update | No | Last password change timestamp |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and idempotentHint=true, so the description adds value by specifying return fields (username, email, status). No contradictions; the description complements 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?
Three concise sentences, front-loaded with the core purpose. Every sentence adds value: purpose, return info, and a usage example. No fluff.
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 tool with rich annotations and explicit return info, the description is fully complete. It covers purpose, usage, and what to expect, leaving no gaps.
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?
Input schema has zero parameters, so baseline 4 applies. The description adds no parameter details (not needed), but it does provide context on what the return data includes, which is useful beyond the empty 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 'Get the current authenticated user's profile' with specific verb and resource. It distinguishes from siblings like get_user and get_user_by_username by focusing on the authenticated user, and explicitly mentions using it to get your own user ID for operations like create_direct_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 provides a clear use case: 'Use to get your own user ID for operations like create_direct_channel.' While it doesn't explicitly state when not to use it or name alternatives, the context implies for current user only, which is sufficient for this simple tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_reactionsARead-onlyIdempotent
Get all reactions on a message.
Returns list of reactions with emoji names and user IDs. Use to see who reacted to a message and with what emoji.
| Name | Required | Description | Default |
|---|---|---|---|
| post_id | Yes | 26-character post/message identifier (e.g., 'o5w8h47pdfbzjc4d8w7dhnhren') |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and idempotentHint; the description adds that it returns a list with emoji names and user IDs, which is useful but not extensive.
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, front-loaded with the action and resource, no wasted words.
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 tool with one required parameter, annotations, and an output schema, the description covers purpose, usage, and return format adequately.
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 description of post_id is thorough (including example), and the tool description adds no extra parameter-specific information, so baseline 3 is appropriate with 100% 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 clearly states 'Get all reactions on a message' with a specific verb and resource, and distinguishes from sibling tools like add_reaction and remove_reaction by indicating it retrieves reactions.
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 says 'Use to see who reacted to a message and with what emoji,' providing clear context for when to invoke the tool, but does not mention exclusions or alternatives like get_channel_messages.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_teamARead-onlyIdempotent
Get team details by ID.
Returns team name, description, and settings. Use when you have the team ID and need detailed information.
| Name | Required | Description | Default |
|---|---|---|---|
| team_id | Yes | 26-character team identifier (e.g., 'o5w8h47pdfbzjc4d8w7dhnhren') |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | Yes | Unique team identifier |
| name | Yes | URL-friendly team name |
| type | Yes | Team type: O=open, I=invite-only |
| Yes | Team contact email | |
| create_at | Yes | Creation timestamp in milliseconds |
| delete_at | Yes | Deletion timestamp (0 if active) |
| invite_id | Yes | Invite link identifier |
| update_at | Yes | Last update timestamp in milliseconds |
| description | Yes | Team description |
| display_name | Yes | Human-readable team name |
| allowed_domains | Yes | Allowed email domains |
| allow_open_invite | Yes | Allow public joining |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint and idempotentHint. Description adds return value details (name, description, settings) but no 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?
Two sentences, no redundancy, efficient and front-loaded.
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?
Covers purpose, usage, and return fields. With output schema present, return is adequate. Missing error handling or prerequisites, but low 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 coverage is 100%, so description adds no extra meaning beyond 'by ID'. 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?
Clearly states 'Get team details by ID' and lists return fields. Distinguishes from siblings like list_teams and get_team_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?
Explicitly says 'Use when you have the team ID and need detailed information.' Implies not to use without ID, but does not explicitly name alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_team_membersARead-onlyIdempotent
Get members of a team.
Returns list of users who belong to the team. Use to discover users before sending direct messages or mentions.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page number (0-indexed) | |
| team_id | Yes | 26-character team identifier (e.g., 'o5w8h47pdfbzjc4d8w7dhnhren') | |
| per_page | No | Results per page |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and idempotentHint, so safety is clear. The description adds that it returns a list of users, but does not disclose pagination behavior (parameters exist) or any potential limitations (e.g., team membership visibility). With annotations present, the bar is lower, but the description misses the nuance of paginated results.
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, each with clear purpose: purpose, output, and use case. No wasted words, and the most critical information is front-loaded.
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 an output schema (so return values need not be detailed), the description sufficiently covers purpose and usage. However, it omits mention of pagination behavior, which is relevant given the cursor parameters. Still, for a simple read operation, 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?
Input schema has 100% description coverage, including details like team_id format and pagination parameters. The description adds no additional parameter semantics beyond what the schema already provides, so baseline score 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?
Clear verb ('get') and resource ('team members'). Description explicitly states it returns a list of users belonging to a team and provides a concrete use case ('discover users before sending direct messages or mentions'), distinguishing it from sibling member-list tools like get_channel_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?
Description includes a use case ('discover users before sending direct messages or mentions'), which guides when to use. However, it does not explicitly mention when not to use or contrast with alternatives, though the context from sibling names provides some implicit differentiation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_threadARead-onlyIdempotent
Get all messages in a thread.
Returns the root post and all replies in chronological order. Use to read full conversation context before replying.
| Name | Required | Description | Default |
|---|---|---|---|
| post_id | Yes | 26-character post/message identifier (e.g., 'o5w8h47pdfbzjc4d8w7dhnhren') |
Output Schema
| Name | Required | Description |
|---|---|---|
| order | Yes | Post IDs in display order |
| posts | Yes | Map of post ID to Post object |
| truncated | No | True when the response hit a Mattermost response cap — more posts exist beyond this batch |
| next_post_id | No | Next post ID for pagination |
| prev_post_id | No | Previous post ID for pagination |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and idempotentHint=true, so the safety profile is covered. Description adds that it returns chronological order and includes the root post, which is useful context beyond annotations. No contradictions, but it does not disclose any limits (e.g., pagination) or error conditions. Given the annotation coverage, a 3 is appropriate as it adds some value but not extensive behavioral detail.
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?
Description is concise with three sentences, zero filler. The core purpose is front-loaded in the first sentence, followed by useful return details, and finally a clear usage note. Every sentence earns its place, and the structure is scannable for an agent.
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 tool with one fully documented parameter, an output schema, and annotations covering safety, the description is complete. It states what it returns (root post and replies in order) and hints at usage. No missing information that would prevent an agent from calling it correctly. The output schema handles return value details, so no 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?
The schema already documents post_id with a clear description including an example. Schema coverage is 100%, so the schema fully explains the parameter. The description does not add any additional meaning about the parameter format or constraints beyond what the schema provides. Baseline 3 is correct as the schema carries 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?
Description clearly states the tool retrieves all messages in a thread, including root post and replies in chronological order. This distinguishes it from sibling tools like get_channel_messages or search_messages, which focus on channels or search results. The verb 'get' plus resource 'thread' is specific and 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?
Description explicitly mentions using this tool to read full conversation context before replying, which provides clear context for when it should be used. It does not explicitly name alternative tools or when not to use it, but the purpose is distinct enough that an agent can infer when to choose it over siblings. Lacks explicit exclusions, but the guidance is adequate for a simple read tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_userARead-onlyIdempotent
Get a user's profile by their ID.
Returns user information including username, email, and status. Use when you have the user ID. For lookup by @username, use get_user_by_username instead.
| Name | Required | Description | Default |
|---|---|---|---|
| user_id | Yes | 26-character user identifier (e.g., 'o5w8h47pdfbzjc4d8w7dhnhren') |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | Yes | Unique user identifier |
| Yes | Email address | |
| roles | Yes | Space-separated system roles |
| locale | Yes | User locale preference |
| nickname | Yes | Nickname |
| username | Yes | Unique username |
| create_at | No | Creation timestamp in milliseconds |
| delete_at | Yes | Deletion timestamp (0 if active) |
| last_name | Yes | Last name |
| update_at | No | Last update timestamp in milliseconds |
| first_name | Yes | First name |
| mfa_active | No | Multi-factor auth enabled |
| auth_service | Yes | Authentication service |
| email_verified | No | Email verification status |
| last_picture_update | No | Last avatar update timestamp |
| last_password_update | No | Last password change timestamp |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint and idempotentHint. The description adds return fields (username, email, status) but no new behavioral traits beyond what annotations indicate. It does not contradict 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?
Three concise sentences front-loaded with main purpose, no filler, each sentence adds essential 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?
Given single parameter, comprehensive annotations, and output schema, the description fully covers what an agent needs: action, input, output, and usage context.
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% with detailed parameter description. The description only mentions 'by their ID' which adds minimal semantic value 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 the specific verb 'Get' and resource 'user's profile' with method 'by their ID'. It clearly distinguishes from sibling 'get_user_by_username' by specifying ID-based lookup vs username.
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?
Explicitly states 'Use when you have the user ID' and provides the alternative 'For lookup by @username, use get_user_by_username instead.' This gives clear context for when to select this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_user_by_usernameARead-onlyIdempotent
Get a user's profile by their username.
Returns user information including username, email, and status. Use when you know the @username but not the user ID. For lookup by ID, use get_user instead.
| Name | Required | Description | Default |
|---|---|---|---|
| username | Yes | Mattermost username |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | Yes | Unique user identifier |
| Yes | Email address | |
| roles | Yes | Space-separated system roles |
| locale | Yes | User locale preference |
| nickname | Yes | Nickname |
| username | Yes | Unique username |
| create_at | No | Creation timestamp in milliseconds |
| delete_at | Yes | Deletion timestamp (0 if active) |
| last_name | Yes | Last name |
| update_at | No | Last update timestamp in milliseconds |
| first_name | Yes | First name |
| mfa_active | No | Multi-factor auth enabled |
| auth_service | Yes | Authentication service |
| email_verified | No | Email verification status |
| last_picture_update | No | Last avatar update timestamp |
| last_password_update | No | Last password change timestamp |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and idempotentHint=true, so description adds value by stating what is returned ('username, email, and status'). No contradiction, but additional behavioral detail is minimal 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?
Three sentences, each serving a distinct purpose: purpose, output, usage guidance. Zero wasted words, efficiently front-loaded.
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?
Simple tool with one parameter and an output schema (implied by context). Description covers input, output, and alternative tool. Complete for its complexity level.
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% with detailed parameter description ('Mattermost username', pattern, length). Description adds the '@username' context but doesn't significantly extend meaning beyond 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?
States 'Get a user's profile by their username' with specific verb+resource. Differentiates from get_user (by ID) and search_users, so purpose is clear and distinct from siblings.
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?
Explicitly says when to use: 'Use when you know the @username but not the user ID' and provides alternative 'For lookup by ID, use get_user instead'. Provides clear context and exclusion.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_user_statusARead-onlyIdempotent
Get a user's online/offline status.
Returns: online, away, dnd (do not disturb), or offline. Use to check if a user is available before sending a message.
| Name | Required | Description | Default |
|---|---|---|---|
| user_id | Yes | 26-character user identifier (e.g., 'o5w8h47pdfbzjc4d8w7dhnhren') |
Output Schema
| Name | Required | Description |
|---|---|---|
| manual | Yes | Manually set status |
| status | Yes | Status: online, away, dnd, offline |
| user_id | Yes | User identifier |
| last_activity_at | Yes | Last activity timestamp |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and idempotentHint. The description adds the specific status values returned, providing useful behavioral context beyond 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?
Three concise sentences with no wasted words. The purpose is front-loaded, followed by return values and usage hint.
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 tool with good annotations and output schema, the description is complete. It covers purpose, output values, and usage context.
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% with a detailed parameter description. The tool description does not add extra meaning beyond the schema, so 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 clearly states the tool's purpose: 'Get a user's online/offline status.' It lists the possible return values (online, away, dnd, offline) and distinguishes from sibling tools like get_user which focus on profile info.
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 includes a direct usage note: 'Use to check if a user is available before sending a message.' This provides clear context, though it lacks explicit when-not or alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
join_channelAIdempotent
Join a public channel.
Adds the authenticated user to the channel. Cannot be used to join private channels. Joining a channel you're already in has no additional effect.
| Name | Required | Description | Default |
|---|---|---|---|
| channel_id | Yes | 26-character channel identifier (e.g., 'o5w8h47pdfbzjc4d8w7dhnhren') |
Output Schema
| Name | Required | Description |
|---|---|---|
| roles | Yes | Space-separated role names |
| user_id | Yes | User identifier |
| msg_count | Yes | Messages seen count, including replies in threads |
| channel_id | Yes | Channel identifier |
| mention_count | Yes | Unread @-mentions count, including thread replies |
| last_update_at | Yes | Last update timestamp |
| last_viewed_at | Yes | Last viewed timestamp |
| msg_count_root | Yes | Root messages seen count, excluding thread replies |
| mention_count_root | Yes | Unread root @-mentions count, excluding thread replies |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond annotations (idempotent, not destructive), description adds that joining a channel you're already in has no effect, which aligns with idempotency. Also clarifies public-only restriction.
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 concise sentences front-load the core action and provide essential constraints. No wasted words.
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 action and presence of output schema, the description covers purpose, scope (public), and behavioral effects (idempotent). Complete for the tool's 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 covers 100% of parameters with a descriptive example. Description adds no extra meaning beyond what the schema provides, so baseline score.
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 tool joins a public channel and adds the authenticated user. Distinguishes from private channels and notes idempotent behavior. Differentiates from sibling tools like leave_channel and add_user_to_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?
Implicitly suggests use for public channels only and notes no effect if already a member. Does not explicitly compare with alternatives like add_user_to_channel for adding others.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
leave_channelAIdempotent
Leave a channel.
Removes the authenticated user from the channel. Cannot leave Town Square or other default channels. Can rejoin public channels later with join_channel.
| Name | Required | Description | Default |
|---|---|---|---|
| channel_id | Yes | 26-character channel identifier (e.g., 'o5w8h47pdfbzjc4d8w7dhnhren') |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses that the user is removed, and adds context about default channels and rejoin capability. Annotations indicate idempotent and non-destructive, but description does not contradict. Could clarify behavior if user is not a member.
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, front-loaded with action, no wasted words. Efficient and clear.
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 one parameter and no output schema, the description covers action, constraints, and post-action behavior (rejoin). Annotations provide additional safety info.
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% with a clear description of channel_id. Description adds no further parameter details, so baseline score 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?
Description clearly states the action (leave) and resource (channel). It distinguishes itself from siblings like join_channel and add_user_to_channel by specifying constraints like cannot leave default channels.
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?
Provides explicit when-to-use (leave a channel) and when-not-to (cannot leave Town Square or other default channels). Mentions alternative join_channel for rejoining.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_bookmarksARead-onlyIdempotent
List all bookmarks in a channel.
Returns bookmarks in sort order. Use to see saved links and files pinned to a channel. For searching messages, use search_messages instead.
Note: Requires Entry, Professional, Enterprise, or Enterprise Advanced edition (not available in Team Edition). Minimum version: v10.1.
| Name | Required | Description | Default |
|---|---|---|---|
| channel_id | Yes | 26-character channel identifier (e.g., 'o5w8h47pdfbzjc4d8w7dhnhren') | |
| bookmarks_since | No | Timestamp to filter bookmarks updated since |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and idempotentHint, so the safety profile is covered. The description adds useful behavioral context beyond those annotations: it states the returned items are in sort order and calls out edition/version constraints (Entry, Professional, Enterprise, Enterprise Advanced; minimum v10.1).
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?
Four short sentences, each earning its place: purpose, output ordering, use case, and availability constraint. The essential information is front-loaded and there is 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?
For a read-only list tool with full schema coverage and an output schema, the description is complete. It includes the intended use, an explicit alternative, sorting behavior, and edition/version restrictions, so an agent has what it needs to select and invoke 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 both parameters. The description does not add detail about bookmarks_since or the channel_id format, but the schema already covers this, 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 opens with a specific verb and resource: 'List all bookmarks in a channel.' This clearly identifies the operation and scope, and the sibling-differentiating note 'For searching messages, use search_messages instead' helps distinguish it from a nearby tool.
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 states when to use the tool ('Use to see saved links and files pinned to a channel') and names an alternative for a different need ('For searching messages, use search_messages instead'). This gives the agent clear routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_my_channelsARead-onlyIdempotent
List channels you are a member of in a team.
Returns your channels with unread counters and the read marker for the authenticated user. Two counter pairs are provided:
unread_msg_count/mention_countcount thread replies too (the channel badge with Collapsed Reply Threads off — the team default).unread_msg_count_root/mention_count_rootcount only root posts (the badge with Collapsed Reply Threads on).
last_viewed_at is the user's read marker for the channel. Pass it as
get_channel_messages(channel_id, since=last_viewed_at) for incremental sync, or
use get_channel_messages(channel_id, unread_only=True) for the unread window
(preferred — deterministic and edit-noise-free).
Channels without a membership record report 0 for all counters and last_viewed_at.
Use channel_types to narrow results: ["O", "P"] for workspace channels without DMs, or ["D"] for direct messages only. Use only_unread=True to get only channels with unread messages. For discovering public channels you haven't joined yet, use list_public_channels.
| Name | Required | Description | Default |
|---|---|---|---|
| team_id | Yes | 26-character team identifier (e.g., 'o5w8h47pdfbzjc4d8w7dhnhren') | |
| only_unread | No | Return only channels with unread messages | |
| channel_types | No | Channel types to include: O=public, P=private, D=direct message, G=group message. Omit to return all types. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and idempotentHint. Description adds meaningful behavioral context: explains the two counter pairs (with and without thread replies), the semantics of last_viewed_at, and that channels without membership return zeros. 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?
First sentence immediately states purpose. The description is well-structured with bullet-like formatting for counter pairs. Each sentence provides distinct information, but could be slightly tightened (e.g., merging counter explanations). Still, no wasted words.
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 (multiple counters, read marker, filtering options), the description covers all usage aspects, edge cases, and relations to other tools. Output schema exists, so return value explanation is not needed.
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 baseline is 3. Description adds value by explaining the meaning of counters and how last_viewed_at is used in subsequent calls. It also gives practical values for channel_types. This enriches parameter understanding beyond 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 'List channels you are a member of in a team,' specifying both the resource (channels) and the scope (your memberships). It distinguishes from sibling 'list_public_channels' by saying 'For discovering public channels you haven't joined yet, use list_public_channels.' Verb and resource are precise.
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?
Provides explicit guidance: use channel_types to narrow results (with examples), use only_unread=True for unread channels, and explicitly names alternative list_public_channels for channels not joined. This covers when and when not to use the tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_public_channelsARead-onlyIdempotent
List public channels available in a team.
Returns all public channels for discovery, including ones you haven't joined. Results are paginated. Use page/per_page to retrieve all channels. Useful for finding channels to join. For channels you are already a member of (including private), use list_my_channels.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page number (0-indexed) | |
| team_id | Yes | 26-character team identifier (e.g., 'o5w8h47pdfbzjc4d8w7dhnhren') | |
| per_page | No | Results per page |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and idempotentHint. Description adds pagination behavior and scope (including unjoined channels), which are useful beyond annotations. No contradictions.
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, no wasted words, front-loaded with the main purpose. Efficient and 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?
Output schema exists, so return values are handled. Description covers the essential: what is returned, pagination, and scope. Could mention that team_id is required, but that's already in schema. Still complete enough.
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 baseline is 3. Description mentions page and per_page in context of pagination, but does not add details beyond schema (e.g., defaults, bounds). Minimal added value.
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 it lists public channels for discovery, including unjoined ones. Distinguishes from sibling list_my_channels which returns channels the user is a member of. Verb+resource is 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?
Explicitly states when to use: for finding channels to join. Provides exclusion: use list_my_channels for channels you are already a member of. Could mention more alternatives but sufficient.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_teamsARead-onlyIdempotent
List teams the current user belongs to.
Returns team name, description, and settings. Use this to discover available teams before listing channels.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and idempotentHint, so the description adds value by specifying return fields (team name, description, settings). No contradictions.
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 that front-load the action and provide essential detail. No redundancy or wasted words.
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 zero parameters, presence of output schema, and annotations that cover safety, the description sufficiently explains the tool's purpose and usage. Minor omission: no mention of pagination or performance, but acceptable for a simple 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?
No parameters exist, so the description cannot add anything beyond the schema. Baseline score of 4 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 'teams' with a clear scope 'current user belongs to'. It distinguishes from siblings like 'get_team' and channel-listing tools by providing a use case.
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?
Explicitly states when to use: 'Use this to discover available teams before listing channels.' While no explicit exclusions are given, the context signals differentiate it from sibling tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
mark_channel_viewedA
Mark a channel as read for the authenticated user.
Clears unread counters and advances last_viewed_at. Use when the user
asks to clear unreads, when a bot has processed
get_channel_messages(unread_only=True) and needs to advance read state
for the next poll, or as a one-shot bootstrap on a channel with
last_viewed_at == 0 so unread_only queries return posts.
Do NOT call on accounts shared with humans — it clears their UI badge.
| Name | Required | Description | Default |
|---|---|---|---|
| channel_id | Yes | 26-character channel identifier (e.g., 'o5w8h47pdfbzjc4d8w7dhnhren') |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses behavioral effects: 'Clears unread counters and advances last_viewed_at'. Warns about clearing UI badges for shared accounts. No annotations contradicted; destructiveHint=false is consistent.
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 paragraph with dense but clear sentences. It is well-structured and front-loaded with the primary purpose, but slightly longer than necessary due to detailed usage examples.
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 one parameter and no output schema, the description covers purpose, usage guidance, behavioral effects, and an anti-pattern. It is fully sufficient for correct agent 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 coverage is 100% with a clear description of the channel_id format. The tool description adds no additional parameter semantics beyond what the schema already provides, so 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 clearly states the action 'Mark a channel as read' and the resource 'channel for authenticated user'. It distinguishes this tool from siblings like leave_channel or create_channel by focusing on read state management.
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?
Explicitly provides three specific use cases (user asks to clear unreads, bot processing unread messages, bootstrap with last_viewed_at==0) and an explicit anti-pattern ('Do NOT call on accounts shared with humans').
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pin_messageAIdempotent
Pin a message in a channel.
Pinned messages appear in the channel's pinned posts section. Pinning an already pinned message has no additional effect.
| Name | Required | Description | Default |
|---|---|---|---|
| post_id | Yes | 26-character post/message identifier (e.g., 'o5w8h47pdfbzjc4d8w7dhnhren') |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | Yes | Unique post identifier |
| type | Yes | Post type (empty for regular posts) |
| edit_at | Yes | Last edit timestamp |
| message | Yes | Post content (supports Markdown) |
| root_id | Yes | Root post ID if in thread |
| user_id | Yes | Author user identifier |
| file_ids | No | Attached file IDs |
| hashtags | Yes | Space-separated hashtags |
| create_at | Yes | Creation timestamp in milliseconds |
| delete_at | Yes | Deletion timestamp (0 if not deleted) |
| is_pinned | Yes | Whether post is pinned |
| update_at | Yes | Last update timestamp in milliseconds |
| channel_id | Yes | Channel where posted |
| original_id | Yes | Original post ID if edited |
| pending_post_id | Yes | Client-side pending ID |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already provide idempotentHint=true and destructiveHint=false, and the description adds meaningful behavioral context: it states the observable effect (message appears in pinned posts) and explicitly clarifies the idempotent behavior ('Pinning an already pinned message has no additional effect'). This goes beyond simply restating the annotation booleans. No contradiction with annotations is present.
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 three short sentences, each with a distinct purpose: state the action, describe the result, and clarify the idempotent edge case. There is no filler or repetition of schema details. It is front-loaded and compact.
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 one-parameter mutating operation, the description plus annotations and schema cover everything an agent needs: required identifier, effect, idempotence, and non-destructive nature. An output schema exists, so return-value documentation is not required here. No meaningful gap remains.
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 only parameter, post_id, is already well-documented with type and example. The description adds no extra meaning about the parameter itself, but it also does not need to, since the schema carries the full burden. Baseline 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 opens with a specific verb and resource: 'Pin a message in a channel.' It clearly defines the tool's function and distinguishes it from the sibling 'unpin_message' by direction of action. Even without reading the schema, an agent knows exactly what this operation 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?
The description implies usage context by explaining that pinned messages appear in the channel's pinned posts section and that pinning an already pinned message is a no-op. However, it does not explicitly state when to prefer this over alternatives or when not to use it. Usage guidance is adequate but mostly inferred rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
post_messageA
Post a message to a Mattermost channel.
Send text messages with Markdown support. Use root_id to reply in a thread. Use file_ids to attach uploaded files. Use attachments for rich formatted content. To read all messages in a thread, use get_thread.
Attachment examples:
Status alert: {"color": "danger", "title": "Build Failed", "text": "Tests failed on main"}
Success notification: {"color": "good", "title": "Deployed", "text": "v1.2.3 is live"}
With fields: {"title": "Ticket", "fields": [{"title": "Status", "value": "Open", "short": true}]}
| Name | Required | Description | Default |
|---|---|---|---|
| message | Yes | Message content (supports Markdown) | |
| root_id | No | Root post ID for threading | |
| file_ids | No | File IDs to attach (from upload_file) | |
| channel_id | Yes | 26-character channel identifier (e.g., 'o5w8h47pdfbzjc4d8w7dhnhren') | |
| attachments | No | Rich message attachments with colors, fields, images |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | Yes | Unique post identifier |
| type | Yes | Post type (empty for regular posts) |
| edit_at | Yes | Last edit timestamp |
| message | Yes | Post content (supports Markdown) |
| root_id | Yes | Root post ID if in thread |
| user_id | Yes | Author user identifier |
| file_ids | No | Attached file IDs |
| hashtags | Yes | Space-separated hashtags |
| create_at | Yes | Creation timestamp in milliseconds |
| delete_at | Yes | Deletion timestamp (0 if not deleted) |
| is_pinned | Yes | Whether post is pinned |
| update_at | Yes | Last update timestamp in milliseconds |
| channel_id | Yes | Channel where posted |
| original_id | Yes | Original post ID if edited |
| pending_post_id | Yes | Client-side pending ID |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description transparently discloses that this action posts/sends a message with Markdown support and attachment capabilities, going well beyond the sole destructiveHint=false annotation. It adds useful behavioral context about thread replies and rich attachments; it does not detail permissions or rate limits, but the behavior is clear for a messaging 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 compact and front-loaded: it states the core action first, then maps each parameter to its use, then gives a cross-reference to get_thread. The attachment examples are focused and non-redundant, adding practical value instead of restating the schema.
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 is complete for this tool's complexity: the schema covers parameter types, the output schema covers returns, and the description covers when to use the tool and provides advanced attachment examples. The explicit pointer to get_thread closes the main alternative-use question an agent might have.
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 met by the schema. The description adds value beyond the schema by explaining the purpose of root_id, file_ids, and attachments, and by including concrete attachment JSON examples for common use cases. This meaningfully helps an agent construct params.
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-resource pair: 'Post a message to a Mattermost channel.' It also distinguishes this from related read operations by pointing to get_thread for reading messages, and the overall message clearly differentiates 'post' from sibling tools like update_message and delete_message.
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 says when to use root_id (reply in a thread), file_ids (attach uploaded files), attachments (rich content), and explicitly routes reading a thread to get_thread. It lacks an explicit 'when not to use this tool' statement, but the alternatives and usage modes are clear enough.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
remove_reactionAIdempotent
Remove your emoji reaction from a message.
Removes a reaction previously added by the authenticated user. Removing a non-existent reaction has no effect.
| Name | Required | Description | Default |
|---|---|---|---|
| post_id | Yes | 26-character post/message identifier (e.g., 'o5w8h47pdfbzjc4d8w7dhnhren') | |
| emoji_name | Yes | Emoji name without colons (e.g., 'thumbsup', 'smile') |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide idempotentHint and destructiveHint. The description adds 'Removing a non-existent reaction has no effect', reinforcing idempotency and safety. No contradiction, and additional context is provided.
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, front-loaded with core action. Every sentence provides essential information without fluff.
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 tool (2 parameters, no output schema, annotations covering idempotency/destructive), the description is complete. It covers purpose, scope, and edge cases (non-existent reaction) adequately.
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% with detailed descriptions and examples for both parameters. The description adds no extra parameter information, so baseline 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 states 'Remove your emoji reaction from a message' with a specific verb and resource, and clarifies it only affects own reactions. It implicitly distinguishes from add_reaction and get_reactions siblings.
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 explicit guidance on when to use versus alternatives like add_reaction. The verb 'remove' implies purpose, but an agent may benefit from a note that this only removes own reactions and not others'.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_messagesARead-onlyIdempotent
Search for messages matching specific criteria across channels.
Searches message content within a team. For simply reading recent channel messages, use get_channel_messages instead.
Search syntax examples:
Simple text: "deployment error"
From user: "from:username bug"
In channel: "in:channel-name release"
Date range: "after:2024-01-01 before:2024-02-01"
Combined: "from:alice in:dev-ops deployment failed"
| Name | Required | Description | Default |
|---|---|---|---|
| terms | Yes | Search terms (Mattermost syntax) | |
| team_id | Yes | 26-character team identifier (e.g., 'o5w8h47pdfbzjc4d8w7dhnhren') | |
| is_or_search | No | Use OR instead of AND for multiple terms |
Output Schema
| Name | Required | Description |
|---|---|---|
| order | Yes | Post IDs in display order |
| posts | Yes | Map of post ID to Post object |
| truncated | No | True when the response hit a Mattermost response cap — more posts exist beyond this batch |
| next_post_id | No | Next post ID for pagination |
| prev_post_id | No | Previous post ID for pagination |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare the operation read-only and idempotent, lowering the burden. The description adds useful behavioral scope beyond annotations by clarifying that search spans a whole team and all channels, not just the current channel.
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 well-structured and front-loaded: purpose first, sibling distinction second, then compact syntax examples. Every line earns its place with 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?
Given the output schema exists, the description does not need to explain return values. The combination of purpose, usage guidance, alternative routing, syntax examples, and schema details fully equips an agent to invoke 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 coverage is 100%, so the baseline is 3, but the description significantly adds value with search syntax examples for the terms parameter: simple text, from, in, date range, and combined queries. This helps an agent construct valid and effective search terms beyond what the schema states.
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 and resource: searching messages across channels within a team. It also distinguishes itself from get_channel_messages, making the tool's scope explicit and easy to differentiate from siblings.
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 tells the agent when to use this tool versus the main alternative: use search_messages for searching content across channels, and use get_channel_messages for simply reading recent channel messages. This gives concrete routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_usersARead-onlyIdempotent
Search for users by name or username.
Searches across username, first name, last name, and nickname. Use to find users when you don't know their exact username or ID.
| Name | Required | Description | Default |
|---|---|---|---|
| term | Yes | Search term | |
| team_id | No | Limit search to a specific team |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and idempotentHint, and description adds that it searches across username, first name, last name, and nickname. No contradictions; fully transparent about 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?
Three concise sentences, front-loaded with the main purpose. No wasted words. Perfectly sized for quick scanning.
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 tool with 2 parameters, high schema coverage, and annotations, the description covers purpose, usage, and search scope. Output schema exists, so return details are likely documented elsewhere. Minor gap: doesn't mention result pagination, but output schema may cover 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 coverage is 100%, but description adds meaning by explaining that the search term applies to multiple fields (username, first name, etc.), which is not evident from the schema's 'Search term' description. Adds value beyond 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?
Clearly states 'Search for users by name or username' and specifies it searches across multiple fields. Distinguishes from sibling tools like get_user (by ID) and get_user_by_username (exact username) by focusing on partial matches.
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?
Explicitly says 'Use to find users when you don't know their exact username or ID,' providing clear context for when to use this tool over exact lookups. Could be improved by naming alternatives, but context is sufficient.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unpin_messageAIdempotent
Unpin a message from a channel.
Removes the message from the channel's pinned posts. Unpinning a non-pinned message has no effect.
| Name | Required | Description | Default |
|---|---|---|---|
| post_id | Yes | 26-character post/message identifier (e.g., 'o5w8h47pdfbzjc4d8w7dhnhren') |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | Yes | Unique post identifier |
| type | Yes | Post type (empty for regular posts) |
| edit_at | Yes | Last edit timestamp |
| message | Yes | Post content (supports Markdown) |
| root_id | Yes | Root post ID if in thread |
| user_id | Yes | Author user identifier |
| file_ids | No | Attached file IDs |
| hashtags | Yes | Space-separated hashtags |
| create_at | Yes | Creation timestamp in milliseconds |
| delete_at | Yes | Deletion timestamp (0 if not deleted) |
| is_pinned | Yes | Whether post is pinned |
| update_at | Yes | Last update timestamp in milliseconds |
| channel_id | Yes | Channel where posted |
| original_id | Yes | Original post ID if edited |
| pending_post_id | Yes | Client-side pending ID |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description explicitly discloses the idempotent and non-destructive behavior by stating 'Unpinning a non-pinned message has no effect'. Annotations already provide idempotentHint=true and destructiveHint=false, but the concrete no-op behavior adds useful context beyond the structured hints.
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 succinct sentences with no filler. The main action is front-loaded in the first sentence, and the second sentence adds only the relevant edge-case behavior.
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?
This is a single-parameter, simple operation. The description, annotations, and input schema together cover the action, the idempotent edge case, and parameter format, so the tool 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?
The sole parameter post_id is fully covered by the input schema (100% coverage) with type, format, and example. The tool description adds no additional semantic meaning to the parameter, 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 states a specific verb and resource: 'Unpin a message from a channel' and clarifies by saying it removes the message from the channel's pinned posts. This semantically distinguishes it from siblings like pin_message and delete_message 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?
No guidance is provided on when to use this tool versus alternatives, nor are exclusions or prerequisites mentioned. The description only states the action itself, leaving the agent to infer that this should be used whenever a message needs unpinning.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_bookmarkAIdempotent
Update a channel bookmark.
Partially updates bookmark properties. Only provided fields are updated; others remain unchanged.
Note: Requires Entry, Professional, Enterprise, or Enterprise Advanced edition (not available in Team Edition). Minimum version: v10.1.
| Name | Required | Description | Default |
|---|---|---|---|
| emoji | No | New emoji icon | |
| link_url | No | New URL | |
| image_url | No | New preview image URL | |
| channel_id | Yes | 26-character channel identifier (e.g., 'o5w8h47pdfbzjc4d8w7dhnhren') | |
| bookmark_id | Yes | 26-character bookmark identifier (e.g., 'o5w8h47pdfbzjc4d8w7dhnhren') | |
| display_name | No | New display name |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | Yes | Unique bookmark identifier |
| file | No | File metadata for file bookmarks |
| type | Yes | Bookmark type: 'link' or 'file' |
| emoji | No | Emoji icon |
| file_id | Yes | File ID for file bookmarks (empty for links) |
| link_url | No | URL for link bookmarks |
| owner_id | Yes | User ID who created the bookmark |
| create_at | Yes | Creation timestamp in milliseconds |
| delete_at | Yes | Deletion timestamp (0 if not deleted) |
| image_url | No | Preview image URL |
| parent_id | No | Parent bookmark ID |
| update_at | Yes | Last update timestamp in milliseconds |
| channel_id | Yes | Channel this bookmark belongs to |
| sort_order | Yes | Position in bookmark list |
| original_id | No | Original bookmark ID if copied |
| display_name | Yes | Bookmark display name |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark the tool as idempotent and non-destructive. The description adds key PATCH-like behavior: only provided fields are updated and others remain unchanged, plus edition/version constraints. 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 three tight sentences with no filler. The core action is front-loaded, the partial-update semantics follow immediately, and the edition/version note is relevant and appropriately placed.
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 6-parameter partial-update operation, the description covers the key semantics, prerequisites, and field-preservation behavior, while required parameters are documented in the schema. An output schema exists so return values needn't be described; minor gaps are lack of explicit permission/error conditions and null-clearing behavior.
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 provides 100% coverage with descriptions for all parameters, so the baseline is 3. The description adds value by clarifying that omitted fields are preserved, which is essential for correctly interpreting the optional parameters, though it doesn't explicitly explain null-vs-omitted 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 identifies a specific operation: updating a channel bookmark's properties via partial update. It distinguishes itself from create/delete/list by focusing on updating an existing bookmark's fields, though it doesn't explicitly contrast with the sibling update_bookmark_sort_order.
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 modifying existing bookmark properties and adds useful edition/version prerequisites, but it doesn't explicitly state when to prefer this over update_bookmark_sort_order or the create/delete/list siblings, nor does it state when not to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_bookmark_sort_orderAIdempotent
Reorder a channel bookmark.
Moves the bookmark to the specified position. Other bookmarks are automatically adjusted. Returns all affected bookmarks with updated positions.
Note: Requires Entry, Professional, Enterprise, or Enterprise Advanced edition (not available in Team Edition). Minimum version: v10.1.
| Name | Required | Description | Default |
|---|---|---|---|
| channel_id | Yes | 26-character channel identifier (e.g., 'o5w8h47pdfbzjc4d8w7dhnhren') | |
| bookmark_id | Yes | 26-character bookmark identifier (e.g., 'o5w8h47pdfbzjc4d8w7dhnhren') | |
| new_sort_order | Yes | New position in bookmark list |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare idempotentHint and non-destructive, while the description goes further by explaining that other bookmarks get automatically adjusted and that the response returns all affected bookmarks with updated positions. It also adds clearly an edition/version constraint (not in Team Edition, min v10.1). 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 extremely concise and front-loaded: the verb phrase appears in the first sentence. It says everything necessary in a compact two-sentence form plus a short note about edition/version. There is no redundancy or unnecessary elaboration.
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?
Although an output schema exists and the description need not explain return values, the description sensibly mentions that the operation returns all affected bookmarks with updated positions, which is enough for the agent. It also discloses the edition/version constraints, which is critical for actionable use. Could add a little about out-of-range positions or failure behavior, but for a simple reorder tool it's essentially 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 has 100% description coverage; the parameters channel_id, bookmark_id, and new_sort_order are fully explained there. The description only restates the meaning of new_sort_order in prose ('moves the bookmark to that specified position') without adding extra detail such as examples or ranges beyond the schema. Baseline 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 opens with 'Reorder a channel bookmark' – a specific verb and resource – then clarifies the behavior: 'Moves the bookmark to the specified position.' This clearly distinguishes it from the sibling update_bookmark, which implies changing bookmark content, and from create/delete/list_bookmarks. The purpose is 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?
Gilt clearly states what the tool does (reorders by moving a bookmark to a position and adjusting others), but it does not explicitly say when to choose this tool versus alternatives like update_bookmark, nor does it describe any when-not-to-use context. The usage scenario is reasonable but implied rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_messageA
Edit an existing message.
Can only edit your own messages (unless admin). The message will show as edited. Original content is replaced; edit history is not preserved.
Attachment examples:
Status alert: {"color": "danger", "title": "Build Failed", "text": "Tests failed on main"}
With fields: {"title": "Ticket", "fields": [{"title": "Status", "value": "Open", "short": true}]}
| Name | Required | Description | Default |
|---|---|---|---|
| message | Yes | New message content | |
| post_id | Yes | 26-character post/message identifier (e.g., 'o5w8h47pdfbzjc4d8w7dhnhren') | |
| attachments | No | Rich message attachments with colors, fields, images |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | Yes | Unique post identifier |
| type | Yes | Post type (empty for regular posts) |
| edit_at | Yes | Last edit timestamp |
| message | Yes | Post content (supports Markdown) |
| root_id | Yes | Root post ID if in thread |
| user_id | Yes | Author user identifier |
| file_ids | No | Attached file IDs |
| hashtags | Yes | Space-separated hashtags |
| create_at | Yes | Creation timestamp in milliseconds |
| delete_at | Yes | Deletion timestamp (0 if not deleted) |
| is_pinned | Yes | Whether post is pinned |
| update_at | Yes | Last update timestamp in milliseconds |
| channel_id | Yes | Channel where posted |
| original_id | Yes | Original post ID if edited |
| pending_post_id | Yes | Client-side pending ID |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses key behavioral details: the message will be marked as edited, original content is replaced, and edit history is not preserved. These details go well beyond the single destructiveHint annotation and help an agent understand the side effects of mutation.
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 front-loaded with the core purpose, then adds only high-value behavioral caveats and concrete attachment examples. Every sentence earns its place and there is 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 description covers permissions, edit-visibility, replacement semantics, history behavior, and attachment formatting examples. It is complete enough for a mutation tool with an output schema, though it could have explicitly noted what happens to existing attachments when the attachments parameter is omitted.
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 schema already documents message, post_id, and attachments thoroughly. The attachment examples add practical formatting guidance, but they show bare attachment objects rather than the array shape the schema expects, which slightly weakens their value.
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 phrase 'Edit an existing message' names a specific verb and resource, and clearly distinguishes this tool from sibling post_message and delete_message. It states what the operation does 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 gives relevant usage context by stating that only the user's own messages can be edited unless the user is admin. It does not explicitly contrast with sibling tools like post_message or delete_message, but the edit-vs-create/edit-vs-delete 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.
upload_fileA
Upload a file to a channel.
The file will be attached to messages in the specified channel. Returns file ID that can be used when posting messages with file_ids parameter.
| Name | Required | Description | Default |
|---|---|---|---|
| filename | No | Override filename | |
| file_path | Yes | Local path to the file to upload; a leading '~' is expanded | |
| channel_id | Yes | 26-character channel identifier (e.g., 'o5w8h47pdfbzjc4d8w7dhnhren') |
Output Schema
| Name | Required | Description |
|---|---|---|
| client_ids | No | Client-provided IDs |
| file_infos | Yes | Uploaded file information |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only include destructiveHint: false, so the description carries some burden. It does disclose the return value (file ID for use with file_ids parameter) and the attachment behavior, which adds value. However, it omits details like authentication requirements, file size limits, or behavior on duplicate filenames. Given the sparse annotations, a 3 is appropriate – it adds some context but not comprehensive transparency.
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. The primary action is front-loaded, and the additional detail about file attachment and return value is concise. Every sentence contributes necessary 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 straightforward upload tool, the description covers the core behavior and return value. It does not discuss error handling, permissions, or rate limits, but these are not essential for a simple upload operation. The output schema likely provides return format details, and annotations indicate non-destructive nature. Given the tool's simplicity, it is sufficiently 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%, meaning all three parameters (channel_id, file_path, filename) are already well documented in the schema. The description adds no extra semantic detail about parameters beyond what the schema provides. The baseline of 3 applies because the schema handles 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 ('Upload') and resource ('a file to a channel'), and clarifies that the file is attached to messages. This distinguishes it clearly from sibling tools like download_file, get_file_info, and post_message. The purpose is 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 clearly conveys the action and its effect ('attached to messages in the specified channel'), making the context obvious. However, it does not explicitly mention alternatives or when not to use it (e.g., for retrieving files). There are no exclusions, but the guidance is implicit rather than explicit.
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.
14 tool updates
v0.6.1- Changed
create_bookmark2 fields changed- added
Output schema / properties / fileAdded value: +{ + "anyOf": [ + { + "additionalProperties": true, + "description": "Uploaded file metadata.\n\nNote: Go source uses CreatorId field name, but JSON response uses \"user_id\".\n\nSee: https://github.com/mattermost/mattermost/blob/master/server/public/model/file_info.go", + "properties": { + "channel_id": { + "description": "Channel where file was uploaded", + "type": "string" + }, + "create_at": { + "description": "Upload timestamp in milliseconds", + "type": "integer" + }, + "delete_at": { + "description": "Deletion timestamp", + "type": "integer" + }, + "extension": { + "description": "File extension without dot", + "type": "string" + }, + "has_preview_image": { + "default": false, + "description": "Has generated preview", + "type": "boolean" + }, + "height": { + "default": 0, + "description": "Image height in pixels", + "type": "integer" + }, + "id": { + "description": "Unique file identifier", + "type": "string" + }, + "mime_type": { + "description": "MIME type", + "type": "string" + }, + "name": { + "description": "File name", + "type": "string" + }, + "post_id": { + "default": "", + "description": "Associated post ID", + "type": "string" + }, + "size": { + "description": "File size in bytes", + "type": "integer" + }, + "update_at": { + "description": "Last update timestamp", + "type": "integer" + }, + "user_id": { + "description": "Uploader user identifier (CreatorId in Go)", + "type": "string" + }, + "width": { + "default": 0, + "description": "Image width in pixels", + "type": "integer" + } + }, + "required": [ + "id", + "user_id", + "channel_id", + "create_at", + "update_at", + "delete_at", + "name", + "extension", + "size", + "mime_type" + ], + "type": "object" + }, + { + "type": "null" + } + ], + "default": null, + "description": "File metadata for file bookmarks" +} - removed
Output schema / properties / file_infoRemoved value: -{ - "anyOf": [ - { - "additionalProperties": true, - "type": "object" - }, - { - "type": "null" - } - ], - "default": null, - "description": "File metadata for file bookmarks" -}
- Changed
delete_bookmark2 fields changed- added
Output schema / properties / fileAdded value: +{ + "anyOf": [ + { + "additionalProperties": true, + "description": "Uploaded file metadata.\n\nNote: Go source uses CreatorId field name, but JSON response uses \"user_id\".\n\nSee: https://github.com/mattermost/mattermost/blob/master/server/public/model/file_info.go", + "properties": { + "channel_id": { + "description": "Channel where file was uploaded", + "type": "string" + }, + "create_at": { + "description": "Upload timestamp in milliseconds", + "type": "integer" + }, + "delete_at": { + "description": "Deletion timestamp", + "type": "integer" + }, + "extension": { + "description": "File extension without dot", + "type": "string" + }, + "has_preview_image": { + "default": false, + "description": "Has generated preview", + "type": "boolean" + }, + "height": { + "default": 0, + "description": "Image height in pixels", + "type": "integer" + }, + "id": { + "description": "Unique file identifier", + "type": "string" + }, + "mime_type": { + "description": "MIME type", + "type": "string" + }, + "name": { + "description": "File name", + "type": "string" + }, + "post_id": { + "default": "", + "description": "Associated post ID", + "type": "string" + }, + "size": { + "description": "File size in bytes", + "type": "integer" + }, + "update_at": { + "description": "Last update timestamp", + "type": "integer" + }, + "user_id": { + "description": "Uploader user identifier (CreatorId in Go)", + "type": "string" + }, + "width": { + "default": 0, + "description": "Image width in pixels", + "type": "integer" + } + }, + "required": [ + "id", + "user_id", + "channel_id", + "create_at", + "update_at", + "delete_at", + "name", + "extension", + "size", + "mime_type" + ], + "type": "object" + }, + { + "type": "null" + } + ], + "default": null, + "description": "File metadata for file bookmarks" +} - removed
Output schema / properties / file_infoRemoved value: -{ - "anyOf": [ - { - "additionalProperties": true, - "type": "object" - }, - { - "type": "null" - } - ], - "default": null, - "description": "File metadata for file bookmarks" -}
- Added
download_file - Changed
get_channel_messages1 field changed- changed
Output schema / properties / posts / additionalProperties / requiredPrevious value: -[ - "id", - "create_at", - "update_at", - "delete_at", - "edit_at", - "user_id", - "channel_id", - "root_id", - "original_id", - "message", - "type", - "hashtags", - "file_ids", - "pending_post_id", - "is_pinned" -]New value: +[ + "id", + "create_at", + "update_at", + "delete_at", + "edit_at", + "user_id", + "channel_id", + "root_id", + "original_id", + "message", + "type", + "hashtags", + "pending_post_id", + "is_pinned" +]
- Changed
get_thread1 field changed- changed
Output schema / properties / posts / additionalProperties / requiredPrevious value: -[ - "id", - "create_at", - "update_at", - "delete_at", - "edit_at", - "user_id", - "channel_id", - "root_id", - "original_id", - "message", - "type", - "hashtags", - "file_ids", - "pending_post_id", - "is_pinned" -]New value: +[ + "id", + "create_at", + "update_at", + "delete_at", + "edit_at", + "user_id", + "channel_id", + "root_id", + "original_id", + "message", + "type", + "hashtags", + "pending_post_id", + "is_pinned" +]
- Changed
list_bookmarks2 fields changed- added
Output schema / properties / result / items / properties / fileAdded value: +{ + "anyOf": [ + { + "additionalProperties": true, + "description": "Uploaded file metadata.\n\nNote: Go source uses CreatorId field name, but JSON response uses \"user_id\".\n\nSee: https://github.com/mattermost/mattermost/blob/master/server/public/model/file_info.go", + "properties": { + "channel_id": { + "description": "Channel where file was uploaded", + "type": "string" + }, + "create_at": { + "description": "Upload timestamp in milliseconds", + "type": "integer" + }, + "delete_at": { + "description": "Deletion timestamp", + "type": "integer" + }, + "extension": { + "description": "File extension without dot", + "type": "string" + }, + "has_preview_image": { + "default": false, + "description": "Has generated preview", + "type": "boolean" + }, + "height": { + "default": 0, + "description": "Image height in pixels", + "type": "integer" + }, + "id": { + "description": "Unique file identifier", + "type": "string" + }, + "mime_type": { + "description": "MIME type", + "type": "string" + }, + "name": { + "description": "File name", + "type": "string" + }, + "post_id": { + "default": "", + "description": "Associated post ID", + "type": "string" + }, + "size": { + "description": "File size in bytes", + "type": "integer" + }, + "update_at": { + "description": "Last update timestamp", + "type": "integer" + }, + "user_id": { + "description": "Uploader user identifier (CreatorId in Go)", + "type": "string" + }, + "width": { + "default": 0, + "description": "Image width in pixels", + "type": "integer" + } + }, + "required": [ + "id", + "user_id", + "channel_id", + "create_at", + "update_at", + "delete_at", + "name", + "extension", + "size", + "mime_type" + ], + "type": "object" + }, + { + "type": "null" + } + ], + "default": null, + "description": "File metadata for file bookmarks" +} - removed
Output schema / properties / result / items / properties / file_infoRemoved value: -{ - "anyOf": [ - { - "additionalProperties": true, - "type": "object" - }, - { - "type": "null" - } - ], - "default": null, - "description": "File metadata for file bookmarks" -}
- Changed
pin_message1 field changed- changed
Output schema / requiredPrevious value: -[ - "id", - "create_at", - "update_at", - "delete_at", - "edit_at", - "user_id", - "channel_id", - "root_id", - "original_id", - "message", - "type", - "hashtags", - "file_ids", - "pending_post_id", - "is_pinned" -]New value: +[ + "id", + "create_at", + "update_at", + "delete_at", + "edit_at", + "user_id", + "channel_id", + "root_id", + "original_id", + "message", + "type", + "hashtags", + "pending_post_id", + "is_pinned" +]
- Changed
post_message1 field changed- changed
Output schema / requiredPrevious value: -[ - "id", - "create_at", - "update_at", - "delete_at", - "edit_at", - "user_id", - "channel_id", - "root_id", - "original_id", - "message", - "type", - "hashtags", - "file_ids", - "pending_post_id", - "is_pinned" -]New value: +[ + "id", + "create_at", + "update_at", + "delete_at", + "edit_at", + "user_id", + "channel_id", + "root_id", + "original_id", + "message", + "type", + "hashtags", + "pending_post_id", + "is_pinned" +]
- Changed
search_messages1 field changed- changed
Output schema / properties / posts / additionalProperties / requiredPrevious value: -[ - "id", - "create_at", - "update_at", - "delete_at", - "edit_at", - "user_id", - "channel_id", - "root_id", - "original_id", - "message", - "type", - "hashtags", - "file_ids", - "pending_post_id", - "is_pinned" -]New value: +[ + "id", + "create_at", + "update_at", + "delete_at", + "edit_at", + "user_id", + "channel_id", + "root_id", + "original_id", + "message", + "type", + "hashtags", + "pending_post_id", + "is_pinned" +]
- Changed
unpin_message1 field changed- changed
Output schema / requiredPrevious value: -[ - "id", - "create_at", - "update_at", - "delete_at", - "edit_at", - "user_id", - "channel_id", - "root_id", - "original_id", - "message", - "type", - "hashtags", - "file_ids", - "pending_post_id", - "is_pinned" -]New value: +[ + "id", + "create_at", + "update_at", + "delete_at", + "edit_at", + "user_id", + "channel_id", + "root_id", + "original_id", + "message", + "type", + "hashtags", + "pending_post_id", + "is_pinned" +]
- Changed
update_bookmark2 fields changed- added
Output schema / properties / fileAdded value: +{ + "anyOf": [ + { + "additionalProperties": true, + "description": "Uploaded file metadata.\n\nNote: Go source uses CreatorId field name, but JSON response uses \"user_id\".\n\nSee: https://github.com/mattermost/mattermost/blob/master/server/public/model/file_info.go", + "properties": { + "channel_id": { + "description": "Channel where file was uploaded", + "type": "string" + }, + "create_at": { + "description": "Upload timestamp in milliseconds", + "type": "integer" + }, + "delete_at": { + "description": "Deletion timestamp", + "type": "integer" + }, + "extension": { + "description": "File extension without dot", + "type": "string" + }, + "has_preview_image": { + "default": false, + "description": "Has generated preview", + "type": "boolean" + }, + "height": { + "default": 0, + "description": "Image height in pixels", + "type": "integer" + }, + "id": { + "description": "Unique file identifier", + "type": "string" + }, + "mime_type": { + "description": "MIME type", + "type": "string" + }, + "name": { + "description": "File name", + "type": "string" + }, + "post_id": { + "default": "", + "description": "Associated post ID", + "type": "string" + }, + "size": { + "description": "File size in bytes", + "type": "integer" + }, + "update_at": { + "description": "Last update timestamp", + "type": "integer" + }, + "user_id": { + "description": "Uploader user identifier (CreatorId in Go)", + "type": "string" + }, + "width": { + "default": 0, + "description": "Image width in pixels", + "type": "integer" + } + }, + "required": [ + "id", + "user_id", + "channel_id", + "create_at", + "update_at", + "delete_at", + "name", + "extension", + "size", + "mime_type" + ], + "type": "object" + }, + { + "type": "null" + } + ], + "default": null, + "description": "File metadata for file bookmarks" +} - removed
Output schema / properties / file_infoRemoved value: -{ - "anyOf": [ - { - "additionalProperties": true, - "type": "object" - }, - { - "type": "null" - } - ], - "default": null, - "description": "File metadata for file bookmarks" -}
- Changed
update_bookmark_sort_order2 fields changed- added
Output schema / properties / result / items / properties / fileAdded value: +{ + "anyOf": [ + { + "additionalProperties": true, + "description": "Uploaded file metadata.\n\nNote: Go source uses CreatorId field name, but JSON response uses \"user_id\".\n\nSee: https://github.com/mattermost/mattermost/blob/master/server/public/model/file_info.go", + "properties": { + "channel_id": { + "description": "Channel where file was uploaded", + "type": "string" + }, + "create_at": { + "description": "Upload timestamp in milliseconds", + "type": "integer" + }, + "delete_at": { + "description": "Deletion timestamp", + "type": "integer" + }, + "extension": { + "description": "File extension without dot", + "type": "string" + }, + "has_preview_image": { + "default": false, + "description": "Has generated preview", + "type": "boolean" + }, + "height": { + "default": 0, + "description": "Image height in pixels", + "type": "integer" + }, + "id": { + "description": "Unique file identifier", + "type": "string" + }, + "mime_type": { + "description": "MIME type", + "type": "string" + }, + "name": { + "description": "File name", + "type": "string" + }, + "post_id": { + "default": "", + "description": "Associated post ID", + "type": "string" + }, + "size": { + "description": "File size in bytes", + "type": "integer" + }, + "update_at": { + "description": "Last update timestamp", + "type": "integer" + }, + "user_id": { + "description": "Uploader user identifier (CreatorId in Go)", + "type": "string" + }, + "width": { + "default": 0, + "description": "Image width in pixels", + "type": "integer" + } + }, + "required": [ + "id", + "user_id", + "channel_id", + "create_at", + "update_at", + "delete_at", + "name", + "extension", + "size", + "mime_type" + ], + "type": "object" + }, + { + "type": "null" + } + ], + "default": null, + "description": "File metadata for file bookmarks" +} - removed
Output schema / properties / result / items / properties / file_infoRemoved value: -{ - "anyOf": [ - { - "additionalProperties": true, - "type": "object" - }, - { - "type": "null" - } - ], - "default": null, - "description": "File metadata for file bookmarks" -}
- Changed
update_message1 field changed- changed
Output schema / requiredPrevious value: -[ - "id", - "create_at", - "update_at", - "delete_at", - "edit_at", - "user_id", - "channel_id", - "root_id", - "original_id", - "message", - "type", - "hashtags", - "file_ids", - "pending_post_id", - "is_pinned" -]New value: +[ + "id", + "create_at", + "update_at", + "delete_at", + "edit_at", + "user_id", + "channel_id", + "root_id", + "original_id", + "message", + "type", + "hashtags", + "pending_post_id", + "is_pinned" +]
- Changed
upload_file1 field changed- changed
Input schema / properties / file_path / descriptionPrevious value: -"Local path to the file to upload"New value: +"Local path to the file to upload; a leading '~' is expanded"
38 tool updates
v0.5.1- First observed
add_reaction - First observed
add_user_to_channel - First observed
create_bookmark - First observed
create_channel - First observed
create_direct_channel - First observed
delete_bookmark - First observed
delete_message - First observed
get_channel - First observed
get_channel_by_name - First observed
get_channel_members - First observed
get_channel_messages - First observed
get_file_info - First observed
get_file_link - First observed
get_me - First observed
get_reactions - First observed
get_team - First observed
get_team_members - First observed
get_thread - First observed
get_user - First observed
get_user_by_username - First observed
get_user_status - First observed
join_channel - First observed
leave_channel - First observed
list_bookmarks - First observed
list_my_channels - First observed
list_public_channels - First observed
list_teams - First observed
mark_channel_viewed - First observed
pin_message - First observed
post_message - First observed
remove_reaction - First observed
search_messages - First observed
search_users - First observed
unpin_message - First observed
update_bookmark - First observed
update_bookmark_sort_order - First observed
update_message - First observed
upload_file
TDQS
Scored across 39 tools
Every tool targets a distinct resource and action, and the descriptions actively cross-reference related tools to prevent confusion. Even similar lookup pairs like get_user/get_user_by_username and get_channel/get_channel_by_name are clearly separated by what identifier they accept.
Tool names mostly follow a clear verb_noun pattern with consistent prefixes like get_, create_, delete_, update_, and list_. Minor inconsistencies exist, such as mixing get_channel_messages with list_my_channels, and special names like get_me and update_bookmark_sort_order break the strict pattern.
At 39 tools, this exceeds the 25-tool threshold and feels heavy even for a broad Mattermost integration. Each tool is individually useful, but the count makes the surface harder for an agent to navigate effectively.
The set covers messaging, files, reactions, bookmarks, users, teams, and channels well, but there are notable lifecycle gaps: create_channel has no update/archive/delete counterpart, and add_user_to_channel has no remove_user_from_channel. These missing operations could cause dead ends in admin workflows.
Maintenance
Related MCP Connectors
Messaging tools for AI agents: send messages, manage chats, groups and channels.
Carbon Voice MCP serves as a bridge that connects AI assistants like ChatGPT, Claude, and Cursor to a user's Carbon Voice account, turning voice messages and conversations into a private, on-demand knowledge base. It provides 28 specialized tools for comprehensive voice messaging management, including creating and sending messages, accessing conversation history with instant transcription, running AI actions (summarization, TLDR generation, meeting notes), and managing workspace collaboration through folders, contacts, and team communications.
- SkilderOAuthai.skilder
One place to build, share, and govern the skills and tools your AI agents use at work.
Control your Discord community: send/read messages, manage channels and forums, and handle webhook…
Related MCP Servers
- FlicenseBqualityDmaintenanceEnables Claude to interact with Mattermost through search functionality, user management, channel operations, and team information retrieval. Supports message search by keywords/users/dates, thread viewing, and displays all timestamps in Korean Standard Time (KST).9-
- AlicenseAqualityDmaintenanceEnables AI assistants to interact with Slack workspaces through comprehensive channel management, messaging, direct messages, search functionality, and user management capabilities.307 npm2MIT
- FlicenseNot gradedqualityDmaintenanceThis server enables interaction with Mattermost workspaces to manage channels, messages, threads, and user profiles via the Mattermost REST API. It provides a comprehensive suite of tools for reading channel history, posting messages, and managing reactions within a trusted environment.-
- FlicenseNot gradedqualityCmaintenanceEnables interaction with Mattermost workspaces to manage channels, messages, threads, reactions, and user profiles via the REST API. This server allows AI models to perform both read and write operations, such as posting messages and retrieving channel history, within a trusted environment.-