scratch-mcp
Enables editing Scratch .sb3 projects programmatically, including sprites, blocks, costumes, sounds, variables, and online project sharing, plus headless VM execution and live-reload in TurboWarp Desktop.
README
scratch-mcp
A Model Context Protocol server for editing
Scratch .sb3 projects, built on scratch4js. It keeps
one project open in memory, exposes the library's editing surface as MCP tools,
and saves back to disk.
It also hosts a live-reload bridge on http://localhost:9060. With the
TurboWarp Desktop userscript installed, every
save_project reloads the project live in the editor — so an agent's edits
appear instantly.
Install
npx scratch-mcp # serves MCP over stdio
Develop
The MCP server lives at the repo root; the libraries it builds on are workspace
packages under packages/.
pnpm install
pnpm run build # builds scratch4js, s-api4js and the userscript
pnpm start # serves MCP over stdio
Configure an MCP client
{
"mcpServers": {
"scratch": {
"command": "node",
"args": ["/abs/path/to/ScratchMCP/src/index.js"]
}
}
}
Set SCRATCH_MCP_BRIDGE_PORT to change the bridge port (default 9060). If the
port is taken the server still starts; only live reload is disabled.
Install as an MCP Bundle (.mcpb)
For one-click installation in Claude Desktop and other MCPB-aware clients, this
server packages as an MCP Bundle — a single
.mcpb file containing the server plus a self-contained node_modules.
pnpm run mcpb # → dist/scratch-mcp-<version>.mcpb
Then open the .mcpb in your client (in Claude Desktop, drag it into
Settings → Extensions). The bundle exposes one setting — the live-reload bridge
port — and needs no other configuration. The build (scripts/build-mcpb.mjs)
vendors the scratch4js and s-api4js workspace packages as tarballs and
installs the git
scratch-vm and its peers into a flat node_modules, as MCPB requires. The
manifest.json is the bundle's source of truth (its version
is stamped from package.json at build time).
Tools
Project
open_project { path }— load an.sb3into memory.save_project { path?, compressionLevel? }— write it back (and live-reload).project_info— targets, extensions, monitors, meta.
Scratch website (online projects, via s-api4js)
scratch_login { username?, password? }— log in to scratch.mit.edu (defaults to$SCRATCH_USER/$SCRATCH_PASS). The session lives in memory for the server process only.open_scratch_project { projectId }— download a project by id and open it for editing (shared projects need no login; your own unshared ones do).push_to_scratch { projectId?, confirm? }— save the open project back to scratch.mit.edu, overwriting it online (uploads assets, thenproject.json).share_project { projectId?, confirm? }— publish a project so it's public.
push_to_scratchandshare_projectchange the live project, so they always ask you to confirm first — via an MCP elicitation prompt when your client supports it, otherwise by requiringconfirm: true(which the agent should only set after you've agreed).
Reading
list_sprites— every sprite with position/size/media.get_target { name }— full details for a sprite or"Stage".get_target_json { name, pointer? }— the target's rawproject.jsonentry (blocks, costumes, sounds, …), or a subtree at a JSON Pointer. Read this before authoring apatch_target.
Block reference (so the agent knows which blocks exist and how to fill them)
list_blocks { category? }— the catalog of standard opcodes, each with its category, shape (hat / stack / c-block / cap / reporter / boolean) and the names of its inputs and fields. Generated at startup from the installedscratch-vm, so it stays in sync.get_block_schema { opcode, target? }— full schema for one opcode: every input with its sb3 shadow encoding (e.g. a text input is[1, [10, "hi"]]), every field with enumerated dropdownoptions, and a ready-to-adapt example block JSON. Dynamic menu options (sprites, sounds, costumes, broadcasts, …) are filled from the open project; passtargetto enumerate that sprite's own costumes and sounds. Covers built-in extension blocks too (pen_*,music_*,microbit_*, …), generated from each extension'sgetInfo().
Extensions
enable_extension { id, url? }— register an extension so its blocks load and show in the palette (required before using any<id>_…block). Pass justidfor a built-in (pen, music, videoSensing, text2speech, translate, makeymakey, microbit, ev3, boost, wedo2, gdxfor); addurlfor a custom/third-party (TurboWarp) extension.list_blocks { category: "<id>" }andget_block_schemadescribe built-in extension blocks;patch_targetwarns when a block uses an extension that isn't enabled. Custom extensions are opaque — mirror an existing block viaget_target_json.
Editing raw JSON (diff/patch)
patch_target { name, patch }— apply an RFC 6902 JSON Patch to a target's raw JSON. This is how you edit a sprite's scripts (blocks) or any field the higher-level tools don't cover — on a sprite you just created or an existing one. Paths are JSON Pointers intoget_target_json; the patch applies atomically (all-or-nothing) and the result reports advisorywarningsfor unknown opcodes or inputs. Patchingcostumes/soundsarrays doesn't move asset bytes — useadd_costume/remove_costumefor that.
Sprites & stage
set_sprite { name, x?, y?, size?, direction?, visible?, draggable?, rotationStyle?, layerOrder?, volume? }add_sprite { name, ...props }/remove_sprite { name }/rename_target { name, newName }set_stage { tempo?, videoState?, videoTransparency?, volume? }
Variables, lists, broadcasts (target is a sprite name or "Stage")
set_variable { target, name, value }/delete_variable { target, name }set_list { target, name, items }/delete_list { target, name }add_broadcast { name }
Costumes & sounds
add_costume { target, name, path, dataFormat?, rotationCenterX?, rotationCenterY? }remove_costume { target, name }add_sound { target, name, path, dataFormat? }/remove_sound { target, name }
Run & test (headless TurboWarp VM, in-process)
vm_load— load the open project into a headless VM (reflects in-memory edits).vm_green_flag— press the green flag (clears bubbles, question, errors).vm_run { seconds?, frames?, untilIdle?, paced? }— advance the VM, then return state plus aneventstimeline (say/think, broadcasts, question/answer, errors) since the last run.vm_state— snapshot: every target's position/size/direction/costume/visibility, variables, lists, monitors, say/think bubbles, pending question, running threads, errors.vm_input { keys?, mouseX?, mouseY?, mouseDown?, answer? }— feed keyboard/mouse input and answerask and wait.vm_stop— stop all scripts.
Live reload & screenshots (require the bridge + userscript)
reload { path? }— load an.sb3from disk in the editor.run_project/stop_project— green flag / stop.screenshot— capture the live stage as a lossless PNG, for when exact pixels matter. Takes no parameters.screenshot_jpeg { quality? }— the same capture re-encoded as a compressed JPEG (smaller, cheaper to read;quality1–100, default 80).
Running and testing a project
The vm_* tools embed TurboWarp's scratch-vm
(the JIT fork) in this process — no browser, no WebGL. The loop is: edit →
vm_load → vm_green_flag → vm_run → read vm_state → assert. It returns
structured state (variable values, sprite positions, say bubbles), which an
agent can assert against directly — far better than reasoning over pixels, and
deterministic enough for CI.
The headless VM has no renderer or audio: costume metadata still loads (so
costume-by-name/number logic works), but renderer-backed blocks (touching
colour/sprite/edge, pen) and sound playback are inert. To see the real rendered
stage, run the project in TurboWarp Desktop and call screenshot.
Events
Notable events — say/think, broadcast, greenflag, stop,
question/answer and runtime/compile errors, each { level, type, message, …fields } — are surfaced two ways:
- In
vm_run's result (events): the ordered timeline since the previousvm_run. This is the agent-facing channel — the model reads it directly in the tool result and can assert on sequence, not just final state. Always on. - As MCP log notifications (
notifications/message,logger: "scratch-vm"): the client/human-facing channel for a host's log view. Off until the client raises its log level vialogging/setLevel—"info"for activity,"debug"to also include run boundaries and bubble-clears,"warning"+ for errors only. (Most clients don't feed notifications back to the model, which is why thevm_runchannel exists.)
Repeated identical say/think bubbles are de-duplicated so a say in a loop
doesn't flood either channel.
How live reload works
The bridge is a plain WebSocket + HTTP server. The userscript connects over
WebSocket and answers JSON requests (loadSB3 / start / stop / screenshot).
On loadSB3 it fetches the bytes from GET /get.sb3?path=… and loads them into
the TurboWarp VM; save_project writes the file then sends loadSB3, so the
editor always shows the latest save. A snapshot comes back as a PNG, which the
server passes through unchanged (screenshot) or re-encodes as a compressed
JPEG (screenshot_jpeg).
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。