Skip to main content
Glama
README.md
<div align="center">

# Sheet

**A design canvas where AI agents design in real HTML and CSS, and you refine what they make.**

Sheet runs on your Mac. Agents work through an [MCP](https://modelcontextprotocol.io) server with 35 design tools, and you watch every layer appear live. Then you polish the result in a full visual editor and export production-ready React code.

[![License: MIT](https://img.shields.io/badge/license-MIT-FF5A36.svg)](LICENSE)
![Platform: macOS](https://img.shields.io/badge/platform-macOS-242220.svg)
![Node 22+](https://img.shields.io/badge/node-%E2%89%A522-242220.svg)
![MCP tools: 35](https://img.shields.io/badge/MCP%20tools-35-FF5A36.svg)

<img src="docs/images/editor.png" alt="The Sheet editor: layers on the left, a mobile screen and a landing page on the canvas, the design panel on the right, and the tool dock at the bottom" width="100%">

</div>

## Why Sheet

Most AI design output looks generic because the agent never sees what it made and has nothing to push it toward taste. Sheet fixes both:

- **The canvas is the code.** Every layer is real HTML and CSS rendered by Chromium. What the agent writes is what you see, and what you export is what you ship.
- **The agent sees its work.** Agents take screenshots, read exact computed styles and measure layouts, so they review their own design the way a designer would.
- **A built-in design playbook.** Before building, the agent reads a guide that teaches good practice:
  - a design brief first, then real fonts and small visible steps;
  - palettes derived from a "mood";
  - aligned lanes in repeated rows;
  - a screenshot review against a checklist after every section.
- **You stay in control.** Everything an agent makes is editable by hand. You get auto layout, typography, fills, borders, effects, tokens, comments, undo and export.

## Designed through the MCP

Both screens were built by a script that calls Sheet's MCP tools exactly as an agent would ([`scripts/demo.mjs`](scripts/demo.mjs)).

<table>
<tr>
<td width="30%"><img src="docs/images/demo-mobile.png" alt="Tidepool: a mobile tide and swim-conditions screen"></td>
<td width="70%"><img src="docs/images/demo-landing.png" alt="Ledgerline: a bookkeeping landing page"></td>
</tr>
</table>

## Features

**Editor**
- A full-window canvas with floating panels and a tool dock: move, hand, frame, rectangle, pen, text, insert and comment.
- Click selects, double-click drills into groups, ⌘-click selects the deepest layer. Drag to move or reorder; resize with handles.
- **Layers panel:** collapsible tree with drag-to-nest, inline rename, and hide and lock toggles.
- **Design panel sections:**
  - Layout (Fixed / Fit / Fill sizing, rotation, flip);
  - Flex (a 3×3 alignment grid, gap, padding);
  - Radius, Blending, Fill (solid / gradient / image);
  - Text (live font picker), Underline, Border, Shadow, Inner shadow, Filters;
  - Selection colors and Export presets.
- **Canvas feedback:** a dashed parent outline, gap and padding marks, and a size badge that shows sizing ("358 × Fill 1006.5").
- **More:** design tokens in the Theme tab, comment threads, undo and redo across your edits and the agent's, and a live code view.

**For agents (MCP)**
- **35 tools** over streamable HTTP at `http://127.0.0.1:4317/mcp`, plus a stdio bridge (`mcp.mjs`).
- A **working indicator** shows which boards an agent is editing, and recent agent calls appear in the panel.
- Images from local paths, remote URLs or data URLs are copied into your files, so designs never break when links change.

**Export**
- React JSX with **inline styles** or **Tailwind v4** classes (`pt-6.75`, `text-sm/4.5`, `rounded-md` and so on).
- PNG, JPG, WebP, AVIF, PDF and SVG, plus **MP4 / WebM** video (frame-exact, encoded with a bundled ffmpeg).
- Multi-board PDFs, and export presets saved per layer.

## Quick start

Requirements: macOS and [Node.js](https://nodejs.org) 22 or newer.

```bash
git clone https://github.com/aryanjsingh/sheet.git
cd sheet
npm run setup      # installs dependencies and the rendering engine, then builds Sheet.app
```

Then open **Sheet** from `~/Applications` (or Spotlight).

- Opening the app starts the editor and the MCP server.
- Quitting stops both, so nothing runs in the background.

Prefer the browser? Run `npm start` and open <http://127.0.0.1:4317>.

## Connect an agent

Sheet's MCP server is live while the app is open.

**Claude Code**
```bash
claude mcp add --transport http --scope user sheet http://127.0.0.1:4317/mcp
```

**Codex** (`~/.codex/config.toml`)
```toml
[mcp_servers.sheet]
url = "http://127.0.0.1:4317/mcp"
```

**Cursor, Windsurf and other clients**
```json
{ "mcpServers": { "sheet": { "type": "http", "url": "http://127.0.0.1:4317/mcp" } } }
```

Clients that only launch stdio servers can run `node /path/to/sheet/mcp.mjs`.

Then ask your agent something like:

> Read the Sheet guide, then design the home screen of a mobile app for a neighborhood bakery.

## How it works

```mermaid
flowchart LR
    A[AI agent] -- MCP over HTTP --> S[Sheet server<br/>127.0.0.1:4317]
    E[Editor<br/>Sheet.app window] -- edits + live updates --> S
    S -- layout, screenshots, exports --> C[Headless Chromium]
    S -- JSON + images --> D[(~/Sheet)]
```

- **One document model, one renderer.** The editor, screenshots and exports all render layers with the same function (`src/core/render.mjs`), so the canvas, the agent's screenshots and your exports always agree.
- **HTML goes in, layers come out.** `write_html` parses an agent's HTML into editable layers: frames, text, rectangles and SVGs. Styles are normalized into a clean stored form, for example gradients in `oklab`, hex colors, and padding folded into the smallest set of properties.
- **Pixel-accurate text.** Text baselines and hug widths are snapped the way a design tool expects, not left to browser rounding.

## Your files

Everything Sheet saves lives in one folder, `~/Sheet` (File → Show Files in Finder):

| Folder | What's inside |
|---|---|
| `Designs/` | one `.json` per design, named `<design name> (<id>).json` |
| `Assets/` | images used in your designs |
| `Exports/` | everything exported, from the editor or by agents |
| `Backups/` | a daily copy of `Designs/`, kept for 14 days |

## MCP tools

| Area | Tools |
|---|---|
| Files & pages | `list_files` `open_file` `create_file` `create_page` `rename_pages` |
| Reading | `get_basic_info` `get_selection` `get_node_info` `get_children` `get_tree_summary` `get_computed_styles` `find_nodes` `get_fill_image` `get_font_family_info` `get_guide` |
| Seeing | `get_screenshot` `get_jsx` |
| Writing | `create_artboard` `write_html` `update_styles` `set_text_content` `rename_nodes` `duplicate_nodes` `move_nodes` `delete_nodes` `finish_working_on_nodes` |
| Tokens | `get_tokens` `create_tokens` `set_tokens` |
| Comments | `list_comment_threads` `get_comment_thread` `list_comment_thread_authors` `set_comment_thread_status` |
| Export | `export` `export_combined_pdf` |

Guides for agents (`get_guide`): `sheet-mcp-instructions`, `mobile-status-bar`, `figma-import`, `image-generation`.

## Keyboard shortcuts

| Keys | Action | Keys | Action |
|---|---|---|---|
| `V` `H` | Move, hand | `⌘D` | Duplicate |
| `F` `R` `P` `T` | Frame, rectangle, pen, text | `⌘G` / `⇧⌘G` | Group / ungroup |
| `C` | Comment | `⇧A` | Wrap in flex |
| `⇧1` / `⇧2` | Zoom to fit / to selection | `⌥C` | Clip content |
| `⌘Z` / `⇧⌘Z` | Undo / redo | `⌘⌥C` | Code view |
| `⌘\` | Hide panels | `⇧⌘K` | Add image |

## Development

```bash
npm start          # server + editor in the browser
npm run app        # the desktop app from source
npm test           # 29 unit tests: import rules, normalization, JSX/Tailwind export
npm run verify     # 29 end-to-end checks: real server, MCP agent, mouse and keyboard in Chromium
npm run test:app   # the desktop app: opens with the MCP, shortcuts work, quitting stops the server
npm run bench      # rendering regression: pixel-diff two benchmark boards against reference renders
npm run build:app  # rebuild ~/Applications/Sheet.app (only needed after moving the folder or updating Electron)
npm run demo       # build the demo file shown above
```

The benchmark boards (`bench/`) render within **0.105%** and **0.193%** of their reference images. What's left is anti-aliasing on rotated text.

### Project layout

```
app/          Electron shell: starts the server with the window, stops it on quit
public/       the editor (vanilla ES modules, no build step)
src/core/     shared by server and editor: document model, HTML import, CSS normalization,
              rendering, JSX + Tailwind export, gradients
src/server/   HTTP server, MCP tools and guides, workspace (files, undo), assets, fonts,
              headless Chromium (layout, screenshots, exports), media encoding
scripts/      build-app, demo, export-jsx, mcp-call (use the MCP from a shell)
test/         unit, end-to-end and app tests; reference exports and renders in fixtures/
bench/        rendering benchmark boards and runner
```

Everything the project needs stays inside the project folder:
- Electron and ffmpeg install into `node_modules/`.
- The headless Chromium goes to `.browsers/`.

## Roadmap

- Components and instances
- Editing pen paths point by point
- Multiplayer and sharing beyond this Mac
- Windows and Linux builds

## License

[MIT](LICENSE) © aryanjsingh