Tldraw

io.github.tldraw由 GitHub 账号 tldraw 发布v0.1.0更新于 Oct 25, 2026

Draw and visually collaborate with your agents on tldraw's canvas.

已验证Streamable HTTP可网页运行开发者工具媒体与设计

概览

AI 生成的概览

远程 tldraw 画布服务器,让助手检索编辑器 API 并运行 JavaScript,在共享画布上绘制和编辑图形。

可以做什么
通过编写接收 spec 对象的 JavaScript,检索 tldraw 编辑器 API 规范中的方法、属性、分类和图形类型。对实时 tldraw 画布执行 JavaScript,未提供 canvasId 时新建画布。保存和读取画布检查点,包括保存用户编辑产生的图形。仅应用内工具用于处理待执行的 exec 请求并获取画布最新检查点。
适用场景
当希望智能体在支持 MCP app 规范的 MCP 客户端中绘制、制图或在 tldraw 画布上可视化协作,而不只是输出文字时使用。
运行要求
使用托管在 Cloudflare Workers 的远程端点,或开发时使用 localhost:8787 的本地 worker。客户端需支持 MCP app 规范并在 iframe 中渲染画布组件。本地开发需要 Node.js 与 pnpm、构建仓库;ChatGPT 还需 HTTPS 的 Cloudflare 隧道及 OpenAI 组织管理员权限。
安装前请注意
exec 工具会对实时编辑器执行任意 JavaScript,代码可能创建、修改或删除画布内容。画布状态会保存到服务端 SQLite 存储和浏览器本地存储,会话闲置 7 天后销毁。Claude Desktop 自定义连接器可能需要付费方案。

安装

在 SourceWeft 中

  1. 打开 控制台中的 Tldraw,将其添加到工作区。
  2. 为需要使用其工具的对话启用该服务。

Web executable,通过 Streamable HTTP。 远程服务在工作区中配置后即可从网页运行时运行。

交给智能体安装

把这段提示词粘贴到 Claude Code、Codex、Cursor 等智能体,或 SourceWeft 对话中。智能体会读取该服务器的安装指南,先向你展示发布者、端点和登录方式,经你同意后再把它添加到你的客户端。密钥不会写进任何命令。

阅读 https://sourceweft.com/mcp/io.github.tldraw%2Ftldraw/install.md,并按其中说明把这个 MCP 服务器接入我的客户端。修改任何配置之前,先告诉我它的发布者、端点和登录方式,等我确认。不要把 API 密钥写进命令或我会提交的文件;问我密钥应从哪里获取。

查看智能体所依据的安装指南

其他 MCP 客户端

把它添加到你客户端的 mcpServers 配置中。

{
  "mcpServers": {
    "tldraw": {
      "type": "http",
      "url": "https://tldraw-mcp-app.tldraw.workers.dev/mcp"
    }
  }
}

README

tldraw MCP app

This is the tldraw MCP app. It exposes an interactive tldraw canvas to AI agents via the Model Context Protocol app specification, so you can work in tldraw with agents in any MCP client that supports the MCP app spec.

Architecture

The app has two parts: a server and a widget.

Server

The server runs in Cloudflare Workers via src/worker.ts, using a Durable Object (TldrawMCP) backed by SQLite for persistent checkpoint storage.

It exposes:

  • search — query the extracted Editor API spec in a sandboxed dynamic worker
  • exec — execute JavaScript against the live editor in the widget via a pending-request callback bridge
  • _exec_callback — app-only tool the widget calls to resolve a pending exec request
  • save_checkpoint / read_checkpoint — app-only tools used by the widget for checkpoint persistence

Widget

The widget is a React app (src/widget/mcp-app.tsx) that renders a full tldraw canvas inside the MCP host's iframe.

When the AI calls exec, the server creates a pending request and the widget picks it up, runs the code through a focused editor proxy (src/widget/focused/) that translates between an AI-friendly shape format (simple string IDs, flat _type shapes) and tldraw's internal TLShape/TLShapeId types, then calls _exec_callback to resolve the pending request with the result. Canvas state is checkpointed to the Durable Object's SQLite database and to the browser's local storage.

