pulp

pulp

Enables AI agents to collaboratively design and edit web pages on an infinite canvas using real HTML/CSS, with tools for reading, mutating, and exporting documents.

Category
访问服务器

README

pulp

The local-first, agent-driven design canvas. pulp is an infinite canvas where drawings are real HTML and CSS, humans and coding agents edit the same document, and the browser remains the source of truth. Ask Claude or Codex to design a page and watch it appear live, refine it by hand, save the editable drawing as a file, or export it as PNG, SVG, HTML, a portable deck, or PDF.

  • Real DOM, not pictures. Every frame is real flexbox layout rendered by the browser. Canvas rendering and export share the same code generator, so HTML export is lossless.
  • Local first. Named workspaces autosave independently in browser storage. Editable .pulp.json files provide explicit backups and handoff; no cloud account or database is required.
  • Agents first. Eighteen MCP tools let Claude, Codex, and other clients read and mutate the document. Multiple agents can share one live workspace or use isolated named sessions without fighting over the bridge port.
  • Review is a loop, not a screenshot. Pin human feedback to a layer or canvas position; agents read the workspace inbox over MCP, make the change, and resolve it with a visible response. The MCP console keeps a searchable, workspace-persistent audit of every received request and response.
  • Rust core, WASM delivery. The scene graph, command API, undo/redo, validation, and HTML codegen are a Rust crate compiled to WebAssembly. The app itself is static and deploys to GitHub Pages.

Browser demo

Watch the browser-only Pulp demo

The 45-second browser-only walkthrough shows the live canvas, presentation mode, the MCP request/response history, and the multi-format export menu.

Quick start

Prerequisites: Node 20+, Rust via rustup with the WASM target, and wasm-pack:

rustup target add wasm32-unknown-unknown
cargo install wasm-pack --locked

Then:

npm install
npm run build:engine   # rerun after Rust changes
npm run build:mcp      # rerun after MCP changes
npm run dev            # http://localhost:5173

Open http://localhost:5173 for the default workspace, or name one in the URL:

http://localhost:5173/?workspace=design-notes

The workspace chip can switch among drawings already saved by that browser. Names are normalized to lowercase letters, numbers, _, and -; use the name shown in the chip when configuring an agent.

Connect agents

The repo's .mcp.json automatically registers Pulp for Claude Code launched inside this directory. For a global registration:

claude mcp add pulp -- node /absolute/path/to/pulp/mcp/dist/index.js
codex mcp add pulp -- node /absolute/path/to/pulp/mcp/dist/index.js

With the default editor open, both clients join the default session and can work on the same canvas. The first local MCP process becomes the lightweight broker; later processes join it automatically, so EADDRINUSE is not a user workflow or an error to work around.

For a named browser workspace, set the MCP session to the same normalized name:

claude mcp add pulp-design-notes -- \
  env PULP_SESSION=design-notes PULP_CLIENT_NAME=claude \
  node /absolute/path/to/pulp/mcp/dist/index.js

codex mcp add pulp-design-notes -- \
  env PULP_SESSION=design-notes PULP_CLIENT_NAME=codex \
  node /absolute/path/to/pulp/mcp/dist/index.js

PULP_SESSION controls routing; PULP_CLIENT_NAME is the label shown in logs and the editor's live agent-activity cards. Agents using the same session share the corresponding editor. Give agents different sessions, with one browser tab per named workspace, to isolate their documents. All normal sessions share port 7857 through the broker.

Advanced local experiments can pair PULP_PORT=7867 with ?port=7867, or use an explicit browser bridge such as ?bridge=ws://127.0.0.1:7867. A hosted HTTPS page requires an explicitly supplied wss:// bridge; this repository does not deploy one.

Once the toolbar says agent live, ask an agent something like:

Design a SaaS landing page in pulp: dark hero, three feature cards, footer.

The agent reads a compact document outline, applies JSON commands, and every change renders immediately. Human edits use the same engine and undo history, so the next agent read sees them. The canvas shows the four most recent agent operations with pending, success, or error state; click a completed targeted operation to reveal its layer. Open MCP for the full searchable request and response history, including source agent, session, target, timing, filters, and copyable JSON.

