Sandbox
@dhakalnirajan/blender-open-mcp

MCP server and add-on for Blender control

This repo connects MCP clients to a live Blender session through a Blender add-on and a FastMCP server. The server exposes scene, object, render, PolyHaven, and LLM provider tools, while the add-on executes Blender actions inside `bpy`.

116 stars34 forksPythonUpdated 13d ago
Who it's for

Builders who want their agent to inspect, edit, and render Blender scenes instead of working only in chat.

What it delivers

You can direct Blender from an MCP client, switch LLM backends at runtime, and keep working without restarting the server.

What it does

Blender TCP bridge

`addon.py` runs a local TCP server in Blender and handles scene, object, material, render, and code execution requests.

MCP tool server

`src/blender_open_mcp/server.py` exposes Blender tools, PolyHaven tools, and LLM provider tools over MCP.

Provider switching

The LLM layer supports Ollama, LM Studio, llama.cpp, OpenAI-compatible endpoints, and Azure, and can switch providers at runtime.

Client CLI and library

`blender-mcp-client` can list tools, call tools, send prompts, and run interactively, with an async Python client API.

Prompt workflows

Built-in MCP prompts include scene building, scene review, and LLM configuration guidance.

How to get it

  1. 1Requires Python ≥ 3.10.
    python -m venv .venv
    .venv/Scripts/pip install -e ".[dev]"   # Windows (bash/PowerShell)
    # or: source .venv/bin/activate && pip install -e ".[dev]"   # macOS/Linux
  2. 2Default LLM backend is Ollama
    blender-mcp                          # Ollama at http://localhost:11434, model llama3.2

README

Blender Open MCP

Local-first Model Context Protocol (MCP) server for controlling a live Blender session from AI agents, with a provider-agnostic LLM backend:

  • Ollama
  • LM Studio
  • llama.cpp server
  • OpenAI (and every OpenAI-compatible endpoint: vLLM, TGI, OpenRouter, Groq, Together, Azure AI Foundry via its OpenAI-compatible surface, …)
  • any server that speaks POST /chat/completions with an optional base URL and API key

Providers are configured at startup (CLI flags or environment variables) and can be switched at runtime through MCP tools, so an agent can hop between backends without restarting the server.

MCP Client ──▶ FastMCP Server ──▶ (TCP 9876) ──▶ Blender add-on (addon.py) ──▶ bpy
                  │
                  └──────────────▶ (HTTP) ──▶ LLM provider (Ollama / LM Studio /
                                               llama.cpp / OpenAI-compatible / Azure)

Repository layout

PathPurpose
addon.pySingle-file Blender add-on: TCP server + scene/render/PolyHaven handlers + sidebar panel
src/blender_open_mcp/server.pyMCP server: Blender tools, PolyHaven tools, LLM prompt + provider tools
src/blender_open_mcp/llm.pyProvider-agnostic LLM layer (registry, adapters, model listing)
src/blender_open_mcp/client/Canonical async MCP client + CLI
client/Thin compat wrapper so from client import … keeps working from source
tests/pytest suites (server, client, addon)

Quick start

1. Install

Requires Python ≥ 3.10.

python -m venv .venv
.venv/Scripts/pip install -e ".[dev]"   # Windows (bash/PowerShell)
# or: source .venv/bin/activate && pip install -e ".[dev]"   # macOS/Linux

2. Enable the Blender add-on

  1. Open Blender.
  2. Edit → Preferences → Add-ons → Install…, choose addon.py.
  3. Enable Blender MCP.
  4. In the 3D Viewport press N, open the Blender MCP tab and click Start MCP Server (listens on localhost:9876 by default).

3. Start the MCP server

Default LLM backend is Ollama:

blender-mcp                          # Ollama at http://localhost:11434, model llama3.2

Or pick a different backend at startup:

# LM Studio (OpenAI-compatible, default localhost:1234/v1)
blender-mcp --llm-provider lmstudio --llm-model "local-model"

# llama.cpp server (default localhost:8080/v1)
blender-mcp --llm-provider llamacpp --llm-model qwen2.5-coder

# OpenAI-compatible generic endpoint
blender-mcp --llm-provider openai_compat --llm-base-url http://my-server:8000/v1 \
            --llm-api-key sk-... --llm-model my-model

# OpenAI
blender-mcp --llm-provider openai --llm-api-key "$OPENAI_API_KEY" --llm-model gpt-4o-mini

# Azure AI Foundry / Azure OpenAI
blender-mcp --llm-provider azure --llm-api-key "$AZURE_API_KEY" \
            --llm-base-url https://my-resource.openai.azure.com \
            --llm-model my-deployment \
            --llm-extra '{"resource":"my-resource","deployment":"my-deployment","api_version":"2024-06-01"}'

Environment variables are honored: BLENDER_OPEN_MCP_PROVIDER, BLENDER_OPEN_MCP_BASE_URL, BLENDER_OPEN_MCP_MODEL, BLENDER_OPEN_MCP_API_KEY.

Other useful flags: --host, --port (MCP endpoint, default 0.0.0.0:8000), --blender-host, --blender-port, --transport streamable_http|http|stdio.

4. Register with an MCP client

Point your MCP client at http://localhost:8000/mcp (streamable HTTP) or run blender-mcp --transport stdio.

Example Claude/Cursor-style config:

{
  "mcpServers": {
    "blender": {
      "url": "http://localhost:8000/mcp"
    }
  }
}

Available MCP tools

Scene / object control (forwarded to the Blender add-on over TCP): blender_get_scene_info, blender_get_object_info, blender_create_object, blender_modify_object, blender_delete_object, blender_set_material, blender_render_image, blender_execute_code.

PolyHaven assets: blender_get_polyhaven_categories, blender_search_polyhaven_assets, blender_download_polyhaven_asset, blender_set_texture.

LLM / provider control:

  • blender_ai_prompt – send a prompt to the active backend (per-call provider/base_url/model/api_key overrides supported).
  • blender_get_llm_provider – show active provider config (API key masked).
  • blender_set_llm_provider – switch/configure the backend at runtime.
  • blender_list_llm_models – list models (Ollama /api/tags or OpenAI-compatible /models).

Legacy aliases: blender_set_ollama_model, blender_set_ollama_url, blender_get_ollama_models keep old Ollama-only clients working.

MCP Prompts (prompts/list / prompts/get):

  • blender_build_scene – guided plan for building a scene from a description.
  • blender_review_scene – read-only inspection workflow.
  • blender_configure_llm – provider-switching instructions with examples.

Prompts are registered in src/blender_open_mcp/prompts.py.

Runtime provider switching (examples)

# Switch to LM Studio
tool blender_set_llm_provider {"provider":"lmstudio","base_url":"http://localhost:1234/v1","model":"local-model"}

# Switch to llama.cpp
tool blender_set_llm_provider {"provider":"llamacpp","base_url":"http://localhost:8080/v1"}

# Back to Ollama
tool blender_set_llm_provider {"provider":"ollama","base_url":"http://localhost:11434","model":"llama3.2"}

Azure AI Foundry (worked example)

Azure's OpenAI-compatible endpoint is deployment-scoped, so three values from your Azure AI Foundry project are required — all of them go into the extra parameter, and the model you name in model must match the deployment name:

  1. Resource name — in the Azure portal, open your resource (e.g. Azure OpenAI or AI Foundry project) and take the short name from its endpoint URL: https://<resource>.openai.azure.com/....
  2. Deployment name — on the Deployments page, e.g. gpt-4o-mini. This is what you pass as model (it is not the base model name).
  3. API key — on the resource's Keys and Endpoint page.
  4. API version (optional) — e.g. 2024-06-01 (the adapter defaults to it).

Switch to Azure at runtime with a single call (CLI form):

blender-mcp-client --host http://localhost:8000 tool blender_set_llm_provider \
  '{"provider":"azure","api_key":"YOUR_AZURE_API_KEY","model":"gpt-4o-mini",' \
  '"extra":{"resource":"my-openai-resource","deployment":"gpt-4o-mini","api_version":"2024-06-01"}}'

The same call through the Python API:

import asyncio
from blender_open_mcp.client.client import BlenderMCPClient

async def main():
    async with BlenderMCPClient("http://localhost:8000") as c:
        # Switch to Azure AI Foundry
        print(await c.set_llm_provider(
            provider="azure",
            api_key="YOUR_AZURE_API_KEY",
            model="gpt-4o-mini",
            extra={
                "resource": "my-openai-resource",
                "deployment": "gpt-4o-mini",
                "api_version": "2024-06-01",
            },
        ))
        # Confirm the active config (API key is masked)
        print(await c.get_llm_provider())
        # Use it
        print(await c.ai_prompt("Create a red cube at the origin"))

asyncio.run(main())

What the adapter does with those values — it builds the deployment-scoped request and sends the key in the api-key header:

POST https://my-openai-resource.openai.azure.com/openai/deployments/gpt-4o-mini/chat/completions?api-version=2024-06-01
api-key: YOUR_AZURE_API_KEY
{"model": "gpt-4o-mini", "messages": [...], "stream": false}

