Skip to main content
Glama
BATTLEHAWK00

blender-server-mcp-docker

by BATTLEHAWK00

Blender Server — Native Blender MCP Container

English | 简体中文

Run Blender 5.2.1, an Xvfb virtual display, and the native MCP server and addon from ahujasid/blender-mcp in one container. Client machines do not need Blender or a manually started addon.

The request path is: HTTP MCP client → native MCP server → in-container addon → persistent Blender process. Xvfb provides the GUI and viewport environment, while Cycles renders on an NVIDIA GPU. The native addon requires a GUI event loop, so the container does not use blender -b.

Quick start

Requirements: Linux x86_64, Docker Compose v2, an NVIDIA driver, and NVIDIA Container Toolkit.

cp .env.example .env
mkdir -p work
# Edit .env: set API_TOKEN and GPU_ID, and set APP_UID / APP_GID to id -u / id -g
docker compose up -d --build
curl --fail http://127.0.0.1:21849/health

The MCP endpoint is http://127.0.0.1:21849/mcp. For remote access, configure BIND_HOST, MCP_ALLOWED_HOSTS, and a strong random API_TOKEN, then expose the service through an HTTPS reverse proxy. Addon port 9876 listens only inside the container. .env, work/, and mcp-client.local.json are excluded from the repository and image.

Related MCP server: dcc-mcp-blender

Client setup

Generic HTTP MCP client configuration (exact fields depend on the client):

{
  "mcpServers": {
    "blender-server": {
      "url": "http://127.0.0.1:21849/mcp",
      "headers": {"Authorization": "Bearer <API_TOKEN from .env>"}
    }
  }
}

Remove or disable any previous uvx blender-mcp stdio configuration, use the remote HTTP configuration above, reconnect, and refresh the tool list. Otherwise, the old service will continue trying to connect to Blender on the client machine and report Could not connect to Blender.

Native tools

Use MCP tools/list to retrieve the complete tool list. It includes get_addon_status, get_scene_info, get_object_info, execute_blender_code, get_viewport_screenshot, and upstream asset search, import, and generation tools. Third-party services require separate integrations and API keys. Upstream telemetry is disabled through environment variables.

For example, call execute_blender_code to create an object:

{"code":"import bpy\nbpy.ops.mesh.primitive_cube_add(location=(2, 0, 0))"}

The persistent Blender process uses Cycles and AUTO GPU selection by default: OptiX first, then CUDA, with no automatic CPU fallback. The selected backend depends on the host driver and GPU. Save scenes and rendered images under /work/..., which maps to ./work/... on the host. In-memory scenes reset when the container restarts. Persist one with:

bpy.ops.wm.save_as_mainfile(filepath="/work/scene.blend")

Native execution tools are synchronous, and the upstream socket timeout is 180 seconds. Use a saved .blend file and a separate batch process for long renders. All clients share one scene, so avoid concurrent modifications. Arbitrary Python execution has the container user's permissions; expose this service only to trusted clients.

MCP file upload and download

The native MCP endpoint registers three additional tools. They use the same Bearer authentication as /mcp; no separate REST request is required.

Tool

Purpose

upload_file(path, data_base64, offset=0, overwrite=false)

Upload a file or append a chunk; each decoded chunk may be up to 1 MiB

download_file(path, offset=0, length=65536)

Download Base64 data; chunks default to 64 KiB and may be up to 1 MiB

list_files(path=".", offset=0, limit=100)

Browse a directory with pagination, including path, type, and size

Paths are relative to /work/sessions/<session-id>/files/. Absolute paths inside that session directory are also accepted. Cross-session paths and symbolic links are rejected. Uploads create parent directories automatically. Set overwrite=true explicitly to replace an existing file from offset zero.

The service uses stateful Streamable HTTP. The client sends initialize, saves the Mcp-Session-Id response header, then sends notifications/initialized. Every later request carries that session ID and the original Bearer token. Standard MCP clients handle this automatically. Session IDs are generated by the server and should be treated as credentials because file isolation under one token depends on their secrecy.

Each session has independent storage. list_files returns an absolute_path that Blender can use for scene and render output; the client can then retrieve the file with download_file. Files directly under /work are outside the file tools' session scope.

At startup, and then every 4 hours, the service removes session directories that have received no requests for 4 consecutive hours and have no active request. Cleanup therefore usually occurs after 4–8 idle hours. It only handles valid server-generated directories under sessions, does not remove legacy /work files, and does not follow session-directory symlinks. Download important results promptly because deleted files cannot be recovered.

After a session expires or the service restarts, clients must initialize again. A new session cannot access files from an old session. Detached background Blender work does not count as an active MCP request; use persistent storage for long detached jobs.

File-tool isolation is not operating-system isolation. execute_blender_code can still execute arbitrary Python, and all clients share the same Blender scene.