Press C or open Review to attach feedback to the selected layer or place a pin on the canvas. Open items are stored per workspace. Agents consume them with pulp_list_feedback and close the loop with pulp_resolve_feedback; their name and response appear on the feedback card. Because MCP stdio is client-initiated, a pin is a durable inbox item for the agent's next read—it does not wake an idle Claude/Codex process by itself.

Agent onboarding is in AGENTS.md. Claude and Codex also receive the matching pulp-design skill from .claude/skills/ and .agents/skills/.

Local-first files and workspaces

Each ?workspace=<name> has its own autosave key, pulp.doc.<normalized-name>, on the current browser origin. Autosave is debounced after document mutations and its state appears in the toolbar.

  • Save downloads the complete editable document as <title>.pulp.json.
  • Open validates a .pulp.json file, replaces the current drawing, and autosaves it into the current workspace.
  • PNG / SVG / HTML export the selected frame as a 2x raster image, scalable wrapper, or lossless standalone DOM page.
  • Presentation HTML turns every root frame into a portable keyboard-driven deck. Print / PDF opens the same frames one per print page.

Browser storage is convenient working state, not a durable backup. Save a .pulp.json file before clearing site data, changing browsers, or handing a drawing to another machine. Invalid or structurally broken document files are rejected without replacing the current canvas.

How it fits together

browser workspace (?workspace=design-notes)
  editor UI -> Rust/WASM document engine -> local autosave / .pulp.json / HTML
       ^
       | session "design-notes" over ws://127.0.0.1:7857
       |
shared MCP broker
  ^                 ^
  | stdio           | stdio
Claude Code       Codex (and other MCP clients)

Every mutation goes through the same engine command API. The document is plain JSON; a patch looks like:

{ "cmd": "set_props", "id": "n4",
  "props": { "style": { "fill": "#0b0b10", "shadow": null } } }

Patches deep-merge: only fields present in the command change, and null clears a field.

Editor controls

Action Input
Pan Space+drag, middle-drag, or scroll
Zoom Pinch or ⌘/Ctrl+scroll
Actual size 0
Fit selection / fit all 1 / 2
Create frame F
Create rectangle / ellipse R / O
Create sticky note / text N / T
Select Click; Shift+click for multi-select
Move / resize Drag a frame or absolute child; drag selection handles
Undo / redo ⌘/Ctrl+Z / Shift+⌘/Ctrl+Z
Duplicate / delete ⌘/Ctrl+D / Delete
Clear selection Escape
Toggle Layers / Inspector [ / ]
Focus mode \
Pin review feedback C; submit with ⌘/Ctrl+Enter
Present frames as slides P; then arrows/space/Page Up/Page Down; Esc exits
Rename Double-click in the Layers panel
Reveal on canvas Alt+double-click in the Layers panel

On initial load, Pulp fits all frames into view. Creation shortcuts place new objects in the active frame, creating a frame first when necessary.

Verification

npm run test:engine       # native Rust engine tests
npm run test:mcp-multi    # shared broker, isolation, failover, timeout tests
npm run test:mcp-tools    # MCP tool registration, including feedback tools
npm run test:feedback     # workspace feedback persistence and isolation
npm test                  # both suites
npm run build             # WASM engine + app + MCP builds
npm run check             # tests, then the full production build

With a local editor open on the matching session, the destructive end-to-end smoke test exercises the MCP tools and creates a sample frame:

node mcp/smoke.mjs

Deploy

Pushing to main runs the test suites, builds the engine and app, and deploys app/dist to GitHub Pages. The hosted editor, named workspaces, local autosave, file Open/Save, all export formats, and presentation mode work without a backend. Agent control defaults to local development because a hosted HTTPS page cannot open an insecure local WebSocket; an explicit wss:// bridge is an opt-in advanced configuration. On HTTPS, the app also registers its manifest and offline shell; after the assets have been cached by an online visit, it can reopen without the network.

Layout

engine/   Rust/WASM document model, commands, validation, history, codegen
app/      Vite/TypeScript editor, canvas UI, workspaces, local files, bridge client
mcp/      MCP tools, shared multi-session WebSocket broker, smoke tests

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选