Skip to main content
Glama
AnNingUI

Blockbench MCP Pro

by AnNingUI

Blockbench MCP Pro

读完 ./repos/ 下五个 Blockbench MCP 项目后,把它们的优点全部吸收、缺点全部修掉,重新写的一个最完善的实现。 96 个工具插件内进程 HTTP MCP(无需额外 Node 进程)+ stdio 网关 双通道、强制随机 Bearer 鉴权文件作用域全量 undo 集成程序化生成器质量门人审门参考图 IoU 比对

  • 协议:MCP 2024-11-05(Streamable HTTP / JSON),另附 stdio 转发网关

  • 宿主:Blockbench Desktop ≥ 5.1.0

  • 许可:MIT(五个参考项目中两个是 GPL,本项目全部重写,不受传染)


目录

  1. 为什么还要第六个

  2. 架构:双通道

  3. 快速开始

  4. 工具总览(95)

  5. 区别表 A:五个参考项目速览

  6. 区别表 B:能力与工程质量矩阵

  7. 区别表 C:逐项目"吸取了什么 / 抛弃了什么"

  8. 安全模型

  9. 质量门与推荐工作流

  10. 发布到 npm

  11. 接入 Blockbench

  12. 接入 AI 客户端

  13. 目录结构

  14. 开发与验证

  15. 已知取舍


Related MCP server: Blockbench MCP

为什么还要第六个

五个项目各自解决了一段路,但没有一个把关键能力凑齐:

  • sosadly/blockbench-mcp 有最好的"让模型真的会建模"的东西(程序化生成器、质量门、人审门、参考图比对),但它是外置 Node 服务端 + 无鉴权的 HTTP 网桥,插件本体是一个 7000+ 行的单文件 JS,没有 UV 布局检查、没有纹理版本控制、能往任意路径写文件。

  • SwagRee/BlockBenchMCP 工程最扎实(zod 契约、UV 模式感知、面局部绘制、纹理 revision token、文件作用域、真实的测试),但没有程序化生成器、没有人审门、没有参考比对、没有动画生成,而且默认共享密钥是硬编码的 dev-local-secret

  • jasonjgardner/blockbench-mcp-plugin 工具面最大(110 个,含网格/材质/会话保活/resources/prompts),但是 GPL-3.0,并且带 emulate_clicks / trigger_action / risky_eval 这类直接点击 UI 的危险工具,没有任何鉴权

  • vasyacullin-Blockbench-mcp 的 token 握手与"万能 action 桥"很好,但同样是 GPL、纯 JS、无 undo 封装、无 UV/纹理检查,只有 41 个工具。

  • Golub4ik-Official-blockbench-mcp 只有 5 个工具,却是唯一做了 monorepo + 预构建产物的,工程形态值得借鉴。

所以本项目的目标很直白:把上面所有"优点"合到一个 MIT 项目里,并且把每一条"缺点"当作设计约束


架构:双通道

                    ┌──────────────────────────────────────────────┐
  HTTP 客户端        │  Blockbench Desktop                          │
  (Cursor / VS Code  │  ┌────────────────────────────────────────┐  │
   / Claude Code     │  │ Blockbench MCP 插件(rolldown 单文件产物) │  │
   / Cline / Ollama) │  │  · 127.0.0.1:39742/mcp  进程内 MCP 服务 │  │
        ───────────────▶  · Bearer + Origin/Host 校验               │  │
                    │  │  · dispatch → 95 个工具 → Blockbench API │  │
                    │  │  · 全部改动包在 Undo.initEdit/finishEdit │  │
                    │  └────────────────────────────────────────┘  │
  stdio 客户端        │                                              │
  (Claude Desktop)   └──────────────────────────────────────────────┘
        ───▶ gateway/index.mjs ───(HTTP + Bearer)──▶ 上面同一个端点
             (零依赖 stdio ⇄ HTTP 转发,工具实现只有一份)
  • 主通道:插件内进程 HTTP MCP。 装一个插件、指向 URL 即可,不需要额外的 Node 适配器进程,关掉 Blockbench 就等于关掉 MCP。

  • 兼容通道:stdio 网关。 只有 stdio 的客户端(Claude Desktop 等)用 gateway/index.mjs 转发。工具实现不在网关里,网关只是 stdio ⇄ HTTP 的管道,所以两条通道的能力永远一致。


快速开始

1. 构建插件

npm install
npm run build          # rolldown 打包
# 产物:packages/plugin/dist/blockbench_mcp.js(单文件插件)
#      packages/plugin/dist/gateway.mjs(stdio 网关)

2. 在 Blockbench 里加载

  1. 打开 Blockbench 桌面版File ▸ Plugins ▸ Load Plugin from File → 选 packages/plugin/dist/blockbench_mcp.js

    ⚠️ Blockbench 要求文件名(去掉 .js)等于 Plugin.register() 里的插件 id。 本项目的产物是 blockbench_mcp.js、id 是 blockbench_mcp,两者必须一致; 改文件名会让它加载失败并提示 "确保插件的基本文件名与 Plugin.register() 中定义的插件ID匹配"。 packages/plugin/test/package.test.mjs 里有断言守住这条。

  2. 首次会请求 network(net)权限 → 选 Always allow for this plugin

  3. 插件自动启动服务,右下角提示 Blockbench MCP ready → http://127.0.0.1:39742/mcp

  4. 菜单:Tools ▸ Start / Stop MCP ServerTools ▸ MCP Server Status / Token

3. 拿到访问令牌

