Skip to content

Transport API

dcc_mcp_core — DccLinkFrame, IpcChannelAdapter, GracefulIpcChannelAdapter, SocketServerAdapter, TransportAddress, TransportScheme, ServiceEntry, ServiceStatus.

Overview

The transport module provides DccLink-based IPC communication between AI agents and DCC applications. Key design decisions:

  • Named Pipes (Windows) and Unix Domain Sockets (macOS/Linux) are preferred for same-machine connections — sub-millisecond latency, zero configuration.
  • DccLink adapters wrap ipckit channels with a binary wire format: [u32 len][u8 type][u64 seq][msgpack body].
  • IpcChannelAdapter.create(name) + wait_for_client() is the recommended server setup.
  • IpcChannelAdapter.connect(name) is the client-side entry point.
  • GracefulIpcChannelAdapter adds graceful shutdown and DCC main-thread integration.
  • SocketServerAdapter provides multi-client connections with a bounded connection pool.

DccLinkFrame

A DCC-Link frame with msg_type, seq, and body fields.

Wire format: [u32 len][u8 type][u64 seq][msgpack body].

Message type tags: 1=Call, 2=Reply, 3=Err, 4=Progress, 5=Cancel, 6=Push, 7=Ping, 8=Pong.

Constructor

python
from dcc_mcp_core import DccLinkFrame

frame = DccLinkFrame(msg_type=1, seq=0, body=b"hello")
ParameterTypeDefaultDescription
msg_typeintMessage type tag (1-8). Raises ValueError if invalid.
seqintSequence number.
bodybytes | NoneNonePayload bytes.

Properties

PropertyTypeDescription
msg_typeintMessage type tag (1=Call, 2=Reply, 3=Err, 4=Progress, 5=Cancel, 6=Push, 7=Ping, 8=Pong)
seqintSequence number
bodybytesPayload bytes

Methods

MethodReturnsDescription
encode()bytesEncode the frame to [len][type][seq][body] bytes
decode(data)DccLinkFrameDecode a frame from bytes including the 4-byte length prefix (static). Raises RuntimeError if malformed.

Example

python
frame = DccLinkFrame(msg_type=1, seq=0, body=b"payload")
encoded = frame.encode()
decoded = DccLinkFrame.decode(encoded)
assert decoded.msg_type == frame.msg_type
assert decoded.seq == frame.seq
assert decoded.body == frame.body

IpcChannelAdapter

Thin adapter over ipckit::IpcChannel using DCC-Link framing. Provides 1:1 framed IPC connections via Named Pipes (Windows) or Unix Domain Sockets (macOS/Linux).

Static Methods

MethodReturnsDescription
create(name)IpcChannelAdapterCreate a server-side IPC channel. Raises RuntimeError if creation fails.
connect(name)IpcChannelAdapterConnect to an existing IPC channel. Raises RuntimeError if connection fails.

Instance Methods

MethodReturnsDescription
wait_for_client()NoneWait for a client to connect (server-side only). Raises RuntimeError if the wait fails.
send_frame(frame)NoneSend a DccLinkFrame to the peer. Raises RuntimeError if the send fails.
recv_frame()DccLinkFrame | NoneReceive a DCC-Link frame (blocking). Returns None if the channel is closed. Raises RuntimeError on unexpected errors.

Example: Server

python
from dcc_mcp_core import IpcChannelAdapter, DccLinkFrame

server = IpcChannelAdapter.create("my-dcc")
server.wait_for_client()

frame = server.recv_frame()
if frame is not None:
    reply = DccLinkFrame(msg_type=2, seq=frame.seq, body=b"result")
    server.send_frame(reply)

Example: Client

python
from dcc_mcp_core import IpcChannelAdapter, DccLinkFrame

client = IpcChannelAdapter.connect("my-dcc")
call = DccLinkFrame(msg_type=1, seq=0, body=b"request")
client.send_frame(call)

reply = client.recv_frame()
if reply is not None:
    print(reply.body)

GracefulIpcChannelAdapter

Graceful IPC channel adapter with shutdown and affinity-pump support. Extends IpcChannelAdapter with graceful shutdown and bind_affinity_thread / pump_pending for integrating with DCC main-thread idle callbacks.

For reentrancy-safe Python dispatch, prefer DeferredExecutor from dcc_mcp_core._core instead of submit().

Static Methods

MethodReturnsDescription
create(name)GracefulIpcChannelAdapterCreate a server-side graceful IPC channel. Raises RuntimeError if creation fails.
connect(name)GracefulIpcChannelAdapterConnect to an existing graceful IPC channel. Raises RuntimeError if connection fails.

Instance Methods

MethodReturnsDescription
wait_for_client()NoneWait for a client to connect (server-side only). Raises RuntimeError if the wait fails.
send_frame(frame)NoneSend a DccLinkFrame to the peer. Raises RuntimeError if the send fails.
recv_frame()DccLinkFrame | NoneReceive a DCC-Link frame (blocking). Returns None if the channel is closed. Raises RuntimeError on unexpected errors.
shutdown()NoneSignal the channel to shut down gracefully.
bind_affinity_thread()NoneBind the current thread as the affinity thread for reentrancy-safe dispatch. Call once on the DCC main thread.
pump_pending(budget_ms=100)intDrain pending work items on the affinity thread within the budget. Call from DCC host idle callback. Returns number of items processed.

Example

python
from dcc_mcp_core import GracefulIpcChannelAdapter, DccLinkFrame

