Skip to main content

Maya plugin for the DCC Model Context Protocol (MCP) ecosystem — embeds a Streamable HTTP MCP server directly inside Maya

Project description

dcc-mcp-maya

Maya plugin for the DCC Model Context Protocol (MCP) ecosystem.

Embeds a standards-compliant MCP Streamable HTTP server (2025-03-26 spec) directly inside Maya — no external gateway or separate IPC process required.

CI codecov PyPI Python License: MIT

Architecture

┌─────────────────────────────────────────────────────────┐
│  Maya (embedded Python)                                  │
│                                                          │
│  import dcc_mcp_maya                                    │
│  handle = dcc_mcp_maya.start_server(port=8765)          │
│                                                          │
│  ┌─────────────────────────────────────────────────┐   │
│  │  McpHttpServer  (dcc-mcp-core / Rust/axum)      │   │
│  │  POST /mcp  ──►  ToolRegistry                   │   │
│  │  GET  /mcp  ──►  SSE stream                     │   │
│  └─────────────────────────────────────────────────┘   │
└─────────────────────────────┬───────────────────────────┘
                               │  http://127.0.0.1:8765/mcp
┌─────────────────────────────▼───────────────────────────┐
│  MCP Host  (Claude Desktop / OpenClaw / Cursor / …)      │
└─────────────────────────────────────────────────────────┘

Installation

Into Maya's Python

mayapy -m pip install dcc-mcp-maya

As a Maya Plugin

  1. Load the plugin via Window > Settings/Preferences > Plug-in Manager and find dcc_mcp_maya.
  2. Or add to your userSetup.py:
    import maya.cmds as cmds
    cmds.loadPlugin("dcc_mcp_maya_plugin")
    

Quick Start

Option A — From Python Script Panel

import dcc_mcp_maya

handle = dcc_mcp_maya.start_server(port=8765)
print(handle.mcp_url())   # http://127.0.0.1:8765/mcp

Point your MCP host at the URL above.

Option B — Load Plugin

Copy maya/plugin/dcc_mcp_maya_plugin.py to a directory on MAYA_PLUG_IN_PATH.
The server starts automatically when the plugin loads.

Configuration

Environment variable Default Description
DCC_MCP_MAYA_PORT 8765 TCP port for the MCP server
DCC_MCP_MAYA_SERVER_NAME maya-mcp Name shown in MCP initialize
DCC_MCP_MAYA_SKILL_PATHS (none) Extra skill directories (semicolon-separated on Windows, colon on Unix)
DCC_MCP_SKILL_PATHS (none) Global fallback skill directories for all DCC adapters
DCC_MCP_MAYA_MINIMAL 1 0 = load all skills at startup (legacy); 1 = minimal core surface
DCC_MCP_MAYA_DEFAULT_TOOLS (none) Comma-separated skill names to load at startup (overrides minimal default)

Progressive Loading (Minimal Mode)

By default, dcc-mcp-maya boots with a minimal tool surface — only core skills (maya-scripting, maya-scene) are loaded, and within those only the essential tools are active:

Tool Role Source skill
execute_python Write + execute maya-scripting (core group)
execute_mel Write + execute maya-scripting (core group)
get_scene_info Read maya-scene (core group)
get_selection Read maya-scene (core group)
get_session_info Read maya-scene (core group)
search_tools Discover core
list_skills Browse core
load_skill Progressive activation core

All other skills appear as __skill__<name> stubs. The agent calls load_skill("maya-primitives") to expand the surface on demand, and activate_group("extended") to expose additional tool groups within a loaded skill.

Opt out (restore legacy full-load):

# Environment variable
export DCC_MCP_MAYA_MINIMAL=0
# Or programmatically
server = MayaMcpServer(port=8765)
server.register_builtin_actions(minimal=False)
handle = server.start()

Custom default tools via environment variable:

# Load only specific skills at startup
export DCC_MCP_MAYA_DEFAULT_TOOLS="maya-scripting,maya-scene,maya-primitives"

Bundled Skills (Zero Configuration)

dcc-mcp-maya automatically loads the bundled general-purpose skills shipped inside the dcc-mcp-core wheel — no path configuration required.