Settings ▸ General ▸ MCP Access Token(首次加载时随机生成,不是默认口令),或点 Tools ▸ MCP Server Status / Token 一次看全状态 + 可直接粘贴的客户端配置。

4. 接入客户端

Cursor / VS Code(.cursor/mcp.json / .vscode/mcp.json)

{
  "mcpServers": {
    "blockbench": {
      "url": "http://127.0.0.1:39742/mcp",
      "headers": { "Authorization": "Bearer <你的令牌>" }
    }
  }
}

Claude Code

claude mcp add blockbench --transport http http://127.0.0.1:39742/mcp \
  --header "Authorization: Bearer <你的令牌>"

Claude Desktop(只支持 stdio → 用网关)

{
  "mcpServers": {
    "blockbench": {
      "command": "node",
      "args": ["/绝对路径/blockbench-mcp-pro/gateway/index.mjs"],
      "env": {
        "BBMCP_URL": "http://127.0.0.1:39742/mcp",
        "BBMCP_TOKEN": "<你的令牌>"
      }
    }
  }
}

mcp-remote / Ollama / Cline 等 只要能发 HTTP + 自定义头,都指向同一个 URL。

5. 先读指南,再动手

任何建模任务的第一批调用应该是:

health → get_project_summary → get_guide { topic: "modeling" }

工具总览(96)

数量

工具

状态与发现

7

health, get_guide, list_formats, get_project_summary, get_elements, list_textures, list_animations

方向(左右)

3

get_orientation, which_side, check_sides

工程与文件

6

create_project, set_project_meta, save_project, export_model, propose_scoped_directory, revoke_scope

几何

12

apply_geometry_batch, update_elements, delete_elements, transform_elements, mirror_elements, array_cubes, radial_array_cubes, duplicate_hierarchy, create_limb, scaffold_biped, measure_model, audit_symmetry

程序化生成器

5

voxelize_matrix, add_hollow_volume, generate_array, extrude_chain, add_wing

UV

7

auto_uv_cubes, pack_box_uv, get_uv_layout, get_uv_map, set_face_uv, transform_uv_islands, resize_texture

纹理

21

ensure_texture, assign_texture, get_texture, get_texture_revision, shade_model_base, paint_face_features, paint_pixel_batch, paint_face_grid, get_face_grid, edit_texture_pixels, replace_texture_color, copy_face_pixels, flood_fill_texture, transform_texture_region, analyze_texture_palette, get_texture_region, audit_texture_quality, import_texture_png, export_texture_png, ensure_material_set, audit_material_set

动画

6

upsert_animation, generate_animation, inspect_animation, transform_animation_keys, delete_animation, set_timeline_time

质量门

3

check_model, audit_complexity, check_rig

渲染/视角

3

capture_views, analyze_view_silhouette, set_camera_angle

参考图匹配

5

load_reference, list_references, get_reference, clear_references, compare_reference

人审门

3

ask_user, request_review, wait_review

通用覆盖

12

list_actions, get_action, run_action, select_action, list_modes, set_mode, list_settings, get_setting, set_setting, list_plugins, install_plugin, uninstall_plugin

历史与逃生舱

3

undo, redo, execute_script(默认关闭)

除工具外还实现了 MCP 的另外两类能力:

  • resources:blockbench-guide://<topic>(8 篇 playbook)、blockbench-mcp://activity(调用日志 + 当前作用域/参考图/待审卡片)

  • prompts:model_from_referencepolish_model


区别表 A:五个参考项目速览

项目

传输

语言/构建

鉴权

工具数

许可

一句话

sosadly/blockbench-mcp

Node stdio 服务端 + 插件内 HTTP 网桥(8787)

TS + 单文件 JS 插件

仅 Origin/Host/Content-Type 校验,无令牌

71

MIT

最"会建模",但网桥无鉴权、无 UV/纹理版本控制

SwagRee/BlockBenchMCP

纯插件内进程 HTTP MCP(39741)

TS + esbuild + zod 契约

Bearer(默认 dev-local-secret)

58

MIT

工程最扎实,但缺生成器/人审/参考比对

jasonjgardner/blockbench-mcp-plugin

插件内 Streamable HTTP(3000/bb-mcp)

Bun + TS

110(含 12 Hytale)

GPL-3.0

工具面最广 + 会话保活/resources,但有 UI 点击类危险工具

vasyacullin-Blockbench-mcp

Node stdio + 自研 TCP/NDJSON 网桥(19888)

纯 JS

token 握手(防 CSRF)

41

GPL-3.0

action 桥 + execute_script 覆盖全,但无 undo/UV 检查

Golub4ik-Official-blockbench-mcp

Node stdio + Socket.IO(9999)

TS + pnpm monorepo

~5

ISC

工程形态(monorepo/预构建产物)值得借鉴,工具极少

本项目 blockbench-mcp-pro

插件内 HTTP MCP + stdio 网关(双通道)

TS + rolldown + zod 契约,全纯函数可测

随机 Bearer + Origin/Host/Content-Type 校验 + 文件作用域

95

MIT

上述优点的合集,并把每条缺点当成设计约束


区别表 B:能力与工程质量矩阵

图例:✅ 有且完整 · 🟡 有但薄弱/需自己补 · ❌ 没有

能力 / 工程点

sosadly

SwagRee

jasonjgardner

vasyacullin

Golub4ik

本项目

免额外 Node 进程(纯插件)

stdio 客户端可用

✅(网关)

传输 Token 鉴权

🟡(弱默认口令)

🟡(需手抄令牌)

✅(随机生成)

防浏览器 drive-by(Origin/Host)

