Skip to content

How a tool call works

Before you begin

  • Complete the quickstart and keep the test message’s channel_id, message_id, and jump_url.
  • Continue using the private test server for every example on this page.

The quickstart used an exact search and risk-matched dispatcher to make the final call predictable on the default progressive surface:

First call mcp_tools_search with query messages_send, then use the returned mcp_tools_write dispatcher with tool messages_send and the supplied channel ID and content. Do not invoke any other Discord tool.

This avoided two common ambiguities: messages_send does not accept a channel name, and the server does not perform a separate human confirmation for this ordinary write. The prompt above is the call you already completed; you do not need to send the message again.

  1. Visible catalog. MCP tools/list returns seven progressive tools when guild architecture is authorized: four search/dispatcher tools plus build_discord_server, guild_blueprint_apply, and guild_blueprint_evidence for preview, approved apply/resume, and independent verification. Without that authorization it returns the four search/dispatcher tools, not all 209 contracts.
  2. Exact discovery. mcp_tools_search returns the messages_send input schema and names mcp_tools_write as the required dispatcher.
  3. Risk-matched dispatch. The client sends the exact hidden tool name and its arguments to mcp_tools_write. A read or destructive dispatcher would be rejected.
  4. Validation. discord-mcp validates channel_id as a Discord snowflake and content as a non-empty string of at most 2,000 characters.
  5. Execution. The server applies its middleware and resilience policy, then sends an HTTP request to Discord’s create-message endpoint.
  6. Result. The tool returns a text summary for the conversation and structured JSON that another tool can reuse.

The client makes two MCP calls. The first loads the exact hidden contract:

{
"name": "mcp_tools_search",
"arguments": {
"query": "messages_send"
}
}

The search result names mcp_tools_write, so the second call wraps the Discord arguments under args:

{
"name": "mcp_tools_write",
"arguments": {
"tool": "messages_send",
"args": {
"channel_id": "112233445566778899",
"content": "hello from discord-mcp"
}
}
}

With the compatibility full surface, the client can select the exact Discord tool directly. The progressive path above is the tutorial default because it keeps the visible catalog small without changing validation, authorization, or the returned result.

The structured result has this shape:

{
"message_id": "112233445566778900",
"channel_id": "112233445566778899",
"jump_url": "https://discord.com/channels/999000999000999000/112233445566778899/112233445566778900",
"timestamp": "2026-08-01T10:00:00.000Z"
}

The IDs and timestamp above are examples. The keys match the runtime output schema.

An MCP client can take message_id and channel_id from the result, search the exact follow-up tool such as reactions_create, messages_pin, or messages_edit, then pass the IDs through the dispatcher returned by that search. This is safer than asking the model to reconstruct identifiers from prose or guess a dispatcher’s risk class.

The strongest boundary is the bot’s Discord role. Give it access only to the servers, channels, and actions required by your workflows.

Result Meaning Next action
TOOL_NOT_AVAILABLE The hidden tool is unavailable to this caller or category scope. Search the exact name again and check MCP_CATEGORIES.
DISPATCH_MODE_MISMATCH The client used read, write, or destructive dispatch incorrectly. Use the exact dispatcher returned by the latest search.
WRITE_PREVIEW MCP_WRITE_MODE=preview blocked the ordinary write before Discord. Keep the read-only proof, or intentionally change the test profile to allow and restart the client before retrying.
Invalid arguments A required field is missing or malformed. Copy the numeric channel ID and keep content within 2,000 characters.
401 The token is invalid or revoked. Reset it in the Developer Portal and update the local config.
403 The bot lacks channel permissions. Check View Channel and Send Messages, including channel overrides.
404 Discord cannot find or expose that channel to the bot. Call channels_list for the correct guild and reuse the returned ID.

See the exact messages_send reference or return to Troubleshooting.

  • I can identify the exact search call and the nested dispatcher call.
  • I know to use the dispatcher returned by mcp_tools_search, not guess one.
  • I can identify message_id, channel_id, jump_url, and timestamp in the result.
  • I understand that messages_send writes immediately and is not confirmation-gated.
  • I know to reuse IDs from structured output instead of reconstructing them from prose.

Continue to Get your first verified Discord outcome when you are ready to plan, approve, apply, and independently verify a complete build in an empty private test guild.