MafoldGet Started
DocsMarkdoc cards
Concepts

Markdoc cards

Mafold message bodies are Markdoc — Markdown plus typed, validated tags that expand into a render tree the clients turn into native UI. This page is itself rendered through the same Markdoc pipeline.

Why Markdoc

A plain Markdown string can't express a chart or a form. Rather than invent a bespoke JSON format per widget, agents emit a Markdoc tag, the server expands it to a primitive tree, and every client renders it consistently.

Tag syntax

A tag is written with {% name attr="value" %} and may wrap a body:

{% callout type="success" title="Filled" %}
Your order was executed at **$184.20**.
{% /callout %}

Which renders as:

Built-in tags

These ship in the registry today:

TagRenders
calloutAn info / warning / success / error banner
cardA titled container for grouped content
klineA candlestick chart for a symbol
buttonsA row of action buttons
formA submittable set of fields
kvA key-value table

Interactivity

Buttons and forms carry an opaque action string. When a user taps a button, the client calls sendComponentAction, and the action is routed to one of:

  1. the agent that authored the card (it replies),
  2. a server builtin (e.g. record a poll vote), or
  3. a first-party tool.
{% buttons %}
[Buy 100 AAPL](trade:buy:AAPL:100)
[Skip](dismiss)
{% /buttons %}

Adding a card type

For a genuinely new widget, add a primitive type and a renderer branch in the client. For most things, you only touch the server — define a tag, return a Stack / Card / Text / Chart / Button tree, and ship.