server = GracefulIpcChannelAdapter.create("my-dcc")
server.bind_affinity_thread()
server.wait_for_client()

# In DCC idle callback:
# processed = server.pump_pending(budget_ms=50)

frame = server.recv_frame()
if frame is not None:
    reply = DccLinkFrame(msg_type=2, seq=frame.seq, body=b"ok")
    server.send_frame(reply)

server.shutdown()

SocketServerAdapter

Minimal wrapper for ipckit::SocketServer (multi-client Unix socket / named pipe). Supports a bounded connection pool.

Constructor

python
from dcc_mcp_core import SocketServerAdapter

server = SocketServerAdapter(
    path="/tmp/my-dcc.sock",
    max_connections=10,
    connection_timeout_ms=30000,
)
ParameterTypeDefaultDescription
pathstrSocket path (Unix) or pipe name (Windows). Raises RuntimeError if creation fails.
max_connectionsint10Maximum concurrent connections.
connection_timeout_msint30000Connection timeout in milliseconds.

Properties

PropertyTypeDescription
socket_pathstrThe socket path this server is listening on.
connection_countintNumber of currently connected clients.

Instance Methods

MethodReturnsDescription
shutdown()NoneGracefully shut down the server (blocks until stopped).
signal_shutdown()NoneSignal shutdown without blocking.

TransportAddress

Protocol-agnostic transport endpoint for DCC communication. Supports TCP, Named Pipes (Windows), and Unix Domain Sockets (macOS/Linux).

Static Methods

MethodReturnsDescription
tcp(host, port)TransportAddressCreate a TCP transport address
named_pipe(name)TransportAddressCreate a Named Pipe transport address (Windows)
unix_socket(path)TransportAddressCreate a Unix Domain Socket transport address
default_local(dcc_type, pid)TransportAddressGenerate optimal local transport for the current platform
default_pipe_name(dcc_type, pid)TransportAddressGenerate a default Named Pipe name for a DCC instance
default_unix_socket(dcc_type, pid)TransportAddressGenerate a default Unix Socket path for a DCC instance
parse(s)TransportAddressParse URI string (tcp://, pipe://, unix://)

Properties

PropertyTypeDescription
schemestrTransport scheme: "tcp", "pipe", or "unix"
is_localboolWhether this is a same-machine transport
is_tcpboolWhether this is a TCP transport
is_named_pipeboolWhether this is a Named Pipe transport
is_unix_socketboolWhether this is a Unix Socket transport

Methods

MethodReturnsDescription
to_connection_string()strURI string, e.g. "tcp://127.0.0.1:18812"

Example

python
import os
from dcc_mcp_core import TransportAddress

addr = TransportAddress.default_local("maya", os.getpid())
print(addr.scheme)   # "pipe" on Windows, "unix" on macOS/Linux
print(addr.is_local) # True

TransportScheme

Transport selection strategy for choosing the optimal communication channel.

Constants

ConstantDescription
AUTOAuto-select best transport (Named Pipe on Windows, Unix Socket on *nix)
TCP_ONLYAlways use TCP
PREFER_NAMED_PIPEPrefer Named Pipe, fall back to TCP
PREFER_UNIX_SOCKETPrefer Unix Socket, fall back to TCP
PREFER_IPCPrefer any IPC (Pipe or Unix Socket), fall back to TCP

Methods

MethodReturnsDescription
select_address(dcc_type, host, port, pid=None)TransportAddressSelect optimal transport address
python
from dcc_mcp_core import TransportScheme

addr = TransportScheme.AUTO.select_address("maya", "127.0.0.1", 18812, pid=12345)

ServiceEntry

Represents a discovered DCC service instance.

Attributes

AttributeTypeDescription
dcc_typestrDCC application type (e.g. "maya")
instance_idstrUUID string
hoststrHost address
portintTCP port
versionstr | NoneDCC version
scenestr | NoneCurrently open scene/file
documentslist[str]Open documents
pidint | NoneProcess ID
display_namestr | NoneDisplay name
metadatadict[str, str]Arbitrary string-only metadata
statusServiceStatusInstance status
transport_addressTransportAddress | NonePreferred IPC address
last_heartbeat_msintLast heartbeat timestamp (Unix ms)

Properties

PropertyTypeDescription
extrasdict[str, Any]Arbitrary DCC-specific extras with JSON-typed values. Unlike metadata (string-only), extras allows nested objects / arrays / numbers / booleans. Returns a fresh dict — mutating it does not update the registry.

Methods

MethodReturnsDescription
effective_address()TransportAddressIPC address or TCP fallback
to_dict()dictSerialize to dict

ServiceStatus

Enum for DCC service instance status.

Constants

ConstantDescription
AVAILABLEAccepting connections (default)
BUSYProcessing a request
UNREACHABLEHealth check failed
SHUTTING_DOWNShutting down

Wire Protocol

DccLink frames use the following binary wire format:

[u32 len][u8 type][u64 seq][msgpack body]
  • len — 4-byte big-endian total frame length (including type + seq + body)
  • type — 1-byte message type tag (1-8)
  • seq — 8-byte big-endian sequence number
  • body — MessagePack-encoded payload

Message types:

TagTypeDirectionDescription
1CallClient → ServerRequest invocation
2ReplyServer → ClientSuccessful response
3ErrServer → ClientError response
4ProgressServer → ClientProgress update
5CancelClient → ServerCancellation signal
6PushServer → ClientServer-pushed message
7PingEitherHeartbeat request
8PongEitherHeartbeat response

Released under the MIT License.