From b6c11a35ac66b38719c8f7a91fb0644b293acbdb Mon Sep 17 00:00:00 2001 From: Teknium <127238744+teknium1@users.noreply.github.com> Date: Wed, 15 Jul 2026 10:21:19 -0700 Subject: [PATCH] refactor(skills): adapt salvaged references to the MCP-tool surface, bump to 2.1.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Follow-up on kshitijk4poor's cherry-picked references: - pitfalls.md rewritten from the raw-socket blender_exec() frame to the MCP-tool frame (dropped 'MCP server is optional, talk to the socket directly' — now the anti-pattern; dropped TCP-helper internals items; kept all bpy/addon knowledge: empty code results in 5.x, temp-file readback, ops-vs-data context, engine names by version, GPU setup) - recipes.md: blender_exec -> execute_blender_code in the agent-side verification snippet - SKILL.md: reference-file table added to Quick Reference, version 2.1.0, kshitijk4poor added to authors - docs page regenerated (scoped to this skill) --- optional-skills/creative/blender-mcp/SKILL.md | 12 +- .../blender-mcp/references/pitfalls.md | 123 +++++++++++------- .../blender-mcp/references/recipes.md | 2 +- .../optional/creative/creative-blender-mcp.md | 12 +- 4 files changed, 96 insertions(+), 53 deletions(-) diff --git a/optional-skills/creative/blender-mcp/SKILL.md b/optional-skills/creative/blender-mcp/SKILL.md index 95e60c897860..a689ac6373b4 100644 --- a/optional-skills/creative/blender-mcp/SKILL.md +++ b/optional-skills/creative/blender-mcp/SKILL.md @@ -1,9 +1,9 @@ --- name: blender-mcp description: Drive Blender via the catalog blender MCP, with bpy recipes. -version: 2.0.0 +version: 2.1.0 requires: Blender 3.0+ desktop instance (headless via xvfb-run) -author: alireza78a + Hermes Agent +author: alireza78a + kshitijk4poor + Hermes Agent tags: [blender, 3d, animation, modeling, bpy, mcp] platforms: [linux, macos, windows] --- @@ -55,6 +55,14 @@ connected. | `get_viewport_screenshot` | Visual check of what you built | | `execute_blender_code` | Everything else — arbitrary bpy Python | +Deeper material lives in the reference files (load on demand): + +| Reference | Contents | +|-----------|----------| +| `references/bpy-api.md` | Essential bpy operations: modeling, materials, modifiers, rendering | +| `references/recipes.md` | Complete working scenes: low-poly terrain, glass sphere, HDRI lighting, turntable animation | +| `references/pitfalls.md` | Hard-won lessons: empty code results in 5.x, ops-vs-data API, engine names by version | + Optional asset-service tools (PolyHaven, Sketchfab, Hyper3D, Hunyuan3D) are disabled by default. If the user has enabled a service in the addon panel, opt into its tools with `hermes mcp configure blender`. diff --git a/optional-skills/creative/blender-mcp/references/pitfalls.md b/optional-skills/creative/blender-mcp/references/pitfalls.md index d6d144a88aa6..7d4ee6ebec1a 100644 --- a/optional-skills/creative/blender-mcp/references/pitfalls.md +++ b/optional-skills/creative/blender-mcp/references/pitfalls.md @@ -1,106 +1,133 @@ # Blender MCP — Pitfalls & Lessons Learned +All interaction goes through the blender MCP tools (`hermes mcp install +blender`): `get_scene_info`, `get_object_info`, `get_viewport_screenshot`, +and `execute_blender_code` for arbitrary bpy Python. + ## Setup & Connection -### 1. Addon must be started BEFORE connecting +### 1. The addon bridge must be started BEFORE the tools work -The Blender MCP addon creates the socket server only when you click "Start MCP Server" in the BlenderMCP sidebar tab. If the agent tries to connect before this, you get ConnectionRefusedError on port 9876. +The Blender MCP addon opens its local bridge socket only when you click +"Connect to Claude" in the BlenderMCP sidebar tab (N-panel). If the MCP +tools error with "connection refused", the addon isn't connected — fix that +in Blender, don't retry the tool. -**Verify with:** `lsof -i :9876 -P -n | grep LISTEN` +**Verify the bridge is up:** `lsof -i :9876 -P -n | grep LISTEN` -### 2. Port 9876 is the default — check for conflicts +### 2. Port 9876 is the addon's default — check for conflicts -Other services may use 9876. If connection fails but Blender is running with the addon started, check with lsof. Change the port in the BlenderMCP addon UI panel if needed, and update blender_exec() accordingly. +Other services may already use 9876. If the tools fail but Blender is +running with the addon started, check with lsof. The port is configurable +in the BlenderMCP addon UI panel. -### 3. The MCP server (uvx blender-mcp) is OPTIONAL for Hermes +### 3. Addon installation requires user interaction -The uvx blender-mcp MCP server is a subprocess bridge designed for Claude Desktop. Hermes can talk directly to the addon's socket using blender_exec() — no MCP subprocess needed. The MCP config is optional and adds a layer of indirection. +Blender addon installation requires the GUI: Edit > Preferences > Add-ons > +Install. The agent cannot automate this. Provide the addon.py path and let +the user install it. -### 4. Addon installation requires user interaction +## Python Execution (`execute_blender_code`) -Unlike TouchDesigner (where we can paste a script into Textport), Blender addon installation requires the GUI: Edit > Preferences > Add-ons > Install. The agent cannot automate this. Provide the file path and let the user install it. +### 4. Only bpy and math are in the namespace -## Python Execution - -### 5. Only bpy and math are in the namespace - -The execute_code command provides a namespace with only bpy and math. If you need os, json, bmesh, mathutils, etc., import them inside the code string: +The code runs in a namespace with only `bpy` and `math`. If you need os, +json, bmesh, mathutils, etc., import them inside the code: ```python -blender_exec("import bmesh; bm = bmesh.new(); ...") +import bmesh +bm = bmesh.new() +... ``` -### 6. execute_code result is always empty in Blender 5.x addon +### 5. Code result is always empty in Blender 5.x -The blender-mcp addon's execute_code returns `{"result": {"executed": true, "result": ""}}` for ALL code — both eval and exec. The eval result is not captured in Blender 5.x. To get values: +The addon returns `{"executed": true, "result": ""}` for ALL code — the +eval result is not captured in Blender 5.x. To get values out: - Use `get_scene_info` or `get_object_info` for queries -- Write results to a temp file and read back: `blender_exec("import json; open('/tmp/result.json','w').write(json.dumps([o.name for o in bpy.data.objects]))")` +- Write results to a temp file and read back: -### 7. Errors in execute_code return {"error": "..."} — always check +```python +import json +open('/tmp/result.json', 'w').write(json.dumps([o.name for o in bpy.data.objects])) +``` -Always check for the error key in the response. The addon catches exceptions and returns them as error strings rather than crashing. +### 6. Errors come back as error strings — always check -### 8. bpy.ops require correct context +The addon catches exceptions and returns them as error text rather than +crashing. Check the tool result for an error before assuming the code ran. -Many bpy.ops functions require the right context. When executing via the socket, context may differ from the interactive UI. Prefer direct data manipulation: +### 7. bpy.ops require correct context + +Many `bpy.ops` functions require the right UI context, which differs when +executing through the bridge. Prefer direct data manipulation: ```python # Prefer data API over ops -blender_exec("bpy.data.objects.remove(bpy.data.objects['Cube'], do_unlink=True)") +bpy.data.objects.remove(bpy.data.objects['Cube'], do_unlink=True) ``` ## Objects & Scene -### 9. Default scene has Cube, Light, Camera +### 8. Default scene has Cube, Light, Camera -New Blender files start with a Cube at (0,0,0), a Light, and a Camera. Clear them before building. +New Blender files start with a Cube at (0,0,0), a Light, and a Camera. +Clear them before building. -### 10. Object names are unique — Blender auto-renames duplicates +### 9. Object names are unique — Blender auto-renames duplicates -Creating an object with name "Cube" when one already exists results in "Cube.001". Always check the returned name. +Creating an object named "Cube" when one already exists results in +"Cube.001". Always check the actual name via `get_scene_info`. -### 11. Rotation in create_object is in DEGREES, not radians +### 10. Degrees vs radians -The addon's create_object command converts degrees to radians internally. But in execute_code, bpy uses radians. Be careful about the distinction. +The addon's own object-creation commands take degrees and convert +internally, but bpy code in `execute_blender_code` uses radians. Be careful +about the distinction. ## Materials -### 12. Principled BSDF is the default shader +### 11. Principled BSDF is the default shader -All materials created by the addon use Principled BSDF. For other shader types, use execute_code to build the node tree manually. +Materials created by the addon use Principled BSDF. For other shader types, +build the node tree manually in `execute_blender_code`. -### 13. Color is RGBA 0-1, not RGB 0-255 +### 12. Color is RGBA 0-1, not RGB 0-255 -Material colors use floating-point RGBA in 0.0-1.0 range. +Material colors use floating-point RGBA in the 0.0-1.0 range. ## Rendering -### 14. Render blocks the connection — set timeout high +### 13. Render blocks the bridge — expect long calls -Rendering is synchronous. For the agent, the command will take longer to respond. Set timeout to 120s+ for render operations. +Rendering is synchronous; the tool call won't return until the render +finishes. Expect renders to take far longer than other calls. -### 15. Engine name varies by Blender version +### 14. Engine name varies by Blender version + +In Blender 5.x, EEVEE is `'BLENDER_EEVEE'` (not `'BLENDER_EEVEE_NEXT'`, +which was Blender 4.x). Discover available engines at runtime: -In Blender 5.x, EEVEE is `'BLENDER_EEVEE'` (not `'BLENDER_EEVEE_NEXT'` which was Blender 4.x). Always discover available engines: ```python -blender_exec("import json; open('/tmp/engines.json','w').write(json.dumps(list(bpy.types.RenderSettings.bl_rna.properties['engine'].enum_items.keys())))") +import json +open('/tmp/engines.json', 'w').write(json.dumps( + list(bpy.types.RenderSettings.bl_rna.properties['engine'].enum_items.keys()))) ``` + Known engine names: `BLENDER_EEVEE`, `BLENDER_WORKBENCH`, `CYCLES` -### 16. GPU rendering requires explicit setup on macOS +### 15. GPU rendering requires explicit setup on macOS Use METAL compute device type on Apple Silicon. Use CUDA or OPTIX on NVIDIA. -## Connection Reliability +## Reliability -### 17. Each command creates a new TCP connection +### 16. All state lives in Blender's scene data -blender_exec() opens and closes a TCP connection per call. All state lives in Blender's scene data, not the socket. +Each tool call is independent — there is no session state in the bridge. +Anything you need later must exist in the scene (or a file you wrote). -### 18. Large responses may need multiple recv() calls +### 17. Blender crash loses the bridge -The blender_exec() helper loops on recv(65536) until valid JSON is parsed. The 30s timeout handles edge cases. - -### 19. Blender crash loses the socket server - -If Blender crashes, relaunch it, re-enable the addon, click "Start MCP Server" again. Save frequently. +If Blender crashes, relaunch it, re-enable the addon, and click "Connect to +Claude" again. Save frequently (`bpy.ops.wm.save_mainfile()`). diff --git a/optional-skills/creative/blender-mcp/references/recipes.md b/optional-skills/creative/blender-mcp/references/recipes.md index 0f58d14e46bc..b3dad83165e5 100644 --- a/optional-skills/creative/blender-mcp/references/recipes.md +++ b/optional-skills/creative/blender-mcp/references/recipes.md @@ -216,7 +216,7 @@ result = os.path.exists('/tmp/blender_render.png') Then from the agent, view the render: ```python -# After blender_exec returns, verify and view +# After execute_blender_code returns, verify and view from hermes_tools import terminal terminal("ls -la /tmp/blender_render.png") # Use vision_analyze to inspect the render diff --git a/website/docs/user-guide/skills/optional/creative/creative-blender-mcp.md b/website/docs/user-guide/skills/optional/creative/creative-blender-mcp.md index 0f082f92cefb..f69cca5afd0e 100644 --- a/website/docs/user-guide/skills/optional/creative/creative-blender-mcp.md +++ b/website/docs/user-guide/skills/optional/creative/creative-blender-mcp.md @@ -16,8 +16,8 @@ Drive Blender via the catalog blender MCP, with bpy recipes. |---|---| | Source | Optional — install with `hermes skills install official/creative/blender-mcp` | | Path | `optional-skills/creative/blender-mcp` | -| Version | `2.0.0` | -| Author | alireza78a + Hermes Agent | +| Version | `2.1.0` | +| Author | alireza78a + kshitijk4poor + Hermes Agent | | Platforms | linux, macos, windows | ## Reference: full SKILL.md @@ -73,6 +73,14 @@ connected. | `get_viewport_screenshot` | Visual check of what you built | | `execute_blender_code` | Everything else — arbitrary bpy Python | +Deeper material lives in the reference files (load on demand): + +| Reference | Contents | +|-----------|----------| +| `references/bpy-api.md` | Essential bpy operations: modeling, materials, modifiers, rendering | +| `references/recipes.md` | Complete working scenes: low-poly terrain, glass sphere, HDRI lighting, turntable animation | +| `references/pitfalls.md` | Hard-won lessons: empty code results in 5.x, ops-vs-data API, engine names by version | + Optional asset-service tools (PolyHaven, Sketchfab, Hyper3D, Hunyuan3D) are disabled by default. If the user has enabled a service in the addon panel, opt into its tools with `hermes mcp configure blender`.