Result cards
Let an MCP server or local connector tool return a card with a title, a few details, an image and up to two buttons, shown right in the conversation.
A tool on an MCP server or a local connector can attach one card to its result. The assistant still reads the result's text to answer, and the user sees the card under the tool step: an order with its status, total and a tracking button, for example.
What the user sees
| Where | Shown as |
|---|---|
| Web App | The full card: icon, title, subtitle, text, detail rows, image and buttons |
| Web widget | The full card, as in the Web App |
| Messaging channels | The card's fallback text, with link buttons as Label: URL, sent after the reply |
| Voice | The assistant speaks the result; the card still appears in the chat history |
| Developer API | The card is passed as-is in the tool_end event for your app to render |
A link button opens the page in a new tab. A message button sends a prepared sentence as the user's next message, such as "Cancel order 1042", for the assistant to handle. When a card is shown, the assistant is told not to repeat its contents in the reply.
Declare a card
Add _meta.assistant_platform.card to the tools/call result:
{
"content": [{ "type": "text", "text": "Order 1042 has been handed to the carrier and should arrive Friday." }],
"_meta": {
"assistant_platform": {
"card": {
"v": 1,
"title": "Order #1042",
"subtitle": "Shipped",
"text": "Arrives Friday.",
"icon_url": "https://shop.example.com/icon.png",
"image_url": "https://shop.example.com/o/1042.jpg",
"fields": [
{ "label": "Total", "value": "1,250,000 ₫" },
{ "label": "Carrier", "value": "GHN" }
],
"actions": [
{ "kind": "url", "label": "Track", "url": "https://shop.example.com/o/1042" },
{ "kind": "message", "label": "Cancel", "text": "Cancel order 1042" }
],
"fallback_text": "Order #1042 shipped, arrives Friday. Total 1,250,000 ₫."
}
}
}
}| Field | Required | Limit |
|---|---|---|
v | No | Card version, currently 1 |
title | Yes | 80 characters |
subtitle | No | 160 characters |
text | No | 300 characters, line breaks kept |
icon_url, image_url | No | https URLs |
fields | No | Up to 4 rows; label 40 characters, value 120 characters |
actions | No | Up to 2 buttons; label 30 characters. kind is url with a url, or message with a text (200 characters) |
fallback_text | Yes | 500 characters, line breaks kept. Shown where the card cannot be drawn |
Every field is plain text, with no Markdown or HTML. The first button is the primary one. Unknown fields are ignored, so an older card still shows once newer versions exist.
When a card is invalid
A card over a limit, without fallback_text or with a URL that is not https is dropped entirely, while the result's text still reaches the assistant, so the reply is unaffected. A card needs no re-approval when it changes: it is part of the result, not of the tool definition.
Keep one card to one thing: an order, an appointment, a result. For several items, let the assistant answer in text and return a card only for the item the user asked about.
Last updated on
Connect local tools with a local connector
Connect MCP servers on your own computer or private network through a connector that dials out, with no public URL or open port.
Device tools
How an ESP32 device offers its own tools, such as volume, screen brightness or a camera, to the assistant during a voice session.