Skill Tools Notes
dcc-diagnostics screenshot, audit_log, action_metrics, process_status Observability & debugging
workflow run_chain Multi-step action chaining
git-automation repo_stats, changelog_gen Git analysis
ffmpeg-media convert, probe, thumbnail Requires ffmpeg on PATH
imagemagick-tools resize, composite Requires ImageMagick on PATH

To opt-out of bundled skills:

# Disable all bundled core skills
handle = dcc_mcp_maya.start_server(include_bundled=False)

# Or fine-grained control
server = MayaMcpServer()
server.register_builtin_actions(include_bundled=False)

Skill search-path priority (highest → lowest):

  1. extra_skill_paths argument
  2. Built-in Maya skills (shipped in this package)
  3. DCC_MCP_MAYA_SKILL_PATHS environment variable
  4. DCC_MCP_SKILL_PATHS environment variable
  5. Bundled dcc-mcp-core skills ← loaded by default
  6. Platform default skills directory

Diagnostic IPC Actions

When register_builtin_actions() is called, three IPC callback actions are automatically registered so the dcc-diagnostics skill can retrieve live runtime data from the running Maya process:

Action Returns
get_audit_log SandboxContext audit entries
get_tool_metrics ToolRecorder performance counters
dispatch_tool Relay for workflow__run_chain

The DCC_MCP_IPC_ADDRESS environment variable is set automatically so skill subprocesses can connect back without any manual configuration.

Available MCP Tools

dcc-mcp-maya ships 64 built-in skill packages and 370+ Maya MCP tools. In the default minimal mode, only the core tools above are active at startup; the rest are progressively loaded via load_skill.

The sections below are representative categories, not an exhaustive inventory.

Scene

Tool Description
get_session_info Maya version, scene path, FPS, object count
new_scene Create a new scene
save_scene Save scene to disk
open_scene Open a scene file
list_objects List DAG objects (optional type filter)
get_selection Get current selection
set_selection Set active selection

Geometry

Tool Description
create_sphere Create polygon sphere
create_cube Create polygon cube
create_cylinder Create polygon cylinder
create_plane Create polygon plane
delete_objects Delete objects from the scene
set_transform Set translate/rotate/scale
get_transform Query translate/rotate/scale
rename_object Rename an object

Material

Tool Description
create_material Create Lambert/Blinn/Phong/Arnold material
assign_material Assign material to objects
set_material_attribute Set material color, roughness, etc.
list_materials List all scene materials

Animation

Tool Description
set_keyframe Set keyframe on object attributes
get_keyframes Get keyframe times for object/attribute
set_timeline Set playback timeline range
get_current_time Get current frame number
set_current_time Set current frame number

Render

Tool Description
set_render_settings Set resolution, frame range, renderer
capture_viewport Capture viewport as base64-encoded PNG
import_file Import FBX/OBJ/Alembic/Maya file
export_selection Export selection to FBX/OBJ/Alembic

Scripting

Tool Description
execute_mel Execute a MEL script
execute_python Execute Python inside Maya

Authoring Skills (execution + affinity)

