How a tool call works
Before you begin
- Complete the quickstart and keep the test message’s
channel_id,message_id, andjump_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_searchwithquerymessages_send, then use the returnedmcp_tools_writedispatcher withtoolmessages_sendand 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.
Request flow
Section titled “Request flow”- Visible catalog. MCP
tools/listreturns seven progressive tools when guild architecture is authorized: four search/dispatcher tools plusbuild_discord_server,guild_blueprint_apply, andguild_blueprint_evidencefor preview, approved apply/resume, and independent verification. Without that authorization it returns the four search/dispatcher tools, not all 209 contracts. - Exact discovery.
mcp_tools_searchreturns themessages_sendinput schema and namesmcp_tools_writeas the required dispatcher. - 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. - Validation. discord-mcp validates
channel_idas a Discord snowflake andcontentas a non-empty string of at most 2,000 characters. - Execution. The server applies its middleware and resilience policy, then sends an HTTP request to Discord’s create-message endpoint.
- 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.
Reuse structured output
Section titled “Reuse structured output”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.
Safety boundary
Section titled “Safety boundary”The strongest boundary is the bot’s Discord role. Give it access only to the servers, channels, and actions required by your workflows.
Common failures
Section titled “Common failures”| 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.
Connection track complete
Section titled “Connection track complete”- 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, andtimestampin the result. - I understand that
messages_sendwrites 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.

