blender-agent
Drives a live Blender session from an AI agent, providing computer-use style tools to observe a scene (scene graph, per-object info, screenshots), discover Blender's operators (keyword search and parameter/enum descriptions across ~2,500 bpy.ops), and act on the scene (calling operators, reading/writing arbitrary RNA properties, checkpoint/restore and save). Supports both headless and GUI sessions, rendering screenshots from the scene camera, and can run as an MCP server or background CLI so a scene can be built up over a multi-turn conversation.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@blender-agentAdd a monkey, apply subdivision, render it, and show me the image."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
blender-agent-sdk
Drive Blender from AI agents with a plain Python SDK — no addon to install. The same tools are also available as an MCP server and as a command line for building a scene over a conversation.
BlenderSession launches Blender (headless -b or with its GUI), injects a small bridge with
--python, and talks to it over a private Unix socket (loopback TCP with a per-session token on
Windows). Linux, Windows and macOS. On top of that sit computer-use style
tools — observe (scene graph, object state, screenshots), discover (search 2,498 operators) and
act (operators, RNA properties, checkpoints) — exported as ready-made OpenAI and Anthropic
function-calling schemas with a one-line dispatch().
The design is grounded in a reverse-engineering pass over the Blender 5.2.2 binary itself with
REA (Ghidra provider). See docs/re/ for the
evidence and its limits.
from blender_agent import BlenderSession
with BlenderSession() as bl: # blender -b, factory startup
bl.call_operator("mesh.primitive_monkey_add", {"location": [0, 0, 1]})
bl.call_operator("object.modifier_add", {"type": "SUBSURF"})
bl.set_property("objects", "Suzanne", "modifiers['Subdivision'].levels", 2)
print(bl.scene_graph()["objects"])
png, meta = bl.screenshot(640, 480) # PNG bytes; renders from the scene cameraInstall
Requires Python ≥ 3.10 and Blender. CI runs the full suite against Blender 5.2.2 on Linux x64
(including the GUI test under Xvfb), Windows x64 and macOS arm64; other Blender versions are untested.
The wheel is pure Python, so one file covers every platform. Blender itself is not bundled; the SDK
finds it through BlenderSession(blender=...), $BLENDER, PATH, or the default install location
(/Applications/Blender.app on macOS, C:\Program Files\Blender Foundation\Blender * on Windows).
pip install https://github.com/yazzang-homelab/blender-agent-sdk/releases/download/v0.2.0/blender_agent_sdk-0.2.0-py3-none-any.whl
# or the development version
pip install git+https://github.com/yazzang-homelab/blender-agent-sdkplatform | transport | GUI sessions |
Linux | Unix socket in a 0700 directory | yes (X11/Wayland, |
macOS | Unix socket in a 0700 directory | untested (hosted runners have no GPU display) |
Windows |
| untested (hosted runners have no GPU display) |
Related MCP server: Blender Open MCP
Work on a scene in a conversation
A script's BlenderSession ends with the script. To build something over many turns (from Claude Code,
GJC, Cursor, or by hand) keep one Blender alive with either of these; both use the SDK's tools and exec
policy unchanged.
MCP server (stdio, standard library only):
claude mcp add blender -- blender-agent mcp --http 8765 # Claude Code
gjc mcp add blender --command blender-agent --arg mcp --arg --http --arg 8765 # GJCBesides the SDK tools the server offers show (render, save to the gallery, return the image),
gallery (where the user can look) and reset_scene.
MCP hosts start servers with a minimal environment, so pass settings as options rather than
environment variables: --blender PATH, --render-engine CYCLES (no GPU), --gui, --allow-exec.
Background session + CLI, for agents without MCP or for typing commands yourself:
blender-agent start --name tree --http 8765 # Blender keeps running between commands
blender-agent call --name tree call_operator '{"idname": "mesh.primitive_cone_add", "params": {"depth": 3}}'
blender-agent show --name tree --label "trunk" # render, record, draw it in the terminal
blender-agent call --name tree checkpoint '{"label": "v1"}'
blender-agent stop --name treeSeeing what the agent did
channel | how |
terminal |
|
live terminal pane |
|
model | MCP |
gallery folder | every screenshot goes to |
browser |
|
Blender itself |
|
The CLI keeps per-session state under ~/.cache/blender-agent (%LOCALAPPDATA% on Windows): a local
socket or named pipe plus a random key that every request must present.
Plug it into an agent
import anthropic
from blender_agent import BlenderSession, anthropic_tools, dispatch
from blender_agent.tools import result_text
client = anthropic.Anthropic()
with BlenderSession() as bl:
messages = [{"role": "user", "content": "Build a snowman and show me."}]
while True:
reply = client.messages.create(model="claude-sonnet-4-5", max_tokens=2048,
tools=anthropic_tools(), messages=messages)
messages.append({"role": "assistant", "content": reply.content})
calls = [b for b in reply.content if b.type == "tool_use"]
if not calls:
break
messages.append({"role": "user", "content": [
{"type": "tool_result", "tool_use_id": c.id, "content": result_text(dispatch(bl, c.name, c.input))}
for c in calls]})openai_tools() is the same list in OpenAI's {"type": "function", ...} shape, and dispatch() accepts
OpenAI's JSON-string arguments directly. examples/agent_loop.py is a complete
loop for both APIs (screenshots are sent back as images) plus a scripted policy that needs no API key:
python examples/agent_loop.py --policy scripted --out agent-output
python examples/agent_loop.py --policy anthropic "build a low-poly tree"Tools
tool | what it does |
| all objects with type, transform, dimensions, visibility, selection, collections; active object, camera, mode, engine |
| one object in depth: world bbox, modifiers, materials, mesh counts, light/camera data, custom props |
| PNG of the scene (see modes below) |
| keyword search over every registered |
| an operator's parameters, types and enum values |
| run |
| read/write any RNA path on a datablock, e.g. |
| snapshot and roll back the whole file |
| write a |
| arbitrary Python inside Blender — off unless |
Errors raised inside Blender come back as RemoteError (type, message, remote traceback) and the
session keeps running; dispatch() turns them into {"ok": false, "error": ...} so the model can
correct itself. A request over the 64 MiB frame limit raises RequestTooLarge without being sent (the
session is unaffected; dispatch() returns it as an error too). A hung or crashed Blender raises
SessionLost after the request timeout and the process is killed.
Background vs GUI sessions
|
| |
execution | bridge blocks Blender's main thread and serves requests | reader thread + one |
| render from the scene camera (Workbench; a temporary camera framing visible objects when there is none) | offscreen draw of the 3D viewport ( |
| refused — |
|
display | none needed | needs a display ( |
Set BLENDER_AGENT_RENDER_ENGINE=CYCLES on machines without a GPU (CI does); Cycles then renders on the CPU.
How it works
your agent ──dispatch()──► BlenderSession ──Unix socket or token-checked loopback TCP, 4-byte length + JSON──► bridge.py in Blender
│ owns the process, timeouts, │ bpy on the main thread
│ Blender log → file (never blocks) │The process is launched as
blender [-b] [--disable-autoexec] [file.blend] [--factory-startup] [extra_args...] --python-exit-code 1 --python bridge.py -- --connect <address> --workdir <dir> [--allow-exec].
<address> is the socket path, or tcp:127.0.0.1:<port> on Windows, where CPython has no AF_UNIX.
The bridge's first frame carries a random token the client put in Blender's environment, and the client
drops any peer without it, so another local process cannot pose as Blender on the loopback port.
The socket, Blender's log, renders and checkpoints all live in one private directory (0700; the user's
own %TEMP% on Windows) that the client removes on every exit path (close, timeout, crash, failed start).
Trust model
Without allow_exec=True the bridge, not only the client, refuses every known way to run agent-controlled
Python inside Blender:
the
exec_pythonmethod;operators that run scripts or code:
script.*,console.*,text.run_script, preset add/execute operators, add-on and extension management (preferences.*,extensions.*), external openers (wm.url_open,wm.path_open,image.external_edit), and any operator taking a Python-evaluated parameter (data_path,eval_string, …, as inwm.context_*) or asettingscollection ofNodeSettingvalues (node.add_node,node.swap_nodeand the zone, group and bundle adders: 12 operators in 5.2.2);operators that write or re-evaluate agent-controlled Python:
anim.keying_set_export(writes a.py) andanim.update_animated_transform_constraints(eval()s every F-Curve and driverdata_path);wm.read_homefile/wm.read_factory_settingswithapp_template, since an app template is a Python package; invoked (INVOKE_*)render.*operators andnode.render_changed, whose render jobs outlive the request (operators are also refused while a render job runs);operators that start another Blender which could run scripts:
asset.open_containing_blend_file, andwm.previews_batch_generate/wm.previews_batch_clearwithuse_trusted=True(forced toFalseotherwise);embedded scripts in
.blendfiles: Blender starts with--disable-autoexec, every file load (open_file,restore,wm.open_mainfile, …) runs withuse_scripts=False, and an explicituse_scripts=Trueis refused;Freestyle, which runs Python whenever it renders regardless of auto-exec: style-module text blocks in script mode, and in editor mode an expression built from view-layer and line-set names that escapes only quotes. The bridge keeps
render.use_freestyleoff in every scene (linked ones included) at startup and after every request, before GUI redraws can render; a request that turned it on, e.g. by opening a file, gets aFreestyleDisablederror after it completes (a failed request keeps its own error, with a note). Turning it on withset_propertyis refused, and so are scene previews (wm.previews_batch_generatewithuse_scenes=True, forced toFalseotherwise), which a child Blender renders with the file's settings. Files opened by operators load without their own UI (load_ui=False;load_ui=Trueis refused).
This closes code execution inside the Blender process. It is not a filesystem sandbox: ordinary
operators can still read and write files the user can reach (save, wm.save_as_mainfile, image and
mesh import/export), including Python text blocks saved with text.save in GUI sessions. Run untrusted
agents in a container or VM with only the files they need.
The guarantee covers what an agent can reach through tool calls. Constructor arguments are the caller's:
extra_args (e.g. --enable-autoexec, --python-expr) and factory_startup=False (user add-ons and
startup file) are passed to Blender unchecked, and in GUI sessions a blend_file given at launch
opens with its own UI. Open untrusted files with open_file instead.
SDK first, MCP optional
Typical Blender MCP servers need an addon installed into the user's Blender and a host that speaks MCP.
Here the core is a child process you own: it can be headless, sandboxed per task, run in CI, and its
tools drop into any function-calling loop. blender-agent mcp is a thin adapter over the same tools for
hosts that speak MCP. Prior art for comparison:
ahujasid/blender-mcp (MCP addon, GUI only) and
ptrthomas/blender-agent (HTTP exec endpoint, no SDK).
Reverse engineering
The SDK's shape comes from taking the stripped 174 MB (166 MiB) Blender 5.2.2 binary apart with REA + Ghidra (full
auto-analysis: 301,393 procedures, 70 min). The results were cross-checked against the v5.2.2 source and a full runtime
RNA dump. Highlights from docs/re/:
CPython is statically linked (
.PyRuntimesection).gpu,bmeshand friends live in an internal_inittab, and_bpyis created at startup withPyModule_New. None of them is exported, so the only bridge that needs no install is a--pythonscript inside Blender's own interpreter.The
-bhandler just setsG.backgroundand mutes audio. The window manager survives, but there is no event loop and the GPU is not initialized, so the bridge owns the main thread under-b. Screenshots come from a render rather thanGPUOffScreen, which would needgpu.init()and a real GPU (GitHub runners have none).bpy_op_fn_call_impl(decompiled) polls, converts kwargs to RNA, releases the GIL and callsWM_operator_call_py(..., is_undo). Thatis_undoflag is why GUI sessions pass it, and why-bsessions use.blendcheckpoints.The binary holds 2,247 operator idnames from about 2,135 static
WM_operatortype_appendcall sites. At runtime there are 2,498 operators. Every difference is accounted for: Python operators, add-on operators, dead and commented-out registrations, keymap strings, and one linker tail-merge. The SDK therefore searches the live registry instead of a static list.
Development
pip install -e ".[test]"
BLENDER=~/blender/blender pytest # needs a real Blender; it fails, not skips, without one
xvfb-run -a pytest # also runs the GUI smoke test
UPDATE_GOLDEN=1 pytest tests/test_tools.py # after an intentional tool-schema changeRegenerate the operator/RNA catalog: blender -b --factory-startup --python tools/dump_rna.py -- data/rna-5.2.2.json.gz.
License
GPL-3.0-or-later. The bridge imports bpy, so the project follows Blender's license.
Blender binaries are never redistributed here.
한국어
AI 에이전트가 MCP 없이 순수 Python SDK로 Blender를 조작(computer-use)하게 해 주는 라이브러리입니다.
BlenderSession이 Blender를 자식 프로세스로 띄우고(-b헤드리스 또는 GUI),--python으로 브리지를 주입해 전용 Unix 소켓(0700 디렉터리, Windows는 세션 토큰으로 인증하는 127.0.0.1 TCP)과 4바이트 길이 접두 JSON으로 통신합니다. 애드온 설치가 필요 없습니다.Linux x64, Windows x64, macOS arm64에서 Blender 5.2.2로 전체 테스트를 CI에서 돌립니다(GUI 테스트는 Linux). 설치:
pip install https://github.com/yazzang-homelab/blender-agent-sdk/releases/download/v0.2.0/blender_agent_sdk-0.2.0-py3-none-any.whl관찰(
scene_graph,object_info,screenshot) · 탐색(search_operators,describe_operator) · 조작(call_operator,set_property,checkpoint/restore,save) 도구를 OpenAI/Anthropic function-calling 스키마로 제공하고dispatch()한 줄로 실행합니다.exec_python은 기본 비활성이며, 브리지가 실행 인자로 직접 차단합니다. 스크립트를 실행하는 연산자 (script.*,text.run_script,data_path/eval_string인자,.blend내장 스크립트 등)도 막지만, 파일시스템 샌드박스는 아니므로 신뢰할 수 없는 에이전트는 컨테이너에서 돌리십시오.Blender 내부 예외는
RemoteError(타입·메시지·원격 traceback)로 돌아오고 세션은 유지됩니다. 멈추거나 죽으면 타임아웃 후 프로세스를 정리하고SessionLost를 던집니다.대화하면서 장면을 완성하려면 Blender를 계속 살려 두는
blender-agent mcp(Claude Code·GJC 등 MCP 호스트) 또는blender-agent start/call/show/stop(CLI)을 씁니다. 결과는 터미널 인라인 이미지(kitty·iTerm2·하프블록), tmux 옆 창의blender-agent watch, 갤러리 폴더(index.html자동 새로고침),--http웹(내부망은--http-bind 0.0.0.0),--guiBlender 창 실시간 보기로 확인합니다.헤드리스(
-b)에는 undo 스택이 없어checkpoint/restore(.blend 스냅샷)를 쓰고, GUI 세션에서는ed.undo와 뷰포트 오프스크린 캡처를 씁니다.설계 근거는 REA(Ghidra 프로바이더)로 Blender 5.2.2 바이너리 자체를 리버싱한 결과입니다. 증거와 한계는
docs/re/에 있습니다.
테스트는 실제 Blender로 돕니다: BLENDER=/path/to/blender pytest (GUI까지: xvfb-run -a pytest).
라이선스는 GPL-3.0-or-later이며 Blender 바이너리는 포함하지 않습니다.
This server cannot be deployed
Maintenance
Related MCP Connectors
Blender-as-a-service for agents: search 3D assets, run Blender Python, or brief the studio agent.
Persistent memory, hybrid search and a goal graph for AI agents, over stdio or remote HTTP.
Cloud Blender for AI agents: build, inspect, render and animate 3D scenes over remote MCP. Keep editable .blend projects and export GLB or STL. Make your first 3D asset free—30 compute minutes per UTC month, no credit card. First 100 eligible Free account owners to use all 30 minutes in one UTC month by December 31, 2026 UTC receive one calendar month of beta free: 4 compute hours per UTC month, 2 concurrent workers per deployment, 2 deployments, 2048×2048 renders at up to 256 samples, and 10 GiB storage. Existing usage counts toward the 4-hour allowance. Limited to 100 rewards; expires January 1, 2027 00:00 UTC. Free resumes afterward without an automatic charge. Examples, eligibility and terms: https://sceneplane.online/launch?utm_source=glama&utm_medium=directory&utm_campaign=first100
A comprehensive Model Context Protocol (MCP) server that enables AI assistants to control Unreal E…
Related MCP Servers
- FlicenseAqualityCmaintenanceEnables AI agents to inspect and drive Blender scenes directly, either through a live editor bridge on port 8190 or automatically via headless background CLI when Blender is closed. Provides token-efficient tools for scene outlining, object creation and modification, modifiers, materials, rendering, asset export, and arbitrary bpy script execution.11-
- FlicenseNot gradedqualityAmaintenanceEnables AI agents to drive a live Blender session — inspecting scenes, creating, modifying and deleting objects, setting materials, rendering images, and searching or downloading PolyHaven assets and textures. It also routes prompts to a pluggable LLM backend (Ollama, LM Studio, llama.cpp, OpenAI-compatible, Azure) that can be listed and switched at runtime without restarting.-
- FlicenseNot gradedqualityAmaintenanceEnables AI agents to inspect and modify live Blender scenes, manage objects and materials, render images, retrieve PolyHaven assets, and send prompts to configurable local or OpenAI-compatible LLM backends.-
- AlicenseNot gradedqualityCmaintenanceLets an AI engine drive a Blender instance the user runs themselves over stdio JSON-RPC, enabling scene inspection, viewport capture and picking, sandboxed code execution, and gated asset search/import and 3D generation. Telemetry is disabled before import, outbound tools are withheld until per-run network consent, and VRAM gating plus a surface-policy tool report what is live and what a station has cleared.Business Source 1.1