Protocols API
dcc_mcp_core.protocols types — MCP specification-compliant type definitions.
ToolDefinition
| Field | Type | Description |
|---|---|---|
name | str | Tool name |
description | str | Tool description |
input_schema | str | JSON Schema string for input (serde: inputSchema) |
output_schema | Optional[str] | JSON Schema string for output (serde: outputSchema) |
from dcc_mcp_core import ToolDefinition
tool = ToolDefinition(
name="create_sphere",
description="Creates a sphere",
input_schema='{"type": "object"}',
)ToolAnnotations
| Field | Type | Description |
|---|---|---|
title | Optional[str] | Human-readable title |
read_only_hint | Optional[bool] | serde: readOnlyHint |
destructive_hint | Optional[bool] | serde: destructiveHint |
idempotent_hint | Optional[bool] | serde: idempotentHint |
open_world_hint | Optional[bool] | serde: openWorldHint |
from dcc_mcp_core import ToolAnnotations
ann = ToolAnnotations(read_only_hint=True)ToolDeclaration
Lightweight declaration of a single MCP tool provided by a Skill. Parsed from the tools: array in SKILL.md frontmatter — no script execution needed for discovery.
| Field | Type | Default | Description |
|---|---|---|---|
name | str | — | Tool name (used as MCP tool identifier) |
description | str | "" | Human-readable description |
input_schema | str | "" | JSON Schema string for input parameters |
output_schema | str | "" | JSON Schema string for output (empty = any) |
read_only | bool | False | True = doesn't modify DCC state |
destructive | bool | False | True = deletes / overwrites data |
idempotent | bool | False | True = safe to call multiple times |
source_file | str | "" | Relative path within skill's scripts/ dir |
from dcc_mcp_core import ToolDeclaration
td = ToolDeclaration(
name="create_sphere",
description="Create a polygon sphere",
input_schema='{"type": "object", "required": ["radius"], "properties": {"radius": {"type": "number"}}}',
output_schema=None,
read_only=False,
destructive=False,
idempotent=False,
source_file="scripts/create_sphere.py",
)
# All fields are get/set
td.name, td.description, td.input_schema, td.output_schema
td.read_only, td.destructive, td.idempotent, td.source_fileRelation to SkillMetadata: skill.tools is List[ToolDeclaration], populated from SKILL.md tools: frontmatter. Each entry maps to one MCP tool. When tools: is absent, the Skill falls back to auto-discovering scripts in scripts/.
ResourceDefinition
| Field | Type | Default | Description |
|---|---|---|---|
uri | str | — | Resource URI |
name | str | — | Resource name |
description | str | — | Description |
mime_type | str | "text/plain" | MIME type (serde: mimeType) |
from dcc_mcp_core import ResourceDefinition
res = ResourceDefinition(uri="scene://objects", name="Objects", description="Scene objects")ResourceTemplateDefinition
| Field | Type | Default | Description |
|---|---|---|---|
uri_template | str | — | URI template (serde: uriTemplate) |
name | str | — | Template name |
description | str | — | Description |
mime_type | str | "text/plain" | MIME type (serde: mimeType) |
from dcc_mcp_core import ResourceTemplateDefinition
tmpl = ResourceTemplateDefinition(
uri_template="scene://objects/{name}",
name="Object",
description="A scene object",
)PromptArgument
| Field | Type | Default | Description |
|---|---|---|---|
name | str | — | Argument name |
description | str | — | Description |
required | bool | False | Whether required |
from dcc_mcp_core import PromptArgument
arg = PromptArgument(name="object_name", description="Object to review", required=True)PromptDefinition
| Field | Type | Description |
|---|---|---|
name | str | Prompt name |
description | str | Description |
from dcc_mcp_core import PromptDefinition
prompt = PromptDefinition(name="review", description="Review a model")DCC Adapter Traits
DCC integration packages implement these traits to expose their application to the MCP ecosystem. All methods are synchronous.
Architecture Overview
DccAdapter — Top-level trait
├── DccConnection — Connection lifecycle
├── DccScriptEngine — Script execution (Python / MEL / MaxScript / …)
├── DccSceneInfo — Scene inspection
└── DccSnapshot — Viewport capture
Cross-DCC Protocol Traits (universal, optional)
├── DccSceneManager — Scene/file management, selection, visibility
├── DccTransform — Object TRS transforms and bounding boxes
├── DccRenderCapture — Viewport capture and scene rendering
└── DccHierarchy — Parent/child hierarchy and groupingDccAdapter
Top-level trait. Implement in your DCC integration package.
| Method | Returns | Description |
|---|---|---|
info() | DccInfo | Static application info (type, version, pid, platform) |
capabilities() | DccCapabilities | Feature flags — advertise which sub-traits are available |
as_connection() | DccConnection | None | Connection lifecycle interface |
as_script_engine() | DccScriptEngine | None | Script execution interface |
as_scene_info() | DccSceneInfo | None | Scene info query interface |
as_snapshot() | DccSnapshot | None | Screenshot/capture interface |
as_scene_manager() | DccSceneManager | None | Universal scene management (optional) |
as_transform() | DccTransform | None | Universal object TRS (optional) |
as_render_capture() | DccRenderCapture | None | Render/capture interface (optional) |
as_hierarchy() | DccHierarchy | None | Scene hierarchy interface (optional) |
DccConnection
| Method | Returns | Description |
|---|---|---|
connect() | None | Establish connection to the DCC |
disconnect() | None | Disconnect from the DCC |
is_connected() | bool | Whether the connection is alive |
health_check() | int | Round-trip ping in milliseconds |
DccScriptEngine
| Method | Returns | Description |
|---|---|---|
execute_script(code, language, timeout_ms) | ScriptResult | Run a script inside the DCC |
supported_languages() | list[ScriptLanguage] | Languages this DCC supports |
DccSceneInfo
| Method | Returns | Description |
|---|---|---|
get_scene_info() | SceneInfo | Info about the currently open scene |
list_objects() | list[tuple[str, str]] | (name, type) pairs for all scene objects |
get_selection() | list[str] | Names of currently selected objects |
DccSnapshot
| Method | Returns | Description |
|---|---|---|
capture_viewport(viewport, width, height, format) | CaptureResult | Capture a viewport as PNG / JPEG / WebP |
DccSceneManager
Universal scene and file management. Supported across Maya, Blender, 3dsMax, Unreal, Unity, Photoshop, Figma.
| Method | Returns | Description |
|---|---|---|
get_scene_info() | SceneInfo | Metadata for the current scene/document |
list_objects(object_type) | list[SceneObject] | All objects; filter by type or None for all |
new_scene(save_prompt) | SceneInfo | Create a new empty scene |
open_file(file_path, force) | SceneInfo | Open scene from disk |
save_file(file_path) | str | Save scene; None = save in place |
export_file(file_path, format, selection_only) | str | Export to FBX / OBJ / USD / PNG etc. |
get_selection() | list[str] | Currently selected object names |
set_selection(object_names) | list[str] | Replace selection |
select_by_type(object_type) | list[str] | Select all objects of a given type |
set_visibility(object_name, visible) | bool | Toggle object/layer visibility |
DccTransform
Universal TRS interface. Coordinate convention: right-hand Y-up world space, Euler XYZ in degrees, centimeter units.
| Method | Returns | Description |
|---|---|---|
get_transform(object_name) | ObjectTransform | World-space TRS |
set_transform(object_name, translate, rotate, scale) | ObjectTransform | Update TRS; pass None to leave a component unchanged |
get_bounding_box(object_name) | BoundingBox | World-space AABB |
rename_object(old_name, new_name) | str | Rename; returns new long name |
DccRenderCapture
Viewport screenshot and scene render output.
| Method | Returns | Description |
|---|---|---|
capture_viewport(viewport, width, height, format) | CaptureResult | Screenshot of active/named viewport |
render_scene(output_path, width, height, renderer) | RenderOutput | Full render to disk |
get_render_settings() | dict[str, str] | Current render settings |
set_render_settings(settings) | None | Update one or more render settings |
DccHierarchy
Parent-child object graph — Maya DAG, Blender collections, UE level, Unity scene graph, Photoshop layer groups, Figma frames.
| Method | Returns | Description |
|---|---|---|
get_hierarchy() | list[SceneNode] | Full scene tree (root nodes with nested children) |
get_children(object_name) | list[SceneObject] | Immediate children; None = scene root |
get_parent(object_name) | str | None | Parent name; None when at scene root |
group_objects(object_names, group_name, parent) | SceneObject | Group under a new container |
ungroup(group_name) | list[str] | Dissolve group; children move to group's parent |
reparent(object_name, new_parent, preserve_world_transform) | SceneObject | Change parent |
DCC Data Types
ScriptLanguage
Enum of script languages supported by DCC applications.
| Value | Description |
|---|---|
PYTHON | Python |
MEL | Maya Embedded Language |
MAXSCRIPT | 3ds Max MAXScript |
HSCRIPT | Houdini HScript |
VEX | Houdini VEX |
LUA | Lua |
CSHARP | C# (Unity, Unreal) |
BLUEPRINT | Unreal Engine Blueprint |
from dcc_mcp_core import ScriptLanguage
lang = ScriptLanguage.PYTHON
assert lang == ScriptLanguage.PYTHONDccErrorCode
Enum of error codes for DCC adapter operations.
| Value | Description |
|---|---|
CONNECTION_FAILED | Could not connect to the DCC process |
TIMEOUT | Operation exceeded time limit |
SCRIPT_ERROR | Script execution failed |
NOT_RESPONDING | DCC is unresponsive |
UNSUPPORTED | Operation not supported by this DCC |
PERMISSION_DENIED | Insufficient permissions |
INVALID_INPUT | Bad input parameters |
SCENE_ERROR | Scene operation failed |
INTERNAL | Internal error in the DCC adapter |
from dcc_mcp_core import DccErrorCode, DccError
err = DccError(DccErrorCode.TIMEOUT, "operation timed out", recoverable=True)
assert err.code == DccErrorCode.TIMEOUTDccInfo
Static information about a running DCC application instance.
| Field | Type | Default | Description |
|---|---|---|---|
dcc_type | str | — | Application type ("maya", "blender", …) |
version | str | — | Application version string |
platform | str | — | OS platform ("windows", "linux", "macos") |
pid | int | — | Process ID |
python_version | str | None | None | Embedded Python version, if any |
metadata | dict[str, str] | {} | Arbitrary extra key/value info |
from dcc_mcp_core import DccInfo
info = DccInfo(
dcc_type="maya",
version="2024.2",
platform="windows",
pid=1234,
python_version="3.10.11",
)
d = info.to_dict() # serialize to plain dictDccCapabilities
Feature flags advertising which sub-traits a DCC adapter supports.
| Field | Type | Default | Description |
|---|---|---|---|
script_languages | list[ScriptLanguage] | [] | Supported script languages |
scene_info | bool | False | Implements DccSceneInfo |
snapshot | bool | False | Implements DccSnapshot |
undo_redo | bool | False | Supports undo/redo |
progress_reporting | bool | False | Supports progress callbacks |
file_operations | bool | False | Supports file open/save/export |
selection | bool | False | Supports object selection |
scene_manager | bool | False | Implements DccSceneManager |
transform | bool | False | Implements DccTransform |
render_capture | bool | False | Implements DccRenderCapture |
hierarchy | bool | False | Implements DccHierarchy |
has_embedded_python | bool | True | Whether the DCC has an embedded Python interpreter (False for bridge-based DCCs) |
bridge_kind | str | None | None | Bridge kind: "http", "websocket", "named_pipe", or custom string |
bridge_endpoint | str | None | None | Bridge endpoint URL or socket path |
extensions | dict[str, bool] | {} | Arbitrary extension flags |
from dcc_mcp_core import DccCapabilities, ScriptLanguage
# Python-embedded DCC (e.g. Maya, Blender)
caps = DccCapabilities(
script_languages=[ScriptLanguage.PYTHON, ScriptLanguage.MEL],
scene_info=True,
snapshot=True,
file_operations=True,
)
# Bridge-based DCC (e.g. Photoshop via WebSocket)
caps_bridge = DccCapabilities(
scene_info=True,
has_embedded_python=False,
bridge_kind="websocket",
bridge_endpoint="ws://localhost:12345",
)
if caps.scene_manager:
print("scene manager available")BridgeKind
BridgeKind describes how a non-Python DCC communicates with the MCP server. Bridge-based DCCs (e.g. ZBrush via HTTP, Photoshop via WebSocket, 3ds Max via Named Pipe) do not have an embedded Python interpreter, so they use a bridge protocol instead.
In Python, BridgeKind is exposed as a str on DccCapabilities.bridge_kind:
| Value | Description | Example DCC |
|---|---|---|
"http" | HTTP REST bridge | ZBrush 2024+ |
"websocket" | WebSocket JSON-RPC bridge | Photoshop (UXP) |
"named_pipe" | Named pipe / COM bridge | 3ds Max |
| Custom string | Application-specific bridge | — |
None | Direct Python-embedded (no bridge) | Maya, Blender, Houdini |
from dcc_mcp_core import DccCapabilities
# Check if a DCC uses a bridge
if caps.bridge_kind == "websocket":
print(f"Connect to bridge at {caps.bridge_endpoint}")
# has_embedded_python is False for bridge-based DCCs
if not caps.has_embedded_python:
print("This DCC requires a bridge connection")DccError
Raised or returned when a DCC adapter operation fails.
| Field | Type | Default | Description |
|---|---|---|---|
code | DccErrorCode | — | Error category |
message | str | — | Human-readable description |
details | str | None | None | Optional extended details |
recoverable | bool | False | Whether retry may succeed |
from dcc_mcp_core import DccError, DccErrorCode
err = DccError(DccErrorCode.SCRIPT_ERROR, "NameError: name 'foo' is not defined")
print(err.code, err.recoverable)ScriptResult
Result returned by DccScriptEngine.execute_script().
| Field | Type | Default | Description |
|---|---|---|---|
success | bool | — | Whether execution succeeded |
execution_time_ms | int | — | Execution duration in milliseconds |
output | str | None | None | Captured stdout / return value |
error | str | None | None | Error message if failed |
context | dict[str, str] | {} | Execution context key/values |
from dcc_mcp_core import ScriptResult
r = ScriptResult(success=True, execution_time_ms=12, output="42")
d = r.to_dict()SceneStatistics
Lightweight scene statistics summary.
| Field | Type | Default | Description |
|---|---|---|---|
object_count | int | 0 | Total scene objects |
vertex_count | int | 0 | Total mesh vertices |
polygon_count | int | 0 | Total polygons |
material_count | int | 0 | Unique materials |
texture_count | int | 0 | Unique textures |
light_count | int | 0 | Light sources |
camera_count | int | 0 | Cameras |
SceneInfo
Information about the currently open scene / document.
| Field | Type | Default | Description |
|---|---|---|---|
file_path | str | "" | Absolute path on disk; empty if unsaved |
name | str | "untitled" | Scene/document name |
modified | bool | False | Unsaved changes present |
format | str | "" | File format extension (.ma, .blend, …) |
frame_range | tuple[float, float] | None | None | (start, end) frames |
current_frame | float | None | None | Active frame |
fps | float | None | None | Frames per second |
up_axis | str | None | None | "Y" or "Z" |
units | str | None | None | Linear units ("cm", "m", …) |
statistics | SceneStatistics | default | Scene object counts |
metadata | dict[str, str] | {} | Arbitrary extra data |
Cross-DCC Data Models
ObjectTransform
| Field | Type | Description |
|---|---|---|
translate | [float, float, float] | World XYZ in centimeters |
rotate | [float, float, float] | Euler XYZ in degrees |
scale | [float, float, float] | Non-uniform scale (sx, sy, sz) |
from dcc_mcp_core import ObjectTransform
t = ObjectTransform(
translate=[10.0, 0.0, 5.0],
rotate=[0.0, 45.0, 0.0],
scale=[1.0, 1.0, 1.0],
)
identity = ObjectTransform.identity() # origin, no rotation, scale=1BoundingBox
| Field | Type | Description |
|---|---|---|
min | [float, float, float] | Minimum corner in world space (cm) |
max | [float, float, float] | Maximum corner in world space (cm) |
from dcc_mcp_core import BoundingBox
bb = BoundingBox(min=[-1.0, 0.0, -1.0], max=[1.0, 2.0, 1.0])
bb.center() # [0.0, 1.0, 0.0]
bb.size() # [2.0, 2.0, 2.0]SceneObject
Lightweight description of any scene object, layer, or actor.
| Field | Type | Description |
|---|---|---|
name | str | Short leaf name (e.g. pCube1) |
long_name | str | Full path / unique ID (e.g. |group1|pCube1) |
object_type | str | Type string (mesh, light, camera, …) |
parent | str | None | Parent long name; None = scene root |
visible | bool | Whether the object is visible |
metadata | dict[str, str] | Arbitrary extra data |
SceneNode
| Field | Type | Description |
|---|---|---|
object | SceneObject | The object at this node |
children | list[SceneNode] | Immediate children (nested recursively) |
FrameRange
| Field | Type | Description |
|---|---|---|
start | float | First frame (inclusive) |
end | float | Last frame (inclusive) |
fps | float | Frames per second |
current | float | Currently active frame |
RenderOutput
Result of DccRenderCapture.render_scene().
| Field | Type | Description |
|---|---|---|
file_path | str | Absolute path to the rendered image |
width | int | Image width in pixels |
height | int | Image height in pixels |
format | str | File format (png, exr, jpg) |
render_time_ms | int | Render duration in milliseconds |