Developing

Prerequisites

The widget build depends on generated files (editor-api.json, method-map.json) that are extracted from the editor's TypeScript declarations. Before you can develop or build the mcp-app, you need to build the core packages first:

bash
# from the repo rootpnpm build

This produces the .tsbuild/ output that pnpm extract-api reads from. The build and dev scripts run extract-api automatically, so you don't need to call it separately.

Package scripts

Run all commands from apps/mcp-app.

CommandWhat it does
pnpm buildBuild the widget HTML
pnpm devBuild widget + start local Cloudflare worker (HTTP MCP on localhost:8787)
pnpm dev:tunnelBuild widget + start a stable named Cloudflare tunnel + local worker with WORKER_ORIGIN set to the tunnel URL
pnpm run deployBuild widget + deploy the Cloudflare worker to production

pnpm dev:tunnel requires the cloudflared CLI to be installed on your machine and a one-time cloudflared tunnel login. It serves a stable per-user hostname (<user>-mcp-app-dev.tldraw.xyz) via a named tunnel, so the URL you register in hosted MCP clients stays the same across runs instead of changing every time. The user slug defaults to whoami; override it (or the zone/port) with MCP_TUNNEL_USER, MCP_TUNNEL_ZONE, and PORT. The zone must be a Cloudflare-hosted zone (tldraw.xyz is; tldraw.dev/tldraw.com are on Vercel and won't work).

The worker defaults to production-safe behavior in wrangler.toml, including setting MCP_IS_DEV="false". Local HTTP dev scripts override that with MCP_IS_DEV=true so local Claude/ChatGPT connectors suppress ui.domain while production deployments keep it enabled.

Cursor setup

Add these two servers in ~/.cursor/mcp.json:

json
{	"mcpServers": {		"tldraw": {			"transport": "http",			"url": "https://tldraw-mcp-app.tldraw.workers.dev/mcp"		},		"tldraw-local": {			"command": "npx",			"args": ["-y", "mcp-remote", "http://127.0.0.1:8787/mcp"]		}	}}

Claude Desktop local setup

For local Claude Desktop development, use claude_desktop_config.json with the local HTTP server:

json
{	"mcpServers": {		"tldraw-local": {			"command": "npx",			"args": ["-y", "mcp-remote", "http://127.0.0.1:8787/mcp"]		}	}}

Claude Desktop remote setup

If you'd like to try the remote MCP server in Claude Desktop, use the in-app connector flow rather than adding the production URL to claude_desktop_config.json.

  1. Open Claude Desktop
  2. In the sidebar, go to Customize
  3. Open Connectors
  4. Click the button to add a connector, then choose Add custom connector
  5. Give it a name such as tldraw
  6. Paste https://tldraw-mcp-app.tldraw.workers.dev/mcp as the server URL

The Add custom connector option is not available on the free plan, so you may need Max or another paid plan.

If you need Notion access in Claude Desktop, use the Notion MCP connector for that separately.

ChatGPT local dev

ChatGPT requires an HTTPS origin, so you need a Cloudflare tunnel. You must be an admin of your OpenAI org/workspace to do local dev.

First-time setup (once per machine):

  1. Run cloudflared tunnel login and choose the tldraw.xyz zone

Then, each session:

  1. Run pnpm dev:tunnel in apps/mcp-app
  2. It serves your stable hostname, e.g. https://<user>-mcp-app-dev.tldraw.xyz (the first run also creates the named tunnel and its DNS route)
  3. In ChatGPT web (not the desktop app), go to Apps and add your app using that URL
  4. You can then test in both ChatGPT web and the desktop or mobile apps

Because the hostname is stable per user, you only add the app in ChatGPT once — subsequent pnpm dev:tunnel runs reuse the same URL.

dev:tunnel automatically wires WORKER_ORIGIN to the stable tunnel URL and sets MCP_IS_DEV=true for the local worker.

Iteration loop

  1. Make code changes in apps/mcp-app
  2. Run the relevant script (dev or dev:tunnel)
  3. Disconnect and reconnect the MCP server in your client (or reload the page/app)
  4. When making widget changes, make sure to rebuild, either by running pnpm build or rerunning any of the dev scripts.

Reconnecting the server after changes is the most reliable way to pick up new code, especially when the widget HTML changes.

Session storage lifecycle

Each MCP session is a TldrawMCP Durable Object. It keeps up to MAX_CHECKPOINTS (50) canvas snapshots and destroys itself after IDLE_TTL_MS (7 days) without a checkpoint save — a schedule armed in init() and re-armed on every check.

Contact

Find us on Twitter/X at @tldraw.

Community

Have questions, comments or feedback? Join our discord. For the latest news and release notes, visit tldraw.dev.

来源:apps/mcp-app/README.md,提交 a0cd8f2

工具

6

exec

Execute Code

Execute JavaScript code on a tldraw canvas. The code runs in the widget with access to the live `editor` instance, helper functions, and normal js. Use the `search` tool first to discover available Editor methods and shape types. Each canvas has a unique `canvasId`. Omit `canvasId` to create a new blank canvas. To edit an existing canvas, pass the `canvasId` that was returned by a previous exec call. Shapes and text grow depending on the amount of text they have. Use clever scripting to ensure there are no unintended overlaps. Examples: - Create a rectangle: editor.createShape({ _type: 'rectangle', shapeId: 'box1', x: 200, y: 120, w: 320, h: 180, text: 'Hello' }) - Connect shapes with an arrow: editor.createShape({ _type: 'arrow', shapeId: 'a1', fromId: 'box1', toId: 'box2', x1: 0, y1: 0, x2: 100, y2: 0 }) - Select and zoom: editor.select('box1'); editor.zoomToSelection() - Read shapes: return editor.getCurrentPageShapes() - Distribute evenly: editor.distributeShapes(editor.getSelectedShapeIds(), 'horizontal') - Box around shapes: boxShapes(['box1', 'box2'], { text: 'Group label', color: 'blue' }) - Stack shapes dynamically: editor.createShape({ _type: 'rectangle', shapeId: 'a', x: 0, y: 0, w: 300, h: 200, text: 'First box\nwith wrapping text' }); const bounds = editor.getShapePageBounds('a'); editor.createShape({ _type: 'rectangle', shapeId: 'b', x: 0, y: bounds.maxY + 20, w: 300, h: 200, text: 'Below first' })

输入参数code必填canvasId

_exec_callback

Exec Callback

App-only: widget calls this to resolve a pending exec request.

输入参数errorresultchannel必填execKey

_get_canvas_state

Get Canvas State

App-only: get the latest checkpoint for a canvas by its canvasId.

输入参数canvasId必填

read_checkpoint

Read Checkpoint

App-only: read shapes from a checkpoint by ID.

输入参数checkpointId必填

save_checkpoint

Save Checkpoint

App-only: save shapes to a checkpoint (from user edits). shapesJson and assetsJson must be JSON array strings.

输入参数canvasIdassetsJsonshapesJson必填bindingsJsoncheckpointId必填

版本历史

1
  1. v0.1.0最新Sep 16, 2026

评分

已满足适用检查项的 90%

该评分衡量此收录条目的完整程度,依据注册中心条目、端点与公开来源计算得出。它不是对服务器本身的评价,也不表示服务器安全或当前可用:可连通性是带日期的检查结果,评分也不包含安装量或用户评价。

  • 近 30 天内可连通必需25 分
  • 已声明认证方式必需10 分
  • 已列出工具必需15 分
  • 描述必需15 分
  • 图标10 分
  • 文档15 分
  • 许可证10 分

    请在仓库或注册中心条目中声明许可证。