Blender MCP Server
# Blender MCP Server
MCP server for **Cursor** that controls **Blender** through a local HTTP bridge.
`bpy` runs **inside Blender** — this repo does not import bpy in the MCP process.
**Separate from [Summit](../summit)** — export `.glb` files to Summit's `Assets/` when ready.
## Architecture
```
Cursor Agent → MCP (this repo) → HTTP bridge → bpy → Blender
```
| Path | Role |
|------|------|
| `server.py` | MCP entry (stdio) |
| `mcp_server/` | Tools exposed to the agent |
| `blender_addon/blender_mcp_bridge/` | Blender addon (HTTP + bpy commands) |
| `config.json` | Bridge port, Summit export paths, default `.blend` |
Blender 5.1: `/home/juan/blender-5.1.2/blender`
## Quick start
### 1. Install MCP server (Python)
```bash
cd /home/juan/source/blender_mcp_server
./scripts/setup_mcp.sh
cp config.example.json config.json # edit paths if needed
```
### 2. Install Blender addon
```bash
BLENDER_VERSION=5.1 ./scripts/install_addon.sh
# Detect version: ls ~/.config/blender/
```
In Blender:
1. **Edit → Preferences → Add-ons** → enable **Blender MCP Bridge**
2. **N panel → MCP tab → Start Server** (default `http://127.0.0.1:9876`)
Or start headless with the default export blend:
```bash
./scripts/start_bridge.sh
```
Logs: `bridge.log` in this repo. Override blend: `BLENDER_MCP_BLEND=/path/to/file.blend ./scripts/start_bridge.sh`
### 3. Connect Cursor
Merge `cursor.mcp.example.json` into `~/.cursor/mcp.json`:
```json
{
"mcpServers": {
"blender": {
"command": "/home/juan/source/blender_mcp_server/.venv/bin/python",
"args": ["/home/juan/source/blender_mcp_server/server.py"],
"env": {
"BLENDER_MCP_CONFIG": "/home/juan/source/blender_mcp_server/config.json"
}
}
}
}
```
Restart Cursor. Open this folder as workspace when animating.
### 4. Test
With Blender bridge running:
```bash
curl -s http://127.0.0.1:9876/health
```
In Cursor chat (with MCP enabled):
> Use ping_blender, then scene_information
## MCP tools
**Connection:** `ping_blender`, `get_server_config`
**Inspection:** `scene_information`, `list_objects`, `list_armatures`, `list_bones`, `list_actions`, `get_object_transform`
**Animation:** `create_action`, `rename_action`, `set_active_action`, `set_frame`, `set_bone_rotation_keyframe`, `set_action_loop_mode`
**Export / validate:** `export_gltf`, `export_to_summit`, `validate_scene_scale`, `validate_action_root_motion`, `validate_rts_asset`, `render_preview`
**Modeling (recipes):** `create_summit_bobcat` — low-poly harvester blockout + `idle` / `harvest` animations
### Bridge-only commands (not MCP tools yet)
Callable via `scripts/run_command.py` or HTTP bridge dispatch:
| Command | Purpose |
|---------|---------|
| `create_natural_idle_action` | Breathing idle from a pose frame (quaternion offsets) |
| `create_rifle_attack_action` | Forward rifle aim + recoil clip |
| `create_idle_action` | Static hold from source action |
| `prepare_rifleman_locomotion` | Import walk GLB, remap bones, strip hip motion, create idle |
| `duplicate_action` | Copy an action |
| `strip_action_root_motion` | Remove root bone location keys |
## Human Rifleman pipeline (current)
Source blends live under `~/Documents/BlenderSaves/summit/`:
| File | Content |
|------|---------|
| `riflemenStand.blend` | `idle` — natural breathing (~48 frames) |
| `riflemenwalk.blend` | `walk` — in-place **rifle run** sprint (22 frames) |
| `riflemenfire.blend` | `attack` — rifle aim + recoil (~24 frames) |
| `riflemenExport.blend` | Merged master (idle + walk + attack) |
| `riflemen-backup-dont-edit.blend` | Safety backup |
**Regenerate walk + attack from stand** (run FBX + procedural fire), then merge + export:
```bash
/home/juan/blender-5.1.2/blender --background --python scripts/prepare_rifleman_animations.py
```
**Body textures (Ch36):** merge exports from `riflemenStand.blend` (painted mesh). The exporter rebuilds `Ch36_Body` for glTF PBR and syncs packed images into the GLB. If sidecar PNGs look stale in Godot, reimport `Rifleman.glb` or run:
```bash
/home/juan/blender-5.1.2/blender --background --python scripts/fix_and_export_rifleman_body.py
/home/juan/blender-5.1.2/blender --background --python scripts/extract_textures_from_glb.py
```
**Re-export only** (if walk/fire blends already exist):
```bash
/home/juan/blender-5.1.2/blender --background --python scripts/prepare_rifleman_export.py
```
Output: `/home/juan/source/summit/Assets/Units/Human/Rifleman.glb`
Godot view: `Scenes/Units/HumanRiflemanView.tscn` (animations `idle`, `walk`, `attack`).
Rifle mesh is parented to `mixamorig1:RightHand` in the fire blend. Attack uses explicit aim quaternions (+Y barrel forward), not a copied walk pose.
Or export from the open blend via MCP:
```
export_to_summit(target_key="summit_human_units", filename="Rifleman.glb", action_names=["idle","walk","attack"])
```
## Bobcat harvester (vehicle recipe)
### V2 (RTS parts catalog — recommended)
Procedural **Generals-style** assembly from reusable mechanical parts:
```bash
BLENDER_VERSION=5.1 ./scripts/install_addon.sh
/home/juan/blender-5.1.2/blender --background --python scripts/create_summit_bobcat_v2.py
```
Output blend: `~/Documents/BlenderSaves/summit/bobcatExport.blend`
Silhouette preview: `~/Documents/BlenderSaves/summit/bobcat_v2_silhouette.png`
Output GLB: `/home/juan/source/summit/Assets/Units/Human/Bobcat.glb` (`idle`, `harvest`)
MCP: `create_summit_bobcat_v2`, `validate_rts_asset`, `validate_rts_silhouette`, `render_rts_silhouette_preview`
Parts catalog (`modeling/parts/`): cabin, wheel, bucket, hydraulic, chassis, fender, exhaust, headlight, arm, grille.
Animated pivots (stable Godot contract): `Bobcat_Arm_L`, `Bobcat_Arm_R`, `Bobcat_Bucket`.
### V1 (blockout)
```bash
/home/juan/blender-5.1.2/blender --background --python scripts/create_summit_bobcat.py
```
## Summit export
Config keys in `config.json`:
```json
"export_targets": {
"summit_human_units": "/home/juan/source/summit/Assets/Units/Human",
"summit_props": "/home/juan/source/summit/Assets/Props"
}
```
Default blend: `riflemenExport.blend` (see `default_blend` in config).
Then switch workspace to `/home/juan/source/summit` to wire Godot views and sim.
## Summit conventions
| Rule | Value |
|------|--------|
| Scale | 1 Blender unit = 1 meter |
| Infantry height | ~**1.6 m** (`Ch36` reference mesh) |
| Forward | **+Y** in Blender |
| Animation names | `idle`, `walk`, `attack`, `death` (infantry); vehicles: `idle`, `harvest` |
| Vehicle tri budget | **2500** tris (blockout recipe) |
| Locomotion | Walk **in place** — no hip translation (`validate_action_root_motion`) |
See also Summit [player identity](../summit/docs/02-Architecture/player-identity.md) for **team color masks** when authoring units:
- Paint tint regions in Blender (vertex color or `*_TeamMask.png`)
- One GLB per unit type; player color applied at runtime in Godot
- Human = military paint zones; Robot = LED emissive mask; etc.
## Headless
```bash
blender mychar.blend --background --python scripts/run_command.py -- '{"command":"scene_information","args":{}}'
```
## Roadmap
- [x] Rifleman idle / walk / attack pipeline + `prepare_rifleman_export.py`
- [x] Bobcat blockout recipe + `create_summit_bobcat.py`
- [x] `validate_rts_asset` + MCP modeling tools
- [x] `create_natural_idle_action`, `create_rifle_attack_action` (bridge)
- [x] `start_bridge.sh` headless bridge daemon
- [ ] Expose locomotion commands as MCP tools
- [ ] Team color mask validation / export hints for Summit shader
- [ ] `death` animation for rifleman
- [ ] Rigging helpers
- [ ] Auto tool registration review gate
TDQS
Scored across 32 tools
Each tool has a highly specific and unique purpose, from creating individual RTS models (e.g., create_summit_bobcat) to distinct validation and export operations. No two tools appear to overlap in functionality, ensuring an agent can reliably select the correct tool.
Tool names follow a consistent verb_noun_snake_case pattern, with clear prefixes like create_, list_, validate_, and export_. Within each category, naming is uniform (e.g., create_summit_*_v# or validate_*), making the tool set predictable and easy to navigate.
32 tools is on the high side, but the server is focused on a specialized RTS asset pipeline, which justifies many specific model creators and validators. However, the sheer number may overwhelm agents, and some generic operations could be consolidated.
The tool set covers the full lifecycle for the Summit RTS asset domain: creation of multiple specific models, validation of conventions, animation management, and export. Minor gaps exist (e.g., no geometry or material editing), but core workflows are well supported.