Building the Catalog & Registry

Create an MCP App with json-render

Chapter 2 ยท Building the Catalog & Registry

๐Ÿ“บ Based on the LinkedIn Learning course "Create an MCP App with json-render" by instructor Eve Porcello, published 17 April 2026. View the original course โ†’

Chapter 1 covered the stack and the packages. This chapter builds the first two real, concrete pieces the whole project depends on: the catalog, which says what components exist, and the registry, which says how each one actually renders.

The Catalog: What the AI Model Is Allowed to Use

catalog/catalog.ts defines the full, allowed set of components an AI-generated spec is permitted to reference โ€” built directly from Shadcn's own component definitions. This is the real, concrete version of Chapter 1's own "constrained output" idea: the model isn't free to invent an arbitrary component name in its response, it can only choose from whatever this file actually lists.

export const catalog = { card: { /* Shadcn Card definition */ }, badge: { /* Shadcn Badge definition */ }, heading: { /* text-style definition */ }, text: { /* text-style definition */ }, stack: { /* layout definition */ }, };
Why This Is Its Own File
Keeping the catalog separate from both the schema (Chapter 1) and the registry (below) means the "what's allowed" list can be reviewed, extended, or trimmed on its own โ€” adding a new component to what the AI can reference is a one-file change, not a change scattered across the rendering logic too.

The Registry: Connecting Types to Real Implementations

registry/registry.tsx is where a component type named in the catalog (like "card" or "badge") gets connected to the actual, real React component that renders it on screen.

"use client"; import { Card, Badge } from "@/components/ui"; export const registry = { card: Card, badge: Badge, // ...every catalog entry needs a real implementation here };
The Real Requirement: "use client"
registry.tsx needs the "use client" directive at the top of the file, making it a real client component in Next.js's App Router. Server Components (Next.js's own default) can't hold live references to interactive React components the way the registry needs to โ€” the registry exists specifically to be handed real component references at render time, which is a client-side concern.

Catalog vs. Registry

CatalogRegistry
AnswersWhat component types exist / are allowed?How does each type actually render?
Consumed byThe AI model (indirectly, via the schema) and validationThe renderer, at the moment a spec is drawn to screen
Filecatalog/catalog.tsregistry/registry.tsx, requires "use client"

Hands-On Exercises

Exercise 1

A new component, "alert", is added to catalog.ts but the AI-generated spec that references it fails to render. Explain, in your own words, the most likely reason, based on this chapter's own catalog/registry distinction.

๐Ÿ“„ View solution
Exercise 2

Explain, in your own words, why registry.tsx needs the "use client" directive while catalog.ts does not.

๐Ÿ“„ View solution
Exercise 3

A teammate suggests merging the catalog and registry into a single file, "since they're always used together anyway." Explain, in your own words, what real flexibility this would give up.

๐Ÿ“„ View solution

Chapter 2 Quick Reference

  • Catalog (catalog/catalog.ts) โ€” the allowed set of components, built from Shadcn definitions
  • Registry (registry/registry.tsx) โ€” connects each catalog type to its real component implementation
  • The registry requires "use client" โ€” it holds live component references, a client-side concern in Next.js's App Router
  • Every catalog entry needs a matching registry entry, or a spec referencing it can't actually render