Every tool in a tools.yaml must declare two fields so the MCP host knows how to dispatch it safely. Omitting either breaks async dispatch (core #318) or crashes Maya when a main-thread-only Maya API is routed to a Tokio worker (core #332):

tools:
  - name: playblast
    description: Capture a viewport screenshot as a base64-encoded PNG
    execution: async            # sync | async — default sync
    affinity: main              # main | any  — default main for Maya tools
    timeout_hint_secs: 600      # required when execution: async

  - name: get_render_settings
    execution: sync
    affinity: main              # cmds.getAttr must run on the UI thread

  - name: list_export_presets
    execution: sync
    affinity: any               # pure filesystem read — worker-thread safe
    annotations:
      read_only_hint: true
      idempotent_hint: true

Classification rules (see issue #84):

Field When to use Notes
execution: async Typical wall-clock > 2s (render, bake, cache, large import/export, simulation) Must also set timeout_hint_secs. Surfaces as MCP deferredHint=true.
execution: sync Bounded-time queries and single-attribute setters Default.
affinity: main Anything that imports maya.*, calls OpenMaya, or uses dcc_mcp_maya.api.validate_* Safe default for Maya tools.
affinity: any Pure filesystem / pure Python tools that never touch Maya Verified by grepping the script for import maya.
timeout_hint_secs: N Required alongside execution: async Positive integer; becomes _meta.dcc.timeout_hint_secs on tools/list.

Annotation workflow for bundled skills:

# Apply the per-skill / per-tool classification table to every tools.yaml
python tools/annotate_skill_affinity.py

# CI lints the result — missing fields or async-without-timeout fail fast
python tools/lint_skill_affinity.py

The lint runs in the Lint Skills CI job, so a PR that adds a new tool without these fields will be rejected. Third-party skill authors can run the same lint against their own skills root:

python tools/lint_skill_affinity.py --skills-root /path/to/your/skills

Prometheus Metrics (issue #87)

Enable the /metrics endpoint for real-time observability (requires a wheel built with the prometheus feature):

# Programmatic:
server = MayaMcpServer(port=8765, metrics_enabled=True)

# Or via env var (useful in Maya's userSetup.py):
# DCC_MCP_MAYA_METRICS=1

Exposed metrics include MayaUiPump overrun cycles, queue depth, and per-tool job-duration histograms. Scrape at: http://127.0.0.1:<port>/metrics

Job Persistence & Recovery (issue #89)

Enable SQLite job persistence so clients can poll interrupted jobs after a Maya restart:

server = MayaMcpServer(
    port=8765,
    job_storage_path="/path/to/maya-jobs.db",  # default: platform data dir
    job_recovery="requeue",  # "drop" (default) | "requeue" idempotent jobs
)

Environment variable equivalents:

Variable Effect
DCC_MCP_MAYA_JOB_STORAGE=<path> SQLite job DB path
DCC_MCP_MAYA_JOB_RECOVERY=requeue Re-queue idempotent interrupted jobs

The jobs.get_status built-in MCP tool is automatically available whenever job_storage_path is configured.

Claude Desktop Integration

Add to claude_desktop_config.json:

{
  "mcpServers": {
    "maya": {
      "url": "http://127.0.0.1:8765/mcp"
    }
  }
}

Requirements

Cooperative Cancellation in Skill Scripts

Long-running skill scripts (renders, bakes, mocap ingest, …) should poll check_maya_cancelled() at safe checkpoints so the dispatcher can preempt them when the MCP client sends notifications/cancelled or when MayaMcpServer.stop() drains pending jobs:

from dcc_mcp_maya import check_maya_cancelled, maya_success

def render_frames(frames):
    for frame in frames:
        check_maya_cancelled()      # raises CancelledError when cancelled
        cmds.currentTime(frame)
        cmds.render()
    return maya_success("rendered", frames=len(frames))

check_maya_cancelled() checks two cancellation sources:

  1. MCP request token (dcc_mcp_core.cancellation.check_cancelled) — set by the HTTP handler when notifications/cancelled arrives for the owning tools/call.
  2. Per-job dispatcher flag — set by MayaUiDispatcher.cancel(...) or MayaUiDispatcher.shutdown(...). Covers jobs launched outside an MCP request (queued batch render, scriptJob, …) where the contextvar token is not installed.

Outside any of those contexts the call is a cheap no-op, so dropping it into a loop is safe even when the script runs from an interactive REPL or a unit test.

MayaUiPump.stats exposes overrun_cycles (idle ticks where a single non-cooperative job exceeded budget_ms × 2) and longest_job_ms (worst single-job wall-clock observed) so operators can tell when a skill needs to be chunked behind check_maya_cancelled() instead of monopolising the UI thread.

MayaMcpServer.stop() calls dispatcher.shutdown("Interrupted") on any dispatcher attached via server.attach_dispatcher(...), so threads blocked inside submit_callable unblock within the normal event.wait() poll instead of hanging when Maya restarts mid-job (issue #89).

Authoring Skills: Execution & Affinity

Every tool declared in a tools.yaml file must tell the MCP gateway how it should be dispatched. This is what lets the gateway return an async job_id instead of blocking, and what prevents main-thread-affine tools from running on a worker thread and crashing Maya.

Each entry in tools.yaml supports three dispatch fields:

tools:
  - name: render_frames
    execution: async          # long-running — spawn as a Job
    affinity: main            # cmds.render touches scene state
    timeout_hint_secs: 600    # required when execution: async
  - name: get_scene_info
    execution: sync
    affinity: main            # cmds.ls is main-thread-only
  - name: list_render_presets
    execution: sync
    affinity: any             # pure filesystem read — worker-thread safe

Rules of thumb:

Property Guidance
execution: async Use for anything that typically runs > 2s (render, bake, simulation, large I/O). Must declare timeout_hint_secs.
execution: sync Use for fast queries, attribute edits, and small creations.
affinity: main Default. Anything that calls maya.cmds or OpenMaya.
affinity: any Pure Python / filesystem only — never touches Maya state.

Two helpers keep the annotations consistent across the 64 bundled skills:

# Annotate every bundled tools.yaml from the SKILL_DEFAULTS table.
python tools/annotate_skill_affinity.py

# CI enforcement — fails if any tool is missing affinity/execution
# or if an async tool is missing timeout_hint_secs.
python tools/lint_skill_affinity.py

Third-party skill authors should run tools/lint_skill_affinity.py against their own skill packages before publishing. See issue #84 for the full categorisation matrix.

Deployment Guides

Development

Clone and Install

git clone https://github.com/loonghao/dcc-mcp-maya
cd dcc-mcp-maya
pip install -e ".[dev]"
pytest tests/

Maya Development Setup

Unix/macOS

# Link source code to Maya modules directory
just maya-link

# Install dcc-mcp-core into Maya Python
just maya-install-core maya-py=/path/to/mayapy
# Or if mayapy is on PATH:
just maya-install-core

# Check link status
just maya-status

# Full setup
just maya-dev

Windows (PowerShell)

# Link source code to Maya modules directory
just maya-link-win

# Install dcc-mcp-core into Maya Python
just maya-install-core-win maya-version=2025

# Check link status
just maya-status-win

# Clean up (remove symlinks)
just maya-unlink-win

Note: Windows symlinks require either:

  • Windows Developer Mode enabled (Windows 10/11)
  • Or running PowerShell as Administrator

If symlinks fail, the scripts will automatically fall back to copying files (changes will require re-running just maya-link-win).

Verify Installation

just verify-deps

Run Tests

just test-quick

License

MIT — see LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

dcc_mcp_maya-0.2.14.tar.gz (621.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

dcc_mcp_maya-0.2.14-py3-none-any.whl (616.1 kB view details)

Uploaded Python 3

File details

Details for the file dcc_mcp_maya-0.2.14.tar.gz.

File metadata

  • Download URL: dcc_mcp_maya-0.2.14.tar.gz
  • Upload date:
  • Size: 621.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for dcc_mcp_maya-0.2.14.tar.gz
Algorithm Hash digest
SHA256 bb450542877bedd279993ad5dcc723803de4e90ac2f1aa40396610d2e7e95499
MD5 cc67b3d3c570b7a416eb32135121d1f9
BLAKE2b-256 c532b87e35ce3c2e036ec5f4d04652e901c99fad48039ae547281bbd7f710e2f

See more details on using hashes here.

Provenance

The following attestation bundles were made for dcc_mcp_maya-0.2.14.tar.gz:

Publisher: release.yml on loonghao/dcc-mcp-maya

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file dcc_mcp_maya-0.2.14-py3-none-any.whl.

File metadata

  • Download URL: dcc_mcp_maya-0.2.14-py3-none-any.whl
  • Upload date:
  • Size: 616.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for dcc_mcp_maya-0.2.14-py3-none-any.whl
Algorithm Hash digest
SHA256 624032c54b37f3483e23361166773a2d1970fcb95ec59df9ba26244b27f6544c
MD5 2fb09c4efd11952ce85fa85b0c570ece
BLAKE2b-256 6d8c7387a1a5e53135a8811e3adbe0d3996c0b81e3b9da00d63fec24749e8040

See more details on using hashes here.

Provenance

The following attestation bundles were made for dcc_mcp_maya-0.2.14-py3-none-any.whl:

Publisher: release.yml on loonghao/dcc-mcp-maya

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page