Specs, the API Route & the Dashboard Builder
Create an MCP App with json-render
Chapter 3 ยท Specs, the API Route & the Dashboard Builder
Chapter 2 built the catalog (what's allowed) and the registry (how each thing renders). This chapter connects them into a real, working feature โ a spec, an API route that generates one from a prompt, and a component that streams the result to the screen.
The Dashboard Spec
specs/dashboard.ts is a real, concrete example of the JSON structure this whole pipeline produces โ a plain object describing which components render and with what props, built entirely from Chapter 2's own catalog entries.
The root is a card; its children are a stack layout, itself containing a heading, a badge, and a text element โ every one of those type names has to exist in the catalog and have a real registry entry, or Chapter 2's own rendering chain breaks at that node.
The API Route: Generating a Spec From a Prompt
app/api/generate/route.ts is the real endpoint that takes a user's prompt and streams an AI-generated spec back to the UI, using streamText from the Vercel AI SDK with Claude Haiku 4.5 as the model.
The Dashboard Builder Component
components/generated/dashboard-builder.tsx is the real, user-facing piece: a form collects the user's prompt, and the response streams back via a useUIStream hook.
Form
User types a prompt
useUIStream
Streams the API route's response
Renderer
Draws the streamed spec, via Chapter 2's registry
Fallback
Shows the static dashboardSpec while loading
dashboardSpec from earlier in this chapter instead of a blank screen โ a real, deliberate UX choice: showing something immediately, then replacing it once the genuinely AI-generated version has finished streaming in.
Hands-On Exercises
The API route's system rules are removed entirely, leaving only the raw user prompt. Explain, in your own words, the most likely real consequence, connecting your answer back to Chapter 2's own catalog/registry material.
๐ View solutionExplain, in your own words, what a user would actually see, moment by moment, from the instant they submit a prompt in the Dashboard Builder to the instant the AI-generated spec finishes streaming in.
๐ View solutionA teammate suggests removing the static dashboardSpec fallback entirely, showing a blank screen while the real spec streams in, "to simplify the component." Explain, in your own words, the real UX tradeoff this would introduce.
Chapter 3 Quick Reference
- Dashboard spec: card root โ stack layout โ heading, badge, text โ every type must exist in the catalog and registry
- API route (
app/api/generate/route.ts):streamText+ Claude Haiku 4.5, with real system rules steering the model toward the catalog's own constraints - Dashboard Builder: form โ
useUIStreamโ renderer, with a static fallback shown while the real spec streams in