ToolCard is built on shadcn/ui Card sub-components. While ToolCard covers the standard use case — logo, name, description, fields list, actions, and footer — understanding the underlying primitives lets you build custom tool UI layouts that follow the same visual language without being constrained by the default structure.
The Card primitives (
Card, CardHeader, CardTitle, CardDescription, CardAction, CardContent, CardFooter) are used internally by ToolCard but are not re-exported from ai-tool-elements. The public API surface of the package is ToolCard, ToolCardProps, toolCatalog, and the TypeScript types (Tool, ToolCatalogItem, ToolField, ToolImage). If you need the Card primitives directly, install shadcn/ui and add the Card component to your project.Available primitives
These are the seven sub-components that make up the shadcn/ui Card used insideToolCard:
Installing shadcn/ui Card
To use these primitives in your own components, add the shadcn/ui Card to your project:components/ui/card.tsx, where you can modify it freely. See the shadcn/ui Card documentation for the full installation guide.
How ToolCard uses the primitives
The structureToolCard builds from these primitives is straightforward. Here is the rendered tree, condensed for clarity:
CardDescription, CardAction, CardContent, and CardFooter are all conditionally rendered: CardDescription only when tool.description is set; CardAction only when actions is provided; CardContent only when tool.fields has at least one entry; CardFooter only when footer is provided.
Customizing with className
BecauseToolCard spreads all extra props onto the underlying Card div, you can pass a className to override or extend any of its default styles without touching the primitives directly:
cn) inside the Card component ensures your class additions compose correctly with the defaults.
Using shadcn/ui Card directly
For fully custom layouts that go beyond whatToolCard provides, use the shadcn/ui Card primitives directly after installing them. The same sub-component structure applies: