MCP server reference
More detail on how the MCP server loads tools and what its tools return: which Blender packs to choose, why a newly enabled pack may not appear in your client, the rules each pack carries, and the identifiers Blueprint tools use. For anyone tuning a client's tool list or an agent working with Blueprints.
MCP Server covers installing the server, its settings and the pack list. This page adds what that one leaves out.
Choosing Blender packs
Every Blender workflow pack brings blender_core with it, both at startup and through mif_enable_pack. So MIF_TOOL_PACKS=core,blender_modeling gives a modeling session its own tools plus the Blender basics, without the Unreal ones you do not need.
A selection made only of Blender packs keeps just the six tools that belong to neither backend: mif_help, find_tools, mif_call, mif_enable_pack, mif_list_packs and run_python. The Unreal tools come back with mif_enable_pack('core') or any Unreal pack, and mif_call reaches them in the meantime.
blender still works as a pack name. It loads all the Blender packs, which is what it loaded when they were one pack.
The three default tools
By default the server loads find_tools, mif_call and run_python. find_tools and mif_call search and call every other tool. run_python is the Python escape hatch for Blender and Unreal alike. These three are marked to load without a search, so a client that normally defers MCP tools sends them up front. A client that defers tools and loads a schema when the model searches for one gets only a shorter list of names from a pack selection.
find_tools also searches the tools that are not loaded and names the pack each one is in. When no tool matches the whole query, it returns the tools whose names hold two or more of your words, marked partial.
A new pack may not appear in your client
mif_enable_pack loads a pack's tools and sends the standard tools/list_changed notification. MCP clients do not all refresh the tool list the model sees, and the response reports the notification as delivered but the client refresh as unverified. This was measured with Claude and Codex clients in September 2026. If the new tools remain unavailable:
- Call them through
mif_call(tool, args). It is incoreand reaches every MifBridge tool by name with no refresh. - Or restart the client with the pack named in
MIF_TOOL_PACKS. Restarting without changingMIF_TOOL_PACKSstarts the same selection again, so on its own it never helps.
Each pack has rules
A pack's rules are the mistakes its kind of work makes easily: the call that succeeds with a result that is not what was asked, the unit, the order that matters, the field that does not prove what it seems to. Each rule comes from a confirmed measurement and is checked against the current code.
The rules reach an agent whichever way it came to the pack:
- the pack's prompt,
mif-pack-<name>; - the response of
mif_enable_pack, once per pack; - the response of each tool
mif_callregisters from a pack, which carries the rules that name that tool and those that name none, each once. This is the path for clients that never refresh their tool list; mif_help.
mif_help('<pack>') returns a pack's rules. Every tool's own mif_help answer carries the rules that name it, which is how a session with every tool loaded gets them. The server's MCP instructions tell the agent that tools come in packs and how to reach one.
One serialized Blender socket
The server's Blender connection is a single socket, so a long operation blocks the ones behind it. Two things keep that from locking you out:
bl_statusbounds both its wait for the socket and its wait for the answer, and when the line is busy it says which operation holds it and for how long. The tool you reach for when Blender is wedged is not itself wedged by it.MIF_BLENDER_CONNECT_TIMEOUT(3 seconds by default) sits just above the roughly 2 seconds Windows takes to report a refused loopback connection. A Blender that is not running therefore reports as refused, not as a connect timeout.
The editor reads MIF_BRIDGE_TOKEN and the optional MIF_BRIDGE_PORT from its own process environment at startup, so set the same token on both sides. See Configuration.
Blueprint tools: identifiers and confirmation
Every tool returns the editor's JSON unchanged. A mutation returns the resulting node, pin or variable state, never a bare ok: true. compile and validate return {ok, numErrors, numWarnings, messages: [...]} with each message mapped to its nodeGuid and pinName.
Three identifiers carry through the Blueprint tools:
| Identifier | What it is | Where you get it |
|---|---|---|
blueprintId |
The asset's object path, such as /Game/Props/BP_Crate.BP_Crate |
open_blueprint |
graphId |
<blueprintPath>::<graphName> |
list_graphs and open_blueprint |
nodeGuid |
The GUID the engine gave the node | Every node-creating tool, and list_nodes |
add_variable, create_function and set_pin_type accept reference-type prefixes: class:X, object:X, softobject:X, softclass:X, interface:X and enum:X, plus bare scalar and struct names. Event parameters (inputs on add_custom_event and add_event_dispatcher) are a list of {name, type, container?}.
recipe_add_debug_print calls the engine's PrintString by default. It is development-only, so a Shipping build compiles it out. Pass functionName to call a function on the Blueprint itself instead, which is created on the fly if it is missing.
Destructive operations such as remove_node, remove_variable and rename_variable require confirm=true, and describe_endpoint lists confirm for each endpoint that takes it. Transacted edits undo with Ctrl-Z in the editor. Saves, cooks, Play-In-Editor, compiles and console commands are not transactions. See Safety and Write Modes.
A quick check that the editor answers
With the editor open and the bridge running:
curl -s -X POST http://127.0.0.1:8791/api/list_blueprints \
-H "X-Mif-Token: dev" -H "Content-Type: application/json" \
-d '{"filter":"BP_"}'