Model, texture, rig and animate in Blockbench by talking to an AI assistant.
An MCP server and a companion Blockbench plugin. Describe what you want; the assistant builds the
model, unwraps and paints it, adds bones and animations, checks its own work with screenshots and
exports to any format Blockbench supports. Every step lands in Blockbench's undo history, so
Ctrl+Z takes back anything you don't like.
Install · Gallery · What you get · Workflows · Tools · Changelog
Modelled, textured, shaded and animated by an AI assistant through this server. The .bbmodel
files are in examples/ so you can open them and look at the rigs and keyframes.
- Minecraft-style models end to end. Bone trees, cubes with mirrored twins, fur and leaf cards,
texture templates, painting by face or by whole limb, keyframes with Molang, 20 motion presets.
Bedrock, Java, OptiFine and glTF out, and Hytale
.blockymodel/.blockyanimwith the Hytale Models plugin. - Low-poly, hand-painted characters. Limbs from cross-sections, extrude / inset / bevel, taper and bend with proportional falloff, island unwrapping, light / AO / edge baking into a pixel-art ramp, palette locking.
- Skinned meshes. Armatures from head and tail points, automatic vertex weights that repair what Blockbench's own solver gets wrong, weight smoothing at the joints, IK on armature bones, glTF export with the skin.
- Materials. Height, normal and MER maps from a colour texture, from built-in presets or the ones you saved in Blockbench. Soft seams across face edges and UV cuts.
- It checks its own work. Screenshots and multi-view captures (also in weight-colour and material view), silhouette comparison against your reference picture, intersection, ground-contact and detached-part checks during animation.
- Pixel art for 2D games. Real pixel-art renders, not downscaled screenshots: 4 / 8 / 16 directions, sprite sheets with Aseprite JSON and a stable feet pivot.
- Extensible. Other Blockbench plugins can add their own tools; the assistant sees them at once.
- Local only. The bridge listens on
127.0.0.1. Other devices on the network can't reach it, and since 1.6.1 neither can websites open in your browser. - Undo anything. Every tool writes to Blockbench's undo history.
- No freezes.
eval_coderefuses Node modules that would open Blockbench's blocking permission dialog. - Nothing phones home. No telemetry, no update checks, no background service besides the server your MCP client starts.
Important
On 1.6.0 or older, any website open in your browser could reach the bridge while Blockbench and the server were running. Update. Details under Security.
1. Get the two files. Download blockbench_mcp.js and mcp-server.js from the
latest release (also as a zip)
and put them in a folder that stays put. The server is bundled; no npm install needed.
2. Load the plugin. In Blockbench: File → Plugins → ⋮ → Load Plugin from File, pick
blockbench_mcp.js, accept the prompt.
3. Register the server with your MCP client.
# Claude Code
claude mcp add --scope user blockbench -- node /path/to/mcp-server.js4. Check it. With Blockbench open, ask for "the Blockbench status". get_status should report a
connected Blockbench and plugin version.
It needs Blockbench 5.2 or newer (5.1.4 works, minus the 5.2 tools) and Node.js 18 or newer. Several clients can run at once: the first server becomes the bridge, the others relay through it.
Build from source
git clone https://github.com/RenasDemirbas/BlockBenchMCP.git
cd BlockBenchMCP
npm install
npm run build # dist/blockbench_mcp.js + dist/mcp-server.js (reads node_modules)
npm run build:release # single-file server with dependencies bundledUpdating
- Overwrite both files with the new ones (or
git pull && npm run build). - Restart Blockbench, then restart your MCP client: a running server keeps the old version.
plugin_version in get_status shows what is loaded.
Make a wolf in the Bedrock entity format. Build only the skeleton and the shape in grey cubes first and show me three views. If I like it, texture it and add a walk cycle.
Build a low-poly knight in the free format from
C:/refs/knight.png. Compare the silhouette as you go, unwrap at 48 px per unit, paint flat colours and bake the shading into its own layer.
Rig the tentacle mesh with an armature of five bones, fix the weights at the joints and make it wave. Export it as GLB.
Render the slime as an 8-direction isometric sprite sheet at 64 px with the pico8 palette.
Building step by step beats asking for everything at once: a screenshot after each step costs less than fixing everything at the end.
Cube model (Minecraft-style entity)
- Project and skeleton.
create_project, then the bone tree withadd_groups(body > head,body > leg_fl…). Animations apply to these groups. - Geometry.
add_cubesinside the groups;mirror: truefor symmetric limbs;add_planesfor fur and leaves. - Check.
capture_multi_viewfrom the front, side and top. Fix proportions now; changing geometry after painting breaks the UVs. - Texture.
generate_texture_templatefirst, thenpaint_texture/paint_faces. Without the template many faces share one UV area and painting one repaints the others. - Animation.
create_animation,set_keyframes,mirror_keyframesfor left-right pairs.validate_modelcatches intersecting and detached parts during the animation;query_geometrychecks that the feet touch the ground. - Export.
project_fileexport/export_animations, orpixel_artexport_sheetfor 2D.
Low-poly, hand-painted character
- Reference.
compare_referencereports silhouette similarity (IoU) and, per height band, how much wider or narrower the model is, in units. - Blockout.
add_loftfor arms, legs, trousers and torso: give each ring's centre and size and get a tapering, bending limb. A cylinder (add_mesh_primitive) for a hat brim; a plane +edit_meshsolidify for a cape. - Shaping.
transform_meshtaper / bend / twist (addfallofffor soft edits),edit_meshextrude / inset / loop cut / bevel. Steps chain withselect: "previous". - UV.
unwrap_mesh {pixel_density: 32-64, density_scale: {"head": 2}}. Limbs unwrap as single strips; existing paint is carried over. - Flat colours.
palette {action: "ramp"}, thenpaint_faces; on meshesfaces: ["up"]picks the upward-facing faces.project_referencecan project the picture as a starting point. - Soften and bake.
blend_seamsevens out colour breaks between parts;bake_texture {layer: "shading"}paints light, AO and edges as hue-shifted pixel-art steps. - Clean up.
palette {action: "quantize"}locks stray colours to the palette. - Record.
record_buildstart/stopturns the build into a part-by-part GIF.
The whole pipeline runs in scripts/examples/build-gunslinger.mjs, which builds a four-armed,
gas-masked gunslinger in a new tab:
OUT=C:/output/folder node scripts/examples/build-gunslinger.mjsSmooth, subdivided mesh
Needs the BlockSmooth plugin (blocksmooth.js) loaded next to the bridge plugin.
- Box-model a coarse cage with quads in the
freeformat: a cube converted withrun_actionconvert_to_mesh, thenedit_meshextrude / inset / loop cut. smooth_mesh {action: "add", type: "subdivision", levels: 2}. The viewport, screenshots and pixel art show the smooth surface; you keep editing the cage.smooth_mesh {action: "crease", angle: 60}keeps every hard edge of the cage sharp; lowervalue(0.3-0.7) gives tight rounded bevels instead.smooth_mesh {action: "add", type: "smooth_by_angle", angle: 30}for crisp shading on flat panels.project_fileexport(OBJ, FBX, glTF/GLB, Collada, STL): the files contain the subdivided mesh atexport_levels; the.bbmodelkeeps the editable cage.
Hytale model
Needs the official Hytale Models plugin (File → Plugins → Available, search "Hytale"). The bridge uses its formats and file writers, so the files are the ones Blockbench's own Hytale export makes.
create_project {format: "hytale_character"}for characters and attachments (a block is 64 units),"hytale_prop"for props and blocks (32 units). Models face +Z (south), unlike Minecraft entities.- Groups are the nodes: give each group one unrotated cube as its shape. Keep cube sizes whole
(scale finely with the cube's
stretch), use one texture at 1 pixel per unit, stay under 255 nodes.add_planeswithdouble_sided: falsemakes a Hytale quad. - Animations snap to 60 FPS by default.
project_fileexportblockymodel; the result lists anything Hytale will show differently underwarnings.export_animationswith a folderpathwrites one<name>.blockyanimper animation.
Skinned mesh (armature)
- Build one continuous mesh (
add_loft,edit_mesh), in thefreeformat. add_armature {bones: [{name, head, tail, parent}], meshes: ["body"]}builds the skeleton and skins the mesh in one call.capture_screenshot {view_mode: "weighted_bone_colors"}shows which bone owns which vertex.vertex_weightssmooth(withnear: {bone, distance}) softens creasing joints;setpaints a weight onto a selection;inspectlists vertices that follow no bone.- Pose with
set_keyframeson the bone names, or drive a chain withadd_ik_controllers. project_fileexportglbwith{armature: true}.
Groups stay the right choice for blocky Minecraft rigs, where parts move rigidly.
Coordinate conventions
- 1 unit = 1/16 block. Y is up; the ground is y = 0.
- +X is east, -Z is north. Entities face north (-Z); the
northcamera preset shows the front. - Rotations are degrees, order ZYX. +X swings a hanging limb forward.
75 tools. Each one's parameters are described in its schema, which the assistant reads on its own.
| Area | Tools |
|---|---|
| Project | get_status, blockbench_window, list_formats, create_project, get_project_info, set_project_settings, project_file (open, save, export, export_animations, import, get_json, switch_tab, close) |
| Geometry | add_groups, add_cubes, add_meshes, add_mesh_primitive, add_loft, edit_mesh, transform_mesh, add_planes, add_locators, add_bounding_boxes, list_outline, get_element, update_elements, delete_elements, duplicate_elements, mirror_elements, select_elements |
| Texture | create_texture, generate_texture_template, list_textures, get_texture, import_texture, apply_texture, paint_texture, paint_faces, bake_texture, blend_seams, generate_pbr_map, palette, texture_layers, resize_texture, set_texture_resolution, delete_texture |
| UV | unwrap_mesh, uv (inspect, set_cube, set_mesh, auto) |
| Animation | create_animation, list_animations, get_animation, update_animation, delete_animation, set_keyframes, edit_keyframes, mirror_keyframes, add_effect_keyframes, apply_animation_preset, variable_placeholders, preview_animation, render_animation |
| Smoothing | smooth_mesh (describe, add, update, remove, move, crease, sharp, apply, shading) — needs the BlockSmooth plugin, except shading |
| Rigging | add_ik_controllers, bake_ik_animation, add_armature, vertex_weights (auto, set, smooth, normalize, clear, inspect) |
| Checking | validate_model, query_geometry, capture_screenshot, capture_multi_view, record_build |
| Reference | compare_reference, project_reference, preview_models, reference_images |
| Pixel art | pixel_art (render, export_sheet, presets) |
| Display | display_transforms (get, set) |
| Other | run_action, eval_code, undo, redo |
What Blockbench 5.2 unlocks
Texture layer groups, IK with poles, movable reference models, reference images as 3D panels, Java
26.3 shade_direction_override, the cushion skin template, Molang variable_placeholders, bounding
boxes in the generic format, the embedded and on_shelf display slots and glTF merge_armature.
Built on top of 5.2:
- Armatures and vertex weights (
add_armature,vertex_weights); IK over armature bones. transform_meshfalloff: proportional editing, in a straight line or along the mesh edges.generate_pbr_map: height, normal and MER maps with the dialog's math and presets.blend_seams: what the screen-space brush is for, done in world space.capture_screenshotview_mode: weight colours, material, normals and the other view modes.- Video reference images: seek, play, pause, mute and volume.
edit_keyframesrelative_to_playhead;project_fileresolve_parentsfor Java child models;molangandpbrflags inlist_formats.
The features field of get_status shows which of these your Blockbench has.
Tips
Texturing
target: {element: "leg_fl", faces: "all"}paints every cube in a group at once;"*"is the whole model.- Give gradients
space: "world", otherwise they restart on every cube and multi-part limbs look banded.stopsmakes multi-stop gradients. - Shadows on their own
layerset tomultiplystay easy to tune. jagged_edgefor fur silhouettes,strandsfor fur grain.- Looks right as an image but wrong on the model? Run
uvinspectfirst.get_texturewith an element and face crops and enlarges that face. - Washed out or covered in a grid? Check Blockbench's
brightnessandpixel_gridsettings before repainting.
Animation
- Keyframe values can be Molang:
"math.sin(query.anim_time*360)*15". - Times snap to the animation's FPS grid (24 by default);
snap: falsekeeps exact times.edit_keyframesretimes and deletes, also everything before or after the playhead. - With a rest rotation on a bone, keyframes add to it; they are not absolute angles.
apply_animation_presetfor quick motion: float, flap, swing, sway, shake, jump, flicker …- Bake IK (
bake_ik_animation) before exporting animations to Bedrock or Java.
Pixel art
- Views:
side,front,back,top,three_quarter,top_down,isometric(2:1),true_isometric, or freeyaw/pitch.directions: 8for a rotation set;mirror_directions: truehalves the work on symmetric models. - Styles:
outlined(default),clean,minecraft,flat. Palettes: the model's own colours, orpico8,sweetie16,endesga32,db32, or your own list, with optional Bayer dithering. export_sheetwrites one PNG plus Aseprite JSON; scale and pivot are fixed once, so frames don't drift. Ask forpixel_artpresetsto see every option.
File paths. Saving and exporting need absolute paths. get_status returns the home, desktop
and temp folders and get_project_info the last folder used per file type; the assistant builds
paths from them.
MCP client ──stdio──► mcp-server.js ◄──ws://127.0.0.1:8188── blockbench_mcp.js (in Blockbench)
The WebSocket server runs on the MCP side and the plugin connects to it, so Blockbench never asks for network permissions. If Blockbench closes, the server keeps running and the plugin reconnects within seconds when it reopens. Timers are kept running while the window is minimized, so long operations don't stall in the background.
The port is 8188. To change it, set BB_BRIDGE_PORT and Settings → General → MCP Bridge Port
to the same value.
Headless mode
With BB_HEADLESS=1 in the server's env, Blockbench doesn't need to be open: when a tool needs it,
the server starts it with the window hidden, waits for the plugin (about 5 s) and runs the tool.
Screenshots and renders draw offscreen.
"env": { "BB_BRIDGE_PORT": "8188", "BB_HEADLESS": "1" }blockbench_windowshows and hides the window, with or without headless mode.- An already running Blockbench is used as it is.
BB_EXECUTABLEpoints to a non-default install;BB_LAUNCH_TIMEOUT_MS(90000) caps the wait.- Hiding the window is Windows-only for now. On macOS and Linux Blockbench starts visibly; on a
Linux server without a display, point
BB_EXECUTABLEat a script that runs it underxvfb-run.
Adding tools from another plugin
Another Blockbench plugin registers tools through window.BlockbenchMCP; the assistant sees them
next to the built-in ones with no server restart. Listen for blockbench_mcp_ready so the tool is
added whichever plugin loads first, and again after the bridge reloads.
let tool;
function addTools() {
tool = BlockbenchMCP.registerTool({
name: 'count_cubes',
title: 'Count cubes',
description: 'Count the cubes in the open project, optionally only those whose name contains a filter.',
inputSchema: { type: 'object', properties: { filter: { type: 'string' } } }, // JSON Schema
annotations: { readOnlyHint: true },
}, ({ filter }) => ({ count: Cube.all.filter((c) => !filter || c.name.includes(filter)).length }));
}
Plugin.register('my_plugin', {
onload() {
if (window.BlockbenchMCP) addTools();
window.addEventListener('blockbench_mcp_ready', addTools);
},
onunload() {
tool?.delete();
window.removeEventListener('blockbench_mcp_ready', addTools);
},
});name: 1–64 characters ofA-Z a-z 0-9 _ - .; names already taken are refused.descriptionis required: it is all the assistant reads to decide when to call the tool.inputSchemais optional and must betype: "object". Arguments are not validated against it; the handler should check them.- The handler may be
async. A string comes back as text, anything else as JSON; put PNG data URLs in__image/__imagesto return images. A thrown error becomes the tool's error. Calls time out after 120 s.registerToolreturns an object whosedelete()removes the tool.
- The bridge listens only on this computer (
127.0.0.1). - Websites can't connect (since 1.6.1). Only connections without an Origin header (Node) and the
Blockbench window (
file://) pass the handshake. Programs on your computer can still connect; they already run with your permissions. eval_codecan't freeze Blockbench. Node modules that open a permission dialog (fs,child_process…) are refused before the code runs;allow_native_modules: trueopts out, with the Blockbench window in the foreground.- A shared
.bbmodelmay contain local paths. Blockbench saves the full path of animation files, which can include your username.
Contributions are welcome: see CONTRIBUTING.md, and SECURITY.md for reporting a vulnerability privately.
npm run build && npm run typecheck # npm run build:release bundles the server + its licenses
node scripts/call-tool.mjs eval_code '{"code":"setTimeout(() => Plugins.devReload(), 300); \"ok\"","undo":false}' # reload the plugin
node scripts/call-tool.mjs pixel_art '{"action":"render","view":"isometric","size":64}' --images e2e-output/tmp # call any toolA running MCP client fixes its tool list when its server starts; call-tool.mjs spawns a fresh
server, so new tools and parameters can be tried without restarting the client.
The source is split by layer: server/src/tools holds the tool schemas, plugin/src/handlers the
Blockbench side of each command (reads, writes, undo), and plugin/src/rig, mesh and texturing
the pure math behind skinning, deformers, PBR maps and seam blending.
Tests
Run any of them with node scripts/<name>.
| Script | What it tests | Needs |
|---|---|---|
smoke-test.mjs |
MCP protocol and bridge, with a fake plugin | Nothing |
verify-bridge-origin.mjs |
The bridge refuses connections from websites | Nothing |
verify-plugin-api.mjs |
Tools added by other plugins: listing, calls, relays, removal, re-adding after a reload (moves the plugin to port 8191 and back) | Open Blockbench |
e2e-test.mjs |
Full modeling scenario | Open Blockbench |
e2e-pro-test.mjs |
Validation, queries, mirroring, painting | Open Blockbench |
verify-paint-ops.mjs |
Paint operations | Open Blockbench |
verify-detached.mjs |
Detached parts at rest and during animation | Open Blockbench |
verify-field-fixes.mjs |
1.3 fixes | An open project |
verify-v52-features.mjs |
Blockbench 5.2 features | Blockbench 5.2 |
verify-v52-additions.mjs |
Armatures and weights, armature IK, falloff, PBR maps, seam blending, playhead selection, molang flag, Java parent chains, video references, view modes | Blockbench 5.2, ffmpeg for the video check |
verify-pixel-art.mjs |
Pixel-art output (PNG and JSON) | Open Blockbench |
verify-blocksmooth.mjs |
smooth_mesh: modifiers, creases, viewport display, exports and cage restore, apply and undo |
Open Blockbench with the BlockSmooth plugin |
verify-lowpoly-tools.mjs |
Mesh painting, unwrap, edit / loft / transform, bake, palette, reference, recording; pick sections with … paint,bake |
Open Blockbench, REF_DIR for the reference tests |
verify-headless.mjs |
Headless launch, hidden-window tools and screenshots, blockbench_window |
Windows, Blockbench closed |
verify-hidden-window-timers.mjs |
Timers while the window is in the background | Minimized Blockbench |
- "Blockbench is not connected". Is Blockbench running, is the plugin enabled under File → Plugins, and is the port the same on both sides (8188)?
- Updated but nothing changed. Restart the MCP client; the running server keeps the old file.
- Long operations time out in the background.
timers.unthrottledinget_statusshould betrue; if not, bring Blockbench to the front. - Logs. Claude Desktop:
%APPDATA%\Claude\logs\mcp-server-blockbench.log. Blockbench:Ctrl+Shift+I→ Console →[MCP]lines.
Copyright (C) 2026 Renas Demirbas
Blockbench MCP is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. It is distributed in the hope that it will be useful, but without any warranty; see the license for details.



