I Turned Notion Into a UI Design Tool โ Claude Reads Your Page and Draws the Screens in Figma
This is a submission for the Notion MCP Challenge
What I Built
NotionCanvas MCP โ a Model Context Protocol server that creates a live pipeline from your Notion workspace directly into Figma.
You write your app idea, feature spec, or product requirements in Notion โ the way you normally would. Then you tell Claude:
"Read my Notion page and generate a mobile UI design in Figma"
And it does. Fully. Screens appear in Figma.
No Figma experience required. No prompt engineering. No copy-pasting. No manually describing your idea to an AI. Your Notion page is the brief โ and NotionCanvas turns it into a real, editable UI in seconds.
The Problem It Solves
Every product builder knows this moment: you have a clear idea written up in Notion โ user flows, feature descriptions, screen names, content โ and then you spend the next hour either:
- Trying to describe that same idea to an AI image generator with mixed results
- Opening Figma and building frames manually from scratch
- Hiring a designer and waiting days for a first draft
The idea is already written. Why describe it again?
NotionCanvas closes that gap entirely. Your Notion page is the single source of truth โ and Claude bridges it to Figma automatically.
How It Works
The system has three parts working together:
Your Notion Page
โ
โผ
notioncanvas-mcp (Node.js MCP Server)
โ
โโโ Notion API โ reads your page content
โโโ Claude API โ interprets it, generates a Design IR (structured JSON)
โโโ WebSocket โ sends commands to the Figma Bridge Plugin
โ
Figma Desktop
(NotionCanvas Bridge Plugin)
draws frames on canvas
Step 1 โ Notion Reader: Reads your page recursively โ headings, paragraphs, lists, callouts, properties โ and builds a clean structured content object.
Step 2 โ Claude Interpreter: Claude receives the Notion content + your design preferences (mobile/web, theme, color, design system) and outputs a Design Intermediate Representation (DIR) โ a validated JSON schema describing every screen, every component, every coordinate, every color.
Step 3 โ DIR Validator: Zod validates every component before anything touches Figma. Malformed AI output never reaches the canvas. Claude gets up to 2 automatic retries with targeted error feedback.
Step 4 โ Figma Writer: The MCP server sends each screen to the Figma Bridge Plugin over a local WebSocket. The plugin executes Figma Plugin API calls โ createFrame(), createText(), createRectangle() โ and your screens appear live on the canvas.
What It Can Generate
From a single Notion page, NotionCanvas produces:
- Full mobile screens (390ร844) or web layouts (1440ร900)
- Text components with font weight, size, alignment
- Input fields with placeholder text
- Buttons with variants (primary, secondary, ghost, destructive)
- Frames with Auto Layout support (vertical/horizontal, padding, spacing)
- Rectangles with stroke, fill, corner radius
- Every component positioned absolutely with proper coordinates
- Background colors derived from your brand description
All components land in Figma as native, editable nodes โ not images, not embeds. You can grab any element and keep designing from there.
The 6 MCP Tools
| Tool | What it does |
|---|---|
generate_ui_design |
Full pipeline: reads your Notion page โ Claude โ Figma screens |
generate_screen |
Single screen from a plain-text description (no Notion needed) |
notion_read_page |
Read and return structured content of any Notion page |
notion_read_db |
Query a Notion database and return all entries |
list_figma_frames |
List all existing frames in a Figma file |
get_design_status |
Check if the Figma Bridge Plugin is connected and ready |
Real Example
I wrote this in Notion:
"I want a simple ride hailing application. Main color theme is red. Use Inter font."
That's it. Two sentences.
NotionCanvas read that page, sent it to Claude, generated a full DesignIR with an onboarding screen, a home screen with a map layout, a booking screen with input fields and a confirm button โ and sent all of it to Figma as native frames.
The whole pipeline ran in under 90 seconds.
Video Demo
Show us the code
GitHub: github.com/TheCodeDaniel/notion_canvas
Project structure
notioncanvas-mcp/
โโโ src/
โ โโโ index.ts โ MCP server entry point (stdio transport)
โ โโโ clients/
โ โ โโโ notion.ts โ Notion API + p-queue rate limiter (2.8 req/s)
โ โ โโโ claude.ts โ Claude API + JSON retry logic (3 attempts)
โ โ โโโ figma-ws.ts โ WebSocket bridge server (localhost:9223)
โ โ โโโ figma-rest.ts โ Figma REST API (read-only frame listing)
โ โโโ interpreter/
โ โ โโโ schema.ts โ Zod DesignIR schema (5 component types)
โ โ โโโ prompt.ts โ Claude system/user prompt builders
โ โโโ tools/ โ 6 MCP tools
โ โโโ types/ โ TypeScript interfaces
โ โโโ utils/ โ logger, retry, PAT expiry checker
โโโ plugin/
โโโ manifest.json โ Figma plugin manifest
โโโ plugin.js โ Figma Plugin API (main thread)
โโโ ui.html โ WebSocket iframe (relay bridge)
Setup is one command after filling your .env
npm install
npm run build
npm run setup # auto-detects Claude Desktop config path, merges entry, resolves absolute paths
The setup command handles everything:
- Reads credentials from your
.env - Detects
claude_desktop_config.jsonpath for macOS or Windows - Creates the file if it doesn't exist
- Merges the
notioncanvasentry without touching your other MCP servers - Auto-resolves the absolute path to
dist/index.jsโ nothing to edit manually
Stack
- TypeScript / Node.js โ ESM, strict mode
-
@modelcontextprotocol/sdkโ MCP server with stdio transport -
@notionhq/clientโ Notion API with p-queue rate limiting -
@anthropic-ai/sdkโ Claude API (claude-sonnet-4-6) -
wsโ WebSocket server for the Figma bridge -
zodโ DesignIR schema validation before any Figma writes - Figma Plugin API โ native canvas writes via the bridge plugin
How I Used Notion MCP
Notion MCP is the foundation that makes this whole idea possible โ and not in a trivial way.
Why Notion as the input source is actually powerful
Most AI design tools start with a blank text box. You describe your idea to the AI. The AI designs something. But that description lives nowhere โ it's not connected to your roadmap, your feature specs, your user stories. It's a one-off prompt.
Notion changes that. Your product thinking already lives there. Feature specs, screen flows, content requirements, user personas โ structured, searchable, shareable with your team. With Notion MCP as the reader, that existing knowledge becomes the direct input to the design pipeline.
You're not describing your idea to an AI. You're pointing an AI at your idea. That's a fundamentally different workflow.
The specific integration
I used the Notion internal integration token (via @notionhq/client) to:
Read pages recursively โ the client traverses the full block tree, handling pagination (100 blocks per request), nested toggles, callouts, lists, and all block types. Pages with hundreds of blocks are handled cleanly.
Query databases โ the
notion_read_dbtool lets you pull structured data from Notion databases and feed it into screen generation. Imagine a database of app screens with properties like "screen type", "primary action", "user role" โ and generating each one automatically.Handle the page-sharing security model correctly โ Notion's integration tokens only work on pages explicitly shared with the integration. The server returns a helpful, specific error message when a 404 is returned, rather than a generic failure.
What Notion MCP unlocks that nothing else does
The pipeline means your Notion page becomes a living design brief. Update the page โ run the tool again โ get updated screens. It's not a one-time export. It's a repeatable process driven by the content you're already maintaining.
For solo founders, indie developers, and small product teams who live in Notion: this means going from written idea to visual screen without leaving your workflow or learning Figma from scratch.
That's the unlock. Notion stops being a notes app and starts being a design input system.
Built with Claude Code, @modelcontextprotocol/sdk, @notionhq/client, and the Figma Plugin API.
Stack: TypeScript ยท Node.js ยท WebSockets ยท Zod ยท claude-sonnet-4-6
Top comments (0)