Guide · MCP
MCP Setup Guide
Connect AiArtEngine to Claude Code and other AI agents: the app ships a local
MCP tool service, so agents can plan workflows, edit graphs, run generation and track
tasks by conversation — the "product as an agent tool" experience, fully local with no
cloud account authorization. The built-in AI chat panel (the “◈” button on the
left of the workspace) runs on this same tool surface: @-reference assets in chat and
let the assistant call the tools below directly.
1. What is MCP
MCP (Model Context Protocol) is the standard protocol for AI agents to call external tools. Once connected, your coding agent gains a set of "AiArtEngine tools" and can drive the app through conversation:
Claude Code / Codex ──stdio(MCP)──▶ mcp-bridge.mjs ──HTTP──▶ AiArtEngine app (127.0.0.1 tool service)
- On startup the app serves a token-protected tool service on
127.0.0.1and writes connection info to%APPDATA%/aiartengine/mcp.json(macOS / Linux paths below). The file persists across restarts and the token stays stable — configure clients once; you can also edit the token in the app under Settings → MCP. - The bridge
scripts/mcp-bridge.mjsis dependency-free: the agent client spawns it, and it translates the protocol and forwards calls. - Communication stays on the loopback interface; everything except the health check requires the token.
workflow_plan-style tools rely on a text model configured in the app.
2. Connect Claude Code in 3 steps (choose one of two)
Option A: stdio bridge (recommended)
- Start the AiArtEngine desktop app.
-
Register the MCP server (the bridge lives in the repository — adjust the path):
or write it into your MCP config file manually:claude mcp add aiartengine -- node C:/path/to/ai-art-engine/scripts/mcp-bridge.mjs{ "mcpServers": { "aiartengine": { "command": "node", "args": ["C:/path/to/ai-art-engine/scripts/mcp-bridge.mjs"] } } } - Restart the agent session and the tools are ready. Other MCP-capable clients (Codex, Trae, …) use the same "command + args" configuration.
Option B: HTTP direct (no Node.js required)
Clients that support streamable HTTP can skip the bridge. The token lives in mcp.json (persisted):
claude mcp add --transport http aiartengine http://127.0.0.1:43110/mcp --header "Authorization: Bearer <token>"
Config template (.mcp.json)
.mcp.json is optional and must be created manually (nothing
generates it for you) — create a text file named .mcp.json, fill in the template below, and
place it in the root of the project where you run Claude Code. Commit it and your team
gets it on clone.
claude mcp add aiartengine -- node C:/path/to/ai-art-engine/scripts/mcp-bridge.mjs and
Claude Code writes the config to ~/.claude.json automatically. Pick either way — no need to
do both.
stdio bridge variant (adjust the path):
{
"mcpServers": {
"aiartengine": {
"command": "node",
"args": ["C:/path/to/ai-art-engine/scripts/mcp-bridge.mjs"],
"env": {
"AIAE_MCP_CONFIG": "C:/Users/<you>/AppData/Roaming/aiartengine/mcp.json"
}
}
}
}
HTTP direct variant (no Node.js required — token from the app-side mcp.json):
{
"mcpServers": {
"aiartengine": {
"type": "http",
"url": "http://127.0.0.1:43110/mcp",
"headers": {
"Authorization": "Bearer <token from the app-side mcp.json>"
}
}
}
}
%APPDATA%/aiartengine/mcp.json, structured
{ "port": 43110, "token": "…", "pid": …, "version": "…" }) is written and removed by the
app automatically — do not edit it by hand. The token is reused across restarts; delete
the file and restart the app to reset it.
3. Tool reference
| Group | Tool | Purpose |
|---|---|---|
| Projects & assets | app_status |
App version, current project, asset count |
project_list / project_open / project_create |
Recent projects, open, create | |
asset_list / asset_read_file |
List assets, read files inside the project | |
asset_write_text |
Update text assets (scripts / notes; synced to the UI) | |
folder_create |
Create a library folder, returns folderId |
|
asset_create |
Create an asset (script / game design doc / world / storyboard / canvas / image / video / voice / 2D action) | |
asset_import |
Import local files by absolute path (image / video / audio / text, up to 50 per call) | |
asset_rename |
Rename an asset (synced to the UI) | |
asset_move |
Move an asset between library folders (media files move with it) | |
asset_delete |
Remove an asset from the library (refuses when still referenced) | |
folder_list |
Library folders (source of folderId for generation tools) | |
| Delivery & post | transcribe_audio |
Transcribe audio / video into timestamped segments (subtitle draft) |
audio_separate |
Separate vocals / instrumental (outputs under Cache/Separated/) |
|
storage_upload |
Upload project media to object storage, returns a shareable URL | |
asset_package_export |
Export a .aipackage delivery pack (headless calls pass an absolute path) |
|
asset_package_import |
Import a .aipackage pack (optionally a guid subset) |
|
stage2d_spine_export |
Export a 2D stage rig as a Spine skeleton pack (part pages + skeleton.json + .atlas) | |
asset_qc |
Engine-readiness check for image assets (holes / fringe / debris / edge clipping / size / naming, read-only) | |
asset_qc_fix |
Edge decontamination rework into a new asset, with before/after metrics | |
timeline_read |
Read the timeline: clips / settings / total duration, filterable by track | |
timeline_rough_cut |
Smart rough cut: squeeze silences out by transcript and ripple the whole sequence, plan-only by default | |
timeline_export |
Render the timeline to MP4 (transitions / mixing / burned-in subtitles / watermark) | |
timeline_edit |
Edit the timeline: lay media on tracks / adjust volume, transitions, subtitle text / remove clips / rebuild subtitles from a transcript | |
timeline_preview |
See the picture: frames captured from the same filter graph as the export, returned to multimodal clients | |
| Planning & execution | workflow_list_presets |
The 12 industry templates (id + title) |
workflow_plan |
Natural language → graph plan (uses the app's configured text model) | |
workflow_commit |
Persist a plan as a host asset (appears in the UI) | |
task_run / task_status |
Run a persisted workflow and poll its execution state | |
graph_node_types |
Addable node types (typeId / label / ports / default params; the graph_edit whitelist) | |
graph_read |
Read a host asset graph structure (ids / edges; prerequisite of graph_edit) | |
| Generation | generate_image |
Text-to-image / image-to-image, saved as a project asset |
generate_video |
Submit video generation as an asset (track via video_job_*) |
|
generate_model3d |
Text/image-to-3D producing a GLB asset | |
decide |
Ask an OpenRouter decision model typed questions about a given state (noul yes/no, choice one-of, score on an ordered scale) and get branchable, probability-carrying verdicts; the three primitives can be mixed in one request and nothing is written to disk | |
| Editing & queries | graph_edit |
Apply node / edge edit batches to a host asset graph (validated in-app) |
graph_icon_refine |
Redraw a single icon, write it back as a per-cell override, then re-run packing (same pipeline as the dialog; the run shows up in the task list and as a spinner on the asset card) | |
models_list |
Enabled providers and per-modality models (incl. OpenRouter decisions models; no secrets) |
|
video_job_list / video_job_get |
Async video task status |
4. Example conversations
Once connected, just give natural-language instructions — the agent combines the tools:
- "List my recent projects and open the first one" →
project_list+project_open - "Plan a workflow from the shortDrama template and save it" →
workflow_plan(presetId=shortDrama) +workflow_commit - "Run the workflow I just created and report back" →
task_run+task_statuspolling - "Add a voice node under this image node and wire it" →
graph_edit(node_upsert + edge_connect) - "What nodes can this graph take? Which type packs icons?" →
graph_node_types(typeId + ports + default params) - "Icon #3 in the pack looks blurry — redraw just that one" →
graph_icon_refine(cellKey + hint; writes back and re-packs) - "Generate a 9:16 poster with my configured model" →
models_list+generate_image
5. Configuration & environment
The bridge reads %APPDATA%/aiartengine/mcp.json by default (macOS:
~/Library/Application Support/aiartengine/; Linux:
~/.config/aiartengine/). To override:
| Environment variable | Purpose |
|---|---|
AIAE_MCP_CONFIG |
Absolute path to mcp.json |
AIAE_MCP_PORT + AIAE_MCP_TOKEN |
Connect directly with a given port and token (overrides the file) |
The app tries ports 43110–43119 in order and skips occupied ones; the actual
port is whatever mcp.json contains.
5.1 stdio bridge settings
Settings → MCP tool server → stdio bridge tab visualizes the
bridge config — no env vars to hand-edit. You can set: the bridge command
(default is still node + the in-repo scripts/mcp-bridge.mjs or the
installer's bundled <install dir>/resources/mcp-bridge.mjs), the
bridge port (default HTTP port the bridge listens on), the
BLENDER_HOST / BLENDER_PORT passthrough for the Blender addon.
Changes persist immediately; external agents just reconnect — no app
restart needed.
scripts/mcp-bridge.mjs; installers bundle one at
<install dir>/resources/mcp-bridge.mjs. The same panel also lets you register
multiple external stdio server entries (see
§5.2 Reverse bridge); they share the same config store as the
Blender stdio bridge.
5.2 Reverse bridge: let dsh (in-app chat panel) connect to stdio MCP servers
The "forward bridge" brings Claude Code and other external agents in via stdio bridge or HTTP.
The reverse bridge goes the other way — the in-app ◈ AI chat panel (DeepSeek
Harness / dsh) can also register and consume any external stdio MCP server
(not limited to its own /mcp endpoint).
Typical scenario: the Blender addon or any other stdio-only MCP server no longer needs to expose a
separate socket port; once dsh registers a claude mcp add --transport stdio ...-style
command, "use Blender to assemble this and screenshot it" in the conversation drives the addon
directly. Configuration lives in the same settings panel —
MCP tool server → stdio bridge tab — and supports multiple external stdio
servers (each with name / command / working dir / env); they share the same store as the Blender
stdio bridge.
Protocol details:
- The reverse bridge forks a stdio subprocess inside the dsh process, translates MCP frames and reuses the existing mcp-client instance — no separate bridge process
-
Protocol errors and subprocess crashes share the same audit log
(
<userData>/logs/mcp-audit.jsonl) as the forward bridge -
Local only, with token auth; external stdio servers do not automatically gain write
access to the app's
/mcpendpoint - Ask / Plan modes also keep reverse-bridge tools read-only — they aren't a side door around panel mode
6. Security & limitations
- The service listens on
127.0.0.1only, with token auth; file access is confined to the project root (the single exception isasset_import, which reads absolute paths you pass in and copies them into the project); secrets are never exposed. - Concurrency gate:
generate_image/generate_speech/decide/workflow_planrun at most 3 concurrently (AIAE_MCP_GEN_LIMITtunable); excess queue is rejected with a friendly error. - Audit trail: every tool call is appended to
<userData>/logs/mcp-audit.jsonl(args truncated, 5MB rotation) so generation and writes can be audited. graph_edit/graph_icon_refinerefuse graphs that are currently open in an editor to avoid clobbering in-memory state.workflow_planruns an LLM and may take tens of seconds;generate_video/generate_model3dare async — track them withvideo_job_*.- Two connection options: the stdio bridge (bundled in installers at
<install dir>/resources/mcp-bridge.mjs; for development use the in-reposcripts/mcp-bridge.mjs, Node.js 18+ required) or HTTP direct (no Node.js needed).
7. Blender tools (advanced)
These tools are not part of the main /mcp toolset — they live on a sibling
endpoint /mcp/blender on the same service (enabled by default in
Settings → MCP → Blender tools; the endpoint returns 403 if you turn it off, and the
main toolset is unaffected).
Let AI drive Blender directly — build scenes, write bpy code, screenshot for self-check,
export GLB / GLTF / FBX into your project. The app makes an outbound socket to the
addon's localhost:9876 — no uv, no Python subprocess, no Blender config tweaks.
Prerequisites
-
Blender is running with an MCP addon enabled (pick the matching type in
Settings → MCP → Blender tools — the two wire protocols are incompatible; mismatch shows up as a
connect timeout or "connection reset"):
-
Community (default):
blender-mcp's
addon.py, installed underEdit → Preferences → Add-ons - Official: the Blender Lab "MCP Server" extension on the Blender Extensions platform — start the service in the extension's preferences
-
Community (default):
blender-mcp's
- Both addons listen on
9876by default; if you change it, update the port in Settings. -
External agents need a second MCP server registered to reach these tools
(
<token>from the app-sidemcp.json):claude mcp add --transport http blender http://127.0.0.1:43110/mcp/blender --header "Authorization: Bearer <token>"The in-app ◈ AI chat panel wires it automatically (dsh registers a second mcp-client instance), so just say "use Blender …" in the conversation.
Tool reference
Tool names, schemas and outputs are identical across both addons — the model side doesn't care which is running:
| Tool | What it does | Prerequisite |
|---|---|---|
get_scene_info |
Scene overview: scene name, object / material counts, name · type · location of the first few objects | Blender running |
get_world_state_snapshot |
Full snapshot: geometry / relations / animation summary, current frame & frame range, FPS, selection, active camera & lights | Blender running |
get_object_info |
Single-object detail (mesh objects include vert / edge / face count and world bounding box) | Blender running |
get_viewport_screenshot |
3D viewport screenshot, returned to multimodal clients in-band (offscreen capture, fallback to window grab) | Blender UI visible |
execute_blender_code |
Run Python inside the Blender process (full bpy access); print returns verbatim; errors carry exception type & traceback |
Blender running |
export_scene |
Export the scene (or selection / named objects) to glb / gltf / fbx / obj / usd / stl — chain with asset_import to land in the asset library |
Blender running |
describe_node_type |
Look up a node type (e.g. ShaderNodeTexImage): sockets and settable properties — call this before writing shader / geometry-node scripts |
Blender running |
bpy_api_lookup |
Look up bpy API in the running Blender (operators / types / properties / functions) — names and defaults come from live RNA | Blender running |
get_addon_status |
Addon version / protocol version / capability list / Blender version — tells you whether "can't connect" means disabled, version mismatch, or Blender not running | Blender running |
Typical loop
get_scene_info Inspect state
↓
execute_blender_code Write bpy: model / material / camera
↓
get_viewport_screenshot Self-check the viewport (multimodal client sees the image)
↓
export_scene Export GLB / GLTF / FBX …
↓
asset_import Land it in the asset library
execute_blender_code steps and parameters — iterate from the screenshot if it's not right.
Safety rails
-
execute_blender_codeno longer applies a lexical code guard: full Python / bpy is allowed (includingclass/lambda/open, etc.). The real write backstop is the §6 mode constraint — Ask / Plan make the whole group read-only, and write calls are rejected. -
Screenshots go through a one-shot temp file:
get_viewport_screenshotwrites to a system temp file the app reads and deletes immediately; the image is returned only in-band to multimodal clients and never touches the project or the audit log. -
Mode is bound to the request, not the client: the Blender endpoint shares the
service's token; Ask / Plan flow through
X-AIArt-Mode/X-AIArt-Run-Id. Ask returns nothing; Plan returns only the read-only tools (get_scene_info/get_world_state_snapshot/get_object_info/get_viewport_screenshot/describe_node_type/bpy_api_lookup/get_addon_status);execute_blender_codeandexport_scenecount as write and are rejected + audited. -
The addon is a socket server: close Blender and the whole group fails
(the error explicitly says "can't connect to addon", not a vague timeout). The app
does not launch Blender and has no headless mode —
get_viewport_screenshoteven requires the window to be visible (minimized captures fail and fall back to the window grab). Connection state refreshes every 4 seconds in the Settings panel;get_addon_statuschecks versions on demand.