Eliminate broken design exports. Build a React Tailwind dashboard using Paper canvas and Claude Code via MCP. A true bidirectional workflow.
I'm going to build an AI Skills Explorer dashboard using Paper's code-native canvas, then connect it to Claude Code via MCP to generate a working React and Tailwind project. This will help me understand how design-to-code workflows can become truly bidirectional, eliminating the broken export step that loses data. I'm interested in this because I've wasted hours fixing lost styles and broken layouts between design tools and development. I want to see if this real-time connection actually delivers on its promise. I'll also push Claude to critique my work directly on the canvas, which feels like having a senior designer looking over my shoulder. That secret mission excites me most because I want honest feedback, not just code generation.
The key tools I used include Paper Desktop for code-native design, Claude Code with MCP plugin for bidirectional communication, the MCP server running locally on port 29979, and React with Tailwind for code generation. I also used Paper's MCP tools like set_text_content, write_html, and get_jsx to read and modify the canvas programmatically.
Key concepts I learnt include designing with flex layouts instead of absolute positioning so AI agents can parse structure cleanly, the difference between DOM-native design versus proprietary vector formats, and how MCP enables real-time design-to-code workflows without export steps. I also learned how to prompt Claude as a design critic, not just an executor, and how to evaluate AI-generated changes against my own design judgment rather than accepting everything blindly.
This project took me approximately 2.5 hours from installation to running the generated React site. The installation and MCP setup took about 30 minutes, building the flex layout manually took around 40 minutes, populating data with Claude took 20 minutes, generating the React project took another 25 minutes, and the secret mission critique and iteration added about 35 minutes including reviewing each change and pushing back on a few.
The most challenging part was definitely getting the MCP connection to stay stable, I had to restart Claude Code twice before /mcp showed the Paper server. Also, trusting Claude to critique my design without adding new sections required explicit prompting and one follow-up correction. The layout polish with real data was trickier than I expected too, because salary ranges and tool descriptions varied so much in length that my original card sizes felt off and I had to adjust gaps and font sizes to restore balance.
In this step, I'm going to download Paper Desktop and create my AI Skills Explorer file. I'll explore the canvas to see how each element's properties panel maps directly to CSS like flexbox, padding, and colors. Paper is different because it doesn't export static images or lossy code snippets. Instead, every frame and card I place is actual HTML/CSS living on the canvas. That means my design isn't just a visual mockup, it's already structured like a real webpage. I want to feel this difference firsthand, so I'll resize boxes, tweak margins, and watch the properties update in real time. This foundation will make the MCP connection with Claude Code actually meaningful later.
The browser version is missing the local MCP server that Claude Code needs to talk directly to my canvas. Paper Desktop matters because it runs that server on my machine, which means Claude can read every element's CSS properties and even modify them in real time. Without that, I'd be stuck exporting designs and losing data, exactly what I want to avoid. So I'm downloading the installer from paper.design/downloads, signing up for a free account, and checking that I have version 0.1 or later. I'll verify from the menu bar under Paper → About Paper. This local connection is what makes the whole bidirectional workflow possible, not just a one-way export.
Paper's layout properties map directly to CSS names like flex-direction, padding, gap, and background-color. When I adjust the gap between rectangles, I'm literally changing the CSS gap property on a real DOM node. This is different from Figma because Figma stores proprietary vector data that requires translation layers and often loses fidelity. Paper stores actual HTML elements with inline styles, so what I see in the properties panel is exactly what I'd write in a style tag. I tested this by adding a frame, turning on flex with Shift+A, and watching the gap and padding controls update the canvas in real time. No export, no conversion, just code-native design from the start.
In this step, I'm going to install Paper's MCP plugin inside Claude Code so my terminal can talk directly to my canvas. MCP lets Claude Code read every element's CSS properties and even write new ones in real time, no export step needed. I'll verify the connection by asking Claude to create a simple element on my canvas, proving the bidirectional link works. This is the core of the whole project, without this, I'd just have a static design file. I need to make sure Paper Desktop is running with my AI Skills Explorer file open, then install the plugin, check that Claude sees the MCP server at http://127.0.0.1:29979/mcp, and run a test prompt to confirm it's alive.
The marketplace command registers Paper's plugin repository with Claude Code, essentially telling it where to find the plugin. The install command actually downloads and enables the Paper Desktop plugin in my current session. I needed both because the marketplace is just a pointer, like adding a source in a package manager, while the install is what wires up the actual functionality. Without the marketplace, Claude wouldn't know where to look. Without the install, I'd have nothing to use. Running these in my project folder ensures the connection is scoped correctly for this AI Skills Explorer build.
Claude Code wrote a real DOM node because it inserted a
In this step, I'm going to build the dashboard layout manually using empty flex containers as the structural skeleton. Flex layouts matter because they give Claude Code clean, predictable HTML nesting that translates directly to React components later. I'll create a main artboard, add a header section, then build three skill category cards in a horizontal row using flex direction row and gap. I'll duplicate that pattern for the Trending AI Tools section. This structure is what Claude will read to populate real data and generate production code. No absolute positioning, just clean flex containers with real CSS properties.
I used a flex column for the main artboard and flex rows for the card containers because this gives Claude Code clear parent-child relationships to parse. Every card sits inside a row frame, and that row sits inside the main column, so the agent can infer that cards are siblings and rows are sequential sections. Absolute positioning would flatten everything into x/y coordinates with no structural meaning, forcing Claude to guess which elements belong together or how they should stack responsively. That guesswork breaks the code generation pipeline.
Duplicating kept padding, border radius, gap, background color, and flex settings perfectly consistent across all cards without me manually re-entering each property three times. It also ensures that when Claude later reads the canvas, every card shares identical CSS values, making it easy to generate a single reusable React component. Placeholder text is fine for now because Claude will query real AI trend data using its web search capability and write that content directly onto each card's text nodes in the next step.
My layout has three sections stacked vertically inside a 1512x982 artboard with a #F3F4F6 background. At the top, a header frame wraps "AI Skills Explorer 2026" in 32px bold text. Below that, a row frame with gap 16px contains three white cards, each with 16px padding and 24px border radius. Below that, "Trending AI Tools" in 24px bold sits above another row with four smaller cards. Every frame is live HTML because I set real CSS properties like flex-direction, padding: 16px, gap: 24px, and background-color: #FFFFFF on actual DOM nodes that render in my browser window, not abstract vector shapes.
In this step, I'm going to hand control over to Claude Code so it can read my empty dashboard layout through MCP, research real AI trends using its built-in knowledge, and write live data directly onto my Paper canvas. Claude Code will update the canvas by using tools like set_text_content to replace placeholder text on each card and write_html to add richer formatted content where needed. I won't copy-paste anything or type manually, Claude will populate skill names, demand scores, salary ranges, and tool descriptions straight from its research. This is where the design stops being a skeleton and becomes a real, data-driven dashboard.
Claude Code used set_text_content to target each card's text nodes directly through Paper's MCP tools, writing real skill names, demand indicators, and salary ranges onto the live DOM. No export step was needed because Paper's canvas is already a browser-rendered HTML tree, so Claude could read my layout structure, identify empty placeholder frames, and push updates straight to those elements in real time. The connection is bidirectional, so Claude didn't need to generate a separate file or wait for me to copy anything, it just wrote data onto the canvas like editing a webpage with developer tools.
Real data changed the layout because variable text lengths for skill names, salary ranges, and tool descriptions caused uneven card heights, awkward line breaks, and cramped padding. My empty placeholders were all uniform, but "Senior AI Prompt Engineer" takes up more space than "ML Engineer", and "150k–220k" is wider than "120k–160k". I adjusted the card widths, increased gap between elements, and reduced font sizes slightly so everything fits cleanly without overflow. I also asked Claude to equalize card heights using a flex alignment fix. Now the layout looks intentional, not like data was just dumped in.
In this step, I'm going to select my entire artboard in Paper and ask Claude Code to generate a fully working React + Tailwind project from that live DOM structure. Claude will read every frame, text node, flex property, padding, gap, and color through MCP, then scaffold a complete project folder with components, styling, and data hardcoded into the JSX. I'll then run the dev server and view the generated site in my browser to compare it side by side with my Paper design. React and Tailwind are the recommended stack because React gives me component-based architecture that matches Paper's nested frames, and Tailwind maps directly to the CSS properties Claude already sees on the canvas, making the translation almost one-to-one without losing fidelity.
Paper's docs recommend React and Tailwind because the get_jsx MCP tool can directly output your design's DOM structure as JSX with Tailwind utility classes, eliminating any manual translation step. React's component model maps perfectly to Paper's nested frame hierarchy, so each frame becomes a component and each child becomes nested JSX. Tailwind's utility-first approach matches Paper's property panel one-to-one: padding: 16px becomes p-4, gap: 16px becomes gap-4, and background-color: #FFFFFF becomes bg-white. This means Claude doesn't have to guess or reinterpret my design, it just reads the CSS values and writes the corresponding Tailwind classes, keeping the output pixel-perfect with minimal effort.
Paper's flex-direction: column became flex-col, padding: 16px became p-4, gap: 16px became gap-4, and border-radius: 24px became rounded-2xl in the generated Tailwind code. The #F3F4F6 background on the main artboard turned into bg-gray-100, and each card's white fill became bg-white. The text size 32px bold mapped to text-3xl font-bold, while 24px bold became text-2xl font-bold. Even the Fill container width setting translated to w-full on the row frames. Every CSS property I set visually in Paper's properties panel was read by Claude through MCP and written directly as a Tailwind utility class, so the browser output matches my canvas almost pixel for pixel without any manual conversion.
In this project extension, I'm going to hand Claude Code my finished AI Skills Explorer dashboard and ask it to act as a senior product designer. Instead of me telling it what to build, I'll prompt it to critique my layout, spacing, typography, and visual hierarchy, then watch it modify existing elements directly on my Paper canvas using MCP tools. It might adjust padding, resize cards, change font weights, or even restructure sections based on design principles it pulls from its training. The challenge isn't whether Claude can make changes, it's whether I can evaluate its design reasoning and decide which suggestions actually improve the dashboard versus which ones just feel different. I want to see if the agent can genuinely enhance my work, or if I end up reverting most of its edits.
In this project extension, Claude Code made five major changes. I agreed with unifying all badges to dark #1F2937 because the previous 7-color system felt noisy and distracted from the content. I also agreed with adding hairline borders (#E5E7EB) for subtle card separation without heavy shadows. The justify-between spacing fix was smart because it distributed content evenly across card heights, making each card feel balanced. However, I overrode the background change from #F3F4F6 to #EBEBED because the cooler gray felt muddy on my screen compared to the crisp light gray I originally chose. I also pushed back on reducing the header from 32px to 28px bold, I preferred the stronger visual anchor of the larger title. Finally, I asked Claude to revert the extra pt-4 on the trending section because the original gap already provided enough breathing room, and the extra space made the vertical rhythm feel disconnected.
I did this project today to learn how to bridge design and code without losing fidelity through exports, and to experience what it feels like when an AI agent can read, write, and critique a live DOM canvas. I also wanted to understand MCP as a practical tool for real workflows, not just a concept.
Another skill I want to learn is how to build custom MCP servers for other design tools or internal component libraries, so I can extend this bidirectional workflow beyond Paper. I'm also curious about using Claude Code to run visual regression tests between design and code, automatically flagging drift when the canvas changes. Lastly, I'd like to get better at prompting agents for high-level design strategy, not just tactical fixes, so they can challenge my decisions more meaningfully in future projects.