Template

3D carousel widget for MCP Apps

Present a few options as cards on a ring that turns in 3D. It pauses when the pointer is over it, and a click on any card asks the chat for more about that option.

Add a UI to your MCP server

Suggest a few getaways for the long weekend in November. Nothing more than a short flight away.

Used show_carousel_3d

The house design: black outline, butter yellow and a marker swipe under the title.

A carousel is for a short set of options that should feel like a showcase rather than a list. The motion draws the eye, and the click turns each card into the next question:

  • Travel ideas: destinations, hotels or routes, with the country as the tag.
  • Product shortlists: three to ten models the model narrowed down from a catalog.
  • Courses or workshops in a catalog, each card with its name and one line on who it is for.
  • People: speakers at an event, members of a team, candidates on a shortlist.
  • Places to eat or visit, as the answer to "where should we go?".

If the options need to be compared field by field, a table does that better. For one option that deserves all the attention, use the aurora card.

The schema asks for a title and between three and ten items. Fewer than three is not a ring and more than ten crowds it, so the limits keep the model from sending a list that would look broken. Each item needs a title; tag, subtitle and color are optional.

  • tag is the small label at the top of the card: a country, a category, a duration.
  • subtitle is one short line. The card has room for a phrase, not a paragraph.
  • color takes any CSS color and paints the card's cover. Leave it out and each card takes the next color of the design palette.

The tool description says to use it "to present options or a showcase in a striking way", so the model reaches for it when the user asks for ideas, not when they ask for a report.

What it does in the chat

The ring is pure CSS 3D: perspective, preserve-3d and one rotation, with no script and no library. Its radius is computed from the number of cards, so three cards and ten cards both make a closed ring with the front card at its real size. The back of each card shows a plain plate in its color, so the far side still reads as part of the ring. It turns once every 24 seconds, stops when the pointer is over it, and does not turn at all for people who prefer reduced motion.

Each card is a host action: it carries a data-wg-message, so clicking it posts a message to the chat asking for more about that item. The model then answers, or calls your tools for prices, availability or detail. Since everything is CSS and the covers are color blocks, the widget is self-contained and needs no CSP domains.

Make it yours

The ring looks different in every design: white cards and a quiet poster in Nordic, glass cards with a light pool under the ring in Aurora, flat saturated cards with a giant number in Brutalist, magazine covers in Editorial, glowing outlines over a grid horizon in Neon, and all the brand-inspired designs and your organization's own. The follow-up message comes in English and Spanish, following the language the host reports, and you can reword it in the markup. Want photos on the covers? Add an image field to the schema, an <img> in the markup and the photo's origin to the widget's image domains, so the host lets it load.

Take it to your server

Link the published carousel from your MCP server or download its HTML and manifest, as explained in add UI to your MCP server. The 3D globe is its WebGL sibling, for when the options are places on a map.

The data it takes

FieldTypeWhat it is
titlerequiredstring
itemsrequiredobject[]
└ tagstring
└ titlerequiredstring
└ subtitlestring
└ colorstringAny CSS color. Optional: without it the card takes the next palette color of the design.

Sample data

{
  "title": "Autumn getaways",
  "items": [
    {
      "tag": "Portugal",
      "title": "Lisbon",
      "subtitle": "3 nights, from Madrid"
    },
    {
      "tag": "Italy",
      "title": "Florence",
      "subtitle": "4 nights, art and markets"
    },
    {
      "tag": "Norway",
      "title": "Bergen",
      "subtitle": "Fjords and wooden houses"
    },
    {
      "tag": "Morocco",
      "title": "Marrakech",
      "subtitle": "A riad in the medina"
    },
    {
      "tag": "Iceland",
      "title": "Reykjavik",
      "subtitle": "Northern lights in November"
    }
  ]
}

The tool that shows it

A widget made from this template is shown by one tool. The model reads its description to decide when to call it and fills the input schema with the data. This is the definition Widgetry exports:

{
  "name": "show_carousel_3d",
  "title": "3D carousel",
  "description": "Shows a small set of items (products, plans, people, places) as cards on a rotating 3D ring. Each card has a tag, a title, a subtitle and an optional color; without one it takes the next color of the design palette. Use it to present options or a showcase in a striking way.",
  "inputSchema": {
    "type": "object",
    "required": [
      "title",
      "items"
    ],
    "properties": {
      "title": {
        "type": "string"
      },
      "items": {
        "type": "array",
        "minItems": 3,
        "maxItems": 10,
        "items": {
          "type": "object",
          "required": [
            "title"
          ],
          "properties": {
            "tag": {
              "type": "string"
            },
            "title": {
              "type": "string"
            },
            "subtitle": {
              "type": "string"
            },
            "color": {
              "type": "string",
              "description": "Any CSS color. Optional: without it the card takes the next palette color of the design."
            }
          }
        }
      }
    }
  }
}

Your first widget, in the chat in minutes

Pick a template, drop in your data and see it as ChatGPT or Claude will show it. Then link it from your MCP server, or let your agent build the next one.