Skip to content

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.

discord-mcp supports these roles and placements:

RoleSupported typesPlacement contract
LayoutContainer, SectionA Container holds up to 10 supported children and cannot nest another Container. A Section holds 1–3 TextDisplays plus one Button or Thumbnail accessory.
ContentTextDisplay, MediaGallery, SeparatorTextDisplay, gallery, and separator nodes can appear at the message root or inside a Container.
InteractiveActionRow, Button, string/user/role/mentionable/channel selectsA root or Container ActionRow holds either 1–5 Buttons or exactly one select. A Button can also be a Section accessory.
AccessoryThumbnail, ButtonThumbnail 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.

ToolIdempotentWhat it does
components_v2_build_containeryesBuild a Container scaffold.
components_v2_build_sectionyesBuild a Section scaffold with its required accessory.
components_v2_build_media_galleryyesBuild a MediaGallery from URLs.
components_v2_validateyesRun the schema validator against a built tree.
components_v2_previewyesRender a client-side text preview of the tree.
components_v2_sendnoSend a message with a V2 component tree.
components_v2_editnoEdit an existing message’s V2 component tree (destructiveHint: false).
components_v2_send_from_templatenoSend 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.

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 requires url, and premium style 6 requires only sku_id plus optional disabled.
  • Top-level placement - Button, select, and Thumbnail nodes must use their permitted ActionRow or Section parent.
  • Interaction identity - every custom_id is 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).

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.

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.

discord-mcp ships 5 pre-built templates as MCP resources, addressable under discord://components-v2/templates/{name}:

TemplateUse case
announcementAnnouncement layout with interpolated title and body.
incident_statusOperational incident and status update.
poll_resultsPoll outcome summary.
release_notesRelease summary and highlights.
welcome_cardWelcome 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 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.

ConcernFile
Type definitions_lib/schema.ts
Validation_lib/validator.ts
Preview rendering_lib/preview.ts
Variable interpolation_lib/interpolate.ts
8 tool definitionstools/components-v2/