blender-meta-mcp
# blender-meta-mcp
轻量 **Blender MCP**:Cursor Agent 用 `blender_exec` 在**已经打开**的 Blender 里执行 bpy。心智模型和 [ae-meta-mcp](https://github.com/shinjiyu/ae_meta_mcp) 的 `ae_exec` 一样。
```text
Cursor Agent ──stdio MCP──▶ Node mcp/index ──HTTP :11588──▶ Addon HTTP 线程
│ 入队
▼
bpy.app.timers(主线程)
│ temp_override + exec
▼
Blender bpy
```
`bpy` 只能在主线程调用。HTTP 跑在 addon 的守护线程里,主线程定时器取出任务再执行。
## 工具
| Tool | 作用 |
|---|---|
| `blender_health` | 桥是否可达,以及 Blender 版本、文件、场景 |
| `blender_exec` | 执行任意 Python,最后一行表达式作为 JSON 结果 |
| `blender_scene_info` | 场景、模式、集合、最多 200 个物体 |
| `blender_viewport` | 当前 3D 视口的 OpenGL PNG,不是完整渲染 |
## 环境
- Blender 4.2 及以上(本仓库在 Blender 5.2.2 LTS / macOS 上跑过 `npm run test:smoke`)
- Node.js >= 18
## 安装
```bash
cd blender_meta_mcp
npm install
npm run install:addon
```
在 Blender 里:**Edit → Preferences → Add-ons → blender-meta-mcp**,启用后保持 Blender 开着。侧栏 **MCP** 页会显示 `127.0.0.1:11588`。
## 接到 Cursor
```bash
npm run setup:cursor
```
把输出贴进 `~/.cursor/mcp.json`(或项目 `.cursor/mcp.json`),然后在 MCP 设置里关掉再打开 `blender-meta-mcp`。样例见 `examples/cursor-mcp.json`。
## 验收
```bash
npm run test:smoke
```
会另开一个 Blender 窗口(配置写在临时目录,不动本机偏好),依次检查:
1. `blender_health` 返回版本号,并且有 3D 视口
2. `blender_exec` 创建名为 `MCP Test` 的立方体
3. `blender_scene_info` 列表里有它
4. 撤消后立方体消失
5. 语法错误返回 traceback,Blender 不退出
6. `blender_viewport` 返回 PNG
7. 关掉这个 Blender 后,health 变为不可达
手测也可以:
```python
import bpy
bpy.ops.mesh.primitive_cube_add(size=2, location=(0, 0, 1))
obj = bpy.context.active_object
obj.name = "MCP Test"
{"name": obj.name, "type": obj.type}
```
## 写脚本
最后一行写成表达式。`bpy` 已经在作用域里。约束和对象模型见 `skills/blender-bpy/SKILL.md`。
## 目录
```text
mcp/ Node stdio MCP(index、core、context、bridge-client)
addon/ Blender addon(HTTP 线程 + 主线程定时器)
scripts/ install-addon、setup-cursor、smoke-test
skills/ blender-bpy agent skill
examples/ cursor-mcp.json
docs/ DEV.md
```
## 故障
| 现象 | 处理 |
|---|---|
| health 连接被拒绝 | Blender 没开,或 addon 没启用;看侧栏 MCP 是否在监听 |
| 端口占用 | 改 addon 偏好里的端口,并设置 `BLENDER_MCP_BRIDGE` |
| context is incorrect | 打开一个 3D 视口。桥会套第一个 `VIEW_3D` 的 `temp_override` |
| 主线程没取走任务 | Blender 正在渲染或处于模态操作;等它结束再调 |
| 界面卡住 | `bpy.ops.render.render` 会占住主线程直到结束 |
## 安全
桥只绑定 `127.0.0.1`。`blender_exec` 是本机 Python,能改 Blender 文件,也能动这台机器上的文件。只在本机开发时开。
## 环境变量
| 变量 | 默认 | 说明 |
|---|---|---|
| `BLENDER_MCP_BRIDGE` | `http://127.0.0.1:11588` | MCP 连 addon 的地址 |
| `BLENDER_MCP_PORT` | `11588` | addon 监听端口(优先于偏好) |
| `BLENDER_MCP_TIMEOUT_S` | `120` | 主线程取任务的等待秒数 |
| `BLENDER_MCP_AUTOSTART` | 启用 | 设为 `0` 则启用 addon 后不自动监听 |
| `BLENDER_BIN` | 自动查找 | `install:addon` / `test:smoke` 用的 Blender 可执行文件 |
## License
MIT
TDQS
Scored across 4 tools
Each tool has a clear primary purpose: health checking, viewport capture, Python execution, and scene summary. Some minor overlap exists between health and scene_info since both report the current scene name, but descriptions make the distinction clear.
All tools use snake_case with the blender_ prefix, which creates a clear family. Naming blends nouns (blender_health, blender_viewport, blender_scene_info) with a verb (blender_exec), but the pattern remains predictable and readable.
Four tools is a reasonable size for a Blender bridge server. It is slightly lean, but the presence of blender_exec as a general-purpose escape hatch means the small count does not feel restrictive.
The tool surface is essentially complete because blender_exec allows arbitrary bpy Python execution, covering any missing operation. The dedicated health, viewport, and scene_info tools handle the most common inspection and interaction workflows without dead ends.