Upload hello.txt through MCP tools/call:

{"name":"upload_file","arguments":{"path":"hello.txt","data_base64":"aGVsbG8K"}}

Download it again:

{"name":"download_file","arguments":{"path":"hello.txt"}}

The result contains data_base64; the client decodes it and writes the bytes locally. For large uploads, split the source into chunks of at most 1 MiB, use offset=0 for the first chunk, and use each response's next_offset for the next chunk. For downloads, continue with next_offset until eof=true, decoding chunks in order. .blend files, textures, rendered images, and archives are transferred as raw bytes.

Build and run

The host does not need Blender or Python dependencies. To build directly:

docker build --build-arg APP_UID="$(id -u)" --build-arg APP_GID="$(id -g)" -t blender-server:local .

Debian uses its official package source by default; pass the APT_MIRROR build argument to select a mirror. The Python lockfile currently uses the USTC index. The official Blender archive is SHA256-verified, and the base image comes from GHCR. Existing download proxies can be passed with --build-arg ALL_PROXY; the proxy is not preserved at runtime. Upstream sources and local patches live in vendor/blender-mcp, with the pinned commit and license recorded there.

Setting

Description

GPU_ID

Host GPU index; defaults to 0

APP_UID / APP_GID

Container user IDs; they must be able to write to work

BIND_HOST / PORT

Bind address and port; defaults to 127.0.0.1:21849

API_TOKEN

HTTP MCP Bearer authentication; the health endpoint is exempt

MCP_ALLOWED_HOSTS

Allowed external IP addresses, hostnames, and ports

Origin / CORS

All origins are allowed; requests still require the Bearer token

The entrypoint supervises Xvfb, Blender, and the HTTP server. If any process exits, the container stops and Compose restarts it. Inspect logs with docker compose logs -f.

To update a deployment, save any in-memory scene, then run:

docker compose up -d --build

Reconnect MCP clients and refresh their tool lists afterward.

Testing

Unit tests and code checks do not require a GPU:

uv sync --locked
uv run --locked ruff check blender_server tests scripts
uv run --locked pytest -q

To test the native tools, addon, scene operations, screenshots, and GPU rendering against a configured deployment:

python3 scripts/native_smoke.py

The smoke test reads the local client configuration, creates MCP_E2E_Cube, and writes work/native-viewport.png, work/native-render.png, and work/native-e2e.blend. It modifies the active scene, so use a test instance.

The previous custom rendering API remains in blender_server/app.py, but the current image starts the native MCP service. The old /jobs endpoint and scripts/smoke.py are not used by the current deployment.

Prebuilt image and publishing

The image is available from GHCR:

ghcr.io/battlehawk00/blender-server-mcp-docker:edge

Set it in .env, then start without a local build:

BLENDER_SERVER_IMAGE=ghcr.io/battlehawk00/blender-server-mcp-docker:edge
docker compose pull
docker compose up -d --no-build

The prebuilt image uses UID/GID 1000. Make sure work/ is writable by that user. APP_UID and APP_GID affect local builds only.

The container image workflow runs for pushes to main, v* tags, and manual dispatches. Pull requests build the image for validation without logging in or pushing. Unit tests and lint must pass before publication. Only linux/amd64 is currently supported.

Trigger

Image tags

Push to main

main, edge, sha-<commit>

Tag v1.2.3

1.2.3, 1.2, latest, sha-<commit>

Tag v1.2.3-rc.1

1.2.3-rc.1, sha-<commit>; does not update latest

Manual dispatch

Current branch or version tag, plus sha-<commit>

The workflow uses the repository's GITHUB_TOKEN; no registry secret is required. Pulling a private image requires GHCR authentication. Use edge before the first stable release; only stable version tags produce latest.

Repository layout and contributing

  • blender_server/: service entrypoint, file/session management, and retained REST rendering implementation.

  • vendor/blender-mcp/: pinned upstream MCP server and addon, patch notes, and license.

  • tests/: unit tests that do not require Blender or a GPU.

  • scripts/: smoke tests for a live deployment.

  • .github/: CI, image build, and repository maintenance configuration.

See CONTRIBUTING.md for development and release instructions, SECURITY.md for the security model, and THIRD_PARTY_NOTICES.md for third-party licenses.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    D
    maintenance
    Enables remote control of Blender via the Model Context Protocol, allowing users to execute Python scripts, query scene data, and generate 3D models from images. It provides a bridge for AI clients to interact directly with Blender's internal environment and automate 3D content creation.
    3
    6
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Connects MCP-compatible clients to a live Blender scene for AI-assisted 3D workflows, enabling inspection and controlled operations on objects, materials, cameras, lights, render settings, animation, UVs, Geometry Nodes, imports, exports, and Python execution.
    1
    MIT