🟡(握手)

文件读写在用户批准目录内

🟡

全量 Undo 集成(单步可撤销)

🟡

🟡

zod 参数契约 / 未知参数硬报错

双端共用的工具目录(单一事实源)

🟡

🟡

UV 模式感知(box / face)

🟡

🟡

UV 布局机检(越界/重叠/密度/翻转)

🟡

面局部绘制(尊重旋转/翻转)

🟡

纹理 revision token(防过期覆盖)

程序化生成器(体素/壳体/阵列/骨链/翼)

质量门(check_model / 复杂度 / 左右 / 骨架)

🟡(仅 check_model)

人审门(阻塞式确认 + pending 轮询)

参考图 IoU 比对 + 合成对比图

动画基础循环生成(9 种)

🟡

万能 action 桥(list/run action)

❌(明确非目标)

🟡(UI 点击)

✅(不含 UI 点击)

settings / modes 读写

🟡

MCP resources / prompts

会话管理 / 保活

🟡(session id)

✅(SSE keepalive)

🟡(session id,无 SSE)

逃生舱 execute_script

✅(默认开)

❌(明确非目标)

✅(默认关)

危险 UI 点击类工具

⚠️(emulate_clicks/risky_eval)

❌(故意不做)

自动化测试

🟡(工具目录)

✅(协议+宿主 mock)

❌(无)

🟡

✅(109 个 Vitest,含交付产物/真实 HTTP/stdio)

许可

MIT

MIT

GPL-3.0

GPL-3.0

ISC

MIT


区别表 C:逐项目"吸取了什么 / 抛弃了什么"

1. sosadly/blockbench-mcp

吸取

  • 程序化生成器:voxelize_matrixadd_hollow_volumegenerate_arrayextrude_chainadd_wing(全部重写为 shared 包里的纯函数,可单测)

  • 质量门:audit_complexity(方块预算 / 单体巨块 / 分层 / 微细节密度)、check_modelcheck_sidescheck_rig

  • 人审门:request_review / ask_user / wait_reviewpending + 轮询 设计(解决 MCP 单次请求超时与分钟级人审的矛盾)

  • 参考图匹配:compare_reference 的 IoU + 缺失/多余质量百分比 + 合成对比图

  • 方向权威:模型面朝 -Z、自身右侧 +X、前视图镜像陷阱、旋转符号表,以及 side:"left"|"right" 参数级拒绝

  • 指南式工具:get_guide 的建模/细节/方向/绑定/贴图/动画/审查/参考八篇 playbook

  • 参数强制转换:把客户端发来的 JSON 字符串解开(coerceArguments)

  • 细节:面局部绘制(paint_face_features)与整面底色光照(shade_model_base)

抛弃

  • ❌ HTTP 网桥无令牌 → 改为随机生成 Bearer 并强制校验

  • ❌ 能写任意路径 → 改为 propose_scoped_directory 批准目录 + 路径越界拒绝

  • ❌ 单文件 7000+ 行插件、无类型、无契约 → 改为 TS + zod 契约 + 多个聚焦模块

  • ❌ 无 UV 布局机检 / 无纹理版本控制 → 补齐 get_uv_layout 与 revision token

  • execute_script 默认开启 → 改为默认关闭,设置里显式打开

  • ❌ 需要外置 Node 服务端才能用 → 主通道改为插件内进程,外置只作为可选的 stdio 网关

2. SwagRee/BlockBenchMCP

吸取

  • 插件内进程 HTTP MCP(不需要第二个进程)——本项目的主通道

  • zod 契约 + 未知参数硬报错 + 统一响应信封 {ok, summary, result, error} + 结构化错误码 E_*

  • UV 模式解析(box / face,含 java_block 必须 face 的校验)与 pack_box_uv / get_uv_layout / get_uv_map / transform_uv_islands

  • 面空间映射(尊重面旋转与 UV 翻转)与 paint_face_grid / get_face_grid 的精确像素往返

  • 纹理 revision token(FNV-1a 内容哈希 + expected_revision 乐观并发)

  • propose_scoped_directory 文件作用域安全模型

  • 离屏多视角截图(Screencam.NoAAPreview,不动用户相机)+ 轮廓分析

  • Undo 端口封装(initEdit / cancelEdit 回滚 / finishEdit 纳入新建元素)

  • ensure_material_set / audit_material_set 的 PBR 通道一致性检查

  • 测试用宿主 mock 的思路

抛弃

  • ❌ 默认共享密钥 dev-local-secret → 改为首次加载随机生成 24 字节令牌

  • ❌ 没有程序化生成器 → 补齐 5 个生成器

  • ❌ 没有人审门 / 参考比对 → 补齐

  • ❌ 没有动画生成(只有 upsert/inspect/transform)→ 补齐 9 种基础循环

  • ❌ 没有左右方向权威与参数级 side 拒绝 → 补齐

  • ❌ 没有 execute_script 逃生舱 → 补上但默认关闭

  • ❌ 无 resources / prompts → 补齐

  • ❌ 单 POST 无 session → 返回 Mcp-Session-Id 便于客户端做会话区分

3. jasonjgardner/blockbench-mcp-plugin

吸取

  • 插件内 Streamable HTTP 形态与 initialize 返回 instructions 的做法

  • MCP resources + prompts(本项目做了 8 篇 guide resource + 2 个 prompt)

  • 插件内 UI 呈现:状态栏/对话框式的状态与令牌展示

  • 声明式工具规格(名称 + 描述 + 参数 + 注解)与"每个工具都要有实现"的纪律(本项目用测试断言)

