DCC-MCP-IPC
Multi-protocol IPC adapter layer for integrating DCC software (Maya, Houdini, Blender, Unreal, Unity) with MCP, enabling tool registration and remote control across multiple transport protocols.
README
DCC-MCP-IPC
<div align="center"> <img src="https://raw.githubusercontent.com/loonghao/dcc-mcp-ipc/main/logo.svg" alt="DCC-MCP-IPC Logo" width="200"/>
Multi-protocol IPC adapter layer for DCC software integration with Model Context Protocol (MCP).
Built on top of dcc-mcp-core (Rust/PyO3 backend), it provides a high-performance, type-safe framework for exposing DCC functionality as MCP tools across multiple transport protocols.
Documentation: docs site | v2.0.0 (Unreleased) — Breaking changes ahead, see CHANGELOG.md
Why DCC-MCP-IPC?
| Feature | Description |
|---|---|
| Protocol-agnostic | RPyC for embedded-Python DCCs (Maya/Houdini/Blender), HTTP for Unreal/Unity, WebSocket, and Rust-native IPC for maximum throughput. |
| Zero-code Skills | Drop a SKILL.md file into a directory — SkillManager auto-registers it as an MCP tool. No Python boilerplate needed. |
| Rust-powered core | Action dispatch, validation, and telemetry handled by dcc-mcp-core via PyO3; Python layer focuses on DCC-specific glue code. |
| Hot-reload skills | SkillWatcher monitors skill directories and re-registers tools on file changes without restarting the DCC. |
| Service discovery | ZeroConf (mDNS) + file-based fallback for automatic DCC server detection. |
| Connection pooling | ConnectionPool with auto-discovery for efficient client-side connection reuse. |
Features
- Thread-safe RPyC / HTTP / WebSocket / Rust-native IPC server implementations
- Skills system — zero-code MCP tool registration from
SKILL.mdfrontmatter with hot-reload - Action system backed by
ActionRegistry+ActionDispatcher(Rust) — JSON-serialised parameter dispatch - Transport factory — pluggable transport layer (
rpyc,http,websocket,ipc) - Service discovery: ZeroConf (mDNS) + file-based fallback via
ServiceDiscoveryFactory - Async client (
asyncio) for non-blocking operations - Abstract base classes for creating DCC-specific adapters (
DCCAdapter) and services - Application adapter pattern for generic app integration
- Scene & snapshot interfaces over RPyC and HTTP transports
- Mock DCC services for testing without actual DCC applications
- Comprehensive error handling with custom exception hierarchy
Architecture
graph TD
A[AI Assistant / MCP Client] --> B[MCP Server Layer]
B --> C[ActionAdapter\nActionRegistry + ActionDispatcher]
C --> D[RPyC Transport\nDCC Python env]
C --> E[IPC Transport\nRust FramedChannel]
C --> F[HTTP Transport\nUnreal / Unity REST]
C --> G[WebSocket Transport]
G[SkillManager\nSKILL.md auto-discovery] --> C
H[dcc-mcp-core\nRust/PyO3 backend] --> C
D --> I[DCC App\nMaya / Houdini / Blender]
E --> I
F --> J[DCC App\nUnreal / Unity]
style C fill:#e1f5fe
style H fill:#fff3e0
style G fill:#e8f5e9
Key Components
| Component | Module | Description |
|---|---|---|
ActionAdapter |
action_adapter.py |
Wraps Rust ActionRegistry + ActionDispatcher; registers handlers and dispatches JSON-parameterised calls |
SkillManager |
skills/scanner.py |
Scans directories for SKILL.md skills, registers them as action handlers, supports hot-reload |
DCCServer |
server/dcc.py |
Manages the RPyC/IPC server lifecycle inside a DCC process |
BaseDCCClient |
client/base.py |
Core client connection/call logic with auto-discovery |
ConnectionPool |
client/pool.py |
Connection pooling for efficient resource management |
IpcClientTransport / IpcServerTransport |
transport/ipc_transport.py |
Rust-native framed-channel IPC, registered as "ipc" protocol |
ServiceDiscoveryFactory |
discovery/factory.py |
Strategy-pattern selector for ZeroConf or file-based discovery |
MockDCCService |
testing/mock_services.py |
Simulates DCC applications for testing |
Installation
pip install dcc-mcp-ipc
With optional ZeroConf support:
pip install "dcc-mcp-ipc[zeroconf]"
Or with Poetry:
poetry add dcc-mcp-ipc
Requirements
- Python >= 3.8 (< 4.0)
- dcc-mcp-core >= 0.12.0 (< 1.0.0)
- rpyc >= 6.0.0 (< 7.0.0)
- Optional: zeroconf >= 0.38.0 for mDNS discovery
Quick Start
Server-side (within DCC application)
<augment_code_snippet path="README.md" mode="EXCERPT">
from dcc_mcp_ipc.server import create_dcc_server, DCCRPyCService
class MayaService(DCCRPyCService):
def get_scene_info(self):
return {"scene": "Maya scene info"}
def exposed_execute_cmd(self, cmd_name, *args, **kwargs):
pass
server = create_dcc_server(
dcc_name="maya",
service_class=MayaService,
port=18812,
)
server.start(threaded=True)
</augment_code_snippet>
Client-side
<augment_code_snippet path="README.md" mode="EXCERPT">
from dcc_mcp_ipc.client import BaseDCCClient
client = BaseDCCClient("maya", host="localhost", port=18812)
client.connect()
result = client.call("get_scene_info")
client.disconnect()
</augment_code_snippet>
Usage Guide
Action System (v2.0.0+)
The Action system is built on the Rust-backed ActionRegistry + ActionDispatcher. All parameters are JSON-serialised:
<augment_code_snippet path="README.md" mode="EXCERPT">
from dcc_mcp_ipc.action_adapter import ActionAdapter, get_action_adapter
adapter = get_action_adapter("maya")
def create_sphere(radius: float = 1.0, name: str = "sphere1") -> dict:
return {"success": True, "message": f"Created {name}", "context": {"name": name}}
adapter.register_action(
"create_sphere",
create_sphere,
description="Create a sphere primitive",
category="modeling",
tags=["primitive", "mesh"],
)
result = adapter.call_action("create_sphere", radius=2.0, name="mySphere")
print(result.success) # True
print(result.to_dict()) # {"success": True, ...}
</augment_code_snippet>
Zero-code Skills via SkillManager
Drop a SKILL.md file into a directory structure:
my_skills/
create_light/
SKILL.md # frontmatter: name, description, tools, scripts
run.py # executed when the tool is called
<augment_code_snippet path="README.md" mode="EXCERPT">
from dcc_mcp_ipc.skills import SkillManager
from dcc_mcp_ipc.action_adapter import get_action_adapter
adapter = get_action_adapter("maya")
mgr = SkillManager(adapter=adapter, dcc_name="maya")
mgr.load_paths(["/pipeline/skills"])
mgr.start_watching()
# Now "create_light" is callable as an MCP tool
result = adapter.call_action("create_light", intensity=100.0)
</augment_code_snippet>
Connection Pool
<augment_code_snippet path="README.md" mode="EXCERPT">
from dcc_mcp_ipc.client import ConnectionPool
pool = ConnectionPool()
with pool.get_client("maya", host="localhost") as client:
result = client.call("execute_cmd", "sphere", radius=5)
print(result)
</augment_code_snippet>
Service Factories
Three factory patterns are available for different lifecycle needs:
<augment_code_snippet path="README.md" mode="EXCERPT">
from dcc_mcp_ipc.server import (
create_service_factory,
create_shared_service_instance,
create_raw_threaded_server,
)
class SceneManager:
def __init__(self):
self.scenes = {}
def add_scene(self, name, data):
self.scenes[name] = data
scene_manager = SceneManager()
# Per-connection instance
service_factory = create_service_factory(MayaService, scene_manager)
# Shared singleton instance
shared_service = create_shared_service_instance(MayaService, scene_manager)
# Raw threaded server
server = create_raw_threaded_server(service_factory, port=18812)
server.start()
</augment_code_snippet>
Rust-native IPC Transport
Zero-copy low-latency messaging via the Rust core:
<augment_code_snippet path="README.md" mode="EXCERPT">
import os
from dcc_mcp_core import TransportAddress
from dcc_mcp_ipc.transport.ipc_transport import (
IpcClientTransport,
IpcServerTransport,
IpcTransportConfig,
)
# Client side
config = IpcTransportConfig(host="localhost", port=19000)
transport = IpcClientTransport(config)
transport.connect()
result = transport.execute("get_scene_info")
transport.disconnect()
# Server side (inside DCC plugin)
def handle_channel(channel):
msg = channel.recv()
# process and respond ...
addr = TransportAddress.default_local("maya", os.getpid())
server = IpcServerTransport(addr, handler=handle_channel)
bound_addr = server.start()
</augment_code_snippet>
Creating a Custom DCC Adapter
<augment_code_snippet path="README.md" mode="EXCERPT">
from dcc_mcp_ipc.adapter import DCCAdapter
from dcc_mcp_ipc.client import BaseDCCClient
class MayaAdapter(DCCAdapter):
def _initialize_client(self) -> None:
self.client = BaseDCCClient(
dcc_name="maya",
host=self.host,
port=self.port,
connection_timeout=self.connection_timeout,
)
def create_sphere(self, radius: float = 1.0):
self.ensure_connected()
assert self.client is not None
return self.client.execute_dcc_command(f"sphere -r {radius};")
</augment_code_snippet>
Async Client
<augment_code_snippet path="README.md" mode="EXCERPT">
import asyncio
from dcc_mcp_ipc.client.async_dcc import AsyncDCCClient
async def main():
client = AsyncDCCClient("maya", host="localhost", port=18812)
await client.connect()
result = await client.call("get_scene_info")
await client.disconnect()
asyncio.run(main())
</augment_code_snippet>
Testing with Mock Services
<augment_code_snippet path="README.md" mode="EXCERPT">
import threading
from dcc_mcp_ipc.testing.mock_services import MockDCCService
from dcc_mcp_ipc.client import BaseDCCClient
server = MockDCCService.start(port=18812)
client = BaseDCCClient("mock_dcc", host="localhost", port=18812)
client.connect()
info = client.get_dcc_info()
print(info) # {"name": "mock_dcc", ...}
client.disconnect()
server.stop()
</augment_code_snippet>
Development
Setup
git clone https://github.com/loonghao/dcc-mcp-ipc.git
cd dcc-mcp-ipc
poetry install
Running Tasks
nox -s pytest # Run tests
nox -s lint # Lint (mypy + ruff + isort)
nox -s lint-fix # Auto-fix lint issues
nox -s build # Build distribution packages
Project Structure
dcc-mcp-ipc/
├── src/dcc_mcp_ipc/
│ ├── __init__.py # Lazy-import public API surface
│ ├── action_adapter.py # Action system (Rust-backed)
│ ├── adapter/ # DCC & application adapters
│ ├── client/ # Synchronous & async clients + pool
│ ├── server/ # RPyC server + factories + lifecycle
│ ├── transport/ # RPyC / HTTP / WS / IPC transports
│ ├── discovery/ # ZeroConf + file-based service discovery
│ ├── skills/ # SkillManager zero-code system
│ ├── scene/ # Scene operations interface
│ ├── snapshot/ # Snapshot interface
│ ├── application/ # Generic application adapter/service/client
│ ├── testing/ # Mock services for testing
│ └── utils/ # Errors, DI, decorators, RPyC helpers
├── tests/ # 68 test files mirroring source layout
├── examples/ # Usage examples
├── docs/ # VitePress documentation site
└── nox_actions/ # Nox task definitions
License
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。