Build a rich announcement
This workflow posts a structured announcement with a header thumbnail and image gallery. Each
builder returns { component }; unwrap that field before passing the node to the next builder.
-
Build a section with its required accessory.
textis an array of one to three Markdown strings. Component type identifiers are numeric.{"name": "components_v2_build_section","arguments": {"text": ["# discord-mcp release","A typed Discord toolset for MCP clients."],"accessory": {"type": 11,"media": { "url": "https://example.com/hero.png" },"description": "Release artwork"}}}{"component": {"type": 9,"components": [{ "type": 10, "content": "# discord-mcp release" },{ "type": 10, "content": "A typed Discord toolset for MCP clients." }],"accessory": {"type": 11,"media": { "url": "https://example.com/hero.png" },"description": "Release artwork"}}} -
Build the media gallery.
Builder inputs use a top-level
url. The builder converts it to Discord’s nestedmedia.urloutput shape.{"name": "components_v2_build_media_gallery","arguments": {"items": [{ "url": "https://example.com/tool-catalog.png", "description": "Tool catalog" },{ "url": "https://example.com/telemetry.png", "description": "Telemetry view" }]}}{"component": {"type": 12,"items": [{ "media": { "url": "https://example.com/tool-catalog.png" }, "description": "Tool catalog" },{ "media": { "url": "https://example.com/telemetry.png" }, "description": "Telemetry view" }]}} -
Wrap both returned components in a container.
Pass
sectionResult.componentandgalleryResult.component, not the wrapper objects.{"name": "components_v2_build_container","arguments": {"components": [{"type": 9,"components": [{ "type": 10, "content": "# discord-mcp release" },{ "type": 10, "content": "A typed Discord toolset for MCP clients." }],"accessory": {"type": 11,"media": { "url": "https://example.com/hero.png" },"description": "Release artwork"}},{"type": 12,"items": [{ "media": { "url": "https://example.com/tool-catalog.png" }, "description": "Tool catalog" },{ "media": { "url": "https://example.com/telemetry.png" }, "description": "Telemetry view" }]}],"accent_color": 5793266}}The result is
{ "component": { "type": 17, ... } }. -
Validate the final top-level array.
{"name": "components_v2_validate","arguments": {"components": [{"type": 17,"components": [{"type": 9,"components": [{ "type": 10, "content": "# discord-mcp release" },{ "type": 10, "content": "A typed Discord toolset for MCP clients." }],"accessory": {"type": 11,"media": { "url": "https://example.com/hero.png" },"description": "Release artwork"}},{"type": 12,"items": [{ "media": { "url": "https://example.com/tool-catalog.png" }, "description": "Tool catalog" },{ "media": { "url": "https://example.com/telemetry.png" }, "description": "Telemetry view" }]}],"accent_color": 5793266}]}}Success is exactly
{ "valid": true, "issues": [] }. There is nocomponent_countin the validator result. -
Send the same validated array.
Use the exact
componentsarray from validation and add the target channel ID:{"name": "components_v2_send","arguments": {"channel_id": "222233334444555566","components": [{"type": 17,"components": [{"type": 9,"components": [{ "type": 10, "content": "# discord-mcp release" },{ "type": 10, "content": "A typed Discord toolset for MCP clients." }],"accessory": {"type": 11,"media": { "url": "https://example.com/hero.png" },"description": "Release artwork"}},{"type": 12,"items": [{ "media": { "url": "https://example.com/tool-catalog.png" }, "description": "Tool catalog" },{ "media": { "url": "https://example.com/telemetry.png" }, "description": "Telemetry view" }]}],"accent_color": 5793266}]}}The result contains
message_id,channel_id,jump_url, andcomponent_count: 1because there is one top-level container.
Why the builder sequence matters
Section titled “Why the builder sequence matters”- Each builder is read-only and can be rerun safely.
- Wrapper objects are never valid component nodes; always pass their
componentvalue. - Offline validation returns precise issue paths without consuming a Discord request.
- The final send automatically sets the Components V2 message flag.
See the exact components_v2 tool category,
the components_v2_send reference, or the
Components V2 architecture.