抛弃

  • GPL-3.0 → 本项目全部重写为 MIT

  • emulate_clicks / trigger_action / risky_eval 这类模拟点击/任意求值的工具 → 不做;需要覆盖时用 list_actions + run_action(命令级,不是鼠标级)

  • ❌ 无鉴权 → 强制 Bearer + Origin/Host 校验

  • ❌ 没有测试 → 109 个自动化测试(Vitest)

  • ❌ 工具名与参数风格不统一 → 统一为动词_名词 + zod 契约

4. vasyacullin-Blockbench-mcp

吸取

  • token 握手拦截浏览器 drive-by 的思路(本项目在 HTTP 层用 Origin/Host/令牌三道校验达到同样效果)

  • 万能 action 桥:list_actions / get_action / run_action + select_action,用命令级覆盖补足专用工具之外的功能

  • list_modes / set_modelist_settings / get_setting / set_setting 的宿主能力透出

  • 默认端口/主机/超时环境变量化的配置思路(本项目改为插件设置 + 网关环境变量)

抛弃

  • GPL-3.0 → MIT 重写

  • ❌ 纯 JS、无类型、无契约 → TS + zod

  • ❌ 无 undo 封装 → 所有写操作进 withUndo

  • ❌ 无 UV/纹理检查、无质量门 → 补齐

  • ❌ 令牌要用户手抄且格式自定义 → 令牌进设置面板,客户端配置可直接复制

  • ❌ 自研 TCP/NDJSON 协议(非标准)→ 改用标准 MCP over HTTP,stdio 交给标准网关

5. Golub4ik-Official-blockbench-mcp

吸取

  • monorepo 形态(shared / plugin / gateway 三个包,职责清晰)

  • 预构建产物随代码一起交付(本项目 npm run build 产出单文件插件 + 网关,无运行时依赖需要用户安装)

  • 简单直白的 README 安装步骤(本项目在 README 里给出逐客户端配置片段)

抛弃

  • ❌ 只有 5 个工具 → 95 个

  • ❌ Socket.IO 传输(额外依赖 + 无标准 MCP)→ 标准 HTTP MCP + stdio 网关

  • ❌ 无鉴权、无 undo、无质量门 → 全部补齐

  • ❌ 无测试 → 109 个(Vitest)


发布到 npm(@anningui/blockbench-mcp)

包名已按你的命名空间配好:packages/plugin/package.jsonname = "@anningui/blockbench-mcp", publishConfig.access = "public"(scoped 包首次发布必须显式 public)。

一次性准备

npm login                # 登录 npmjs 账号(需要拥有 anningui 这个 scope/组织)
npm whoami               # 确认身份

registry 已经固定在仓库根的 .npmrc,不依赖你机器的全局配置:

# .npmrc
registry=https://registry.npmjs.org/
access=public            # scoped 包默认私有,这里显式公开

packages/plugin/package.json 里也写了 publishConfig: { access: "public", registry: "https://registry.npmjs.org/" }, 所以即使换机器/换工具,发布目标也不会跑偏。校验:

pnpm config get registry        # → https://registry.npmjs.org/

⚠️ 不要在仓库根目录跑 npm publish

npm 在 workspace 根目录执行 publish 时,会把根包 + 所有非 private 的 workspace 一起发, 而且 npm publish --prefix packages/plugin 里的 --prefix 对 publish 无效(只影响 npm run)。 踩过一次的现场:根包 blockbench-mcp-pro@1.0.0 被误发到 registry,而真正的插件包没发出去。

护栏(已配置):

状态

blockbench-mcp-pro

private: true

@bbmcp/shared

private: true

@bbmcp/gateway

private: true

@anningui/blockbench-mcp

唯一可发布(publishConfig.access: public)

根脚本 pnpm run publish 已经写成 cd packages/plugin && npm publish --access public, 只会在插件目录里发布。

下架 / 弃用

# 1) 先看线上有什么
npm view <pkg> versions
npm view <pkg> time.created time.modified       # 判断是否还在 72 小时窗口内

# 2) 删掉某个版本(72 小时内;需要 --force;-dry-run 先预演)
npm unpublish <pkg>@<version> --force
npm unpublish <pkg>@<version> --force --dry-run

# 3) 整个包下架(仅剩一个版本、且没有别人依赖时)
npm unpublish <pkg> --force

# 4) 过了 72 小时就只能"弃用"而不是删除
npm deprecate <pkg>@<version> "误发布,请改用 @anningui/blockbench-mcp"

规则(npm 官方限制,不是本项目加的):

规则

说明

72 小时

发布时间超过 72 小时的版本不能 unpublish,只能 deprecate

无依赖者

被别的包依赖时不能下架

24 小时冷却

同名同版本下架后,短时间内不能再用同一个版本号发(改版本号即可绕过)

权限

需要包的 owner/maintainer 身份;开了 2FA 要 --otp=123456

下架 ≠ 撤回

下架不影响已装到本地 node_modules 的副本;npm i 缓存也可能命中旧的

每个版本的发布流程

cd blockbench-mcp-pro
npm run build            # rolldown 构建 → packages/plugin/dist/{blockbench_mcp.js,gateway.mjs}
npm run typecheck        # 可选的类型检查
npm run pack:check       # npm pack --dry-run,确认 tarball 内容
npm run publish          # = npm publish -w @anningui/blockbench-mcp --access public

版本号用 npm version patch|minor|major -w @anningui/blockbench-mcp 升(会自动改 package.json)。

包里有什么

