Build beautiful MCP App experiences with mcpcn
Create beautiful chat experiences with our comprehensive component library designed for agentic applications.
Installation
$ pnpm dlx shadcn@latest add @mcpcn/hero
Usage
import {
Hero,
HeroActions,
HeroContent,
HeroDescription,
HeroLogos,
HeroTechLogos,
HeroTitle,
} from "@/components/ui/hero";<Hero>
<HeroContent>
<HeroLogos />
<HeroTitle />
<HeroDescription />
<HeroActions />
<HeroTechLogos />
</HeroContent>
</Hero>Composition
Use the following composition to build an Hero:
Hero
├── HeroActions
├── HeroContent
├── HeroDescription
├── HeroLogos
├── HeroTechLogos
└── HeroTitleExamples
Two Logos
Acme × mcpcn
Combining the best of both worlds to deliver exceptional user experiences.
"use client";
import {
Hero,
HeroActions,
HeroContent,
HeroDescription,
HeroLogos,
HeroTitle,
} from "@/components/ui/hero";
export function HeroTwoLogosDemo() {
return (
<Hero
data={{
logo1: { text: "Acme" },
logo2: { text: "mcpcn" },
logoSeparator: "×",
primaryButton: { label: "Get Started" },
secondaryButton: { label: "GitHub" },
subtitle:
"Combining the best of both worlds to deliver exceptional user experiences.",
title: "Acme × mcpcn",
}}
>
<HeroContent>
<HeroLogos />
<HeroTitle />
<HeroDescription />
<HeroActions />
</HeroContent>
</Hero>
);
}With Tech Logos
Build your next project with Acme
Create beautiful experiences with our comprehensive platform designed for modern applications.
Built with open-source technologies
"use client";
import {
Hero,
HeroActions,
HeroContent,
HeroDescription,
HeroLogos,
HeroTechLogos,
HeroTitle,
} from "@/components/ui/hero";
export function HeroTechLogosDemo() {
return (
<Hero
data={{
logo1: { text: "Acme" },
primaryButton: { label: "Get Started" },
secondaryButton: { label: "GitHub" },
subtitle:
"Create beautiful experiences with our comprehensive platform designed for modern applications.",
techLogos: [
{
alt: "Next.js",
name: "Next.js",
url: "https://cdn.jsdelivr.net/gh/devicons/devicon/icons/nextjs/nextjs-original.svg",
},
{
alt: "TypeScript",
name: "TypeScript",
url: "https://cdn.jsdelivr.net/gh/devicons/devicon/icons/typescript/typescript-original.svg",
},
{
alt: "React",
name: "React",
url: "https://cdn.jsdelivr.net/gh/devicons/devicon/icons/react/react-original.svg",
},
{
alt: "Tailwind CSS",
name: "Tailwind CSS",
url: "https://cdn.jsdelivr.net/gh/devicons/devicon/icons/tailwindcss/tailwindcss-original.svg",
},
],
techLogosLabel: "Built with open-source technologies",
title: "Build your next project with Acme",
}}
>
<HeroContent>
<HeroLogos />
<HeroTitle />
<HeroDescription />
<HeroActions />
<HeroTechLogos />
</HeroContent>
</Hero>
);
}Minimal
Welcome to the Future
A simple, clean hero without logos or extra elements.
"use client";
import {
Hero,
HeroActions,
HeroContent,
HeroDescription,
HeroTitle,
} from "@/components/ui/hero";
export function HeroMinimalDemo() {
return (
<Hero
data={{
primaryButton: { label: "Get Started" },
subtitle: "A simple, clean hero without logos or extra elements.",
title: "Welcome to the Future",
}}
>
<HeroContent>
<HeroTitle />
<HeroDescription />
<HeroActions />
</HeroContent>
</Hero>
);
}OpenUI Integration
Install the OpenUI React packages.
pnpm add @openuidev/react-lang zodAdd Hero to a component library and map it to the installed component.
import { createLibrary, defineComponent } from "@openuidev/react-lang";
import { z } from "zod/v4";
import {
Hero,
HeroActions,
HeroContent,
HeroDescription,
HeroLogos,
HeroTechLogos,
HeroTitle,
} from "@/components/ui/hero";
const OpenUIHero = defineComponent({
name: "Hero",
description:
"Landing hero section with optional logos, title, subtitle, CTA buttons, and tech logos footer. Supports image or text logos with separator.",
props: z.object({}),
component: () => (
<Hero>
<HeroContent>
<HeroLogos />
<HeroTitle />
<HeroDescription />
<HeroActions />
<HeroTechLogos />
</HeroContent>
</Hero>
),
});
export const heroLibrary = createLibrary({
root: "Hero",
components: [OpenUIHero],
});For richer generated compositions, define the child primitives separately and connect them with .ref fields. See Defining Components in the OpenUI documentation.
json-render Integration
Install the json-render React packages.
pnpm add @json-render/core @json-render/react zodAdd Hero to a component catalog and map it to the installed component.
import { defineCatalog } from "@json-render/core";
import { defineRegistry } from "@json-render/react";
import { schema } from "@json-render/react/schema";
import { z } from "zod";
import {
Hero,
HeroActions,
HeroContent,
HeroDescription,
HeroLogos,
HeroTechLogos,
HeroTitle,
} from "@/components/ui/hero";
export const catalog = defineCatalog(schema, {
components: {
Hero: {
props: z.object({}),
description:
"Landing hero section with optional logos, title, subtitle, CTA buttons, and tech logos footer. Supports image or text logos with separator.",
},
},
});
export const { registry } = defineRegistry(catalog, {
components: {
Hero: () => (
<Hero>
<HeroContent>
<HeroLogos />
<HeroTitle />
<HeroDescription />
<HeroActions />
<HeroTechLogos />
</HeroContent>
</Hero>
),
},
});Use catalog.prompt() to constrain model output, then render the generated spec with the json-render React Renderer. See the json-render Quick Start for the provider and streaming setup.
API Reference
See the Base UI documentation for more information.