maya-mcp
maya-mcp lets Claude control a live Autodesk Maya session in natural language — building, animating, importing and rendering 3D scenes, with RAG doc search, safety scanning, and optional AI 3D generation.
Primitives & assets: create cubes/spheres/cylinders/cones/planes/torus, assign materials (lambert/blinn/phong/aiStandardSurface), create lights and cameras.
Modeling: transform (move/rotate/scale, world or relative), extrude, bevel, booleans, combine, separate, smooth.
Animation: keyframe any attribute (translate/rotate/scale/visibility) with tangent control (auto/linear/flat/spline/step).
I/O: import OBJ, FBX, GLB/GLTF, Alembic, MA/MB and BVH mocap; reference files with version swap, load/unload lifecycle.
Rendering & review: instant viewport PNG/JPG grabs, Arnold ray-traced stills via out-of-process kick, deterministic colour-managed 360° turntable playblasts.
Session & scripting: ping/launch Maya, new/save scene, list objects, scene snapshot, delete, run arbitrary Python, create shelf buttons.
Pipeline integration: drive the native ShotGrid Toolkit publisher (preview/publish), read an opt-in durable audit log.
Knowledge engine: hybrid RAG search across maya.cmds, PyMEL, Arnold, USD and anti-patterns corpora; save learned patterns; report token/RAG efficiency stats.
Optional AI generation: Vision3D image-to-3D and text-to-3D, AI texturing, poll/download/import results; World Labs Marble image-to-Gaussian-splat environments converted and loaded for Arnold.
Safety: 14+ dangerous-pattern detectors before code reaches Maya, undo chunks for rollback, and model trust gates on knowledge writes.
Provides tools for creating, manipulating, and managing 3D scenes in Autodesk Maya, including primitive creation, material assignment, transformations, lighting, cameras, mesh operations, keyframing, file import, viewport capture, session management, and more.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@maya-mcp create a red sphere and a blue cube"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
maya-mcp
Control Autodesk Maya with natural language using Claude and the Model Context Protocol (MCP)
Experimental project — use at your own risk. This is an independent, unofficial experiment created with Claude Code. It is not affiliated with, endorsed by, or officially supported by Autodesk in any way. The Maya name and trademarks belong to Autodesk, Inc.
Executing AI-generated code inside a live Maya session carries real risks: unexpected crashes, loss of unsaved work, unintended modifications to scenes, rigs, or assets. Always work on a duplicate or test scene. Never run this on production material without a full backup. The author(s) accept no responsibility for data loss, corruption, or any other damage resulting from its use.
📊 Code knowledge graph
Interactive, auto-published map of this codebase — modules, functions, call/import edges and community clusters — rebuilt by graphify and deployed to GitHub Pages on every push to src/:
abrahamadsk.github.io/maya-mcp · part of the MCP ecosystem graph hub.
MCP server for Autodesk Maya — 17 MCP tools with RAG-powered documentation search, anti-hallucination safety, self-learning patterns, and optional AI-driven 3D generation via the Vision3D addon.
Related MCP server: Maya MCP
Features
Production Maya Operations
Beyond primitives, maya-mcp handles real production tasks: polygon modeling (extrude, bevel, boolean, combine, smooth), animation keyframing with tangent control, multi-format I/O (OBJ, FBX, GLTF, Alembic, USD, MA/MB), viewport capture/playblast, full scene snapshots, and shelf button creation. All operations use undo chunks for safe rollback.
AI-Powered 3D Generation (optional addon)
Optionally integrates with Vision3D for image-to-3D and text-to-3D generation. Non-blocking async workflow: submit job → poll status → download results → import into Maya. Runs on a remote GPU server so your local machine stays responsive. Vision3D is not required — maya-mcp works fully without it.
Embedded Maya Console Panel
A dockable Qt panel that lives inside Maya as a workspaceControl tab (next to the Attribute Editor). Provides a chat interface to Claude with live Maya context (scene name, object count, selection, renderer). Installs automatically — the first time Claude connects to Maya (via maya_ping or maya_launch), the MCP Pipeline menu and panel are injected into the running Maya session. No manual userSetup.py editing required. The panel persists across Maya sessions — if left open, it auto-restores on next launch. Uses PySide2 (Maya 2023–2024) or PySide6 (Maya 2025+) automatically via a compatibility shim. All MCP servers (maya-mcp, fpt-mcp, flame-mcp) are accessible from the panel through Claude Code CLI.
Cross-MCP Orchestration
Works alongside fpt-mcp (ShotGrid/Flow Production Tracking) and flame-mcp (Autodesk Flame). Each DCC has its own embedded console, and all consoles access all MCP servers via Claude Code CLI. When multiple servers are configured, Claude can orchestrate end-to-end VFX workflows across applications. Consistent architecture across all three servers.
Review & Colour Management
Review previews are colour-correct and deterministic. The Viewport 2.0 capture paths (review_turntable, maya_viewport_capture) pin the colour-management view transform before the playblast and restore it after, so a version preview matches the viewport instead of riding the session's current view. The view is configurable (config.json → review_view_transform, default Un-tone-mapped (sRGB) — the view of Maya's built-in default OCIO config). For Arnold file renders, color_policy.py (and docs/ARNOLD_API.md) provide a preview-vs-EXR policy: bake the output transform for an 8-bit preview, but force the driver to Raw for scene-linear EXRs — the guardrail that keeps a display transform out of the EXRs the comp/Flame stage consumes.
Architecture
Claude / LLM
↕ MCP protocol (stdio)
FastMCP server (src/maya_mcp/server.py) — 17 MCP tools
├── RAG engine (src/maya_mcp/rag/)
│ ├── ChromaDB + BM25 hybrid search
│ ├── HyDE adaptive query expansion
│ └── In-session cache + RRF fusion
├── Safety module (src/maya_mcp/safety.py)
│ └── 14+ dangerous pattern detectors
├── Maya bridge (src/maya_mcp/maya_bridge.py)
│ └── TCP socket → Command Port :8100
└── Vision3D client (HTTP)
└── GPU server for 3D generationTools (17 MCP tools)
Maya Direct Tools (10 tools)
Tool | Description |
| Create cube / sphere / cylinder / cone / plane / torus |
| Create and assign material (lambert / blinn / phong / aiStandardSurface) |
| Move / rotate / scale with world/object space and relative mode |
| Create directional / point / spot / area / ambient lights |
| Create cameras with focal length and look-at target |
| Extrude, bevel, boolean (union/diff/intersect), combine, separate, smooth |
| Keyframe any attribute with tangent control (auto/linear/flat/spline/step) |
| Import OBJ, FBX, GLB/GLTF, Alembic, MA/MB, BVH mocap with namespace and scale (streams progress; 120s budget for heavy assets, 240s for BVH) |
| Reference files and manage the reference lifecycle: create, list, replace (version swap), load, unload. Keeps the live link to the source file that |
| Playblast screenshot to PNG/JPG at any resolution |
Dispatcher Tools (3 tools)
Tool | Description |
| Session lifecycle + generic Maya ops (see action table below) |
| Optional Vision3D addon (see action table below) |
| Optional World Labs (Marble) addon — image→Gaussian-splat environment, convert + load into Maya for Arnold (see action table below) |
RAG & Intelligence (4 tools)
Tool | Description |
| Hybrid RAG search across 5 Maya API corpora with relevance scores |
| Save validated working patterns for future sessions (with trust gates) |
| Token efficiency report: RAG savings, safety blocks, patterns learned, p_fallo |
| Zero the session counters immediately (manual companion to the 30-min idle auto-reset) |
Maya Session Dispatcher (maya_session — 12 actions)
Action | Description |
| Verify connection, returns Maya version and scene info |
| Open Maya and wait for Command Port to respond (streams progress while waiting) |
| New empty scene (refuses if the scene has unsaved changes; pass confirm=true to discard them) |
| Save current scene |
| List scene objects with type and name filters |
| Full scene state: file, renderer, object counts, plugins, units |
| Delete objects with safety checks on wildcards |
| Execute arbitrary Python in Maya (safety scanning; optional timeout param up to 600s with 10s progress heartbeats) |
| Create reusable shelf buttons with custom Python commands |
| Read recent durable-audit records (read-only; requires MAYA_AUDIT_LOG=1). Optional filters: limit, tool, action, status |
| Drive the native Toolkit publisher (tk-multi-publish2) inside an engine'd Maya launched via tank. mode preview/publish, include/exclude intent tokens, comment, timeout. Captures dependencies automatically. |
| Deterministic Viewport 2.0 turntable playblast to a .mov (long op, runs in Maya). Frames the model, orbits 360° over start–end at the given fps, 16:9 / square pixels / overscan, offscreen (never Arnold), colour-managed (the review view transform is pinned and restored so the preview matches the viewport). Needs out_path (resolve via fpt tk_resolve_path, template movie_asset_publish); returns the mov plus a Version code Asset_Task to name the review Version after its task. |
| Single-frame Arnold ray-traced still to a PNG at the exact out_path (long op). This is what "a still" means — a real render, not the Viewport 2.0 grab that maya_viewport_capture does. Maya only exports a |
Vision3D Dispatcher (maya_vision3d — 7 actions, optional, requires Vision3D)
Action | Description |
| Set the Vision3D server URL for the rest of this MCP session (runtime-only, asked from the user in the chat) |
| Check availability and model status of the selected server |
| Image-to-3D generation (full pipeline) |
| Text-to-3D generation |
| Texture an existing mesh with AI |
| Poll async job status |
| Download completed results to local disk |
Skills (3)
Tools are what the server can do. Skills are the recipe — which tools, in
what order, and what fails silently. They live in docs/skills/,
version controlled with the code they describe, and load only when the request
matches their trigger, so they cost almost nothing until they are relevant.
Skill | Fires on |
| Heavy or crash-prone work that should leave the Command Port: batch renders, cache export/import, multi-file sweeps |
| References — create/replace/version-swap, namespaces, deferred refs, and the save-after-scripted-open trap |
| Retarget and character animation: HumanIK, mocap/BVH, cycles and loops, reach semantics |
Activate them on a fresh clone by symlinking into your user skills directory:
for s in maya-headless-batch maya-scene-assembly maya-anim-transfer; do
ln -s "$PWD/docs/skills/$s" ~/.claude/skills/"$s"
doneSee docs/skills/README.md for the four-layer split
(tool / skill / RAG / memory) and why they are not under .claude/.
RAG — Knowledge Engine
Architecture
LLMs hallucinate Maya API details constantly — wrong flag names (width= instead of w=), nonexistent commands (cmds.usdExport instead of cmds.mayaUSDExport), incorrect return types. maya-mcp includes a hybrid RAG engine (ChromaDB semantic + BM25 lexical, fused via Reciprocal Rank Fusion) with 5 curated documentation corpora covering maya.cmds, PyMEL, Arnold/mtoa, Maya-USD, and a comprehensive anti-patterns database. The LLM calls search_maya_docs before writing any unfamiliar code, getting verified syntax with relevance scores.
HyDE Query Expansion
Short queries like "set keyframe tangent" don't match code-heavy documentation well. maya-mcp uses Hypothetical Document Embedding (HyDE) — it detects which Maya API domain the query targets (cmds, PyMEL, Arnold, USD, MEL) and wraps the query in a domain-specific code template before embedding. This bridges the gap between natural-language questions and code documentation.
Dangerous Pattern Detection
Before any code reaches Maya, the safety module scans for 14+ dangerous patterns: bulk deletes without filters, undo system tampering, filesystem operations on scene files, plugin deregistration with active nodes, namespace deletions, referenced geometry modification, and more. Each pattern includes an explanation of WHY it is dangerous and a SAFE alternative.
Self-Learning
When the RAG returns low-relevance results (< 60%) but the operation succeeds, the LLM can call learn_pattern to save the working pattern for future sessions. Model trust gates ensure only Opus/Fable can write directly to docs — other models stage candidates for human review. Knowledge grows over time without manual curation.
Token Tracking
Every tool call tracks tokens in/out. The session_stats tool reports how much context was saved by RAG vs loading full documentation, making the efficiency gains measurable and visible.
Project Structure
maya-mcp/
├── src/
│ └── maya_mcp/
│ ├── __init__.py
│ ├── __main__.py
│ ├── server.py # FastMCP server — 17 MCP tools
│ ├── maya_bridge.py # TCP bridge → Maya Command Port :8100
│ ├── safety.py # Dangerous pattern detection (14+ patterns)
│ ├── config.example.json
│ ├── rag/
│ │ ├── config.py # Embedding model, search params, token tracking
│ │ ├── build_index.py # Chunk docs → ChromaDB + BM25 corpus
│ │ ├── search.py # Hybrid search: BM25 + semantic + HyDE + RRF
│ │ ├── index/ # ChromaDB persistent index (auto-generated)
│ │ └── corpus.json # BM25 corpus (auto-generated)
│ └── docs/
│ ├── CMDS_API.md # maya.cmds reference (commands, flags, patterns)
│ ├── PYMEL_API.md # PyMEL object-oriented API reference
│ ├── ARNOLD_API.md # Arnold/mtoa shaders, AOVs, render settings
│ ├── USD_API.md # Maya-USD import/export, proxy shapes, pxr API
│ └── ANTI_PATTERNS.md # Common LLM hallucinations + wrong flag names
├── docs/
│ └── skills/ # Claude Code skills (symlinked into ~/.claude/skills/)
│ ├── maya-headless-batch/ # mayapy/kick out-of-process work + runner template
│ ├── maya-scene-assembly/ # references, namespaces, version swaps
│ └── maya-anim-transfer/ # HumanIK retarget, cycles, reach semantics
│
├── console/ # Qt console — Maya panel + legacy standalone
│ ├── qt_compat.py # PySide2 (Maya 2023-2024) / PySide6 (2025+) shim
│ ├── maya_panel.py # Dockable workspaceControl panel for Maya
│ ├── chat_widget.py # Reusable MCPChatWidget (shared by panel & standalone)
│ ├── claude_worker.py # QThread worker — Claude CLI subprocess bridge
│ ├── server_panel.py # MCP server discovery, health checks, ServerStatusBar
│ ├── userSetup_snippet.py # Paste into Maya's userSetup.py for auto-setup
│ ├── app.py # Legacy standalone entry point (use fpt-mcp console)
│ ├── chat_window.py # Legacy standalone chat window
│ └── build_app_bundle.py # Legacy macOS .app bundle generator
│
├── tests/
├── pyproject.toml # Build config, entry point: python -m maya_mcp.server
├── reference/ # Pipeline I/O (git-ignored)
├── CLAUDE.md # Project documentation for Claude
├── WORKFLOW_GUIDE.md # Workflow guide
├── .env.example # Configuration template
└── README.mdRequirements
macOS
Autodesk Maya 2023 or later
Python 3.13 or higher (ships with Maya 2027)
Node.js v22 or higher (required by Claude Code)
Claude Code 2.x
A Claude account — Pro, Max, or API key
Optional
Ollama >= 0.17.6 — for local / free inference instead of Anthropic cloud
macOS:
brew install ollama && brew services start ollamaLinux: https://ollama.com/download/linux (systemd)
Verify:
ollama --versionCreate the
qwen3.5-mcpmodel (required for Ollama backends):ollama pull qwen3.5:9b cat > /tmp/Modelfile.qwen35mcp <<'EOF' FROM qwen3.5:9b PARAMETER num_ctx 16384 PARAMETER temperature 0.7 PARAMETER top_p 0.8 PARAMETER top_k 20 EOF ollama create qwen3.5-mcp -f /tmp/Modelfile.qwen35mcpSee MODEL_STRATEGY.md for the full rationale (num_ctx bump,
think: falserequirement, KEEP_ALIVE tuning, KV-cache dtype)
Vision3D server for AI-powered 3D generation
Installation
Automatic Installation
git clone https://github.com/abrahamADSK/maya-mcp.git
cd maya-mcp
chmod +x install.sh
./install.shThe installer creates a virtual environment, installs dependencies, builds the RAG index, and registers the MCP server with Claude Code.
1. Clone and configure
git clone https://github.com/abrahamADSK/maya-mcp.git
cd maya-mcp
cp .env.example .env
# Optional: set GPU_API_URL as a *suggested default* for Vision3D.
# It is never auto-selected — Claude will surface it when asking you
# which Vision3D URL to use, and you have to confirm it explicitly.
# Example: GPU_API_URL=http://<your-gpu-host>:80002. Install dependencies
python3 -m venv .venv
source .venv/bin/activate
pip install -e .
# RAG dependencies (optional but recommended)
pip install chromadb sentence-transformers rank-bm253. Build the RAG index
python -m maya_mcp.rag.build_indexFirst run downloads the embedding model (~570 MB, cached afterwards). The index is stored in src/maya_mcp/rag/index/ and can be committed to git.
4. Set up Maya Command Port — automatic
install.sh does this for you. Step 7 of the installer detects every Maya version installed on the host, locates each version's user scripts dir, and writes an idempotent guarded block into userSetup.py that:
Adds the maya-mcp repo root to
sys.pathOpens the Command Port on
MAYA_PORT(from.env, default8100) bound tolocalhostusingsourceType='mel'with thename=kwarg form (the localhost bind keeps the port reachable only from this host — an all-interfaces bind would expose an unauthenticated arbitrary-code-execution port to the LAN; Maya 2027 also silently ignores the positional form whensourceTypeis specified)Registers the MCP Pipeline menu via
executeDeferred
The block is bounded by sentinel markers and reruns of install.sh are safe — the installer replaces the whole region when the markers are found.
Run ./install.sh --doctor after install to verify userSetup.py was written for every detected version (plus 4 other install-completeness checks).
Port 8100 default rationale: maya-mcp historically used port 7001, the Maya commandPort convention. On hosts with Autodesk Flame installed, port 7001 is already held by Flame's S+W Service Discovery and S+W Probe Server, and connections silently succeed against Flame instead of Maya — producing empty responses that the bridge (prior to v1.4.2) misinterpreted as successful no-ops. The default was moved to 8100 to coexist with Flame. Override via
MAYA_PORTin.envif your environment still uses 7001.
The MCP Pipeline Console panel installs itself automatically. The first time Claude connects to Maya (via maya_ping or maya_launch), the server injects the panel menu and UI through the Command Port. The panel docks next to the Attribute Editor and persists across sessions.
Add to your Maya userSetup.py:
Windows:
%USERPROFILE%/Documents/maya/<version>/scripts/userSetup.pymacOS:
~/Library/Preferences/Autodesk/maya/<version>/scripts/userSetup.pyLinux:
~/maya/<version>/scripts/userSetup.py
# --- MCP Pipeline Console auto-setup ---
import sys as _mcp_sys
_mcp_root = r"/path/to/maya-mcp" # replace with your clone path
if _mcp_root not in _mcp_sys.path:
_mcp_sys.path.insert(0, _mcp_root)
import maya.utils as _mcp_utils
def _mcp_open_command_port():
try:
import maya.cmds as _mc
# Bind to localhost: an all-interfaces (":8100") bind exposes an
# unauthenticated arbitrary-code-execution port to the whole LAN.
if not _mc.commandPort("localhost:8100", query=True):
_mc.commandPort(name="localhost:8100", sourceType="mel")
except Exception:
pass
def _mcp_menu_startup():
try:
from console.maya_panel import install_menu
import maya.cmds as _mc
if not _mc.menu("mcpPipelineMenu", exists=True):
install_menu()
except Exception:
pass
_mcp_utils.executeDeferred(_mcp_open_command_port)
_mcp_utils.executeDeferred(_mcp_menu_startup)
# --- end MCP Pipeline Console ---5. Configure Claude Code
claude mcp add maya-mcp -s user -- /path/to/maya-mcp/.venv/bin/python -m maya_mcp.serverOr for Claude Desktop, add to ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"maya-mcp": {
"command": "/path/to/maya-mcp/.venv/bin/python",
"args": ["-m", "maya_mcp.server"],
"cwd": "/path/to/maya-mcp",
"env": {
"GPU_API_URL": "http://your-gpu-host:8000",
"GPU_API_KEY": "your-api-key-here"
}
}
}
}6. Vision3D addon (optional — for AI 3D generation)
maya-mcp can optionally integrate with Vision3D for image-to-3D and text-to-3D generation. This is not required for core Maya functionality.
Vision3D URL is never stored. maya-mcp does not hold any Vision3D endpoint in config files, environment presets, or hardcoded defaults. On the first Vision3D call of each MCP session:
The dispatch returns
vision3d_url_required.Claude asks you in the chat which Vision3D URL to use.
You type the URL (e.g. a local Mac MPS instance or a remote CUDA host).
Claude calls
maya_vision3d(action="select_server", params={"url": "<the-url>"}).The URL is cached in the MCP process memory until restart and used for every subsequent call of the session.
You can switch servers mid-session by calling select_server again with a different URL. No restart required.
Suggested default via GPU_API_URL — if the environment variable GPU_API_URL is set, Claude surfaces it to you as a suggested default when asking for the URL. You still have to confirm or override it explicitly; it is never auto-selected. This is the only escape hatch for pre-selector installs. GPU_API_KEY is only needed if your Vision3D server has an API key configured.
Usage
Once installed, maya-mcp is available through Claude Code or any MCP-compatible client. Open Maya, ensure the Command Port is running, and start a conversation:
You: "Create a 2x2 grid of spheres with 0.5 unit spacing"
Claude → maya_create_primitive (sphere) × 4 → maya_transform (position each) → ResultYou: "Generate a 3D model from this reference image and import it"
Claude → maya_vision3d(action='generate_image', ...) → maya_vision3d(action='poll', ...) → maya_vision3d(action='download', ...) → maya_import_file → ResultAll operations go through the safety scanner before reaching Maya. Dangerous patterns are blocked with an explanation and a safe alternative.
Configuration Reference
Variable | Description | Default |
| Maya host |
|
| Maya Command Port |
|
| Optional suggested default for the Vision3D URL prompt. Never auto-selected — Claude asks the user to confirm or override at the first Vision3D call of each session. | — |
| Vision3D API key | — |
| Verify TLS certificates for |
|
| Shape generation timeout (seconds) |
|
| Texture generation timeout (seconds) |
|
| Opt-in durable audit log of tool executions. Set to | off |
config.json (not env vars) also accepts, besides backend/model/Ollama settings:
Key | Description | Default |
| Colour-management view pinned for review/preview captures ( |
|
| Static AST validation of |
|
| Models allowed to write learned patterns to the RAG corpus; others stage candidates for review. |
|
Audit Log (opt-in)
A durable, append-only record of what the model executed in Maya, and what happened — for accountability and forensics, separate from the logs/timings.jsonl efficiency telemetry.
Off by default. It only writes when
MAYA_AUDIT_LOGis set to a truthy value (1/true/yes/on). When unset there is zero perf, disk, or privacy impact and no behaviour change.What it records. One JSON line per call to
src/maya_mcp/logs/audit.jsonl:ts,tool,action, sanitisedparams,status(ok/error/safety_blocked/ast_rejected), plusmodel/backend. It coversexecute_python, the dedicated mutation tools, the mutatingmaya_sessionactions, and blocked attempts (safety scan / AST dry-run rejections). Read-only actions (ping,list_scene,scene_snapshot) are excluded.Size & privacy. For
execute_pythonthe code is stored truncated to ~2000 chars plus a SHA-256 of the full code and its length; Maya result payloads are never stored. The file rotates at 5 MB toaudit.jsonl.1(one rollover) and lives under the git-ignoredlogs/dir.Write-only. There is no MCP tool to read it (the tool count is unchanged). Inspect it with
jq/grep, e.g.jq 'select(.status=="safety_blocked")' src/maya_mcp/logs/audit.jsonl.
Cross-MCP Pipeline
When both maya-mcp and fpt-mcp are configured, Claude can orchestrate end-to-end VFX workflows: query ShotGrid for an asset → download reference image → generate 3D via Vision3D → import into Maya → register the publish back in ShotGrid. All from one conversation.
All three MCP servers (maya-mcp, fpt-mcp, flame-mcp) share the same architecture: hybrid RAG, HyDE, safety layer, self-learning, token tracking, and model trust gates.
Troubleshooting
Maya Command Port not responding — Verify in Maya's Script Editor: cmds.commandPort('localhost:8100', query=True). If False, run the open_command_port() snippet.
RAG search returns "index not found" — Run python -m maya_mcp.rag.build_index to build the index.
Shape inference fails immediately — Model weights may be incomplete. Check that hunyuan3d-dit-v2-0-turbo/model.fp16.safetensors (~4.6 GB) exists on the GPU server.
GPU API connection refused — Verify Vision3D is running: curl $GPU_API_URL/api/health.
Ecosystem
maya-mcp is part of a four-component VFX pipeline. Each component has a defined role:
Repo | Role |
Controls Autodesk Flame for compositing, conform, and finishing | |
Controls Autodesk Maya for 3D modeling, animation, and rendering | |
Connects to Autodesk Flow Production Tracking (ShotGrid) for production tracking, asset management, and publishes | |
GPU inference server for AI-powered 3D generation — the remote backend for maya-mcp's image-to-3D and text-to-3D tools |
maya-mcp sits at the 3D creation stage of the pipeline. It consumes vision3d via HTTP — submitting image-to-3D or text-to-3D jobs and importing the resulting .glb files into Maya. It works alongside fpt-mcp for end-to-end workflows: query ShotGrid for an asset, generate or load reference, build the 3D asset in Maya, and register the publish back in ShotGrid. flame-mcp typically operates downstream, receiving rendered outputs from Maya for finishing.
License
MIT License — see LICENSE for details.
Available Tools
17 toolslearn_patternA
Save a validated working pattern to the RAG knowledge base.
Call this after a successful operation when search_maya_docs returned low relevance (< 60%), indicating the pattern was not well-documented. The pattern will be available in future sessions.
Model trust gates: only Opus/Fable can write directly. Other models stage candidates for review.
Inputs: params (required). Returns: result
maya_assign_materialA
Create a material (lambert, blinn, phong, aiStandardSurface) with RGB color and assign it to an object.
Inputs: params (required). Returns: result
maya_create_cameraC
Create a camera in Maya with configurable position, look-at point, and focal length.
Inputs: params (required). Returns: result
maya_create_lightB
Create a light in Maya (directional, point, spot, area, ambient) with configurable intensity and color.
Inputs: params (required). Returns: result
maya_create_primitiveB
Create a 3D primitive in Maya (cube, sphere, cylinder, cone, plane, torus) with optional position, scale, and rotation.
Inputs: params (required). Returns: result
maya_import_fileA
Import 3D files into Maya: OBJ, FBX, GLB/GLTF, Alembic ABC, Maya MA/MB, BVH mocap. With namespace, parent group, and scale options.
GLB/GLTF: uses Maya's native glTF scene parser (type='glTF Import');
if the parser is not registered or import fails, falls back to the
Vision3D sibling pattern — mesh_uv.obj + texture_baked.png next
to the GLB — building an aiStandardSurface with the texture in
baseColor and assigning it to the imported meshes.
BVH: Maya has no native BVH import, so .bvh motion-capture files are
parsed and rebuilt by the pure-Python maya_mcp.bvh_import module
(hierarchy → joints, motion → keyframes, with the per-joint
BVH→Maya rotate-order mapping handled internally). namespace and
scale_factor are forwarded to the builder; the skeleton lands under a
<namespace>:bvh_grp group. The result feeds a HumanIK retarget onto a
rigged character (mocap → generic animation library).
Inputs: params (required). Returns: result
maya_mesh_operationC
Execute mesh operations: extrude, bevel, boolean (union/difference/intersection), combine, separate, smooth.
Inputs: params (required). Returns: result
maya_referenceA
Reference a file into the Maya scene and manage the reference lifecycle: create, list, replace (version swap), load, unload.
A reference keeps a live link to the source file; maya_import_file
copies content in and breaks that link. Production scenes are assembled
from references, so prefer this tool whenever the content has its own
publish and may be re-versioned.
replace is the version-swap path: it repoints an existing reference
node at a new file without disturbing the namespace or anything built on
top of it. list returns every reference node with its file, namespace
and loaded state — the reference_node the other operations require.
unload keeps the link and drops the content from memory; it is the
reversible counterpart of load. Removing a reference outright is NOT
offered here: it is destructive and the safety module requires explicit
user confirmation for it.
Inputs: params (required). Returns: result
maya_sessionA
Manage Maya session, query scene state, and run utility commands.
Available actions:
• ping — Check connection to Maya, return version/scene/renderer. No params needed. • launch — Open Maya and wait for Command Port to respond. No params needed. • new_scene — Create a new empty scene. Refuses if the current scene has unsaved changes; pass {"confirm": true} to discard them. • save_scene — Save the current scene. No params needed. • list_scene — List objects in the scene. Optional params: {"object_type": "mesh", "name_filter": "sphere"} • scene_snapshot — Full scene state: file, modified flag, frame range, object counts by type, renderer, plugins, resolution. No params needed. • delete — Delete objects by name (wildcards supported). Required params: {"object_name": "sphere"} • execute_python — Run arbitrary Python in Maya. Assign result to 'result' variable. Required params: {"code": "import maya.cmds as cmds; ..."} Optional: {"timeout": 60} — seconds to wait for Maya (default 10, max 600); use for long operations, progress heartbeats stream every 10s while waiting. • shelf_button — Create a shelf button with Python code. Required params: {"label": "MyBtn", "command": "print('hello')"} Optional: {"tooltip": "...", "shelf_name": "Custom", "icon_label": "MCP"} • operation_history — Read recent durable-audit records (read-only; needs MAYA_AUDIT_LOG=1). Optional params: {"limit": 50, "tool": "maya_transform", "action": "execute_python", "status": "error"} • publish — Drive the native Toolkit publisher (tk-multi-publish2) inside an engine'd Maya (launched via 'tank'). params: {"mode": "preview"|"publish", "include": ["rig"], "exclude": ["render"], "comment": "...", "timeout": 600}. 'preview' returns the collected publish tree; 'publish' activates matching tasks then validate→publish→finalize. Dependencies are captured automatically by the publish plugins. • review_turntable — Deterministic Viewport-2.0 turntable playblast → .mov (RUNS IN MAYA, long op). Frames the model, orbits 360° over [start,end] at fps, 16:9 / square pixels / overscan, offScreen (never Arnold). Required params: {"out_path": "/path.mov"} (resolve via fpt tk_resolve_path template 'movie_asset_publish' with name= so the file is {Asset}{Task}v###.mov, e.g. DJ_Model_v001.mov — NOT 'turntable'). Optional: {"start":1,"end":100,"fps":25,"width":1920,"height":1080,"objects":[...],"focal":50,"timeout":600}. Returns the .mov plus the engine asset/task and a Version code {Asset}{Task} so the review Version is named after the task it was generated in. • render_still — Single-frame Arnold ray-traced still → a PNG at the exact out_path (long op). This is what "a still / render a still" means — a real Arnold render, NOT the VP2.0 grab of maya_viewport_capture (use that for a fast screenshot). Maya only EXPORTS the scene to a .ass; kick renders it out of process, so the review view transform actually applies (a Render View dump writes scene-linear and ignores colour management), no Render View window is opened, and the render can never hang Maya's main thread. Required params: {"out_path": "/review/….png"} (resolve via fpt tk_resolve_path so it lands in the review area with the pipeline name). Optional: {"camera":"persp","frame":42,"width":1920,"height":1080,"aa_samples":3,"view_transform":"…","timeout":600}. Returns JSON {rendered, size_kb, camera, frame, resolution, asset, task, version_code} or {error}. For a still "for review" the version_code ({Asset}{Task}) is what names the ShotGrid review Version — rendering alone does not put it in review; create the Version (fpt sg_create type=Version) + sg_upload the PNG afterwards.
Inputs: params (required). Returns: result
maya_set_keyframeB
Create an animation keyframe on an object. Allows animating translate, rotate, scale, and visibility per frame.
Inputs: params (required). Returns: result
maya_transformB
Move, rotate, or scale an object in the Maya scene.
Inputs: params (required). Returns: result
maya_viewport_captureA
Capture the Maya viewport as PNG/JPG image and return it for visual analysis. Does not do Arnold render — it is an instant Viewport 2.0 grab (<1s); for a ray-traced still use maya_session(action='render_still'). Useful for visually verifying scene state, checking lighting, framing, and detecting issues.
NEVER captures the user's focused viewport: it playblasts a throw-away Viewport-2.0 window (its own modelPanel forced to rendererName='vp2Renderer'), so an Arnold IPR / render-override active on the user's panel can never be captured — which would saturate Maya's main thread and hang it (memory feedback_maya_gs_arnold_ipr_hang; same technique as review_turntable).
Inputs: params (required).
maya_vision3dA
AI-powered 3D asset generation via Vision3D server (requires GPU with Hunyuan3D-2).
Server selection is fully per-session and runtime-only: the first
action that needs a GPU call returns vision3d_url_required. The
LLM must ask the user for the Vision3D URL in the chat and then call
select_server with that URL. Nothing is persisted to disk — the
URL lives only in process memory until the MCP server restarts.
After selection, jobs are non-blocking: start → poll → download.
Available actions:
• select_server — Set the Vision3D server URL for the rest of the session. Required params: {"url": "http://..."}. Accepts any valid http/https URL; ask the user first. • health — Check if the selected Vision3D server is running and what GPU/models are available. No params. • generate_image — Start 3D generation from a reference image. Required params: {"image_path": "/path/to/image.png", "output_subdir": "my_asset"} Optional: {"preset": "medium", "model": "turbo", "octree_resolution": 384, "num_inference_steps": 20, "target_faces": 50000} • generate_text — Start 3D generation from a text prompt. Required params: {"text_prompt": "a medieval sword", "output_subdir": "sword"} Optional: {"preset": "medium", "model": "turbo", "octree_resolution": 384, "num_inference_steps": 20, "target_faces": 50000} • texture — Texture an existing mesh using a reference image. Required params: {"output_subdir": "my_asset"} Optional: {"mesh_filename": "mesh.glb", "image_filename": "input.png"} • poll — Check job progress (call repeatedly while running). Required params: {"job_id": "uuid-from-generate"} • download — Download completed job results. Required params: {"job_id": "uuid", "output_subdir": "my_asset"} Optional: {"files": ["textured.glb", "mesh.glb"]}
Inputs: params (required). Returns: result
maya_worldlabsA
Generate a World Labs (Marble) Gaussian-splat ENVIRONMENT from an image and load it into Maya for Arnold.
Pipeline — call the actions in order: generate → poll → download → convert → build. Credits are spent ONLY by generate with confirm=true. Call status on a work area to resume an interrupted run from disk without re-generating.
Actions:
• health — Check the WorldLabs API key + credit balance. No params. • generate — Start image→world generation. Required params: {"image": "/path.png" or "https://..."}. Optional: {"output_subdir": "world", "model": "marble-1.1"|"marble-1.1-plus", "display_name": ..., "text_prompt": ..., "confirm": true, "work_dir": "/work/worldlabs/"}. WITHOUT confirm=true it returns a cost-confirmation payload and spends NOTHING. Pass work_dir (the Toolkit work area, resolved via fpt-mcp tk_resolve_path) to write a resume sidecar so an interrupted run resumes without re-generating. • poll — Poll a generation (~5 min). Required params: {"operation_id": "..."}. • download — Download a finished world's assets to the work area. Required params: {"operation_id": "...", "dest_dir": "/work/worldlabs/"}. Optional: {"which": ["splats_full_res", "pano"]}. Updates the resume sidecar (world_id + downloaded paths). • convert — Convert the downloaded SPZ to PLY (Arnold-readable, via gsbox). Required params: {"spz_path": "/path.spz"}. Optional: {"ply_path": "/out.ply"}. • build — Load into Maya (RUNS IN MAYA): aiGaussianSplat + coloured point proxy + emission shader + eye-level centred camera, plus a fake-HDR panorama dome if given. Required params: {"ply_path": "/world.ply"}. Optional: {"pano_path": "/pano.png", "eye_height": 1.5, "proxy_step": 1, "relight": false, "draw_mode": 2, "focal": 15.0, "timeout": 300, "save_path": "/…/maya/scene.v001.ma"}. draw_mode: 2=Gaussian Splat (default, draws natively in VP2.0), 1=Point Cloud, 0=Bounding Box. focal: camera focal length in mm (default 15, wide for environments). save_path: when given (the Toolkit work-file path resolved via fpt-mcp tk_resolve_path on template maya_asset_work — Toolkit naming/versioning), the assembled scene is saved there so "open in Maya" lands the work file at the config-correct path with no manual Workfiles pick. • status — Report the resumable state of a work area (sidecar + on-disk .spz/.ply/.png). Required params: {"work_dir": "/work/worldlabs/"}. Returns where the pipeline left off (needs_generate / needs_download / needs_convert / ready_to_build).
Inputs: params (required). Returns: result
reset_session_statsA
Zero the session stats counters immediately.
Use at the start of a new Claude session (or a fresh debugging run) when the idle-based auto-reset has not fired — for example when two sessions happen back-to-back. Returns a confirmation line with the new reset timestamp.
Inputs: no named parameters. Returns: result
search_maya_docsA
Search Maya API documentation using hybrid RAG (semantic + BM25).
Call this BEFORE writing complex Maya commands, using unfamiliar flags, or when unsure about command names, return values, or syntax. Returns the most relevant documentation chunks with relevance scores.
Covers: maya.cmds, PyMEL, Arnold/mtoa, Maya-USD, and common anti-patterns. Uses HyDE query expansion + Reciprocal Rank Fusion for high precision.
Inputs: params (required). Returns: result
session_statsA
Show session efficiency statistics: token usage, RAG savings, patterns learned.
Call at the end of multi-step tasks or when asked about efficiency. Shows how much context was saved by RAG vs loading full documentation.
Inputs: no named parameters. Returns: result
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 17 tools
Most tools target distinct operations, and the descriptions go out of their way to distinguish rendering paths (maya_viewport_capture vs maya_session render_still vs review_turntable) and import vs reference. However, maya_session is a god-tool bundling 13 actions (render, publish, turntable, delete, execute_python) that overlap conceptually with dedicated tools like maya_import_file and maya_viewport_capture, making boundaries hard to reason about.
The core tools use a predictable maya_verb_noun snake_case pattern (maya_create_primitive, maya_assign_material, maya_transform). A few deviate with a noun-verb or no-prefix form (search_maya_docs, learn_pattern, session_stats, reset_session_stats), but all remain snake_case and readable.
17 top-level tools is slightly above the comfortable range, but the real issue is that three of them (maya_session, maya_vision3d, maya_worldlabs) are multi-action mega-tools hiding ~27 additional actions, making the effective surface far larger than the count suggests.
Coverage of the DCC automation domain is broad: primitives, transforms, materials, lights, cameras, mesh ops, keyframes, import, references, rendering, publishing, docs search, and learning. Minor gaps exist (no standalone delete/update for objects beyond transform, no rigging/joint tools), but they are workable via maya_session(execute_python).
Maintenance
Related MCP Connectors
Use AI models for chat, image, and video generation from Claude Code and other MCP hosts.
A comprehensive Model Context Protocol (MCP) server that enables AI assistants to interact with yo…
A comprehensive Model Context Protocol (MCP) server that enables AI assistants to control Unreal E…
Augments MCP Server - A comprehensive framework documentation provider for Claude Code
Related MCP Servers
- AlicenseNot gradedqualityNot gradedmaintenanceEnables AI assistants to connect to and control Autodesk Maya for 3D modeling, animation, and rendering operations through the Model Context Protocol, supporting object creation, transformation, scene queries, and Python command execution.MIT
- AlicenseNot gradedqualityCmaintenanceEnables AI assistants like Claude Desktop to control Autodesk Maya via natural language through the Model Context Protocol.MIT
- AlicenseNot gradedqualityDmaintenanceEnables AI-assisted 3D modeling and scene control in Autodesk Maya through natural language commands, supporting object creation, transformation, material application, and more.53 npm8MIT
- AlicenseNot gradedqualityBmaintenanceEnables Claude and other MCP clients to control Autodesk Maya 2024 through 244 typed tools, including modeling, rigging, previs, FX, Arnold rendering, asset libraries, AI 3D generation, and a real-time change stream for Unreal.MIT