files 白名单只放运行必需的东西(构建脚本、源码、测试都不会进 tarball):

文件

用途

dist/blockbench_mcp.js

给 Blockbench 的单文件插件(self-contained,含 zod 与全部工具)

dist/gateway.mjs

stdio ⇄ HTTP 网关(bin 的实现)

bin/blockbench-mcp.mjs

CLI:--plugin-path / --http-url / --cdn-url / --help,不带参数时启动网关

README.mdLICENSE

没有任何 dependencies(全部在构建时打进产物),用户 npx 不需要额外安装。

发布后用户可以这样装

npm i -g @anningui/blockbench-mcp     # 或直接用 npx
blockbench-mcp --plugin-path          # 打印插件绝对路径

不需要 clone 仓库就能拿到 Blockbench 插件。


接入 Blockbench

方式 1:本地文件(最常用)

npx -y @anningui/blockbench-mcp --plugin-path
# → /path/to/node_modules/@anningui/blockbench-mcp/dist/blockbench_mcp.js
  1. Blockbench 桌面版 → File ▸ Plugins ▸ Load Plugin from File → 选上面那个文件

  2. 弹网络权限时选 Always allow for this plugin(网关要监听 net)

  3. 右下角出现 Blockbench MCP ready → http://127.0.0.1:39742/mcp 即成功

  4. Tools ▸ Start / Stop MCP ServerTools ▸ MCP Server Status / Token 可随时启停与取令牌

方式 2:从 URL 加载(不用装包)

发布到 npm 后,jsDelivr 会直接提供文件:

https://cdn.jsdelivr.net/npm/@anningui/blockbench-mcp/dist/blockbench_mcp.js

Blockbench → File ▸ Plugins ▸ Load Plugin from URL → 粘贴上面的地址。 (npx -y @anningui/blockbench-mcp --cdn-url 会打印它。)

拿令牌

Settings ▸ General ▸ MCP Access Token,或 Tools ▸ MCP Server Status / Token 一次看到 状态 + 令牌 + 可直接粘贴的客户端配置。首次加载随机生成,不是默认口令。

验证服务是否活着:

curl http://127.0.0.1:39742/health
# {"ok":true,"server":"blockbench-mcp-pro",...}

接入 AI 客户端

通用规则:能发 HTTP 的客户端直接用 URL + Bearer 头;只能 stdio 的客户端用 bin 转发。

客户端

传输

配置要点

pi(pi-mcp-adapter)

HTTP 或 stdio

见下面两段,写进 ~/.pi/agent/mcp.json

Cursor

HTTP

.cursor/mcp.jsonurl + headers.Authorization

VS Code / Copilot

HTTP

.vscode/mcp.jsonurl + headers

Claude Code

HTTP

claude mcp add ... --transport http <url> --header "Authorization: Bearer <token>"

Claude Desktop

stdio(仅支持 stdio)

command: node + args: [<gateway.mjs>] + env.BBMCP_TOKEN

Cline / mcp-remote / Ollama

HTTP

填 URL 与自定义头

pi(你当前使用的,pi-mcp-adapter)

注意:adapter 读取的路径是 ~/.pi/agent/mcp.json(agent,不是 agents)。 它也读项目级 .mcp.json~/.config/mcp/mcp.json~/.agents/mcp.json, 优先级:后者覆盖前者,.pi/mcp.json 最高。改完在 pi 里执行 /reload

推荐:HTTP 直连(少一个进程,工具直接可用)

编辑 ~/.pi/agent/mcp.json,在 mcpServers 里加:

{
  "mcpServers": {
    "blockbench": {
      "type": "http",
      "url": "http://127.0.0.1:39742/mcp",
      "headers": {
        "Authorization": "Bearer <Blockbench 里的 MCP Access Token>"
      }
    }
  }
}

可选:stdio 网关(客户端只给 command/args 时用)

{
  "mcpServers": {
    "blockbench": {
      "command": "npx",
      "args": ["-y", "@anningui/blockbench-mcp"],
      "env": {
        "BBMCP_URL": "http://127.0.0.1:39742/mcp",
        "BBMCP_TOKEN": "<Blockbench 里的 MCP Access Token>"
      }
    }
  }
}

本地开发(没发布 npm 时)把 command/args 换成本地脚本:

{ "command": "node", "args": ["D:/Dev-Project/t/blockbench-mcp-research/blockbench-mcp-pro/gateway/index.mjs"],
  "env": { "BBMCP_TOKEN": "<token>" } }

在 pi 里验证

  1. 重启 pi(或 /reload),执行 /mcp 应能看到 blockbench

  2. 问它:「调用 blockbench 的 health」→ 应返回 plugin_versioncapabilitiesuv_mode

  3. pi 的 adapter 是工具按需发现(search → describe → call),所以典型对话是: mcp({search:"blockbench 建模"})mcp({tool:"apply_geometry_batch", args:{...}})

给模型的操作提示(可直接粘进 pi 的提示或 skill):

Blockbench 相关任务先调 health → get_project_summary → get_guide(topic:"modeling")。
细节用 add_hollow_volume / generate_array / extrude_chain / voxelize_matrix / add_wing。
贴图前必须 audit_complexity 不再是 too_primitive,并且 check_model 0 error。
贴图流程:pack_box_uv → shade_model_base → paint_face_features → audit_texture_quality。
动画用 generate_animation,然后 set_timeline_time + capture_views 看一眼。
有参考图就 compare_reference 迭代到 match_percent >= 85。
声明"做完了"之前先 request_review;pending 和超时都不算通过。

