{"_id":"@airmix/mcp-excalidraw-server","name":"@airmix/mcp-excalidraw-server","dist-tags":{"latest":"1.0.6"},"versions":{"1.0.6":{"name":"@airmix/mcp-excalidraw-server","version":"1.0.6","description":"Advanced MCP server for Excalidraw with real-time canvas, WebSocket sync, and comprehensive diagram management","main":"dist/index.js","type":"module","bin":{"mcp-excalidraw-server":"dist/index.js"},"scripts":{"start":"npm run build:server && node dist/index.js","canvas":"npm run build:server && node dist/server.js","build":"npm run build:frontend && npm run build:server","build:frontend":"vite build","build:server":"npx tsc","build:types":"npx tsc --emitDeclarationOnly","dev":"concurrently \"npm run dev:server\" \"vite\"","dev:server":"npx tsc --watch","production":"npm run build && npm run canvas","prepublishOnly":"npm run build","type-check":"npx tsc --noEmit"},"dependencies":{"@excalidraw/excalidraw":"^0.18.0","@excalidraw/mermaid-to-excalidraw":"^1.1.3","@modelcontextprotocol/sdk":"latest","cors":"^2.8.5","dotenv":"^16.3.1","express":"^4.18.2","mermaid":"^11.12.1","node-fetch":"^3.3.2","react":"^18.3.1","react-dom":"^18.3.1","winston":"^3.11.0","ws":"^8.14.2","zod":"^3.22.4","zod-to-json-schema":"^3.22.3"},"devDependencies":{"@types/cors":"^2.8.17","@types/express":"^4.17.21","@types/node":"^20.19.7","@types/react":"^18.3.3","@types/react-dom":"^18.3.0","@types/ws":"^8.5.10","@vitejs/plugin-react":"^4.7.0","concurrently":"^9.2.0","typescript":"^5.8.3","vite":"^6.4.1"},"keywords":["mcp","mcp-server","excalidraw","model-context-protocol","ai","drawing","diagrams","canvas","real-time","websocket","visualization","claude","ai-tools"],"author":{"name":"yctimlin","email":"c22647809@gmail.com"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/yctimlin/mcp_excalidraw.git"},"homepage":"https://github.com/yctimlin/mcp_excalidraw#readme","bugs":{"url":"https://github.com/yctimlin/mcp_excalidraw/issues"},"engines":{"node":">=18.0.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"gitHead":"ec609277683d83da32bdcdf7ea7611fe87240be5","types":"./dist/index.d.ts","_id":"@airmix/mcp-excalidraw-server@1.0.6","_nodeVersion":"25.4.0","_npmVersion":"11.7.0","dist":{"integrity":"sha512-M5GDBuOSLzqOeG78i+RvMq2AQOtBRDZDC7cg1oxT91bk8Tu3Z5INJeJgaNmEFL6FHAcR5TS1ZzKNqbU31ZH3nw==","shasum":"4be3bd2bc6a08f5a364da5b5c930a61946e9ad50","tarball":"https://registry.npmjs.org/@airmix/mcp-excalidraw-server/-/mcp-excalidraw-server-1.0.6.tgz","fileCount":182,"unpackedSize":9319323,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCRudduwfHKBo7y2UtXIrG5fwbhG/OaJnHGsUi4L5MC0QIhAPrub7YDALqJakv1w2jZXHgB+5fy2L25EfB91sLwWZUK"}]},"_npmUser":{"name":"airmix","email":"dor.ezra93@gmail.com"},"directories":{},"maintainers":[{"name":"airmix","email":"dor.ezra93@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/mcp-excalidraw-server_1.0.6_1772839980541_0.5526908295177726"},"_hasShrinkwrap":false}},"time":{"created":"2026-03-06T23:33:00.442Z","1.0.6":"2026-03-06T23:33:00.811Z","modified":"2026-03-06T23:33:01.039Z"},"maintainers":[{"name":"airmix","email":"dor.ezra93@gmail.com"}],"description":"Advanced MCP server for Excalidraw with real-time canvas, WebSocket sync, and comprehensive diagram management","homepage":"https://github.com/yctimlin/mcp_excalidraw#readme","keywords":["mcp","mcp-server","excalidraw","model-context-protocol","ai","drawing","diagrams","canvas","real-time","websocket","visualization","claude","ai-tools"],"repository":{"type":"git","url":"git+https://github.com/yctimlin/mcp_excalidraw.git"},"author":{"name":"yctimlin","email":"c22647809@gmail.com"},"bugs":{"url":"https://github.com/yctimlin/mcp_excalidraw/issues"},"license":"MIT","readme":"# Excalidraw MCP Server & Agent Skill\n\n[![CI](https://github.com/yctimlin/mcp_excalidraw/actions/workflows/ci.yml/badge.svg)](https://github.com/yctimlin/mcp_excalidraw/actions/workflows/ci.yml)\n[![Docker Build & Push](https://github.com/yctimlin/mcp_excalidraw/actions/workflows/docker.yml/badge.svg)](https://github.com/yctimlin/mcp_excalidraw/actions/workflows/docker.yml)\n[![NPM Version](https://img.shields.io/npm/v/mcp-excalidraw-server)](https://www.npmjs.com/package/mcp-excalidraw-server)\n[![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)\n\nRun a live Excalidraw canvas and control it from AI agents. This repo provides:\n\n- **MCP Server**: Connect via Model Context Protocol (Claude Desktop, Cursor, Codex CLI, etc.)\n- **Agent Skill**: Portable skill for Claude Code, Codex CLI, and other skill-enabled agents\n\nKeywords: Excalidraw agent skill, Excalidraw MCP server, AI diagramming, Claude Code skill, Codex CLI skill, Claude Desktop MCP, Cursor MCP, Mermaid to Excalidraw.\n\n## Demo\n\n![MCP Excalidraw Demo](demo.gif)\n\n*AI agent creates a complete architecture diagram from a single prompt (4x speed). [Watch full video on YouTube](https://youtu.be/ufW78Amq5qA)*\n\n## Table of Contents\n\n- [Demo](#demo)\n- [What It Is](#what-it-is)\n- [How We Differ from the Official Excalidraw MCP](#how-we-differ-from-the-official-excalidraw-mcp)\n- [What's New](#whats-new)\n- [Quick Start (Local)](#quick-start-local)\n- [Quick Start (Docker)](#quick-start-docker)\n- [Configure MCP Clients](#configure-mcp-clients)\n  - [Claude Desktop](#claude-desktop)\n  - [Claude Code](#claude-code)\n  - [Cursor](#cursor)\n  - [Codex CLI](#codex-cli)\n  - [OpenCode](#opencode)\n  - [Antigravity (Google)](#antigravity-google)\n- [Agent Skill (Optional)](#agent-skill-optional)\n- [MCP Tools (26 Total)](#mcp-tools-26-total)\n- [Testing](#testing)\n- [Troubleshooting](#troubleshooting)\n- [Known Issues / TODO](#known-issues--todo)\n- [Development](#development)\n\n## What It Is\n\nThis repo contains two separate processes:\n\n- Canvas server: web UI + REST API + WebSocket updates (default `http://localhost:3000`)\n- MCP server: exposes MCP tools over stdio; syncs to the canvas via `EXPRESS_SERVER_URL`\n\n## How We Differ from the Official Excalidraw MCP\n\nExcalidraw now has an [official MCP](https://github.com/excalidraw/excalidraw-mcp) — it's great for quick, prompt-to-diagram generation rendered inline in chat. We solve a different problem.\n\n| | Official Excalidraw MCP | This Project |\n|---|---|---|\n| **Approach** | Prompt in, diagram out (one-shot) | Programmatic element-level control (26 tools) |\n| **State** | Stateless — each call is independent | Persistent live canvas with real-time sync |\n| **Element CRUD** | No | Full create / read / update / delete per element |\n| **AI sees the canvas** | No | `describe_scene` (structured text) + `get_canvas_screenshot` (image) |\n| **Iterative refinement** | No — regenerate the whole diagram | Draw → look → adjust → look again, element by element |\n| **Layout tools** | No | `align_elements`, `distribute_elements`, `group / ungroup` |\n| **File I/O** | No | `export_scene` / `import_scene` (.excalidraw JSON) |\n| **Snapshot & rollback** | No | `snapshot_scene` / `restore_snapshot` |\n| **Mermaid conversion** | No | `create_from_mermaid` |\n| **Shareable URLs** | Yes | Yes — `export_to_excalidraw_url` |\n| **Design guide** | `read_me` cheat sheet | `read_diagram_guide` (colors, sizing, layout, anti-patterns) |\n| **Viewport control** | Camera animations | `set_viewport` (zoom-to-fit, center on element, manual zoom) |\n| **Live canvas UI** | Rendered inline in chat | Standalone Excalidraw app synced via WebSocket |\n| **Multi-agent** | Single user | Multiple agents can draw on the same canvas concurrently |\n| **Works without MCP** | No | Yes — REST API fallback via agent skill |\n\n**TL;DR** — The official MCP generates diagrams. We give AI agents a full canvas toolkit to build, inspect, and iteratively refine diagrams — including the ability to see what they drew.\n\n## What's New\n\n### v2.0 — Canvas Toolkit\n\n- 13 new MCP tools (26 total): `get_element`, `clear_canvas`, `export_scene`, `import_scene`, `export_to_image`, `duplicate_elements`, `snapshot_scene`, `restore_snapshot`, `describe_scene`, `get_canvas_screenshot`, `read_diagram_guide`, `export_to_excalidraw_url`, `set_viewport`\n- **Closed feedback loop**: AI can now inspect the canvas (`describe_scene`) and see it (`get_canvas_screenshot` returns an image) — enabling iterative refinement\n- **Design guide**: `read_diagram_guide` returns best-practice color palettes, sizing rules, layout patterns, and anti-patterns — dramatically improves AI-generated diagram quality\n- **Shareable URLs**: `export_to_excalidraw_url` encrypts and uploads the scene to excalidraw.com, returns a shareable link anyone can open\n- **Viewport control**: `set_viewport` with `scrollToContent`, `scrollToElementId`, or manual zoom/offset — agents can auto-fit diagrams after creation\n- **File I/O**: export/import full `.excalidraw` JSON files\n- **Snapshots**: save and restore named canvas states\n- **Skill fallback**: Agent skill auto-detects MCP vs REST API mode, gracefully falls back to HTTP endpoints when MCP server isn't configured\n- Fixed all previously known issues: `align_elements` / `distribute_elements` fully implemented, points type normalization, removed invalid `label` type, removed HTTP transport dead code, `ungroup_elements` now errors on failure\n\n### v1.x\n\n- Agent skill: `skills/excalidraw-skill/` (portable instructions + helper scripts for export/import and repeatable CRUD)\n- Better testing loop: MCP Inspector CLI examples + browser screenshot checks (`agent-browser`)\n- Bugfixes: batch create now preserves element ids (fixes update/delete after batch); frontend entrypoint fixed (`main.tsx`)\n\n## Quick Start (Local)\n\nPrereqs: Node >= 18, npm\n\n```bash\nnpm ci\nnpm run build\n```\n\nTerminal 1: start the canvas\n```bash\nPORT=3000 npm run canvas\n```\n\n> **Security note:** The server defaults to binding on `localhost` only. If you need to expose it on a network interface (e.g. Docker, remote access), set `HOST=0.0.0.0` — but ensure you have network-level access controls in place, as the API has no built-in authentication.\n\nOpen `http://localhost:3000`.\n\nTerminal 2: run the MCP server (stdio)\n```bash\nEXPRESS_SERVER_URL=http://localhost:3000 node dist/index.js\n```\n\n## Quick Start (Docker)\n\nCanvas server:\n```bash\ndocker run -d -p 3000:3000 --name mcp-excalidraw-canvas ghcr.io/yctimlin/mcp_excalidraw-canvas:latest\n```\n\nMCP server (stdio) is typically launched by your MCP client (Claude Desktop/Cursor/etc.). If you want a local container for it, use the image `ghcr.io/yctimlin/mcp_excalidraw:latest` and set `EXPRESS_SERVER_URL` to point at the canvas.\n\n## Configure MCP Clients\n\nThe MCP server runs over stdio and can be configured with any MCP-compatible client. Below are configurations for both **local** (requires cloning and building) and **Docker** (pull-and-run) setups.\n\n### Environment Variables\n\n| Variable | Description | Default |\n|----------|-------------|---------|\n| `EXPRESS_SERVER_URL` | URL of the canvas server | `http://localhost:3000` |\n| `ENABLE_CANVAS_SYNC` | Enable real-time canvas sync | `true` |\n\n---\n\n### Claude Desktop\n\nConfig location:\n- macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`\n- Windows: `%APPDATA%\\Claude\\claude_desktop_config.json`\n- Linux: `~/.config/Claude/claude_desktop_config.json`\n\n**Local (node)**\n```json\n{\n  \"mcpServers\": {\n    \"excalidraw\": {\n      \"command\": \"node\",\n      \"args\": [\"/absolute/path/to/mcp_excalidraw/dist/index.js\"],\n      \"env\": {\n        \"EXPRESS_SERVER_URL\": \"http://localhost:3000\",\n        \"ENABLE_CANVAS_SYNC\": \"true\"\n      }\n    }\n  }\n}\n```\n\n**Docker**\n```json\n{\n  \"mcpServers\": {\n    \"excalidraw\": {\n      \"command\": \"docker\",\n      \"args\": [\n        \"run\", \"-i\", \"--rm\",\n        \"-e\", \"EXPRESS_SERVER_URL=http://host.docker.internal:3000\",\n        \"-e\", \"ENABLE_CANVAS_SYNC=true\",\n        \"ghcr.io/yctimlin/mcp_excalidraw:latest\"\n      ]\n    }\n  }\n}\n```\n\n---\n\n### Claude Code\n\nUse the `claude mcp add` command to register the MCP server.\n\n**Local (node)** - User-level (available across all projects):\n```bash\nclaude mcp add excalidraw --scope user \\\n  -e EXPRESS_SERVER_URL=http://localhost:3000 \\\n  -e ENABLE_CANVAS_SYNC=true \\\n  -- node /absolute/path/to/mcp_excalidraw/dist/index.js\n```\n\n**Local (node)** - Project-level (shared via `.mcp.json`):\n```bash\nclaude mcp add excalidraw --scope project \\\n  -e EXPRESS_SERVER_URL=http://localhost:3000 \\\n  -e ENABLE_CANVAS_SYNC=true \\\n  -- node /absolute/path/to/mcp_excalidraw/dist/index.js\n```\n\n**Docker**\n```bash\nclaude mcp add excalidraw --scope user \\\n  -- docker run -i --rm \\\n  -e EXPRESS_SERVER_URL=http://host.docker.internal:3000 \\\n  -e ENABLE_CANVAS_SYNC=true \\\n  ghcr.io/yctimlin/mcp_excalidraw:latest\n```\n\n**Manage servers:**\n```bash\nclaude mcp list              # List configured servers\nclaude mcp remove excalidraw # Remove a server\n```\n\n---\n\n### Cursor\n\nConfig location: `.cursor/mcp.json` in your project root (or `~/.cursor/mcp.json` for global config)\n\n**Local (node)**\n```json\n{\n  \"mcpServers\": {\n    \"excalidraw\": {\n      \"command\": \"node\",\n      \"args\": [\"/absolute/path/to/mcp_excalidraw/dist/index.js\"],\n      \"env\": {\n        \"EXPRESS_SERVER_URL\": \"http://localhost:3000\",\n        \"ENABLE_CANVAS_SYNC\": \"true\"\n      }\n    }\n  }\n}\n```\n\n**Docker**\n```json\n{\n  \"mcpServers\": {\n    \"excalidraw\": {\n      \"command\": \"docker\",\n      \"args\": [\n        \"run\", \"-i\", \"--rm\",\n        \"-e\", \"EXPRESS_SERVER_URL=http://host.docker.internal:3000\",\n        \"-e\", \"ENABLE_CANVAS_SYNC=true\",\n        \"ghcr.io/yctimlin/mcp_excalidraw:latest\"\n      ]\n    }\n  }\n}\n```\n\n---\n\n### Codex CLI\n\nUse the `codex mcp add` command to register the MCP server.\n\n**Local (node)**\n```bash\ncodex mcp add excalidraw \\\n  --env EXPRESS_SERVER_URL=http://localhost:3000 \\\n  --env ENABLE_CANVAS_SYNC=true \\\n  -- node /absolute/path/to/mcp_excalidraw/dist/index.js\n```\n\n**Docker**\n```bash\ncodex mcp add excalidraw \\\n  -- docker run -i --rm \\\n  -e EXPRESS_SERVER_URL=http://host.docker.internal:3000 \\\n  -e ENABLE_CANVAS_SYNC=true \\\n  ghcr.io/yctimlin/mcp_excalidraw:latest\n```\n\n**Manage servers:**\n```bash\ncodex mcp list              # List configured servers\ncodex mcp remove excalidraw # Remove a server\n```\n\n---\n\n### OpenCode\n\nConfig location: `~/.config/opencode/opencode.json` or project-level `opencode.json`\n\n**Local (node)**\n```json\n{\n  \"$schema\": \"https://opencode.ai/config.json\",\n  \"mcp\": {\n    \"excalidraw\": {\n      \"type\": \"local\",\n      \"command\": [\"node\", \"/absolute/path/to/mcp_excalidraw/dist/index.js\"],\n      \"enabled\": true,\n      \"environment\": {\n        \"EXPRESS_SERVER_URL\": \"http://localhost:3000\",\n        \"ENABLE_CANVAS_SYNC\": \"true\"\n      }\n    }\n  }\n}\n```\n\n**Docker**\n```json\n{\n  \"$schema\": \"https://opencode.ai/config.json\",\n  \"mcp\": {\n    \"excalidraw\": {\n      \"type\": \"local\",\n      \"command\": [\"docker\", \"run\", \"-i\", \"--rm\", \"-e\", \"EXPRESS_SERVER_URL=http://host.docker.internal:3000\", \"-e\", \"ENABLE_CANVAS_SYNC=true\", \"ghcr.io/yctimlin/mcp_excalidraw:latest\"],\n      \"enabled\": true\n    }\n  }\n}\n```\n\n---\n\n### Antigravity (Google)\n\nConfig location: `~/.gemini/antigravity/mcp_config.json`\n\n**Local (node)**\n```json\n{\n  \"mcpServers\": {\n    \"excalidraw\": {\n      \"command\": \"node\",\n      \"args\": [\"/absolute/path/to/mcp_excalidraw/dist/index.js\"],\n      \"env\": {\n        \"EXPRESS_SERVER_URL\": \"http://localhost:3000\",\n        \"ENABLE_CANVAS_SYNC\": \"true\"\n      }\n    }\n  }\n}\n```\n\n**Docker**\n```json\n{\n  \"mcpServers\": {\n    \"excalidraw\": {\n      \"command\": \"docker\",\n      \"args\": [\n        \"run\", \"-i\", \"--rm\",\n        \"-e\", \"EXPRESS_SERVER_URL=http://host.docker.internal:3000\",\n        \"-e\", \"ENABLE_CANVAS_SYNC=true\",\n        \"ghcr.io/yctimlin/mcp_excalidraw:latest\"\n      ]\n    }\n  }\n}\n```\n\n---\n\n### Notes\n\n- **Docker networking**: Use `host.docker.internal` to reach the canvas server running on your host machine. On Linux, you may need `--add-host=host.docker.internal:host-gateway` or use `172.17.0.1`.\n- **Canvas server**: Must be running before the MCP server connects. Start it with `npm run canvas` (local) or `docker run -d -p 3000:3000 ghcr.io/yctimlin/mcp_excalidraw-canvas:latest` (Docker).\n- **Absolute paths**: When using local node setup, replace `/absolute/path/to/mcp_excalidraw` with the actual path where you cloned and built the repo.\n- **In-memory storage**: The canvas server stores elements in memory. Restarting the server will clear all elements. Use the export/import scripts if you need persistence.\n\n## Agent Skill (Optional)\n\nThis repo includes a skill at `skills/excalidraw-skill/` that provides:\n\n- **Workflow playbook** (`SKILL.md`): step-by-step guidance for drawing, refining, and exporting diagrams\n- **Cheatsheet** (`references/cheatsheet.md`): MCP tool and REST API reference\n- **Helper scripts** (`scripts/*.cjs`): export, import, clear, healthcheck, CRUD operations\n\nThe skill complements the MCP server by giving your AI agent structured workflows to follow.\n\n### Install The Skill (Codex CLI example)\n\n```bash\nmkdir -p ~/.codex/skills\ncp -R skills/excalidraw-skill ~/.codex/skills/excalidraw-skill\n```\n\nTo update an existing installation, remove the old folder first (`rm -rf ~/.codex/skills/excalidraw-skill`) then re-copy.\n\n### Install The Skill (Claude Code)\n\n**User-level** (available across all your projects):\n```bash\nmkdir -p ~/.claude/skills\ncp -R skills/excalidraw-skill ~/.claude/skills/excalidraw-skill\n```\n\n**Project-level** (scoped to a specific project, can be committed to the repo):\n```bash\nmkdir -p /path/to/your/project/.claude/skills\ncp -R skills/excalidraw-skill /path/to/your/project/.claude/skills/excalidraw-skill\n```\n\nThen invoke the skill in Claude Code with `/excalidraw-skill`.\n\nTo update an existing installation, remove the old folder first then re-copy.\n\n### Use The Skill Scripts\n\nAll scripts respect `EXPRESS_SERVER_URL` (default `http://localhost:3000`) or accept `--url`.\n\n```bash\nEXPRESS_SERVER_URL=http://127.0.0.1:3000 node skills/excalidraw-skill/scripts/healthcheck.cjs\nEXPRESS_SERVER_URL=http://127.0.0.1:3000 node skills/excalidraw-skill/scripts/export-elements.cjs --out diagram.elements.json\nEXPRESS_SERVER_URL=http://127.0.0.1:3000 node skills/excalidraw-skill/scripts/import-elements.cjs --in diagram.elements.json --mode batch\n```\n\n### When The Skill Is Useful\n\n- Repository workflow: export elements as JSON, commit it, and re-import later.\n- Reliable refactors: clear + re-import in `sync` mode to make canvas match a file.\n- Automated smoke tests: create/update/delete a known element to validate a deployment.\n- Repeatable diagrams: keep a library of element JSON snippets and import them.\n\nSee `skills/excalidraw-skill/SKILL.md` and `skills/excalidraw-skill/references/cheatsheet.md`.\n\n## MCP Tools (26 Total)\n\n| Category | Tools |\n|---|---|\n| **Element CRUD** | `create_element`, `get_element`, `update_element`, `delete_element`, `query_elements`, `batch_create_elements`, `duplicate_elements` |\n| **Layout** | `align_elements`, `distribute_elements`, `group_elements`, `ungroup_elements`, `lock_elements`, `unlock_elements` |\n| **Scene Awareness** | `describe_scene`, `get_canvas_screenshot` |\n| **File I/O** | `export_scene`, `import_scene`, `export_to_image`, `export_to_excalidraw_url`, `create_from_mermaid` |\n| **State Management** | `clear_canvas`, `snapshot_scene`, `restore_snapshot` |\n| **Viewport** | `set_viewport` |\n| **Design Guide** | `read_diagram_guide` |\n| **Resources** | `get_resource` |\n\nFull schemas are discoverable via `tools/list` or in `skills/excalidraw-skill/references/cheatsheet.md`.\n\n## Testing\n\n### Canvas Smoke Test (HTTP)\n\n```bash\ncurl http://localhost:3000/health\n```\n\n### MCP Smoke Test (MCP Inspector)\n\nList tools:\n```bash\nnpx @modelcontextprotocol/inspector --cli \\\n  -e EXPRESS_SERVER_URL=http://localhost:3000 \\\n  -e ENABLE_CANVAS_SYNC=true -- \\\n  node dist/index.js --method tools/list\n```\n\nCreate a rectangle:\n```bash\nnpx @modelcontextprotocol/inspector --cli \\\n  -e EXPRESS_SERVER_URL=http://localhost:3000 \\\n  -e ENABLE_CANVAS_SYNC=true -- \\\n  node dist/index.js --method tools/call --tool-name create_element \\\n  --tool-arg type=rectangle --tool-arg x=100 --tool-arg y=100 \\\n  --tool-arg width=300 --tool-arg height=200\n```\n\n### Frontend Screenshots (agent-browser)\n\nIf you use `agent-browser` for UI checks:\n```bash\nagent-browser install\nagent-browser open http://127.0.0.1:3000\nagent-browser wait --load networkidle\nagent-browser screenshot /tmp/canvas.png\n```\n\n## Troubleshooting\n\n- Canvas not updating: confirm `EXPRESS_SERVER_URL` points at the running canvas server.\n- Updates/deletes fail after batch creation: ensure you are on a build that includes the batch id preservation fix (merged via PR #34).\n\n## Known Issues / TODO\n\nAll previously listed bugs have been fixed in v2.0. Remaining items:\n\n- [ ] **Persistent storage**: Elements are stored in-memory — restarting the server clears everything. Use `export_scene` / snapshots as a workaround.\n- [ ] **Image export requires a browser**: `export_to_image` and `get_canvas_screenshot` rely on the frontend doing the actual rendering. The canvas UI must be open in a browser.\n\nContributions welcome!\n\n## Development\n\n```bash\nnpm run type-check\nnpm run build\n```\n","readmeFilename":"README.md","_rev":"1-1da8b5988b849eaae609b4df464c5d1f"}