YAML Metadata Warning:empty or missing yaml metadata in repo card
Check out the documentation for more information.
- Blender + AI: как подключить любую нейросеть к Blender
- TL;DR — минимум, чтобы начать (3 шага)
- 1. Что это вообще такое (архитектура за 30 секунд)
- 2. Порт — самое главное число
- 3. Установка: пошагово с нуля
- 4. Проверка, что всё работает
- 5. Команды: все 175
- 6.
execute_code— песочница (главный инструмент) - 7. Грабли, которые стоят часа отладки
- 7.1 Физика (rigid body / cloth / fluid) НЕ симулируется
- 7.2
Action.fcurvesбольше нет (Blender 5.x) - 7.3
obj.rigid_body = None— read-only - 7.4 Рендер блокирует всё остальное
- 7.5 Модальные операторы блокируют сервер
- 7.6 Обновление аддона: обязательно полный перезапуск Blender
- 7.7 Порт привязан к сцене, а не к Blender
- 8. Рабочий цикл агента
- 9. Где что лежит (пути)
- 10. Ссылки
- Файлы в этом репозитории
- TL;DR — минимум, чтобы начать (3 шага)
Blender + AI: как подключить любую нейросеть к Blender
Назначение этого репозитория: дать нейросети с абсолютно нулевым контекстом всё, что нужно, чтобы за несколько минут начать управлять живым Blender кодом. Никаких предварительных знаний о Blender, Python или MCP не требуется — только этот документ.
Кому адресовано: агенту (Claude, GPT, Gemini, локальной модели — любой), которого подключили к Blender и который не знает, с чего начать. Читай по порядку.
Статус: проверено на живом Blender 5.2.1 LTS, аддон blend-ai v1.3.0, Windows 11.
TL;DR — минимум, чтобы начать (3 шага)
- Blender:
Nв 3D-вьюпорте → вкладка blend-ai → Start Server (порт9876). - Скачать:
git clone https://github.com/HoldMyBeer-gg/blend-ai+uv pip install -e . - Проверить связь: отправить
{"command": "get_scene_info"}на127.0.0.1:9876.
Если ответ пришёл — можно работать. Всё остальное ниже.
1. Что это вообще такое (архитектура за 30 секунд)
Тут два раздельных куска, и путать их — самая частая ошибка:
┌──────────────┐ MCP / stdio ┌─────────────────┐ TCP socket ┌──────────────┐
│ Нейросеть │ ───────────────► │ MCP-сервер │ ───────────────► │ Аддон │
│ (клиент) │ ◄─────────────── │ blend-ai │ ◄─────────────── │ внутри │
└──────────────┘ │ (Python, у вас)│ 127.0.0.1:9876 │ Blender │
└─────────────────┘ └──────────────┘
"клиент" "сервер" (внутри Blender)
| Часть | Что это | Где живёт | Кто запускает |
|---|---|---|---|
| Аддон | TCP-сервер внутри Blender, принимает команды и выполняет их через bpy |
AppData\Roaming\Blender Foundation\Blender\<ver>\extensions\user_default\blend_ai |
Ты, кнопкой в Blender |
| MCP-сервер | Python-процесс на твоей машине, транслирует MCP-вызовы в TCP-сообщения | Клон репозитория blend-ai |
Клиент (автоматически) |
Ключевое, что нужно понять: Blender — это сервер. Он принимает входящие соединения. Нейросеть — клиент. Поэтому порт должен быть открыт в Blender до того, как агент попробует подключиться. Если Blender не запущен или сервер не нажат — подключения не будет, и выглядит это как «агент не работает», хотя проблема на стороне Blender.
Важно про терминологию. В этом репозитории слово «сервер» перегружено: аддон внутри Blender называется сервером (он слушает порт), а MCP-процесс в докe называется сервером MCP (он слушает stdio). Когда говорят «включи сервер» — обычно имеют в виду кнопку в Blender. Держи это в голове при чтении чужих инструкций.
2. Порт — самое главное число
| Параметр | Значение |
|---|---|
| Порт по умолчанию | 9876 |
| Адрес | 127.0.0.1 (только localhost, наружу не торчит) |
| Допустимый диапазон | 1024–65535 (меняется в UI) |
| Транспорт | TCP, SO_KEEPALIVE |
| Формат сообщения | 4 байта длины (big-endian, >I) + UTF-8 JSON |
| Лимит сообщения | 100 МБ |
| Таймаут сокета | 30 с на чтение, 30 с на соединение |
Порт можно менять. Поле Port в N-панели, сохраняется в сцене как scene.blendai_port
(IntProperty, default 9876, min 1024, max 65535).
⚠️ Если поменял порт в Blender — поменяй его и на стороне клиента. Иначе получишь
Connection refused, который выглядит как «Blender выключен».
Как проверить порт вручную
# Windows
netstat -ano | findstr :9876
# Linux / macOS
ss -ltnp | grep 9876 # или: lsof -i :9876
Если порт слушается — Blender готов. Если пусто — сервер в Blender не запущен.
Формат сообщения (для ручной отладки)
Запрос:
import json, socket, struct
sock = socket.create_connection(("127.0.0.1", 9876), timeout=30)
payload = json.dumps({"command": "get_scene_info", "params": {}}).encode("utf-8")
sock.sendall(struct.pack(">I", len(payload)) + payload)
length = struct.unpack(">I", sock.recv(4, socket.MSG_WAITALL))[0]
response = json.loads(sock.recv(length, socket.MSG_WAITALL).decode("utf-8"))
print(response)
sock.close()
Ответ всегда такой формы:
{
"status": "ok",
"result": { }
}
status бывает: "ok" | "error" | "busy".
⚠️ "busy" — не ошибка. Пока Blender рендерит, главный поток занят, и сервер
отвечает "busy" вместо выполнения. Правильное поведение — подождать и повторить.
Клиент blend-ai ждёт до ~5 минут (150 попыток с шагом 2 с).
Ловушка отладки.
recv(n)не обязан вернуть ровноnбайт — он может вернуть меньше. Читай в цикле, пока не наберёшь нужное, иначеjson.loadsупадёт на обрезанном куске. В Python для сокета естьsocket.MSG_WAITALL.
3. Установка: пошагово с нуля
Предварительные требования
| Что | Версия | Обязательно? |
|---|---|---|
| Blender | 4.2 LTS или новее | Да. 4.0/4.1 не поддерживаются — аддон поставляется как Blender Extension |
uv |
любая свежая | Да для установки MCP-сервера |
| Python | ≥ 3.10 | Только для MCP-сервера; сам аддон использует лишь stdlib + bpy |
⚠️ uv не входит в поставку. Если uv нет — поставь его первым:
# Windows (PowerShell)
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"
# Linux / macOS
curl -LsSf https://astral.sh/uv/install.sh | sh
⚠️ Пакета blend-ai нет на PyPI (проверено: NotFound). Установка только из git-клона.
Команда pip install blend-ai не сработает — не трать на неё время.
Шаг 1 — скачать MCP-сервер
git clone https://github.com/HoldMyBeer-gg/blend-ai.git
cd blend-ai
uv pip install -e .
Эквивалент через venv, если uv использовать не хочется:
python -m venv .venv
# Windows: .venv\Scripts\activate
# Linux/macOS: source .venv/bin/activate
pip install -e .
Зависимости: mcp>=1.26.0, pydantic>=2.0. Точка входа — blend-ai → blend_ai.server:main.
Шаг 2 — установить аддон в Blender
Способ А (рекомендуемый) — из релиза:
- Скачать
blend_ai-1.3.0.zip:https://github.com/HoldMyBeer-gg/blend-ai/releases/download/v1.3.0/blend_ai-1.3.0.zip(все релизы:https://github.com/HoldMyBeer-gg/blend-ai/releases) - Blender → Edit → Preferences → Get Extensions → стрелка ▾ справа сверху → Install from Disk…
- Выбрать скачанный
.zip. - Включить галочку blend-ai в списке расширений.
Способ Б — симлинк на клон (удобно для разработки):
# Windows (запускать от имени администратора!)
mklink /D "%APPDATA%\Blender Foundation\Blender\<ver>\extensions\user_default\blend_ai" "%cd%\addon"
# macOS
ln -s "$(pwd)/addon" ~/Library/Application\ Support/Blender/<ver>/extensions/user_default/blend_ai
# Linux
ln -s "$(pwd)/addon" ~/.config/blender/<ver>/extensions/user_default/blend_ai
<ver> — версия Blender, например 4.2 или 5.2.
Способ В — вручную распаковать (когда нет прав на симлинк и не хочется UI):
распаковать содержимое zip в
%APPDATA%\Blender Foundation\Blender\<ver>\extensions\user_default\blend_ai\
так, чтобы внутри лежал __init__.py.
Шаг 3 — ВКЛЮЧИТЬ сервер в Blender (самый забываемый шаг)
Установка аддона ≠ запуск сервера. Это два разных действия.
- В 3D-вьюпорте нажать
N(открыть боковую панель). - Найти вкладку blend-ai (вертикальные иконки справа).
- Проверить поле Port (по умолчанию
9876). - Нажать Start Server.
Должно появиться:
Server: Running (port 9876)
Если видишь Server: Stopped — сервер не запущен, агент работать не будет.
Порт задаётся per-scene. Поле
Portпривязано к текущей сцене (scene.blendai_port). Открыл другой.blend— проверь, что порт тот же, и что сервер всё ещё запущен.
⚠️ Сервер НЕ запускается автоматически при старте Blender. Это осознанное решение автора аддона. После каждого перезапуска Blender кнопку надо нажимать снова. Если агент «внезапно перестал работать» — с вероятностью 90% причина в этом.
Шаг 4 — настроить клиента (MCP)
Claude Code:
claude mcp add blend-ai -- uv run --directory /path/to/blend-ai blend-ai
Claude Desktop — claude_desktop_config.json:
{
"mcpServers": {
"blend-ai": {
"command": "uv",
"args": ["run", "--directory", "/path/to/blend-ai", "blend-ai"]
}
}
}
Пути конфига: macOS ~/Library/Application Support/Claude/claude_desktop_config.json,
Windows %APPDATA%\Claude\claude_desktop_config.json.
Другой клиент (любой MCP-совместимый):
uv run --directory /path/to/blend-ai blend-ai
# или напрямую:
python -m blend_ai.server
| Поле конфига | Значение |
|---|---|
command |
uv |
args |
["run", "--directory", "/path/to/blend-ai", "blend-ai"] |
env |
не требуется |
| Транспорт | stdio |
⚠️ Запускать MCP-сервер надо не «руками в терминале», а через клиента — он сам поднимает процесс и общается с ним по stdio. Ручной запуск в терминале выглядит как «зависло» — это нормально, сервер ждёт JSON-RPC на stdin.
4. Проверка, что всё работает
Порядок диагностики — сверху вниз. Останавливайся на первой сломанной ступени.
| # | Проверка | Как | Если не прошло |
|---|---|---|---|
| 1 | Blender запущен | посмотреть на экран | открыть Blender |
| 2 | Аддон включён | Preferences → Get Extensions → blend-ai | включить галочку |
| 3 | Сервер запущен | N-панель: Server: Running (port 9876) |
нажать Start Server |
| 4 | Порт слушается | netstat -ano | findstr :9876 |
проверить порт в UI и в клиенте |
| 5 | Хендшейк на сокете | скрипт из §2 | см. таблицу ошибок ниже |
| 6 | MCP-сервер поднят | клиент видит инструменты | проверить путь в конфиге, uv в PATH |
Таблица типовых ошибок
| Симптом | Причина | Лечение |
|---|---|---|
Connection refused |
сервер в Blender не запущен, или другой порт | нажать Start Server; сверить порт |
timed out |
Blender занят рендером или модальным оператором | подождать, повторить; выйти из модального режима (Esc) |
status: busy |
идёт рендер | подождать и повторить, это нормально |
Unknown command: '...' |
опечатка в имени команды | сверить с §5; в ошибке придёт полный список |
Invalid JSON in request |
битая JSON-строка | проверить кавычки/экранирование |
Non-finite JSON constant |
в JSON пришёл NaN/Infinity |
заменить на нормальное число |
Module 'os' is blocked |
ограничение песочницы execute_code |
см. §6 |
| Клиент не видит инструментов | неверный путь в args |
проверить /path/to/blend-ai |
Быстрый диагностический скрипт
Сохрани как check_blender.py и запусти — проверит всё разом:
import json, socket, struct, sys
HOST, PORT = "127.0.0.1", 9876
def recv_exactly(sock, n):
buf = b""
while len(buf) < n:
chunk = sock.recv(n - len(buf))
if not chunk:
raise ConnectionError("Blender closed the connection")
buf += chunk
return buf
def send(command, params=None, timeout=30.0):
sock = socket.create_connection((HOST, PORT), timeout=timeout)
try:
msg = {"command": command}
if params:
msg["params"] = params
payload = json.dumps(msg).encode("utf-8")
sock.sendall(struct.pack(">I", len(payload)) + payload)
length = struct.unpack(">I", recv_exactly(sock, 4))[0]
return json.loads(recv_exactly(sock, length).decode("utf-8"))
finally:
sock.close()
if __name__ == "__main__":
try:
r = send("get_scene_info")
if r.get("status") == "ok":
info = r["result"]
objs = info.get("objects", [])
print(f"OK scene='{info.get('scene_name')}' objects={len(objs)}")
for o in objs[:10]:
print(f" {o['type']:<8} {o['name']}")
if len(objs) > 10:
print(f" ... and {len(objs)-10} more")
else:
print("Blender replied:", r)
except ConnectionRefusedError:
print("FAIL Nothing listening on 127.0.0.1:9876.")
print(" -> open Blender, press N, blend-ai tab, 'Start Server'")
sys.exit(1)
except socket.timeout:
print("FAIL Timeout. Blender may be rendering or in a modal operator.")
sys.exit(1)
5. Команды: все 175
Полный список с описанием параметров — в COMMANDS.md.
Краткая карта — ниже.
⚠️ Список команд не надо помнить. Отправь заведомо неверную команду — сервер вернёт ошибку с полным актуальным списком:
Unknown command: 'xxx'. Available commands: ['add_annotation_layer', ...]
Это самый надёжный способ узнать, что доступно в конкретной сборке.
Карта по областям
| Область | Кол-во | Примеры команд |
|---|---|---|
materials |
22 | create_material, set_material_color, add_shader_node, connect_shader_nodes |
mesh_editing |
16 | extrude_faces, inset_faces, bevel_edges, mark_seam |
objects |
15 | create_object, list_objects, duplicate_object, join_objects |
modeling |
13 | add_modifier, subdivide_mesh, boolean_operation, set_modifier_property |
curves |
10 | create_curve, create_text, convert_curve_to_mesh |
physics |
9 | add_rigid_body, add_cloth_sim, bake_physics ⚠️ см. §7 |
sculpting |
8 | enter_sculpt_mode, remesh, set_sculpt_brush |
animation |
8 | insert_keyframe, set_frame, create_animation_path |
camera |
7 | capture_viewport, create_camera, point_camera_at |
lighting |
7 | create_light, create_light_rig, set_world_background |
rendering |
7 | render_image, render_animation, set_render_engine |
scene |
7 | get_scene_info, list_scenes, get_installed_extensions |
armature |
6 | create_armature, add_bone, set_pose |
transforms |
6 | set_location, set_rotation, set_scale |
file_ops |
5 | import_file, export_file, save_file, open_file |
geometry_nodes |
5 | create_geometry_nodes, set_geometry_node_input |
collections |
4 | create_collection, move_to_collection |
booltool |
4 | booltool_auto_union, booltool_auto_difference |
uv |
4 | uv_unwrap, smart_uv_project, pack_uv_islands |
viewport |
3 | focus_on_object, set_viewport_shading |
physics/прочее |
… | см. COMMANDS.md |
execute_code |
1 | песочница Python — самый мощный инструмент, см. §6 |
Первые команды, которые стоит вызвать
{"command": "get_scene_info"} // что вообще есть в сцене
{"command": "list_objects"} // список объектов
{"command": "list_materials"} // список материалов
{"command": "get_installed_extensions"} // какие аддоны стоят
{"command": "get_object_info", "params": {"object_name": "Cube"}}
6. execute_code — песочница (главный инструмент)
Одна команда заменяет собой почти всё остальное: выполняет произвольный Python внутри
Blender с полным доступом к bpy.
{"command": "execute_code", "params": {"code": "import bpy\nprint(len(bpy.data.objects))"}}
Что возвращает:
{"status": "ok", "result": {"output": "16", "success": true}}
Всё, что код напечатал через print(), попадает в result.output. Если код упал —
вернётся RuntimeError с текстом ошибки и всем выводом до падения.
Что РАЗРЕШЕНО
bpy, bmesh, mathutils, math, json, random, collections, itertools, re —
и вообще всё, кроме списков ниже.
Что ЗАПРЕЩЕНО (жёстко, на уровне песочницы)
Заблокированные модули (импорт падает с ImportError):
os, subprocess, socket, shutil, sys, ctypes, importlib, pathlib, signal,
multiprocessing, pickle, shelve, tempfile, http, urllib, ftplib, smtplib,
xmlrpc, code, codeop, compileall, webbrowser, antigravity, turtle, tkinter
Удалённые встроенные функции: __import__, exec, eval, compile, open,
globals, locals, vars, input, breakpoint, exit, quit, help, memoryview.
Практические следствия (это ловит почти каждого)
| Хочется | Нельзя | Как обойти |
|---|---|---|
| Прочитать/записать файл | open(), pathlib |
команды save_file / import_file / export_file |
| Узнать путь к Blender | sys, os |
не нужно; работай через bpy.path / bpy.data.filepath |
| Обойти директорию | os.walk |
bpy.path.abspath() |
| Список модулей | importlib |
bpy.ops.* / dir() |
| Свои модули | sys.path |
весь код одним блоком |
Главная ловушка песочницы.
osиsysзаблокированы не случайно — это защита от выполнения произвольного кода. Если твой код начинается сimport os— он упадёт целиком, причём сообщение будет про конкретный модуль, а не про то, что ты хотел. Пиши код безos/sysс самого начала.
Приём: передавай код файлом, а не строкой
Если код многострочный, экранировать его в JSON руками — мучение, и легко получить
невнятное Expecting property name enclosed in double quotes. Лучше так:
# params.json
{"code": "import bpy\nfor o in bpy.data.objects:\n print(o.name)"}
python blender_cmd.py execute_code @params.json
7. Грабли, которые стоят часа отладки
Здесь собрано только то, что проверено на практике и что реально ломает работу.
7.1 Физика (rigid body / cloth / fluid) НЕ симулируется
Это самая дорогая ловушка в репозитории.
Команды add_rigid_body, add_cloth_sim, add_fluid_sim, bake_physics выполняются
без ошибок, конфигурация читается назад корректной (substeps=10, solver_iterations=10,
time_scale=1.0, кэш 1..250), bake_physics даже возвращает is_baked: True — но объекты
не двигаются ни на одном кадре, и после бейка в них нет ни animation_data, ни action.
Вывод: не проектируй рабочий процесс вокруг физических солверов. Движение делай ключевыми кадрами, драйверами или geometry nodes. Если нужна гравитация — считай параболу по кадрам в Python и ставь ключи. Это предсказуемо и видно глазами.
Как это было установлено: ключевые кадры на тех же объектах и тех же кадрах
движение дают (z 9.0 → 4.32 → 2.0 → 1.09 → 1.0), а rigid body — нет. Значит канал
set_frame рабочий, проблема именно в солвере.
7.2 Action.fcurves больше нет (Blender 5.x)
Старый путь action.fcurves падает с AttributeError. Актуальный:
action.layers[0].strips[0].channelbag(action.slots[0]).fcurves
Все старые примеры из интернета и большинство документации — устарели.
7.3 obj.rigid_body = None — read-only
Снять физическое тело присваиванием нельзя, будет AttributeError: ... is read-only.
Только оператором, с активным и выделенным объектом:
bpy.ops.rigidbody.object_remove()
7.4 Рендер блокирует всё остальное
Во время рендера главный поток занят, сервер отвечает status: "busy". Если нужно
заниматься чем-то ещё — execute_code в это время не пройдёт. Жди или сбрасывай
reset_render_guard.
7.5 Модальные операторы блокируют сервер
Если пользователь ушёл в sculpt/edit mode или запустил модальный оператор (Ctrl+R,
G, S) и не завершил — сервер не может выполнить команду, будет таймаут. Лечение:
Esc в Blender. В скриптах оборачивай в bpy.ops.object.mode_set(mode='OBJECT').
7.6 Обновление аддона: обязательно полный перезапуск Blender
Фоновый TCP-поток переживает Reload Scripts. Поэтому после обновления аддона:
выключить сервер → выключить/удалить аддон → полностью закрыть Blender → запустить
заново → включить аддон. Иначе получишь старый код вперемешку с новым.
При разработке аддона помогает то, что при disable/enable аддон сам чистит кэш
субмодулей (_purge_submodules_from_cache) — но это не спасает от старого потока.
7.7 Порт привязан к сцене, а не к Blender
scene.blendai_port — свойство сцены. Переключил .blend — проверь порт и статус сервера.
8. Рабочий цикл агента
Проверенный порядок действий — от него меньше всего сюрпризов:
1. get_scene_info # осмотреться, понять что есть
2. (сделать изменения) # команды или execute_code
3. capture_viewport → прочитать PNG # ПОСМОТРЕТЬ на результат
4. (если плохо) вернуться к шагу 2
5. render_image # финальный результат
6. save_file # сохранить, если нужно
Правило: всегда смотри на результат
Не верь, что команда сработала, если не видел картинку. Типичный сценарий провала:
команда вернула status: ok, а на экране ничего не изменилось (объект за камерой,
материал не назначен, модификатор не применён).
{"command": "capture_viewport", "params": {"filepath": "C:/tmp/check.png", "width": 1280, "height": 720}}
Ответ даёт путь к PNG — прочитай файл глазами (умеющие модели читают изображения). Только после этого считай шаг выполненным.
Уборка за собой
Если создавал временные объекты для проверки гипотезы — удали их в конце и верни сцену в исходное состояние. Пользователь смотрит на тот же вьюпорт, что и ты.
9. Где что лежит (пути)
Аддон (по версиям Blender)
| ОС | Путь |
|---|---|
| Windows | %APPDATA%\Blender Foundation\Blender\<ver>\extensions\user_default\blend_ai |
| Linux | ~/.config/blender/<ver>/extensions/user_default/blend_ai |
| macOS | ~/Library/Application Support/Blender/<ver>/extensions/user_default/blend_ai |
Внутри: __init__.py, server.py, dispatcher.py, thread_safety.py, render_guard.py,
ui_panel.py, blender_manifest.toml, handlers/ (25 файлов — по областям).
MCP-сервер (клон)
blend-ai/
├── addon/ # исходники аддона (то, что симлинкуется в Blender)
├── src/blend_ai/
│ ├── server.py # точка входа, FastMCP("blend-ai"), transport="stdio"
│ ├── connection.py # TCP-клиент; DEFAULT_HOST/PORT здесь
│ ├── tool_registry.py
│ ├── tools/ # 24 модуля — обёртки MCP над командами
│ ├── resources/ # MCP resources
│ └── prompts/ # готовые промпты-воркфлоу
├── tests/ # ~1190 тестов
└── pyproject.toml
10. Ссылки
| Что | Где |
|---|---|
| Репозиторий | https://github.com/HoldMyBeer-gg/blend-ai |
| Релизы (zip аддона) | https://github.com/HoldMyBeer-gg/blend-ai/releases |
| Конкретно v1.3.0 | https://github.com/HoldMyBeer-gg/blend-ai/releases/download/v1.3.0/blend_ai-1.3.0.zip |
| Лицензия | AGPL-3.0-or-later (сервер), GPL-3.0-or-later (аддон) |
| Автор | jabberwock |
Файлы в этом репозитории
| Файл | Что внутри |
|---|---|
README.md |
этот документ — онбординг с нуля |
COMMANDS.md |
все 175 команд с параметрами и примерами |
TROUBLESHOOTING.md |
диагностика: симптом → причина → лечение |
AGENT_QUICKSTART.md |
сжатая выжимка для агента — скопировать в контекст |
check_blender.py |
скрипт проверки связи (запускается как есть) |
blender_cmd.py |
CLI-обёртка: python blender_cmd.py get_scene_info |
Проверено на Blender 5.2.1 LTS + blend-ai v1.3.0, сентябрь 2026. Версии аддона и клиента должны совпадать — смешивание версий даёт трудноуловимые сбои.