Cursor / VS Code

// .cursor/mcp.json 或 .vscode/mcp.json
{
  "mcpServers": {
    "blockbench": {
      "type": "http",
      "url": "http://127.0.0.1:39742/mcp",
      "headers": { "Authorization": "Bearer <token>" }
    }
  }
}

Claude Code

claude mcp add blockbench --transport http http://127.0.0.1:39742/mcp   --header "Authorization: Bearer <token>"

Claude Desktop(无 HTTP 支持 → 走网关)

{
  "mcpServers": {
    "blockbench": {
      "command": "node",
      "args": ["<你的项目路径>/blockbench-mcp-pro/gateway/index.mjs"],
      "env": { "BBMCP_URL": "http://127.0.0.1:39742/mcp", "BBMCP_TOKEN": "<token>" }
    }
  }
}

排错

现象

原因 / 处理

401 Unauthorized

令牌不对或没带 Authorization: Bearer <token>;从 Tools ▸ MCP Server Status / Token 重取

Cannot reach Blockbench on ...

Blockbench 没开 / 插件没加载 / 服务停了(Tools ▸ Start MCP Server)

浏览器 / 网页工具报 403

有意为之:带 Origin 的请求一律拒绝,避免网页 drive-by

端口被占用

Settings ▸ General ▸ MCP Server Port 换端口,并同步改客户端 BBMCP_URL

工具里出现 E_SCOPE_DENIED

需先调 propose_scoped_directory 并在 Blockbench 里点 Allow

工具里出现 E_AUTH_FAILED(execute_script)

该工具默认关闭,去 Settings ▸ General ▸ Allow execute_script 打开


安全模型

措施

修掉了谁的弱点

网络

只绑定 127.0.0.1

全部

鉴权

首次加载随机生成 24 字节令牌,Authorization: Bearer <token> 强制校验;x-mcp-secret 亦接受

sosadly(无令牌)、jasonjgardner(无鉴权)、SwagRee(弱默认口令)

CSRF / drive-by

Origin 头的请求一律 403;Host 非回环一律 403(DNS rebinding)

SwagRee、jasonjgardner、Golub4ik

请求体

application/json,上限 8MB

文件系统

读写必须落在 propose_scoped_directory 用户批准过的目录内,越界路径直接拒绝

sosadly(任意路径)、vasyacullin、Golub4ik

代码执行

execute_script 默认关闭,需用户在设置里显式打开,且有超时上限

sosadly(默认开)

危险 UI 自动化

不提供 emulate_clicks / trigger_action / risky_eval

jasonjgardner

信任边界

README 明说:MCP 客户端(含被提示注入的模型)可调用全部工具;execute_script 打开后拥有 Blockbench 全权限

全部


质量门与推荐工作流

health ─ get_project_summary ─ get_guide(modeling)
   │
create_project ─ scaffold_biped / apply_geometry_batch        ← 主形体
   │
add_hollow_volume / generate_array / extrude_chain / add_wing / voxelize_matrix  ← 真细节
   │
audit_complexity  ← 必须不再是 too_primitive
check_model       ← 必须 0 error(z-fighting / 空组 / 未贴图面 / 越界 UV)
check_sides       ← 左右名字与坐标必须一致
check_rig         ← 3 段肢体、无游离 cube
   │
pack_box_uv ─ get_uv_layout(out_of_bounds=0) ─ shade_model_base ─ paint_face_features
   │                                    └─ get_texture_revision → expected_revision
audit_texture_quality ─ check_model
   │
generate_animation ─ set_timeline_time ─ capture_views        ← 看一眼再改
   │
compare_reference ≥ 85(有参考图时)
   │
request_review → 用户点 Approve 才算完成(pending / 超时都不算)

目录结构

blockbench-mcp-pro/
├── docs/reference-projects.md   # 五个参考项目的逐项阅读笔记
├── packages/
│   ├── shared/       # 协议常量、zod 工具目录、8 篇 playbook、全部纯逻辑
│   │   ├── src/pure/ #   vec / color / uv / generate / audit —— 无宿主依赖,可单测
│   │   └── test/     #   30 个纯逻辑测试
│   └── plugin/       # Blockbench 插件
│       ├── src/host.ts     # 宿主端口(undo/纹理/画布/格式/截图/对话框)
│       ├── src/bb.ts       # 元素与工程读写 + 批量落地 + side 守卫
│       ├── src/session.ts  # 文件作用域 / 参考图 / 待审卡片 / 活动日志
│       ├── src/http.ts     # net 上的 HTTP + 鉴权 + Origin/Host 校验
│       ├── src/rpc.ts      # MCP JSON-RPC + resources + prompts + 图片内容块
│       ├── src/dispatch.ts # 校验 → 执行 → 统一信封
│       ├── src/tools/      # 按域拆分的 96 个工具
│       ├── types.d.ts      # 宿主类型:官方 blockbench-types + 少量浏览器 API 补齐(无 any 全局)
│       ├── bin/            # npm bin:blockbench-mcp(网关 + --plugin-path/--cdn-url)
│       ├── build/           # rolldown.config.ts + 它自己的 tsconfig(types: node)
│       ├── test/           # 宿主 mock + 分发/HTTP/产物/打包 测试
│       └── dist/blockbench_mcp.js  # 交付给用户的单文件插件
└── gateway/          # stdio ⇄ HTTP 零依赖网关(+ 3 个测试)

真机验证(需要 Blockbench)

一键打包 + 安装 + 全量测试的说明也在 release/INSTALL.md(release/ 里已经放好插件文件)。

