{
  "markdown": "# excalidraw-mcp-server\n\nThe only Excalidraw MCP server with security hardening, inline diagram rendering, and real-time canvas sync.\n\n[![CI](https://github.com/debu-sinha/excalidraw-mcp-server/actions/workflows/ci.yml/badge.svg)](https://github.com/debu-sinha/excalidraw-mcp-server/actions/workflows/ci.yml)\n[![npm](https://img.shields.io/npm/v/excalidraw-mcp-server)](https://www.npmjs.com/package/excalidraw-mcp-server)\n[![npm downloads](https://img.shields.io/npm/dt/excalidraw-mcp-server)](https://www.npmjs.com/package/excalidraw-mcp-server)\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)\n[![Node](https://img.shields.io/badge/node-%3E%3D18-brightgreen.svg)](https://nodejs.org/)\n\n<p align=\"center\">\n  <img src=\"docs/demo.gif\" alt=\"Demo: architecture diagram being drawn element-by-element in real-time through WebSocket sync\" width=\"720\" />\n</p>\n\n## What it does\n\nAsk your AI to draw a diagram, and it appears right inside the chat. The MCP server gives Claude Desktop, ChatGPT, VS Code, and Cursor a full set of drawing tools backed by the Excalidraw format -- with API authentication, rate limiting, and input validation on every operation.\n\nv2.0 adds **MCP Apps support**: diagrams stream inline as interactive SVG widgets with draw-on animations, and you can export any diagram to excalidraw.com with one click.\n\n## Two modes, zero config\n\n**Standalone mode** (default) -- just install and go. The server runs with an in-process element store. No canvas server, no API keys, no setup. Your MCP client calls the tools, and diagrams render inline.\n\n**Connected mode** -- start the optional canvas server for real-time browser sync. Multiple clients can collaborate on the same canvas through authenticated WebSocket connections. File persistence keeps state across restarts.\n\nThe server auto-detects which mode to use: if a canvas server is reachable, it connects to it. Otherwise it falls back to standalone.\n\n## Architecture\n\n<p align=\"center\">\n  <img src=\"docs/architecture-v2.svg\" alt=\"Architecture: MCP clients connect via stdio to the server, which operates in standalone mode with an in-process store and inline widget, or in connected mode with a canvas server, WebSocket browser frontend, and file persistence\" width=\"800\" />\n</p>\n\n*Diagram created with excalidraw-mcp-server -- [edit in Excalidraw](docs/architecture-v2.excalidraw.json)*\n\n## Features\n\n**MCP Apps (v2.0)**\n- Inline diagram rendering in Claude Desktop, ChatGPT, and VS Code\n- Streaming SVG with draw-on animations as elements arrive\n- Export to excalidraw.com with one click\n- Element reference cheatsheet via `read_me` tool\n\n**16 MCP tools**\n- Create, update, delete, and query elements (rectangle, ellipse, diamond, arrow, text, line, freedraw)\n- Batch create up to 100 elements at once\n- Group, ungroup, align, distribute, lock, unlock\n- Mermaid diagram conversion\n- SVG and PNG export\n\n**Security**\n- API key authentication with constant-time comparison\n- Origin-restricted CORS (no wildcards)\n- WebSocket auth with token and origin validation\n- Standard and strict rate limiting tiers\n- Bounded Zod schemas with `.strict()` on every endpoint\n- Helmet.js security headers with CSP\n\n**Infrastructure**\n- Real-time WebSocket sync across browser clients\n- Optional atomic-write file persistence\n- Structured pino audit logging\n\n## Install\n\n```bash\nnpm install -g excalidraw-mcp-server\n```\n\nOr run directly:\n\n```bash\nnpx excalidraw-mcp-server\n```\n\n## Quick start\n\n### Standalone (recommended for most users)\n\nJust point your MCP client at the server. No canvas server needed.\n\n```json\n{\n  \"mcpServers\": {\n    \"excalidraw\": {\n      \"command\": \"npx\",\n      \"args\": [\"excalidraw-mcp-server\"]\n    }\n  }\n}\n```\n\nThen ask your AI: *\"Draw an architecture diagram showing a load balancer, three app servers, and a database\"*\n\n### Connected mode (real-time browser sync)\n\n```bash\n# Generate an API key\nnode scripts/generate-api-key.cjs\n\n# Start the canvas server\nEXCALIDRAW_API_KEY=<your-key> npm run canvas\n\n# Open http://localhost:3000 to see the live canvas\n```\n\nPoint your MCP client at the server with the same API key:\n\n```json\n{\n  \"mcpServers\": {\n    \"excalidraw\": {\n      \"command\": \"npx\",\n      \"args\": [\"excalidraw-mcp-server\"],\n      \"env\": {\n        \"EXCALIDRAW_API_KEY\": \"<your-key>\",\n        \"CANVAS_SERVER_URL\": \"http://127.0.0.1:3000\"\n      }\n    }\n  }\n}\n```\n\n## MCP tools\n\n| Tool | Description |\n|------|-------------|\n| `create_view` | Render elements as an inline SVG widget with streaming animations (MCP Apps) |\n| `read_me` | Get the element reference cheatsheet (types, colors, sizing tips) |\n| `create_element` | Create a single element (rectangle, ellipse, diamond, arrow, text, line, freedraw) |\n| `update_element` | Update an existing element by ID |\n| `delete_element` | Delete an element by ID |\n| `query_elements` | Search elements by type, locked status, or group ID |\n| `get_resource` | Get scene state, all elements, theme, or library |\n| `batch_create_elements` | Create up to 100 elements in one call |\n| `group_elements` | Group multiple elements together |\n| `ungroup_elements` | Remove elements from a group |\n| `align_elements` | Align elements (left, center, right, top, middle, bottom) |\n| `distribute_elements` | Distribute elements evenly (horizontal or vertical) |\n| `lock_elements` | Lock elements to prevent modification |\n| `unlock_elements` | Unlock elements |\n| `create_from_mermaid` | Convert a Mermaid diagram to Excalidraw elements |\n| `export_scene` | Export the canvas as SVG or PNG |\n\n## Security comparison\n\n| Feature | Typical MCP servers | excalidraw-mcp-server |\n|---------|--------------------|-----------------------|\n| Authentication | None | API key (constant-time compare) |\n| CORS | `*` wildcard | Origin allowlist |\n| WebSocket auth | None | Token + origin validation |\n| Rate limiting | None | Standard + strict tiers |\n| Input validation | Minimal | Bounded Zod with `.strict()` |\n| Security headers | None | Helmet.js + CSP |\n| Request size limit | None | 512KB body, 1MB WebSocket |\n| Audit logging | None | Structured pino logs |\n\n## Configuration\n\nAll settings via environment variables. Copy `.env.example` to `.env` and adjust as needed.\n\n| Variable | Default | Description |\n|----------|---------|-------------|\n| `STANDALONE_MODE` | `true` | Use in-process store (no canvas server needed) |\n| `CANVAS_HOST` | `127.0.0.1` | Canvas server bind address |\n| `CANVAS_PORT` | `3000` | Canvas server port |\n| `EXCALIDRAW_API_KEY` | Auto-generated | API key for auth (min 32 chars) |\n| `CORS_ALLOWED_ORIGINS` | `http://localhost:3000,http://127.0.0.1:3000` | Comma-separated origin allowlist |\n| `RATE_LIMIT_WINDOW_MS` | `60000` | Rate limit window in milliseconds |\n| `RATE_LIMIT_MAX_REQUESTS` | `100` | Max requests per window (standard tier) |\n| `PERSISTENCE_ENABLED` | `false` | Enable file-based persistence |\n| `PERSISTENCE_DIR` | `./data` | Directory for persistent storage |\n| `CANVAS_SERVER_URL` | `http://127.0.0.1:3000` | URL the MCP server uses to reach the canvas |\n| `LOG_LEVEL` | `info` | Log level: debug, info, warn, error |\n| `AUDIT_LOG_ENABLED` | `true` | Enable audit logging |\n| `MAX_ELEMENTS` | `10000` | Maximum elements on canvas |\n| `MAX_BATCH_SIZE` | `100` | Maximum elements per batch create |\n\n## MCP client configuration\n\n### Claude Desktop\n\nAdd to `claude_desktop_config.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"excalidraw\": {\n      \"command\": \"npx\",\n      \"args\": [\"excalidraw-mcp-server\"]\n    }\n  }\n}\n```\n\n### Cursor\n\nAdd to `.cursor/mcp.json` in your project root:\n\n```json\n{\n  \"mcpServers\": {\n    \"excalidraw\": {\n      \"command\": \"npx\",\n      \"args\": [\"excalidraw-mcp-server\"]\n    }\n  }\n}\n```\n\n### VS Code\n\nAdd to your MCP settings:\n\n```json\n{\n  \"mcpServers\": {\n    \"excalidraw\": {\n      \"command\": \"npx\",\n      \"args\": [\"excalidraw-mcp-server\"]\n    }\n  }\n}\n```\n\nFor connected mode, add `\"env\": { \"EXCALIDRAW_API_KEY\": \"<key>\", \"CANVAS_SERVER_URL\": \"http://127.0.0.1:3000\" }` to the config above. Replace `<key>` with the key from `node scripts/generate-api-key.cjs`.\n\n## Development\n\n```bash\n# Install dependencies\nnpm ci\n\n# Run in development mode (watch + Vite dev server)\nnpm run dev\n\n# Run tests\nnpm test\n\n# Run tests with coverage\nnpm run test:coverage\n\n# Lint\nnpm run lint\n\n# Type check\nnpm run type-check\n\n# Build (server + widget + frontend)\nnpm run build\n```\n\n## Project structure\n\n```\nsrc/\n  mcp/              MCP server (stdio transport)\n    tools/          16 tool implementations\n    apps/           MCP Apps wiring, standalone store, cheatsheet\n    schemas/        Zod schemas and input limits\n    canvas-client.ts  HTTP client for canvas server\n    index.ts        MCP server entry point\n  canvas/           Canvas server (Express + WebSocket)\n    middleware/      Auth, CORS, rate limiting, audit, security headers\n    routes/         REST API routes + SVG export\n    ws/             WebSocket handler and protocol\n    store/          Element storage (memory + file)\n    index.ts        Canvas server entry point\n  shared/           Shared config, types, logging\nwidget/             MCP Apps inline widget (Vite + singlefile build)\nfrontend/           Excalidraw React frontend (browser)\ntest/               Unit and integration tests (290 tests)\n```\n\n## Migrating from v1.x\n\nZero-config upgrade. All 14 original tools work identically -- `create_view` and `read_me` are additive. The canvas server is now optional (standalone mode activates automatically).\n\n```bash\nnpm install -g excalidraw-mcp-server@2\n```\n\nExisting MCP client configs (stdio transport, tool names) continue to work without changes.\n\n## License\n\n[MIT](LICENSE)\n",
  "bytes": 9654,
  "sha": "ff339a6e92dc0f1a879e9806a67b7858a7df3cc41986485893e77b26a6d74877",
  "repo_slug": "debu-sinha/excalidraw-mcp-server",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_debu_sinha_excalidraw_2550b5a9/readme"
}