Components V2
Discord’s Components V2 combines layout, content, accessory, and interactive component types for richer message UI. discord-mcp wraps it in 8 tools, a schema validator, a client-side preview renderer, and 5 templates for common shapes. This page explains how those pieces fit.
The component types
Section titled “The component types”discord-mcp supports these roles and placements:
| Role | Supported types | Placement contract |
|---|---|---|
| Layout | Container, Section | A Container holds up to 10 supported children and cannot nest another Container. A Section holds 1–3 TextDisplays plus one Button or Thumbnail accessory. |
| Content | TextDisplay, MediaGallery, Separator | TextDisplay, gallery, and separator nodes can appear at the message root or inside a Container. |
| Interactive | ActionRow, Button, string/user/role/mentionable/channel selects | A root or Container ActionRow holds either 1–5 Buttons or exactly one select. A Button can also be a Section accessory. |
| Accessory | Thumbnail, Button | Thumbnail is valid only as a Section accessory; Button style and credential fields must agree. |
File components require a matching uploaded attachment. The current
components_v2_send and components_v2_edit inputs do not accept attachment
uploads, so the validator rejects File nodes instead of publishing a payload
Discord cannot resolve.
The 8 tools
Section titled “The 8 tools”| Tool | Idempotent | What it does |
|---|---|---|
components_v2_build_container | yes | Build a Container scaffold. |
components_v2_build_section | yes | Build a Section scaffold with its required accessory. |
components_v2_build_media_gallery | yes | Build a MediaGallery from URLs. |
components_v2_validate | yes | Run the schema validator against a built tree. |
components_v2_preview | yes | Render a client-side text preview of the tree. |
components_v2_send | no | Send a message with a V2 component tree. |
components_v2_edit | no | Edit an existing message’s V2 component tree (destructiveHint: false). |
components_v2_send_from_template | no | Send from one of 5 pre-built templates. |
There is no build_action_row tool. ActionRow nodes are passed
in hand-written, as entries in the components array of
components_v2_build_container (or of components_v2_send directly) - they
have no dedicated builder.
The build_* tools are pure construction helpers - they don’t hit Discord;
and produce JSON the agent can stitch together. A builder is not a substitute
for validating the final composed tree: build_container accepts unknown child
values, so invalid combinations can still be assembled. validate
and preview are also Discord-free. Three tools make REST calls: send and
send_from_template (POST /channels/:id/messages) and edit
(PATCH /channels/:id/messages/:id).
See components-v2-announcement recipe
for an end-to-end example.
The validator
Section titled “The validator”Source: tools/components-v2/_lib/validator.ts
Enforces Discord’s V2 constraints before sending, so the agent sees a
clear VALIDATION_FAILED error rather than Discord’s terse 400 response:
- Max 40 components recursively in a single message tree; each Container can have at most 10 direct children.
- Container ⊂ Section / MediaGallery / ActionRow - Containers cannot contain Containers.
- ActionRow ⊂ Button / SelectMenu - only interactive children allowed.
- ActionRow cardinality - one to five Buttons, or exactly one select; no button/select mixing.
- Button style contracts - styles 1–4 require
custom_id, style 5 requiresurl, and premium style 6 requires onlysku_idplus optionaldisabled. - Top-level placement - Button, select, and Thumbnail nodes must use their permitted ActionRow or Section parent.
- Interaction identity - every
custom_idis unique across the complete message tree. - MediaGallery items: 1–10 entries, each with a URL.
- Required fields: every Container needs at least one child; every Section needs one to three TextDisplay children and a Button or Thumbnail accessory.
Failure shape: ValidationError with an issues array, each entry pointing
to the JSON path where the violation occurred (for example,
components[0].components[3] for a nested issue).
The schema
Section titled “The schema”Source: tools/components-v2/_lib/schema.ts
A single Zod tree describes the V2 model, and the validator adds recursive
domain checks with precise paths. Always call components_v2_validate after
assembling multiple builder results and before sending.
The preview
Section titled “The preview”Source: tools/components-v2/_lib/preview.ts
Renders a text-only approximation of how the tree will look when Discord
displays it: container borders as box-drawing characters, sections as
indented blocks, action rows as [Button] [Select▼] stubs. Useful for the
agent to sanity-check the layout before spending a send call.
components_v2_send_from_template does not return a preview. Its structured
result contains message_id, channel_id, jump_url, and template; use
components_v2_preview separately when a human needs to inspect a custom tree.
The templates
Section titled “The templates”discord-mcp ships 5 pre-built templates as MCP resources, addressable
under discord://components-v2/templates/{name}:
| Template | Use case |
|---|---|
announcement | Announcement layout with interpolated title and body. |
incident_status | Operational incident and status update. |
poll_results | Poll outcome summary. |
release_notes | Release summary and highlights. |
welcome_card | Welcome message for a member or community. |
Each template accepts variables (e.g. {{title}}, {{accent_color}})
interpolated at send time via
tools/components-v2/_lib/interpolate.ts.
components_v2_send_from_template accepts a template name + a vars object
and emits the fully-resolved tree.
The flags = 32768 contract
Section titled “The flags = 32768 contract”The flag is a one-way switch per message: V2 mode disables content,
embeds, and stickers in the same message. A V2 send is therefore
mutually exclusive with the legacy embed path.
Source map
Section titled “Source map”| Concern | File |
|---|---|
| Type definitions | _lib/schema.ts |
| Validation | _lib/validator.ts |
| Preview rendering | _lib/preview.ts |
| Variable interpolation | _lib/interpolate.ts |
| 8 tool definitions | tools/components-v2/ |
Related
Section titled “Related”components-v2-announcementrecipe - full end-to-end build + validate + send.- Architecture → Pipeline - chain a V2 send with later role and event calls in one sequential request.
- Architecture → Confirmation - note that
components_v2_send/_edit/_send_from_templateare not confirm-gated: they write to the channel on the first call, with no__confirmand regardless ofMCP_DRY_RUN.