# Opendesignr

> Zero-build React canvas CLI for AI agents — scaffold, live-edit JSX, export PNG via Playwright.

- **Type:** MCP server
- **Install:** `agentstack add mcp-opendesignr-opendesignr`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [opendesignr](https://agentstack.voostack.com/s/opendesignr)
- **Installs:** 0
- **Category:** [AI & ML](https://agentstack.voostack.com/c/ai-and-ml)
- **Latest version:** 0.1.0
- **License:** Apache-2.0
- **Upstream author:** [opendesignr](https://github.com/opendesignr)
- **Source:** https://github.com/opendesignr/opendesignr

## Install

```sh
agentstack add mcp-opendesignr-opendesignr
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# OpenDesignr

[](https://www.apache.org/licenses/LICENSE-2.0)
[](https://www.npmjs.com/package/opendesignr)

Zero-build React canvas CLI for AI agents.

Scaffold a design project, live-edit JSX with auto-reload, export pixel-perfect PNGs via Playwright. No bundler, no framework lock-in, no ceremony — just JSX, tokens, and a browser.

Built so Claude Code (or any AI coding agent) can edit a component, read back the rendered pixels, and iterate — the loop that a designer-in-a-box actually needs.

## Why

Most design tools are built for humans dragging shapes. OpenDesignr is built for agents editing code.

- **Zero build step.** Components are plain JSX, transpiled in the browser via `@babel/standalone`. No Webpack/Vite/Next.js to fight.
- **`window.X` globals.** Components register themselves globally so boards just use `` without imports. This lets agents discover the component surface area by scanning `components/`.
- **Board-first, not story-first.** A board is an artboard: fixed width × height, one JSX entry, direct DOM render. Perfect for App Store screenshots, OG cards, marketing shots.
- **Playwright export.** Real Chromium → pixel-accurate PNG at any `deviceScaleFactor`.

## Install

```bash
npm install -g opendesignr
# or run without install:
npx opendesignr init my-canvas
```

## Quick start

```bash
npx opendesignr init my-canvas
cd my-canvas
npm install               # pulls Playwright
opendesignr serve         # http://localhost:8765
```

Edit `boards/hello.jsx`. The browser reloads within ~100 ms.

## OpenDesignr Home

Use the local home dashboard when you want one place for every canvas:

```bash
opendesignr home          # http://localhost:8765
```

Home is global to your machine, not tied to the directory where you run it.
It stores its project registry at `~/.opendesignr/workspace.json`. New managed
projects created from Home or `opendesignr projects create` live under
`~/OpenDesignr//`; linked projects stay in their existing folders.

## Commands

```bash
opendesignr init [dir]              # scaffold template into dir (default: .)
opendesignr init my-canvas --force  # overwrite non-empty dir
opendesignr init my-canvas --no-register

opendesignr home                    # local dashboard for all projects
opendesignr projects list           # registered projects
opendesignr projects create "Launch Graphics"
opendesignr projects link /abs/path/to/existing-canvas
opendesignr projects rename launch-graphics "Launch Kit"
opendesignr projects open launch-graphics

opendesignr serve                   # dev server @ localhost:8765
opendesignr serve --port 3000

opendesignr render                  # render every board → ./out/.png
opendesignr render --board hello    # single board
opendesignr render --out ./exports  # custom output dir
opendesignr render --scale 2        # retina (./out/hello@2x.png)
opendesignr render --motion-at end  # capture start | end | milliseconds

opendesignr add hello-v2 --from hello          # new board, optionally from existing
opendesignr duplicate hello hello-v2           # explicit copy
opendesignr rename hello-v2 hello-final        # renames file + config + function
opendesignr resize hello-final 1200x630        # config-only; jsx literals preserved
opendesignr remove hello-final                 # drops jsx + config entry

opendesignr handoff og-card --target "SwiftUI Home screen"
#   → ./out/handoff/og-card/ { bundle.md, board.jsx, tokens.js, components/, render.png }

opendesignr export og-card --format frames --motion-duration 1200 --motion-fps 30
opendesignr export og-card --format gif    --motion-duration 1200 --motion-fps 24
opendesignr export og-card --format mp4    --motion-duration 1200 --motion-fps 30
```

## Live sliders (BOARD_CONTROLS)

A board can expose live controls that show up as sliders / color pickers / inputs in the overview's right-side panel. No chat round-trip needed to iterate on values.

```jsx
// boards/og-card.jsx
const { Box, Text } = window;
const T = window.TOKENS;

window.BOARD_CONTROLS = {
  padding: { label: "Padding", type: "range", min: 0, max: 120, step: 4, default: 48 },
  bg:      { label: "Background", type: "color", default: T.color.cream },
  heading: { label: "Heading",    type: "text",  default: "Ship it" },
  bold:    { label: "Bold",       type: "boolean", default: true },
};

const P = window.BOARD_PARAMS || {};

function OgCard() {
  const padding = Number(P.padding ?? 48);
  const bg = P.bg ?? T.color.cream;
  // ...
}
```

Supported `type`s: `range`, `number`, `color`, `text`, `boolean`, `select` (with `options: [...]`). Values persist in the URL, so a tweaked board is shareable by link.

## Handoff bundles

When a board is ready to port into production code, pack it up:

```bash
opendesignr handoff og-card --target "marketing landing hero"
```

This writes a directory containing the board JSX, the token snapshot, any shared components, a pixel-true PNG, and a `bundle.md` with a ready-to-paste prompt template. Drop the bundle into a Claude Code session on the target repo and ask it to port — no manual context-stitching.

## Project layout

After `opendesignr init`:

```
my-canvas/
├── opendesignr.config.js   # list your boards here
├── canvas.html             # zero-build HTML shell
├── tokens.js               # window.TOKENS for boards
├── tokens/tokens.json      # source of truth (Style Dictionary shape)
├── boards/
│   └── hello.jsx           # one file per board
├── components/
│   ├── primitives.jsx      # Box, Card, Text, Button, Stack
│   └── icon.jsx            #  from ./icons/
├── icons/                  # SVGs — paths use currentColor
└── package.json
```

## Writing a board

```jsx
// boards/og-card.jsx
const { Box, Card, Text } = window;
const T = window.TOKENS;

function OgCard() {
  return (
    
      
        
          Ship it
        
      
    
  );
}

ReactDOM.createRoot(document.getElementById("root")).render();
```

Then register it in `opendesignr.config.js`:

```js
export default {
  boards: [
    { name: "hello", entry: "boards/hello.jsx", width: 1320, height: 2868 },
    { name: "og-card", entry: "boards/og-card.jsx", width: 1200, height: 630 },
  ],
};
```

Visit `http://localhost:8765/?board=og-card`.

## Why it works for AI agents

- **Files are the UI.** No Figma file format, no API call — the agent edits `.jsx` and reads back HTML + a PNG.
- **Token file is a flat JS object.** Agents can grep `T.color.brand` and know what's available.
- **Each board is isolated.** One JSX file = one board. Small context window, big signal.
- **`opendesignr render` is deterministic.** Run it from CI or an agent loop; the PNG is the source of truth for visual diff.

## Skills (chat drawer steering)

The browser chat drawer routes through `@anthropic-ai/claude-agent-sdk`, which auto-loads **agent skills** (SKILL.md files) from `.claude/skills/` in your canvas. Skills give Claude structured, opinionated knowledge instead of letting it improvise — so "design a hero" produces consistent output across sessions.

Every `opendesignr init` scaffolds bundled system skills:

- **`opendesignr-system`** — how the canvas actually works: `window.*` globals, the CLI, BOARD_CONTROLS, JSX well-formedness rules.
- **`opendesignr-tokens`** — token discipline: never hardcode colors/spacing/radius/shadows/fonts, always read `T.color.*` etc.
- **`dotlottie-web`** — official LottieFiles dotLottie guidance for `window.Lottie`, `.lottie` assets, state machines, themes, slots, and motion export.

Install curated UI/UX skills on top:

```bash
opendesignr skills install                   # defaults include dotlottie-web
opendesignr skills install react-best-practices
opendesignr skills catalog                   # show curated list with URLs
opendesignr skills list                      # show what's installed
```

Bundled catalog (default set installs with `init` — use `init --no-skills` to opt out):

| Skill | Source | Notes |
|---|---|---|
| `frontend-design` | `anthropics/skills` | Framework-agnostic aesthetic direction — type, layout, color, motion. |
| `web-design-guidelines` | `vercel-labs/agent-skills` | 100+ UI / UX / a11y audit rules. |
| `ui-ux-pro-max` | `nextlevelbuilder/ui-ux-pro-max-skill` | Design intelligence pack: 67 UI styles, 161 palettes, 57 font pairings, 99 UX rules. |
| `dotlottie-web` | `LottieFiles/dotlottie-web` | Official dotLottie runtime guidance for web Lottie animations. |
| `react-best-practices` | `vercel-labs/agent-skills` | React component-hygiene rules. |

Author your own skill any time — drop a new folder under `.claude/skills//SKILL.md` with YAML frontmatter (`name`, `description`) and markdown body. The chat drawer picks it up automatically on the next message.

## MCP (Claude Code, agents)

OpenDesignr ships an MCP server so agents can drive the canvas natively:

```bash
opendesignr mcp           # stdio transport
```

Tools exposed:
- `list_boards` — returns `[{name, width, height, entry}]`
- `get_tokens` — returns flat token JSON (colors, spacing, radius, shadows, fonts)
- `render_board` — renders a board and returns BOTH the PNG as image content AND the saved file path, so the agent can literally see the pixels it just produced

### Hook into Claude Code

Add to your `~/.claude.json` (or project-level `.mcp.json`):

```json
{
  "mcpServers": {
    "opendesignr": {
      "command": "opendesignr",
      "args": ["mcp", "--cwd", "/absolute/path/to/your/canvas"]
    }
  }
}
```

Then ask Claude Code things like *"render the og-card board and show me"* — it'll call `render_board`, get the PNG back, see it, and suggest edits.

File editing (JSX, tokens) uses Claude Code's built-in `Read`/`Edit` tools, so MCP stays minimal and focused on the board/token/render triangle.

### HTTP transport (cloud / remote)

When `OPENDESIGNR_MCP_HTTP_PORT` is set, the MCP server uses Streamable HTTP instead of stdio. Used by the cloud deployment so external Claude Code can drive a remote canvas — the local `opendesignr mcp` default stays stdio.

```bash
OPENDESIGNR_MCP_HTTP_PORT=8766 opendesignr mcp --cwd /path/to/canvas
# Then point an MCP client at http://localhost:8766
```

## Cloud sync

If you have a OpenDesignr Cloud deployment (the optional `app.` SaaS shell), four CLI commands keep a local checkout in sync with your hosted canvas:

```bash
# 1. Issue a personal access token from your hosted canvas → Settings → Cloud account
opendesignr cloud login --token bwc_…   # saves ~/.opendesignr/cloud.json (mode 0600)

# 2. Pull the cloud project to your laptop
opendesignr cloud pull --slug my-canvas
cd ~/OpenDesignr/cloud-my-canvas
opendesignr home                        # same UI as local-only, just on cloud files

# 3. Edit boards locally, then push back
opendesignr cloud push --slug my-canvas

# 4. Inspect state
opendesignr cloud status
```

`pull` writes a fresh tar.gz extract; pass `--force` to overwrite an existing directory. `push` is a server-side `tar | rsync --delete`, so the remote tenant's chokidar fires per-file events and the cloud canvas live-reloads in any open browser tab.

The CLI is purely a sync transport — there's no cloud-specific runtime divergence. The same `opendesignr home`, the same `boards/*.jsx`, the same render pipeline run on both sides.

## What's next

- Platform-specific token emit (Swift enums, CSS custom properties) from `tokens/tokens.json`.
- Storybook-style MDX docs per board (optional).

## Contributing

Pull requests welcome. See [CONTRIBUTING.md](CONTRIBUTING.md) and sign the [CLA](CLA.md) (handled automatically on your first PR via cla-assistant.io).

## Security

Found a vulnerability? See [SECURITY.md](SECURITY.md) for private reporting channels. Please don't open public issues for security problems.

## License

Apache License 2.0 — see [LICENSE](LICENSE) and [NOTICE](NOTICE).

"OpenDesignr" is a trademark of Ahmet Gül. The Apache License does not grant permission to use the OpenDesignr name, logo, or marks. You may fork, modify, and redistribute the code (including commercially), but you may not use the OpenDesignr brand for derivative products.

**Commercial licensing, enterprise support, and custom deployments** — see [COMMERCIAL.md](COMMERCIAL.md) or email ahmet.gul.0@yandex.com.

## Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [opendesignr](https://github.com/opendesignr)
- **Source:** [opendesignr/opendesignr](https://github.com/opendesignr/opendesignr)
- **License:** Apache-2.0

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/mcp-opendesignr-opendesignr
- Seller: https://agentstack.voostack.com/s/opendesignr
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