Notes:

  • You may omit base_url entirely (the placeholder https://RESOURCE.openai.azure.com is filled in from extra.resource) or pass the full base URL explicitly.
  • If you use an AI Foundry serverless model endpoint (the *.services.ai.azure.com/models surface) instead of a deployment-scoped resource, point provider at the generic OpenAI-compatible adapter with the serverless base URL: provider="openai_compat", base_url="https://<resource>.services.ai.azure.com/models".
  • The same configuration can be applied at startup instead of at runtime:
blender-mcp --llm-provider azure \
  --llm-api-key "$AZURE_API_KEY" \
  --llm-model gpt-4o-mini \
  --llm-extra '{"resource":"my-openai-resource","deployment":"gpt-4o-mini","api_version":"2024-06-01"}'

---

## Client CLI

```bash
blender-mcp-client --host http://localhost:8000 tools
blender-mcp-client --host http://localhost:8000 tool blender_get_scene_info
blender-mcp-client --host http://localhost:8000 tool blender_set_llm_provider '{"provider":"lmstudio"}'
blender-mcp-client --host http://localhost:8000 prompt "Create a metallic sphere at 0,0,2"
blender-mcp-client --host http://localhost:8000 interactive

As a library:

import asyncio
from blender_open_mcp.client.client import BlenderMCPClient

async def main():
    async with BlenderMCPClient("http://localhost:8000") as c:
        print(await c.get_scene_info())
        await c.create_object("SPHERE", location=(0, 0, 2))
        print(await c.ai_prompt("What should I build next?"))

asyncio.run(main())

Provider layer internals

src/blender_open_mcp/llm.py keeps a registry of provider specs and routes every request through one chat helper:

  • OpenAI-style providers post to <base_url>/chat/completions with a Bearer token when an API key is set, and parse choices[0].message.content.
  • Ollama posts to /api/chat natively (or to its /v1/chat/completions surface when the base URL ends in /v1).
  • Azure posts to https://<resource>.openai.azure.com/openai/deployments/<deployment>/chat/completions?api-version=… using the api-key header.
  • Model listing: Ollama /api/tags, others /models (Azure deployments are managed in the portal and not listed).

Add new backends by inserting an entry in PROVIDERS (plus an alias in PROVIDER_ALIASES); nothing else changes.


Development

.venv/Scripts/python -m pytest tests -q

The suites mock bpy (addon tests), httpx (provider/PolyHaven routing), and the MCP client wire format, so they run without Blender or a live LLM.

tests/test_integration.py additionally proves the layers work together:

  • an in-process fastmcp.Client session lists tools/prompts and calls provider tools over the real MCP protocol;
  • the actual addon.py TCP server loop is started on a local port (bpy mocked) and driven through the MCP server's Blender bridge, so blender_get_scene_info and blender_execute_code round-trip over a real socket;
  • a parity test pins every bridge command to a registered addon handler and every blender_* tool to a registered MCP tool.

Notes / known gaps

  • Tests exercise the server without a live Blender; run them against a real Blender session to validate addon.py end to end.
  • See ARCHITECTURE.md for the component diagram and AGENTS.md for contributor conventions.

Files in the repo

Repository payload10 top-level entries
  • client
  • src
  • tests
  • .gitignore
  • addon.py
  • AGENTS.md
  • ARCHITECTURE.md
  • LICENSE
  • pyproject.toml
  • README.md

Discussion (0)

Ask about usage, or say what you built with it

Sign in to join the discussion.

No comments yet. Be the first to say what this is good for.

More connectors

High-performance code intelligence MCP server. Indexes codebases into a persistent knowledge graph — average repo in milliseconds. 158 languages, sub-ms queries, 99% fewer tokens. Single static binary, zero dependencies.

43k

Universal provider proxy for OpenAI Codex & Claude Code — use any LLM (Claude, Gemini, Grok, DeepSeek, Ollama…) with Codex CLI, App, SDK, and Claude Code

14k
okf-memory/
okf-agent-memory

Git-native persistent memory for AI coding agents. Implements Google OKF v0.2 with sub-300µs in-memory BM25 search, embedded MCP server, and progressive disclosure. Slashes token bloat by 80% with zero external databases or dependencies. Built in pure Go.

547
tirth8205/
code-review-graph

Local-first code intelligence graph for MCP and CLI. Builds a persistent map of your codebase so AI coding tools read only what matters, with benchmarked context reductions on reviews and large-repo workflows.

31k
2akouwu/
reverify

Stop your AI from making things up — it proposes, deterministic tools decide, every claim checked against ground truth with evidence. Grounded facts and context survive resets. Reverse engineering is the proving ground. MCP server + CLI.

1.1k
t8y2/dbxConnectors

20 MB lightweight cross-platform database client for 90+ databases, including MySQL, PostgreSQL, SQLite, Redis, MongoDB, DuckDB, SQL Server, and Dameng. Built-in AI, MCP Server, CLI, desktop and Docker. | 轻量级跨平台数据库管理工具,支持 MySQL、PostgreSQL、SQLite、Redis、MongoDB、达梦等 90+ 数据库,提供桌面端、Docker、CLI、内置 AI 助手和 MCP Server。

19k