两套脚本:

脚本

用途

scripts/live-test.mjs

全量:10 组 / 30+ 用例 = 正式流程 + 边缘用例 + 传输层硬化 + 协议 + 并发,落盘截图/模型/报告(live-report.json)

scripts/live-smoke.mjs

快速冒烟(约 10 秒):一条顺畅路径,确认装好了没

scripts/configure-pi-mcp.mjs

从 Blockbench 设置存储里读令牌,自动写 ~/.pi/agent/mcp.json(先备份)

先说清楚自动化测试的边界:pnpm test 里的 109 个测试跑的是纯逻辑 + 我写的 mock 宿主 (假的 Cube/Group/Texture/Codecs,假的截图 data URL)。它验证的是 参数校验、批次语义、UV 打包数学、审计规则、HTTP/鉴权/MCP 协议、交付产物能否加载, 不验证真 Blockbench 的 mapAutoUVTexture.edit、undo 行为、离屏渲染、权限对话框与文件导出。 所以 mock 测试不会产出 .bbmodel 之类的模型文件。

要真跑一遍并拿到真实产物,用 scripts/live-smoke.mjs:它对着正在运行的 Blockbench 里的插件 走完整流程并把结果落盘。

# 1) 在 Blockbench 里加载插件(或把 dist/blockbench_mcp.js 放进 Blockbench 的 plugins 目录后重启)
#    File ▸ Plugins ▸ Load Plugin from File → packages/plugin/dist/blockbench_mcp.js
#    允许 net 权限,等到提示 "Blockbench MCP ready"

# 2) 跑真机冒烟(令牌见 Tools ▸ MCP Server Status / Token)
pnpm run smoke:live -- --token <MCP Access Token> --out ./out/live-smoke

# 或
BBMCP_TOKEN=<token> node scripts/live-smoke.mjs

它会依次执行并断言:health → create_project → apply_geometry_batch(side 守卫) → add_hollow_volume / generate_array / extrude_chain → check_model / check_sides / check_rig / audit_complexity → ensure_texture → pack_box_uv → get_uv_layout(越界/重叠必须为 0)→ shade_model_base → paint_face_features → audit_texture_quality → generate_animation(双腿对侧相位)→ set_timeline_time → capture_views(PNG 落盘)→ analyze_view_silhouette → propose_scoped_directory → save_project(真 .bbmodel)→ export_model(真 .geo.json)。

产物(默认 out/live-smoke/):

文件

说明

view-*.png

真渲染的多视角截图

smoke.bbmodel

真工程文件,可直接拖回 Blockbench

smoke.geo.json

用当前格式 codec 导出的几何 JSON

report.json

本次运行的摘要(版本/尺寸/UV 统计/动画名)

常用参数:--no-blocks(只做基础形体)、--no-save(不弹权限对话框)、--views north,east,iso--url--out

开发与验证

npm 与 pnpm 都支持(仓库里提交的是 pnpm-lock.yaml;用 npm 时它会自己生成 package-lock.json):

# npm
npm install
npm run verify          # build → typecheck → test

# pnpm(本仓库用 pnpm 开发)
pnpm install
pnpm run verify

pnpm 的两个必要配置(已写进 pnpm-workspace.yaml,否则会踩坑):

配置

为什么必须

