# BlenderLens (pypi · blenderlens-mcp)

MCP server that lets AI agents build, check, preview and export game assets in Blender

- Trust score: 86/100 (high trust)
- Change this week: +5
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-10-24

## Components

- npm · `blenderlens-mcp`: 49/100, [markdown](https://verifymcp.io/servers/pzalutski-pixel-blenderlens/blenderlens-mcp.md), [page](https://verifymcp.io/servers/pzalutski-pixel-blenderlens/blenderlens-mcp)
- pypi · `blenderlens-mcp`: 86/100 (this document), [markdown](https://verifymcp.io/servers/pzalutski-pixel-blenderlens/blenderlens-mcp-2.md), [page](https://verifymcp.io/servers/pzalutski-pixel-blenderlens/blenderlens-mcp-2)

## Channel facts

- Registry: `pypi`
- Package: `blenderlens-mcp`
- Version: `0.2.0`
- Transport: `stdio`

## Trust breakdown

How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. Scores are 0–100 per category. Scoring method: https://verifymcp.io/docs/scoring (what has changed: https://verifymcp.io/docs/scoring/changelog)

Scored 2026-10-24.

- **Supply Chain Security**: 100/100
  - No malware found by supply-chain analysis.
  - No known CVEs affecting this package version or its production dependencies.
  - Runs hatchling.build at install time, a recognised build step with no custom scripting around it.
  - No production dependencies, so there is no dependency health to assess.
- **Provenance & Transparency**: 97/100
  - Source repository is publicly reachable at the declared URL.
  - Cryptographically verified build provenance (signed, bound to pzalutski-pixel/blenderlens-mcp).
  - Clear OSI-approved license (Apache-2.0).
  - Actively maintained (last published 13 days ago).
  - Disclosure check failed: no security disclosure policy was found in the source repository.
- **Schema Quality & AI Usability**: 78/100
  - 100% of prompts and resources have a non-trivial description (not blank, and not just the item's name).
  - AI-judged instruction clarity (good).
  - Context-footprint check failed: tool/resource definitions use about 5206 tokens (~126/item across 41 items; 40 tools + 1 resources), over budget; trim descriptions and params.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 33/100
  - Stability observed for 10 of 30 days with no destabilising changes; credit accrues until the full window elapses.
- **Tool Coverage**: 100/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 100% of tool parameters carry a description.
- **Tool Safety**: 100/100
  - No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.
  - All 2 tool(s) whose name or description implies an irreversible operation declare an MCP destructiveHint annotation.
  - An AI judge read all 42 captured unit(s) of tool text and found none that tries to manipulate the model reading it.
- **Capabilities**: 100/100
  - Implements a current MCP spec version (2026-07-28).

## Install

### How do I install the BlenderLens MCP server?

BlenderLens runs locally as a PyPI package, launched with uvx blenderlens-mcp. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.

### Claude

```bash
claude mcp add pzalutski-pixel-blenderlens -- uvx blenderlens-mcp
```

### Cursor

```json
{
  "mcpServers": {
    "pzalutski-pixel-blenderlens": {
      "command": "uvx",
      "args": [
        "blenderlens-mcp"
      ]
    }
  }
}
```

### VS Code

```json
{
  "servers": {
    "pzalutski-pixel-blenderlens": {
      "command": "uvx",
      "args": [
        "blenderlens-mcp"
      ]
    }
  }
}
```

### Codex

```bash
codex mcp add pzalutski-pixel-blenderlens -- uvx blenderlens-mcp
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "pzalutski-pixel-blenderlens": {
      "type": "local",
      "command": [
        "uvx",
        "blenderlens-mcp"
      ],
      "enabled": true
    }
  }
}
```

### OpenClaw

```bash
openclaw mcp add pzalutski-pixel-blenderlens --command uvx --arg blenderlens-mcp
```

### Hermes

```yaml
mcp_servers:
  pzalutski-pixel-blenderlens:
    command: "uvx"
    args: ["blenderlens-mcp"]
```

### Netclaw

```json
{
  "McpServers": {
    "pzalutski-pixel-blenderlens": {
      "Transport": "stdio",
      "Command": "uvx",
      "Arguments": [
        "blenderlens-mcp"
      ]
    }
  }
}
```

### Vellum

```bash
assistant mcp add pzalutski-pixel-blenderlens -t stdio -c uvx -a blenderlens-mcp
```

### Other

```json
{
  "mcpServers": {
    "pzalutski-pixel-blenderlens": {
      "command": "uvx",
      "args": [
        "blenderlens-mcp"
      ]
    }
  }
}
```

## Changelog

Every change recorded for this component, newest first. Days that predate change tracking, or that we cannot explain, say so: "we were watching and nothing happened" and "we were not watching" are different claims.

### 2026-10-23 (score 86, +1)

No change was recorded against any check on this day. Stability & Change Management went from 27 to 30. That category is still filling its 30-day observation window: 8 days of observed history at the previous scan, 9 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-10-22 (score 85, +4)

- [functional improvement] Stability: unverified → 0.27

### 2026-10-14 (score 81, +32)

- [security improvement] Injection markers: unverified → pass
- [security] First check of Judged manipulation: pass
- [security] Stability: Stability not yet verified: not enough scan history yet (needs a 30-day window).
- [functional improvement] Tool coverage: unverified → 100
- [functional improvement] Schema quality: unverified → 100
- [functional improvement] MCP protocol: unverified → pass
- [functional] First check of Schema quality: good
- [functional] First check of Tool coverage: 100
- [functional] First check of Schema quality: fail
- [functional] First check of Schema quality: fail
- [functional] First check of Destructive annotations: 100

### 2026-10-12 (score 49)

First indexed and scored.

## MCP tools (40)

### `get_status` (~54 tokens)

Get Status

Report the attached Blender without starting one. Returns: the session (busy: what it runs), add-on, Blender, render_dir, recovery copies. WHEN TO CALL: first; after not_connected, connection_lost, busy.

### `open_session` (~90 tokens)

Open Session

Attach to the live Blender window or start a background one. Returns: the session. WHEN TO CALL: to pick a mode or file; else the first call attaches by BLENDERLENS_MODE.

Input parameters:

- `discard` (boolean): Allow losing unsaved or busy work
- `file` (string): .blend to open
- `mode` (string): auto (default): live if the add-on replies

### `close_session` (~51 tokens)

Close Session

Disconnect: a background Blender exits, a live one stays open. Returns: the mode closed. WHEN TO CALL: when the work is saved.

Input parameters:

- `discard` (boolean): Allow losing unsaved or busy work

### `get_scene` (~47 tokens)

Get Scene

Read the scene. Returns: file state, units, and each object's type, parent, location, dimensions, counts, materials, modifiers. WHEN TO CALL: before building; after not_found.

### `get_object` (~53 tokens)

Get Object

Read one object in full. Returns: transform, bounds, properties, counts before and after modifiers, modifier settings by Blender's names, slots. WHEN TO CALL: before set_modifier.

Input parameters:

- `object` (string, required): Name

### `get_mesh` (~107 tokens)

Get Mesh

List a mesh's faces. Returns: each face's index, center, normal, side, area, material slot. WHEN TO CALL: for face indices; again after faces change.

Input parameters:

- `evaluated` (boolean): After modifiers
- `include_vertices` (boolean): List vertices too
- `limit` (integer): Default 200
- `material` (integer|string): Its faces only: slot or name
- `object` (string, required): Name
- `space` (string): Default world

### `list_materials` (~39 tokens)

List Materials

List materials. Returns: each one's values (linear, as glTF) and users. WHEN TO CALL: before set_material, to reuse one.

### `check_asset` (~134 tokens)

Check Asset

Check meshes as exported: topology, normals, scale, origin, UVs, textures, morphs, overlaps; and a project's rules or rules_file (the guide lists the keys). Returns: passed; per object stats, issues {code, severity, count, faces}. WHEN TO CALL: before export_glb.

Input parameters:

- `budget` (integer): Total triangle limit
- `evaluated` (boolean): After modifiers (true)
- `objects` (array): With children (default: all export_glb writes)
- `rules` (object): The project's rules
- `rules_file` (string): Rules as a .json file

### `measure_objects` (~99 tokens)

Measure Objects

Measure between objects' surfaces as exported, in world space, or cast a ray. Returns: per pair distance, closest points, touching, overlapping, overlap_faces, inside; ray object, location, normal, face. WHEN TO CALL: to fit parts, find gaps.

Input parameters:

- `direction`: Ray, world
- `objects` (array): 2 to 16; a ray may hit only these
- `origin` (array): Ray start

### `create_object` (~353 tokens)

Create Object

Add a primitive (tube, lathe and text too) or an empty, sized in the mesh so scale stays 1. Returns: its name (.001 on a clash), transform, counts. WHEN TO CALL: to start a part.

Input parameters:

- `bevel_resolution` (integer): tube: 4+2n sides (2)
- `collection` (string): Created if missing
- `depth` (number): Cylinder, cone height (2)
- `extrude` (number): text depth (size/10)
- `fill` (boolean): Caps (true; circle: false)
- `kind` (string, required): empty has no mesh
- `location` (array): Metres
- `minor_radius` (number): Torus tube (0.25)
- `name` (string): Default from kind
- `parent` (string): location relative to it
- `points` (array): tube path, mesh space
- `profile` (array): lathe: [radius, z] about Z
- `radius` (number): Default 1; tube 0.05
- `radius_top` (number): Cone top (0)
- `rings` (integer): uv_sphere 16, torus 12
- `rotation` (array): Degrees
- `scale`: Default 1
- `segments` (integer): Default 32, torus 48
- `size`: cube edges (2); plane, grid [x, y]; monkey, empty, text: a number
- `smooth` (boolean): tube: curved (true) or straight
- `subdivisions` (integer): ico_sphere 2, grid 10
- `text` (string): Its words

### `create_mesh` (~138 tokens)

Create Mesh

Build a mesh object from vertices and faces in its own space. Returns: as create_object. WHEN TO CALL: for a shape no primitive gives.

Input parameters:

- `collection` (string): Created if missing
- `edges` (array): Loose edges
- `faces` (array): Vertex indices around each
- `location` (array): Metres
- `name` (string, required): Object and mesh
- `parent` (string): location relative to it
- `recalc_normals` (boolean): Outward (default true)
- `rotation` (array): Degrees
- `scale`: Default 1
- `vertices` (array, required): Metres

### `edit_mesh` (~324 tokens)

Edit Mesh

Run one operation on the faces picked (faces, facing) or all. bevel: the picked faces' rim edges (all edges if all faces), or with angle the edges sharper than it. amount, offset, pivot: mesh space. Returns: result_faces (extrude: the cap; inset: inner faces), counts. WHEN TO CALL: to shape a primitive.

Input parameters:

- `amount` (number): extrude distance, inset border, bevel width, merge distance, solidify thickness (inward)
- `angle` (number): Degrees: sharper edges stay sharp (shade_smooth), bevel, seam (30); dissolve_planar (5)
- `cuts` (integer): subdivide (1)
- `depth` (number): inset: in (-) or out
- `direction`: extrude this way; bisect plane normal (world)
- `faces` (array): Indices from get_mesh
- `facing`: World direction
- `factor`: scale by
- `fill` (boolean): bisect: cap the cut (true)
- `individual` (boolean): inset each face alone
- `keep` (string): bisect: side kept (below)
- `object` (string, required): Name
- `offset` (array): translate by
- `operation` (string, required): What to do
- `pivot` (array): scale, rotate about; bisect plane point (default center)
- `rotation` (array): rotate by, degrees
- `segments` (integer): bevel (1)
- `tolerance` (number): Degrees off facing (30)

### `add_modifier` (~96 tokens)

Add Modifier

Add a modifier to an object's stack. Returns: its settings, the stack, counts. WHEN TO CALL: for detail that stays editable.

Input parameters:

- `name` (string): Default from type
- `object` (string, required): Name
- `settings` (object): Blender's names (width, count, levels, operation...); objects by name
- `type` (string, required): bevel, array, boolean, subdivision, mirror, solidify...

### `set_modifier` (~84 tokens)

Set Modifier

Change a modifier's settings, place or visibility. Returns: as add_modifier. WHEN TO CALL: to tune one.

Input parameters:

- `index` (integer): Stack position, 0 first
- `modifier` (string, required): Name
- `object` (string, required): Name
- `settings` (object): By Blender's property names
- `show` (boolean): In viewport and render

### `apply_modifier` (~60 tokens)

Apply Modifier

Bake a modifier into the mesh; refused for a shared mesh or in edit mode. Returns: the stack, counts. WHEN TO CALL: when edit_mesh must see its result.

Input parameters:

- `modifier` (string, required): Name
- `object` (string, required): Name

### `remove_modifier` (~47 tokens)

Remove Modifier

Remove a modifier unapplied. Returns: the stack left, counts. WHEN TO CALL: to undo add_modifier.

Input parameters:

- `modifier` (string, required): Name
- `object` (string, required): Name

### `set_material` (~285 tokens)

Set Material

Create or update a material, optionally on an object or its picked faces; all its users change; '' clears an image or vertex_color. Returns: its values, slot, faces. WHEN TO CALL: after shaping.

Input parameters:

- `alpha` (number): Below 1 blends
- `alpha_cutoff` (number): clip below (0.5)
- `alpha_mode` (string): With an image or vertex_color, their alpha
- `backface_culling` (boolean): Hide back faces (true for new)
- `base_color`: [r, g, b(, a)] linear, or '#RRGGBB' sRGB
- `base_color_image` (string): Image file
- `emission_color`: Alone sets strength 1
- `emission_image` (string): Image file
- `emission_strength` (number): Above 1 glows
- `faces` (array): Indices from get_mesh
- `facing`: World direction
- `material` (string, required): Created if missing
- `metallic` (number): 0 to 1
- `normal_image` (string): Image file
- `object` (string): Mesh to put it on
- `roughness` (number): 0 to 1
- `tolerance` (number): Degrees off facing (30)
- `vertex_color` (string): Color attribute as base colour

### `set_vertex_color` (~134 tokens)

Set Vertex Color

Paint the faces picked (faces, facing) or all into a color attribute. Returns: faces painted, materials wired, and not_wired (setups not BlenderLens's). WHEN TO CALL: for colour without textures; exports as COLOR_0.

Input parameters:

- `attribute` (string): Default Col, made white
- `color` (required): As base_color
- `faces` (array): Indices from get_mesh
- `facing`: World direction
- `object` (string, required): Name
- `tolerance` (number): Degrees off facing (30)
- `use_in_material` (boolean): Wire into its materials (true)

### `unwrap_uv` (~125 tokens)

Unwrap UVs

Unwrap a mesh into a UV map; projections are packed. Returns: islands, area used, overlapping and out-of-bounds faces, texel density (px/m at 1024). WHEN TO CALL: before texturing or baking; unwrap needs seams (edit_mesh mark_seams).

Input parameters:

- `margin` (number): Between islands, to 0.1; lightmap to 0.01 (0.01)
- `method` (string): Default smart
- `object` (string, required): Name
- `uv_map` (string): Made if missing (default active)

### `join_objects` (~53 tokens)

Join Objects

Join meshes into the first, keeping each piece's materials and faces. Returns: the object, slots and their faces. WHEN TO CALL: to make one part of pieces.

Input parameters:

- `objects` (array, required): The first stays

### `set_transform` (~116 tokens)

Set Transform

Set an object's location, rotation, scale or dimensions; null keeps a component. Returns: the transform; after drop, landed_on and moved_by. WHEN TO CALL: to place parts.

Input parameters:

- `dimensions` (array): Metres, reached by scale
- `drop` (boolean|string): Then move along Z to rest on what is below, or on this object
- `location` (array): Metres, parent space
- `object` (string, required): Name
- `rotation` (array): Degrees
- `scale`: Factors

### `apply_transform` (~110 tokens)

Apply Transform

Bake rotation and scale into the mesh, or move its origin, mesh and children staying put; refused for a shared mesh or in edit mode. Returns: the transform. WHEN TO CALL: after scaling, before bevel or solidify.

Input parameters:

- `location` (boolean): Default false
- `object` (string, required): Name
- `origin`: New origin, or a world point
- `rotation` (boolean): Default true; false with origin
- `scale` (boolean): Default true; false with origin

### `set_parent` (~65 tokens)

Set Parent

Parent an object, or clear its parent. Returns: the transform. WHEN TO CALL: to assemble parts into one node tree.

Input parameters:

- `keep_transform` (boolean): Keep world position (true)
- `object` (string, required): Name
- `parent` (string|null): null clears

### `set_collection` (~69 tokens)

Set Collection

Move objects into a collection. Returns: their collections. WHEN TO CALL: to group parts.

Input parameters:

- `collection` (string, required): Created if missing
- `keep_other` (boolean): Stay in others too
- `objects` (array, required): Names
- `parent` (string): Parent of a new one

### `set_object` (~148 tokens)

Set Object Properties

Rename or hide an object, or set its display or custom properties (exported as glTF extras). Returns: its state. WHEN TO CALL: to name, hide or tag parts.

Input parameters:

- `display` (string): Viewport
- `empty_display` (string): An empty's shape: ARROWS, CUBE, SPHERE...
- `hide` (boolean): Viewport; export skips it
- `hide_render` (boolean): Renders
- `object` (string, required): Name
- `properties` (object): JSON values, 8 levels deep; null removes
- `rename` (string): New name
- `rename_data` (boolean): Unshared mesh too (default true)

### `duplicate_object` (~78 tokens)

Duplicate Object

Copy an object with modifiers, materials and children. Returns: the copies. WHEN TO CALL: for repeated parts.

Input parameters:

- `linked` (boolean): Share the mesh
- `name` (string): For the copy
- `object` (string, required): Name
- `offset` (array): Metres
- `with_children` (boolean): Default true

### `delete_object` (~50 tokens)

Delete Objects

Delete objects and unused mesh data. Returns: the names deleted. WHEN TO CALL: to remove parts.

Input parameters:

- `objects` (array, required): Names
- `with_children` (boolean): Else they stay in place

### `export_glb` (~265 tokens)

Export glTF Binary

Write a .glb, Y-up (-Y front becomes +Z), for a target engine; what it cannot load is refused, as is edit mode. Returns: the file read back, with warnings for the target. WHEN TO CALL: to deliver.

Input parameters:

- `animations` (boolean): Default true
- `apply_modifiers` (boolean): Default true
- `at_origin` (boolean): Roots written at 0,0,0
- `cameras` (boolean): Default false
- `clean_names` (boolean): Drop .001 where unique (true for godot)
- `collection` (string): Its objects
- `draco` (boolean): Compress meshes
- `extras` (boolean): Custom properties (default true)
- `image_format` (string): Default auto
- `lights` (boolean): Default false
- `objects` (array): With children (default all)
- `path` (string, required): Ends in .glb
- `tangents` (boolean): For normal maps
- `target` (string): Default generic; threejs drops -colonly proxies
- `texcoords` (boolean): UVs (default true)
- `vertex_colors` (string): Default material: those a material reads
- `visible_only` (boolean): Default true

### `import_file` (~111 tokens)

Import File

Import a .glb, .gltf, .obj, .fbx, .stl or .ply, or append from a .blend what is named. Returns: what it added. WHEN TO CALL: for a reference, or to check an export.

Input parameters:

- `collection` (string): For what it adds
- `collections` (array): .blend
- `materials` (array): .blend
- `objects` (array): .blend: with children
- `path` (string, required): File

### `save_file` (~62 tokens)

Save File

Save the open file. Returns: path, size. WHEN TO CALL: at milestones; before closing a background session.

Input parameters:

- `copy` (boolean): A checkpoint; the open file keeps its path
- `path` (string): .blend; default the last save

### `open_file` (~53 tokens)

Open File

Open a .blend in place of the open file. Returns: the scene. WHEN TO CALL: to resume work.

Input parameters:

- `discard` (boolean): Allow losing unsaved changes
- `path` (string, required): .blend

### `create_file` (~63 tokens)

Create File

Start a new, unsaved file in place of the open one. Returns: the scene. WHEN TO CALL: for a new model.

Input parameters:

- `discard` (boolean): Allow losing unsaved changes
- `empty` (boolean): Default true; else Blender's default scene

### `render_preview` (~289 tokens)

Render Preview

Render a PNG of objects (and children) or all visible geometry, framed, others hidden, the scene unchanged. Returns: its path (open it, or inline). WHEN TO CALL: after each build step.

Input parameters:

- `azimuth` (number): Degrees, front 0, right 90
- `context` (array): Shown, not framed
- `elevation` (number): Degrees up
- `engine` (string): Default auto: cycles (CPU); eevee needs GPU
- `hide_from_camera` (array): Unseen, still casting shadows
- `inline` (boolean): Return the image too
- `lighting` (string): Default studio
- `margin` (number): Framing slack (1.1)
- `markers` (array): Return their pixels
- `objects` (array): Default all visible
- `ortho_scale` (number): Metres on long side
- `path` (string): *.png, only over a PNG (default render_dir)
- `projection` (string): Default perspective
- `resolution`: Pixels (768)
- `samples` (integer): Default 32
- `style` (string): clay, random use workbench
- `timeout` (number): Seconds (120)
- `transparent` (boolean): Background
- `view` (string): Default three_quarter
- `views` (array): Several, in one PNG

### `animate_object` (~143 tokens)

Animate Object

Key an object's transform and shape keys into a named clip on an NLA track, exported as one glTF animation; a call replaces the object's keys in it. Returns: channels, frames, seconds, Godot warnings. WHEN TO CALL: for doors, rotors, morphs.

Input parameters:

- `clip` (string, required): Animation name, shared across objects
- `interpolation` (string): Default linear
- `keys` (array, required): {frame, location, rotation (degrees), scale, shape_key: {name: value}}; null skips an axis
- `loop` (boolean): Repeat; default as Godot reads the name
- `object` (string, required): Name

### `create_collision` (~114 tokens)

Create Collision

Add a collision proxy over a mesh, wire-drawn and parented; named for Godot, three.js exports leave it out. Returns: its name, counts, closed, volume_ratio. WHEN TO CALL: for physics props.

Input parameters:

- `naming` (string): godot (default): -colonly, convex -convcolonly; plain: _collision
- `object` (string, required): Name
- `ratio` (number): decimated: faces kept (0.25)
- `shape` (string): Default convex

### `bake_texture` (~163 tokens)

Bake Texture

Bake a mesh's materials into a PNG through a UV map with Cycles (CPU), wired into them; render settings and selection are put back. Returns: path, size, seconds, image_driven channels. WHEN TO CALL: for procedural materials, AO.

Input parameters:

- `from_objects` (array): High-poly sources
- `object` (string, required): Name
- `path` (string, required): *.png, only over a PNG
- `samples` (integer): Default 32
- `size` (integer): Pixels a side (1024)
- `timeout` (number): Seconds (120)
- `type` (string): Default diffuse; ao multiplies base colour
- `use_in_material` (boolean): Default true
- `uv_map` (string): Default active

### `export_file` (~119 tokens)

Export File

Write FBX, OBJ, STL, PLY or USD (by extension), objects chosen as export_glb does; the file is read back in a scratch scene. Returns: path, bytes, read_back counts. WHEN TO CALL: for tools that take no glTF.

Input parameters:

- `collection` (string): Its objects
- `objects` (array): With children (default all)
- `path` (string, required): .fbx .obj .stl .ply .usd(a|c|z)
- `visible_only` (boolean): Default true

### `run_python` (~69 tokens)

Run Python

Run Python in Blender (bpy, bmesh, mathutils); names persist; set result to return it. Returns: stdout, stderr, result. WHEN TO CALL: only for what no tool covers.

Input parameters:

- `code` (string, required): Python source
- `timeout` (number): Seconds (120)

### `run_script` (~126 tokens)

Run Script

Run a .py file in Blender as run_python does, with args; its folder, and parents up to a blenderlens.toml, are importable afresh each run. Returns: result, stdout, stderr, objects added, removed, changed. WHEN TO CALL: to build a model from its script.

Input parameters:

- `args` (object): The script's args
- `discard` (boolean): Allow losing unsaved changes
- `fresh` (boolean): Start from an empty file
- `path` (string, required): .py file
- `timeout` (number): Seconds (120)

### `undo_change` (~84 tokens)

Undo Change

Step back through undo steps, one per call that changed something; Python references go stale. Returns: steps undone, counts, unsaved_changes. WHEN TO CALL: to take back calls that went wrong.

Input parameters:

- `force` (boolean): Undo steps whatever made them
- `list` (boolean): Name the steps; undo none
- `steps` (integer): Default 1

## Diagnostics

Captured diagnostic sections: Provenance, Install scripts, Dependencies. The full working is on the page: https://verifymcp.io/servers/pzalutski-pixel-blenderlens/blenderlens-mcp-2#diagnostics

## Score history

- 2026-10-24: 86
- 2026-10-23: 86
- 2026-10-22: 85
- 2026-10-21: 81
- 2026-10-20: 81
- 2026-10-19: 81
- 2026-10-18: 81
- 2026-10-17: 81
- 2026-10-16: 81
- 2026-10-15: 81
- 2026-10-14: 81
- 2026-10-13: 49
- 2026-10-12: 49

## Common questions

### What is the BlenderLens MCP server?

BlenderLens is an MCP server listed in the public MCP registry as io.github.pzalutski-pixel/blenderlens. MCP server that lets AI agents build, check, preview and export game assets in Blender. This page covers its PyPI package (blenderlens-mcp).

### Is the BlenderLens MCP server safe to use?

BlenderLens scores 86 out of 100 on VerifyMCP. We found no known CVEs affecting it as of 24 October 2026. Its build provenance is signed and verified. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.

### What tools does the BlenderLens MCP server expose?

BlenderLens exposes 40 tools: get_status, open_session, close_session, get_scene, get_object, and 35 more. Their descriptions and schemas cost roughly 4,670 tokens of context every time the server is loaded.

### Is the BlenderLens MCP server still maintained?

BlenderLens is still listed as active in the MCP registry. We last reached this channel on 24 October 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.

### What licence is the BlenderLens MCP server under?

BlenderLens declares the Apache-2.0 licence, which is OSI-approved. That covers the source only, and says nothing about the cost of any service it calls.

## Links

- PyPI project: https://pypi.org/project/blenderlens-mcp/
- Socket report: https://socket.dev/pypi/package/blenderlens-mcp
- Repository: https://github.com/pzalutski-pixel/blenderlens-mcp
- Changelog RSS feed: https://verifymcp.io/servers/pzalutski-pixel-blenderlens/blenderlens-mcp-2.xml
- Changelog JSON feed: https://verifymcp.io/servers/pzalutski-pixel-blenderlens/blenderlens-mcp-2.json
- HTML version of this page: https://verifymcp.io/servers/pzalutski-pixel-blenderlens/blenderlens-mcp-2
