Skip to content

Dynamic Cards

Dynamic Cards

The Matter assistant composes UI cards on the fly — one per conversation moment, never templates. Cards are a recursive tree of in-library primitives, validated by Zod, streamed via the AI SDK, and rendered by a single <DynamicCard> component.

116
31 create71 manage14 exit

How it works

Three artifacts are the entire surface:

  1. Primitives — every Card, Pill, Stat, Progress, Button, … registered in @matter/components/cards. One file per primitive: schema + few-shot + render fn.
  2. SchemaCardZ is built at module load from the registry. Adding a primitive is one file; the schema, the AI prompt, and the renderer all update.
  3. Gallery — the exemplar collection on this site doubles as the AI's few-shot pool. If you can't express a card cleanly with existing primitives, the build fails until a new primitive lands.

Phases

Browse the gallery by lifecycle phase:

  • Create — bring an entity into existence
  • Manage — operate the live entity
  • Exit — wind it down

Action contract

Every button in a card carries one CardAction. The action is the typed bridge between the rendered UI and the Matter API surface:

{ "kind": "navigate",      "to": "/equity/grants/grt_…" }
{ "kind": "open_resource", "resource_id": "doc_…" }
{ "kind": "approve",       "resource_id": "grt_…" }
{ "kind": "tool_call",     "tool": "matter_…", "payload": { } }
{ "kind": "regenerate",    "hint": "make the grant 40,000 shares" }
{ "kind": "dismiss" }

tool_call.tool resolves against the generated MCP catalog at apps/mcp/src/tools/generated.ts — a card click and an agent-driven MCP call go through the same dispatcher.

Forward-compat

Unknown primitive names, unknown action kinds, unknown schema_version values all degrade to a labeled fallback card. The renderer never throws — failed parses surface in telemetry, not in user-facing crashes.

On this page