blender-asset-mcp
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| BLENDER_MCP_PORT | No | Bridge port | 9876 |
| BLENDER_MCP_TOKEN | No | Must match the add-on's Access token, if you set one | |
| BLENDER_MCP_WORKSPACE | No | Where previews, checkpoints and exports go | ~/blender-asset-mcp/workspace |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": false
} |
| prompts | {
"listChanged": false
} |
| resources | {
"subscribe": false,
"listChanged": false
} |
| experimental | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| pingA | Check that this MCP server process is alive. Does not contact Blender. |
| ping_blenderA | Check that Blender is running with the AI Bridge started. Call this first if any other Blender tool fails to connect. |
| get_blender_versionA | Blender version, build and Python version of the running instance. |
| get_bridge_statusA | Bridge health: version, host/port, scene name, open .blend path, workspace directories, command counters and the last error. Use this to diagnose connection problems or to find out where previews, checkpoints and exports are written. |
| list_bridge_actionsA | List every action the Blender bridge accepts. Useful when a structured tool is missing: the action may still exist, and execute_blender_python can always fill the gap. |
| get_scene_infoA | Overview of the current Blender scene: every object with its type and location, counts by type, total vertices/triangles, active camera, selection, collections, materials, render settings and world bounds. Call this before modelling so you know what is already there. |
| list_objectsA | List scene objects with name, type, location, size and visibility. Lighter than get_scene_info when you only need names of one kind. |
| get_objectA | Everything about one object: transform (rotation in degrees), dimensions, visibility, collections, parent and children, material slots, world bounds, and for meshes the geometry statistics, UV layers and modifier stack. Returns statistics, not raw mesh arrays -- use get_mesh_data for those. |
| get_selected_objectsB | The current selection and the active object. |
| get_active_objectA | The active object in full detail, or null when nothing is active. |
| list_collectionsB | Collection tree with object membership and visibility flags. |
| list_materialsA | Every material in the blend file with its users and blend settings. |
| list_camerasB | Every camera with transform, lens, field of view and clipping range. |
| list_lightsB | Every light with type, energy, colour and type-specific settings. |
| list_imagesA | Every image datablock: path, resolution, colour space and usage. |
| get_mesh_dataA | Raw vertex/edge/face arrays for a mesh. Only for small meshes you need to reason about vertex by vertex; it refuses
meshes above |
| create_primitiveA | Add a primitive mesh object to the scene. Rotation is in DEGREES. Sizes are radius/size/depth in Blender units; the primitive-specific options are ignored by primitives that do not have them. Returns the created object's full record. |
| create_cubeB | Create a cube at (x, y, z). Kept for compatibility with the original bridge; create_primitive is the general tool and takes rotation, scale and collection too. |
| create_emptyA | Create an Empty. Useful as a parent, a pivot, or the offset target of an Array modifier. |
| delete_objectA | Delete one object. DESTRUCTIVE -- make a checkpoint first if it matters. |
| delete_objectsB | Delete several objects. DESTRUCTIVE -- make a checkpoint first. |
| duplicate_objectA | Duplicate an object, optionally moving the copy. |
| rename_objectA | Rename an object. Blender appends .001 if the name is taken. |
| set_active_objectC | Make an object active. Many operators act on the active object. |
| select_objectsC | Set the selection. Tools that default to "the selection" use this. |
| deselect_allA | Clear the selection. Worth doing before export or a tool that falls back to "the selection", so a stale selection cannot pull in objects you did not mean to touch. |
| hide_objectA | Hide an object. Hidden objects are skipped by render_preview's auto framing. |
| show_objectA | Unhide an object in the viewport and (by default) in renders. |
| move_to_collectionA | Move objects into a collection, unlinking them from their current ones. |
| create_collectionB | Create a collection, optionally nested inside another. |
| set_parentA | Parent one object to another (or clear its parent). |
| set_transformA | Set an object's ABSOLUTE location, rotation (degrees) and/or scale. Omitted components are left alone. Use translate/rotate/scale_object for relative changes. |
| translate_objectB | Move an object by a delta (relative). |
| rotate_objectB | Rotate an object by a delta in degrees (relative). |
| scale_objectB | Scale an object. By default |
| apply_transformsA | Bake rotation and scale into the mesh data. Game engines generally expect assets with applied rotation and scale and a scale of exactly 1. This modifies the mesh -- checkpoint first. |
| set_originB | Move an object's origin without moving its geometry. |
| create_meshA | Build a mesh from explicit geometry. Indices are validated before anything is created, so a bad face index is a clean error rather than a broken mesh. Keep it to a few thousand vertices; for anything procedural and large, use execute_blender_python with bmesh. |
| join_objectsA | Join mesh objects into one. The others are consumed. DESTRUCTIVE. |
| separate_objectC | Split one mesh object into several. |
| recalculate_normalsA | Make face normals consistent and outward-facing. Run this when a render shows black or inside-out shading. |
| shade_smoothC | Switch objects to smooth shading, optionally with an auto-smooth angle. |
| shade_flatA | Switch objects to flat (faceted) shading. |
| mesh_cleanupA | Conservative mesh hygiene: merge coincident vertices and drop loose geometry. Modifies the mesh -- checkpoint first. |
| triangulate_meshA | Convert every face to triangles, permanently. Usually unnecessary: exporters triangulate on the way out. Use this only when the triangulated topology itself must live in the blend file. |
| add_modifierB | Add and configure a modifier in one call. Returns the modifier's resulting state and the object's full stack. An unknown property name fails with the list of valid ones. |
| set_modifierC | Change settings on an existing modifier. Angles are DEGREES. |
| remove_modifierA | Remove a modifier without applying it. |
| apply_modifierB | Bake a modifier into the mesh. IRREVERSIBLE without undo or a checkpoint. Returns before/after geometry counts so you can see what it cost. |
| apply_all_modifiersA | Bake the whole modifier stack, in order. IRREVERSIBLE -- checkpoint first. |
| list_modifiersC | The object's modifier stack with each modifier's key settings. |
| add_bevelC | Add a Bevel modifier -- the cheapest way to make hard edges catch light. |
| add_subdivisionB | Add a Subdivision Surface modifier. Each level multiplies faces by ~4 -- keep levels low for game assets. |
| add_mirrorB | Add a Mirror modifier -- model half an asset and get the other half free. |
| add_solidifyA | Add a Solidify modifier to give a flat surface real thickness. |
| add_arrayB | Add an Array modifier to repeat geometry (fences, stairs, pillars). |
| add_booleanA | Add a Boolean modifier to cut one object with another. Booleans make messy topology -- check the result with analyze_game_asset and a render before applying. |
| add_decimateA | Add a Decimate modifier to reduce triangle count. For LOD chains prefer create_lod, which builds named copies and leaves the source untouched. |
| add_weighted_normalA | Add a Weighted Normal modifier. Put this last in the stack, after a bevel with harden_normals, to get clean hard-surface shading that survives export. |
| create_materialA | Create a Principled BSDF material. Colors are [r, g, b] or [r, g, b, a] floats in 0..1 LINEAR space -- not 0-255 and not sRGB hex. Returns the material's resulting properties. |
| get_materialC | A material's Principled BSDF values, render settings and users. |
| set_material_propertiesB | Update Principled BSDF properties on an existing material. Fails clearly if a property is driven by a texture node -- edit that node instead, or disconnect it first. |
| assign_materialA | Assign a material to objects. By default this replaces every existing slot, which is what a single-material game prop wants. Pass replace=false to add a second material slot instead -- each extra slot is an extra draw call in most engines. |
| remove_materialB | Unassign a material from an object, or delete the material datablock. |
| get_material_nodesA | The material's full shader node graph: nodes, their socket values and every link. Read this before rewiring anything. |
| create_nodeC | Add a shader node to a material. |
| set_node_inputsA | Set default values on a node's unlinked input sockets, keyed by socket name. |
| connect_nodesA | Link one node's output to another node's input. Socket names come from get_material_nodes; a numeric string selects by index. |
| disconnect_node_inputB | Remove every link feeding one input socket. |
| delete_nodeA | Delete a shader node. Refuses the Material Output node unless forced. |
| load_imageB | Load an image file into Blender and report its metadata. Paths are validated: reads outside the workspace (or the open .blend file's folder) are refused unless the user enables it in the add-on preferences. |
| create_imageC | Create a blank generated image, for example as a bake target. |
| get_imageB | Metadata for one image datablock: resolution, depth, colour space, path. |
| create_image_texture_nodeB | Add an Image Texture node and wire it into the material. Give either |
| set_node_imageB | Point an existing Image Texture node at a different image. |
| list_uv_layersD | UV layers on a mesh, and which is active. |
| create_uv_layerB | Add a UV map. A mesh can hold at most 8 (a second one is the usual place for a lightmap). |
| set_active_uv_layerC | Choose which UV map is active. |
| smart_uv_projectA | Automatically unwrap meshes. The right first choice for a prop with no seams marked. Creates a UV map if the mesh has none. |
| unwrap_selectedA | Unwrap along marked seams. Only useful once seams exist -- use mark_seams_by_angle first, or smart_uv_project for a seamless automatic result. |
| mark_seams_by_angleA | Mark UV seams on sharp edges -- a decent preparation step before unwrap_selected on hard-surface models. |
| delete_uv_layerA | Delete a UV map from a mesh. Textures bound to that map will lose their coordinates, so check list_uv_layers first if the mesh has more than one. |
| create_cameraA | Create a camera. To point it at something, give look_at/look_at_object here, or use frame_objects_with_camera which also works out the distance. |
| get_cameraC | A camera's transform and lens settings. |
| set_active_cameraC | Choose which camera the scene renders from. |
| set_camera_transformC | Move a camera and adjust its lens in one call. |
| look_atA | Rotate an object so its -Z axis points at a target. Cameras and lights look down -Z, so this aims them. Give either |
| frame_objects_with_cameraA | Position a camera so the given objects exactly fill the frame. Distance is computed from the render aspect ratio and the camera's field of view, and the clipping range is widened to suit. Use this before render_preview when you want to control the angle. |
| create_lightA | Create a light. For a quick, even setup to inspect an asset, use create_preview_lighting instead of placing lights one at a time. |
| set_light_propertiesC | Update a light's settings. Angles are DEGREES. |
| delete_lightC | Delete a light object and its data. |
| create_preview_lightingA | Build a neutral three-point studio rig sized to the subject. Creates AI_Key, AI_Fill and AI_Rim area lights in an AI_PreviewLighting collection, with power scaled to the asset's size. Safe to re-run: it replaces the previous rig. Use this before render_preview when the scene has no lighting of its own. |
| delete_preview_lightingA | Remove the AI_PreviewLighting rig and its collection. |
| set_world_backgroundA | Set the world background colour and strength. The world lights the scene: a strength of 0 makes shadows pitch black. |
| get_render_settingsA | Current render engine, resolution, samples and output format. |
| set_render_settingsA | Change the scene's persistent render settings. render_preview already overrides resolution, samples and format for its own render and restores them afterwards -- use this only when you want the change to stick. |
| render_previewA | Render a preview image and return its absolute path. THEN OPEN THAT IMAGE AND LOOK AT IT. Read the returned Auto-frames the given objects, creates an AI_PreviewCam if the scene has no camera, renders with EEVEE at 512x512 by default, and restores the scene's render settings afterwards. Images land in workspace/previews. |
| render_turntableA | Render the same subject from several angles at once. The fastest way to catch problems a single view hides -- a front view will not show that the back is hollow. Returns one image path per view; look at all of them. |
| list_previewsB | Most recent preview renders on disk, newest first. |
| read_preview_imageA | Return a rendered preview as an image so it can be looked at directly. Use this when you cannot read the PNG from disk yourself; otherwise reading
|
| get_workspace_infoB | Where the bridge writes previews, checkpoints, exports and logs, plus the currently open .blend file and whether it has unsaved changes. |
| save_blendA | Save the user's open .blend file in place. Only do this when the user asks. Fails if the file has never been saved -- use save_blend_as then. |
| save_blend_asA | Save a copy of the scene into the workspace. Never writes outside the workspace and, by default, never changes which file Blender considers open. |
| create_checkpointA | Save a timestamped checkpoint copy before risky work. Writes _.blend into workspace/checkpoints. The user's own .blend file is never touched or re-targeted. Do this before applying modifiers, deleting objects, or any multi-step change you might need to back out of. begin_operation makes one automatically. |
| list_checkpointsC | Checkpoints on disk, newest first. |
| restore_checkpointA | Load a checkpoint, replacing the current session. DESTRUCTIVE: everything unsaved in Blender right now is lost. Confirm with the user before calling this with confirm=true. |
| undoA | Step back through Blender's undo history. Undo reflects Blender's UI history, so it reverses whatever happened last -- including the user's own edits. For rolling back your own work reliably, prefer checkpoints. |
| redoB | Step forward through Blender's undo history. |
| push_undoA | Insert a named undo checkpoint so the user can step back to here. |
| export_glbA | Export to a single self-contained .glb file. The usual choice for game engines and web viewers: geometry, materials and textures in one file. Returns the absolute path and file size. |
| export_gltfA | Export to .gltf with separate .bin and texture files. Use export_glb unless you specifically need the textures as loose files. |
| export_fbxA | Export to .fbx for Unreal or Unity pipelines. Defaults to meshes/empties/armatures with modifiers applied. Returns the absolute path, file size and the triangle count that was exported. |
| export_objB | Export to .obj. Simple static geometry only -- no animation, no PBR. |
| list_exportsA | Files in the workspace exports directory, newest first. |
| analyze_game_assetA | Read-only report on an asset: object and mesh counts, vertices, triangles (base and after modifiers), materials, referenced textures, bounding dimensions, and a list of issues -- missing UVs, unapplied transforms, non-manifold geometry, objects with no material. Modifies nothing. Pair it with a render: statistics catch budget problems, renders catch everything else. |
| validate_game_assetB | Check an asset against explicit budgets and conventions. Returns passed/errors/warnings. Constraints you do not set are reported as warnings rather than failures, so a plain call is still a useful health check. Read-only: it never modifies the asset, so fix anything it finds with the relevant tool. |
| create_box_collisionA | Create a UCX_ box collider matching an object's bounding box. Built in the object's local space, so a rotated asset gets a tight oriented box. Named UCX__01, displayed as wireframe and excluded from renders -- the convention Unreal expects. |
| create_convex_collisionA | Create a UCX_ convex hull collider. Builds a convex hull and decimates it toward max_vertices, re-hulling afterwards so the result stays convex. Use this for shapes a box cannot approximate; use create_box_collision when a box will do, since it is cheaper at runtime. |
| list_collision_objectsA | Every UCX_ collision object in the scene with its complexity. |
| create_lodA | Generate an LOD chain by duplicating and decimating. Creates _LOD0, _LOD1, ... and NEVER modifies the source object. Returns the triangle count of each level so you can see what each step actually saved. |
| execute_blender_pythonA | Run Python inside Blender on the main thread. The escape hatch. Use this when the structured tools cannot express what you need: bmesh surgery, geometry nodes, uncommon operators, bulk edits. Prefer the structured tools when they fit -- they validate inputs and return tidy results. Captures stdout and stderr, returns the traceback on failure, and reports
which objects appeared or disappeared. Assign to a variable named This is TRUSTED LOCAL EXECUTION: the code has the same reach as Blender's own scripting console, in the user's live session. There is no shell tool, no subprocess and no outbound network in this bridge -- do not try to add them here. |
| evaluate_blender_expressionA | Evaluate one Python expression in Blender and return its repr. A quick lookup that does not need a whole script. |
| begin_operationA | Open a named operation: an undo boundary plus a checkpoint. Wrap multi-step asset work in begin_operation / end_operation so it reads as one task in Blender's history and can be abandoned in one call. |
| end_operationA | Close the open operation and summarise what changed. Returns which objects were created and removed, and how long it took. |
| cancel_operationA | Abandon the open operation and roll back. With a checkpoint this reloads it, which DISCARDS everything done since begin_operation -- including any of the user's own edits in that window. Without one it falls back to stepping the undo stack, which is best effort; the response says which path was taken. |
| get_operation_statusB | Whether an operation is open, its label, elapsed time and checkpoint. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
TDQS
Scored across 126 tools
Most tools target a specific resource and action, and the descriptions are unusually clear, but several pairs overlap purposefully: add_modifier duplicates the specialized add_bevel/add_subdivision/... wrappers, create_primitive duplicates create_cube, and analyze_game_asset/validate_game_asset plus execute_blender_python/evaluate_blender_expression sit close together. An agent can usually disambiguate by reading descriptions, but the boundaries are not always crisp.
Names overwhelmingly follow a snake_case verb_noun pattern (list_objects, create_material, apply_modifier), which makes the set predictable. The pattern breaks in spots: bare verbs (undo, redo, ping), noun-first or adjective-first names (mesh_cleanup, smart_uv_project), and inconsistent singular/plural pairs (delete_object vs delete_objects, connect_nodes vs disconnect_node_input) keep it from being perfect.
At 126 tools this is far beyond the 3-15 well-scoped range and above any reasonable surface for an agent to consider; many are convenience wrappers that could be consolidated (8+ add_<modifier> tools, 7 export/read/render variants). Even if Blender is a wide domain, this tool count is an extreme mismatch and will hurt selection reliability.
The surface covers the full game-asset pipeline: scene/object CRUD, mesh editing, modifiers, materials/nodes, UVs, cameras/lights, rendering/previews, exports, checkpoints, validation, collisions, and LODs. Gaps like structured armature/rigging and animation tools, collection/image deletion, and a singular collection getter remain, though execute_blender_python acts as an escape hatch.