packages: [packages/*, gateway] + linkWorkspacePackages: true

pnpm 不认 package.json 的 "workspaces" 字段;没有这个文件,@bbmcp/shared 会被当成外部依赖去 registry 找 → ERR_PNPM_FETCH_404

strictDepBuilds: false

pnpm 11 默认 true:任何"被忽略的构建脚本"都会直接中断安装(ERR_PNPM_IGNORED_BUILDS)。我们对 electron(blockbench-types 的依赖)是有意忽略的,只取它的 .d.ts

安装时看到这一段是预期的、无害的:

Ignored build scripts: electron@40.10.6.
Run "pnpm approve-builds" to pick which dependencies should be allowed to run scripts.

根脚本用 npm --prefix <dir> run … 而不是 npm run -w <name>,这样 npm 与 pnpm 两种 node_modules 布局下都能跑。

  • pnpm run build — shared(tsc)+ rolldown -c build/rolldown.config.ts(插件/测试入口/网关三份产物)

  • npm run typecheck — 三个包的 TS 检查(strict)

  • pnpm test109 个测试(shared 31 / plugin 75 / gateway 3),Vitest 并行跑,全套约 3 秒:

测试跑在 Vitest(vitest run,每个测试文件独立进程 + 全局 mock 隔离),文件之间并行,整套约 3 秒。

套件

数量

验证内容

packages/shared/test/pure.test.mjs

31

向量/旋转、颜色、UV 映射与翻转、shelf 打包不重叠、体素化/壳体/阵列/骨链/翼、check_model、复杂度门、左右门、骨架门、测量、轮廓 IoU、revision 哈希、面质检、工具目录完整性

packages/plugin/test/dispatch.test.mjs

51

用 mock 宿主真实执行每个工具:批量几何单步 undo、side 拒绝、生成器落地、pack UV 不重叠、面局部绘制的像素往返(revision 一致)、过期 revision 被拒、贴图质检、动画生成的对侧相位、审查 pending→回答、参考图比对、action 桥、设置/插件/历史

packages/plugin/test/http.test.mjs

18

真实 net 服务器 + fetch/原始 socket:无令牌 401、错令牌 401、Origin 403、Host(DNS rebinding)403、非 JSON 415、initialize/session id、tools/list schema、tools/call 信封、图片内容块、resources/prompts、JSON-RPC 错误码、202/204/405

packages/plugin/test/package.test.mjs

4

打包体检:文件名 ↔ 插件 id 必须一致(Blockbench 硬性要求)、CLI 各开关、CLI 真的把 stdio 转成 HTTP(踩过坑,故加断言)

packages/plugin/test/bundle.test.mjs

2(快)

直接加载交付产物 dist/blockbench_mcp.js,调用 Blockbench 会调的 onload,再访问它真的起在回环上的端点(令牌随机生成、401、tools/list)

gateway/test/stdio.test.mjs

3

stdio 网关对着真实插件 HTTP 服务端跑通 initialize → tools/list → tools/call → resources/read;错令牌与不可达都返回合法 JSON-RPC 错误

调试插件时可只跑单个套件,例如:

# 最快的一次冒烟(约 1s):确认交付产物能加载、能起服务、CLI 可用
pnpm --filter @anningui/blockbench-mcp exec vitest run test/bundle.test.mjs test/package.test.mjs

类型来源

插件的宿主类型来自官方 blockbench-types(devDependency),不是手写 any:

// packages/plugin/tsconfig.json
"types": ["blockbench-types"],   // Cube / Group / Texture / Animation / Preview / Undo / Canvas /
                                 // Project / Format(s) / BarItems / Modes / Dialog / Action /
                                 // Codecs / Settings / Plugin(s) / newProject ... 全部是真类型
"strict": true, "noImplicitAny": true

插件包里有两个 tsconfig,因为两类文件的类型环境完全不同:

配置

覆盖

types

packages/plugin/tsconfig.json

src/**(跑在 Blockbench 渲染进程里)

blockbench-types(无 node、无 DOM)

packages/plugin/build/tsconfig.json

build/rolldown.config.ts(跑在 Node 里)

node

pnpm run typecheck 会把两个都跑一遍。构建配置刻意放在独立目录 build/: TS server 是按"离文件最近的 tsconfig.json"给文件归项目的,tsconfig.node.json 这种命名配置 除非被 solution 引用否则不会被采用,所以用目录隔离最稳。

packages/plugin/types.d.ts 只补两类官方包没有的东西:

  1. require(桌面端 scoped 模块)+ Plugin.register / new Animation() 两个只有类型没有值的运行时入口(类型仍取自官方包,例如动画片段用官方的 _Animation)

  2. 极简浏览器 API —— 本项目刻意不引 lib.dom(Blockbench 的 Animation/Image 与 DOM 同名),只声明用到的那几个成员

blockbench-types 依赖 electron,npm 安装时会去下 Electron 二进制。CI/离线环境用 ELECTRON_SKIP_BINARY_DOWNLOAD=1 npm install 跳过(类型不受影响);pnpm 侧见 pnpm-workspace.yamlignoredBuiltDependencies

three.js 不是本项目的依赖,也不会被下载。

视角

three 会被下载吗

说明

使用者(从 npm 装)

不会

发布包 dependencies 为空。实测:npm inode_modules/ 里只有 @anningui/blockbench-mcp,tarball 88.8 KB

贡献者(克隆本仓库)

不会(经 override)

blockbench-types → wintersky → three 只是 dev 传递依赖;pnpm overrides 把它指向仓库内的空壳 stubs/three,干净安装体积 119 MB → 91 MB

运行时

three 由 Blockbench 自己提供,插件只调用它递过来的对象

插件代码不引用 THREE,产物里 0 处 three;唯一碰到相机的地方(captureView 的正交相机)用本地结构类型 OrthoCamera 收窄,连 three 的类型也不依赖 —— 所以空壳替代不会影响类型检查。

为什么不干脆去掉 blockbench-types?那就要回到手写类型(即 any 全局),得不偿失。 空壳只影响 wintersky 的运行时(我们从没执行过它),.d.ts 一个不缺。

这套类型当场抓出了 5 个真实 API 错误:Canvas.updateSelection(应为 updateSelected)、 Settings.add(应为 new Setting(id, data))、Timeline.setAnimation(应为 animation.select())、 Texture.setDataURL(不存在)、Screencam.NoAAPreview.resize(不存在,尺寸由 screenshotPreview 的 options 决定)。

已知取舍

诚实列出为了保持"少而正确"而故意没做的东西,以及升级路径:

  1. 人审卡片的 UI 用的是宿主原生对话框(可带图片行),不是 sosadly 那种自定义面板。升级路径:换成一个常驻面板,带缩略图、评论框与活动日志。当前的 pending + wait_review 轮询协议已经是最终形态,换 UI 不影响工具契约。

  2. 不做网格(mesh)编辑、骨骼权重、PBR 材质实例这类 jasonjgardner 有的能力——它们需要一整套顶点级工具,和"方块建模"主线是两条产品线。需要时用 execute_scriptrun_action 过渡。

  3. 没有 SSE 流式响应:插件内是单次 JSON POST,足够所有主流 HTTP MCP 客户端;标准 SSE 会显著增加插件里的 HTTP 实现复杂度。stdio 客户端走网关。

  4. install_plugin 依赖宿主是否暴露安装 API;不暴露时返回明确提示让用户手动安装(而不是假装成功)。

  5. mapAutoUV / 截图 / 对话框等宿主 API 在测试里的 mock 只覆盖被用到的子集;真机行为以 Blockbench 5.1+ 为准,health 会报告 blockbench_supported

License

MIT — 本项目为独立重写,未复制任何 GPL 项目代码。

Related MCP Connectors

Related MCP Servers