原始内容
name: dcc-mcp-creator description: >- Infrastructure skill - guide developers and agents through creating or modernizing a DCC-MCP adapter or standalone internal MCP service for Nuke, Blender, 3ds Max, Unreal, ZBrush, Houdini, Maya, and custom studio systems. Use when building server, dispatcher, gateway, packaging, and runtime integration. Not for authoring individual SKILL.md tool packages - use dcc-mcp-skills-creator. license: MIT-0 allowed-tools: Bash Read Write Edit metadata: dcc-mcp: dcc: python layer: infrastructure compatibility: "dcc-mcp-core 0.17+, Python 3.7+" version: "0.19.89" # x-release-please-version search-hint: >- create DCC MCP adapter, Nuke MCP, DccServerBase, HostExecutionBridge, dispatcher, readiness, resources, gateway, Blender, 3ds Max, Unreal, ZBrush, Houdini, Maya, standalone internal MCP service, private intranet, non-DCC server, chunked main-thread jobs, cooperative cancellation tags: "adapter-development, internal-mcp-service, standalone, host-runtime, dispatcher, gateway, nuke, blender, 3dsmax, unreal, zbrush" skill-reference-docs: - "references/*.md" openclaw: homepage: https://github.com/dcc-mcp/dcc-mcp-core/blob/main/skills/dcc-mcp-creator/SKILL.md
DCC-MCP Creator
Use this skill when you are creating a new DCC-MCP adapter, modernizing an existing adapter repository, or exposing a private non-DCC studio system as a standalone MCP service: server composition, host-thread dispatch, sidecar/gateway wiring, readiness, resources, project state, diagnostics, install lifecycle, or cross-DCC verification. A local folder, intranet source tree, or private monorepo is sufficient; GitHub is not a runtime requirement.
For individual skill packages (SKILL.md, tools.yaml, scripts, groups, and
skill taxonomy), load dcc-mcp-skills-creator instead.
Install and Route
Install the published
@loonghao/dcc-mcp-creator
package, then start a new agent turn:
openclaw skills install @loonghao/dcc-mcp-creator
npx --yes clawhub@0.23.1 install @loonghao/dcc-mcp-creator
Use dcc-mcp to operate an
existing DCC. Use
dcc-mcp-skills-creator
when only a DCC-specific Skill package is needed.
CLI-First Control Path
Use the dcc-mcp skill and dcc-mcp-cli for discovery, validation, and live
DCC control whenever the agent can run shell commands. If the CLI is missing,
follow the consent-gated official installation instructions in dcc-mcp.
Before long-lived validation, run dcc-mcp-cli update check; use
dcc-mcp-cli update apply to stage the latest CLI for the next launch. This
does not replace a running server binary.
Runtime Vocabulary
- DCC startup hook: adapter code running inside the host at application startup; it prepares env/instance data and launches the service path without blocking the DCC UI/main thread.
- Per-DCC service: one registered runtime row for one concrete DCC instance; Python
DccServerBaseand Rust sidecars both participate as per-DCC services. - Sidecar: the Rust
dcc-mcp-sidecarchild launched through the stabledcc-mcp-server sidecarcommand; it bridges host RPC to MCP/REST and exits when the watched DCC dies. - Gateway daemon: the one machine-wide
dcc-mcp-server gatewayprocess that owns routing, dynamic capability search/describe/call, and Gateway Admin. - Guardian: a lightweight loop inside daemon-backed services that probes gateway
/healthand re-ensures the daemon throughgateway-launch.lock; it is not a separate process. - Service heartbeat: registry freshness for the service row only. Do not describe heartbeat as the gateway restart trigger.
- Service owner: the process that owns the registry sentinel and MCP endpoint; its
pid/sentinel prove the service itself is alive. - Bound DCC host: optional external process identified by
host_pid; both owner and host must stay alive. Standalone/headless services intentionally have no bound host.
Fast Workflow
- Classify the ownership boundary before creating files:
- Public DCC adapter: run
dcc-mcp-cli dcc-types; improve an existing adapter instead of creating a duplicate. Add a genuinely new public adapter todcc-mcp-catalog.ymland the compatibility matrix. - Private non-DCC service: work in the supplied local or intranet project,
keep its stable custom service id private, and do not require a GitHub
repository, public catalog entry, issue, or release. Use a studio-owned
catalog only when operators need
dcc-mcp-cli installplans. - Skill package only: switch to
dcc-mcp-skills-creator.
- Public DCC adapter: run
- Classify the runtime integration:
- Embedded Python host: Blender, 3ds Max Python, Houdini, Maya, Nuke.
- External bridge host: ZBrush, Photoshop, Unity, custom tools.
- Game/editor host with mixed Python or C++ bridge: Unreal, Unity.
- Standalone internal service: no host bridge; use inline execution for ordinary service/file/API tools and keep every tool typed.
- Read the relevant reference:
- ADAPTER_WORKFLOW.md for the build path.
- INTERNAL_SERVICE_WORKFLOW.md for a private non-DCC service with no public repository requirement.
- HOST_PATTERN_MATRIX.md for host-specific wiring.
- CORE_ESCALATION_CHECKLIST.md before adding adapter-local glue.
- TESTING_AND_RELEASE.md before validating or publishing.
- Python 3.7 policy: native py37 is an LTS profile with no automatic calendar expiry. Verify the aggregate Python 3.7 gate is green and
requires-python = ">=3.7"is unchanged before any release.py37-litefallback does NOT satisfy release gates. Removal requires an accepted superseding ADR, a major release, and at least 180 days of notice. - docs/guide/gateway.md for gateway daemon lifecycle details.
- docs/guide/adapter-install-lifecycle.md for sidecar launch/readiness details.
- docs/guide/adapter-release-checklist.md for release train compliance.
- docs/guide/new-adapter-onboarding.md for new adapter scaffolding.
- docs/guide/adapter-compatibility-matrix.md for the per-DCC compatibility table.
- Start from
DccServerBase+DccServerOptions.from_env(...). Classify the runtime lifetime explicitly:- Embedded adapter: the service owner is the DCC process; no separate host PID is needed.
- Standard sidecar: pass
watch_pid=current_dcc_pid; core publishes the sidecar owner and bound host as separate liveness signals. - Other out-of-process adapter: pass
dcc_pid=current_dcc_pidsoMcpHttpConfig.host_pidbinds discovery to the DCC lifetime. - Standalone/headless service: pass
instance_type="standalone", leavedcc_pidunset, and do not bind it to an optional GUI process. Runtime identity is independent fromstandalone_main_thread, which controls tool execution only.
- Route host API calls through
HostExecutionBridge; do not hand-roll a second script executor. Standalone services with no host-thread boundary should keep the default inline execution path. - Keep service identity data-driven:
dcc_name/custom service id,server_name, env-var prefix, skill names, and gateway metadata. Leave the instance port unset so core resolvesDCC_MCP_<DCC>_PORTor asks the OS for a free port. - Use core helpers for skill discovery,
MinimalModeConfig, project tools, resources, diagnostics, context snapshots, install lifecycle, and gateway failover before writing adapter-local wrappers. PythonDccServerBase.collect_skill_search_paths()includes marketplace-installed skills under~/.dcc-mcp/marketplace/<dcc>(orDCC_MCP_MARKETPLACE_INSTALL_ROOT/<dcc>) when the directory exists, so adapters should not add a second marketplace path convention. Hermetic adapter tests should setDCC_MCP_DISABLE_DEFAULT_SKILL_PATHS=1; this excludes implicit local/platform defaults, marketplace installs, and Admin custom paths while explicit, bundled, and environment-provided skill paths remain active.- For Windows visual UI fallback, reuse the bundled
ui-controlskill and the isolateddcc-mcp-ui-control-host.exe; do not instantiateComputerUseSessionor add adapter-local screenshot/SendInputwrappers. Keepui_control__snapshotandui_control__actin the same long-lived adapter process so one thin named-pipe client retains the opaque host capability. Preservecapture_provenancewhen snapshots or recordings become evidence. Native Windows pixels requirebackend=windows-ui-control-hostandpixels_captured=true; use one logical UI Controlsession_idplus one stable gatewayagent_context.session_idfor attributable acceptance runs. The per-logon-session host owns the screenshot/UIA observations, visible banner, Esc stop token, input owner, confirmation, and native input.ui-controldeclaresrequires_in_process: truewhile keepingaffinity: any; registerHostExecutionBridgebefore skill loading. Never weaken this into per-call subprocess execution or route it onto a blocked DCC UI thread. A minimized or hidden exact HWND is recovered only through the host-ownedget_window_state/restore_window/show_window/activate_windowactions. They need no snapshot, must retain the existing capability-bound PID/HWND, and must never become desktop discovery or adapter-local Win32/input fallbacks. - Keep structured DCC skills, host APIs, and adapter scripts ahead of
ui-control. Agents should make an explicit, agent-directed transition into the scopedsnapshot→ oneact→snapshotloop only when an operation is unsupported, no suitable tool exists, or semantic UI Automation cannot reach the required control. Re-observe after every action. - Keep raw pointer and keyboard input operator-controlled. The adapter may
document
DCC_MCP_COMPUTER_USE_ALLOW_RAW_INPUT, but it must not enable the ceiling itself. Before raw input can start, the adapter/operator must setDCC_MCP_UI_CONTROL_UIA_PROCESS_IDorDCC_MCP_UI_CONTROL_UIA_WINDOW_HANDLEto the adapter's own DCC target; request scope may only narrow that trusted PID/HWND. Require a visible unlocked desktop and matching Windows integrity level, preserve the click-through border/banner/pointer feedback, and preserveuser_interruptedwithout automatic retry,session_idchanges, or fallback. Once Esc stops an session, onlyui_control__snapshot(resume_computer_use=true)may request a resume, and the isolated host must still obtain trusted user confirmation before clearing the latch. Always callui_control__stop_computer_usewhen the workflow ends. Never transition or retry through another UI/input path after a policy, authorization, authentication, security, confirmation,desktop_unavailable, oruser_interruptedresult. Keep mutating UI Control tools annotated as destructive. The optionalintentmay only raise the native host's independent UIA/input classification. Do not introduce a model-suppliedconfirmed/approvedflag or environment bypass. - For plug-in setup outside a window, reuse
ui_control__system_operationinstead of adding adapter-local PowerShell,reg.exe,mklink, or generic file-system tools. The host catalog named byDCC_MCP_UI_CONTROL_SYSTEM_GRANTS_FILEis operator-owned, and the adapter selects only its grant id throughDCC_MCP_UI_CONTROL_SYSTEM_GRANT_ID. Keep operations exact, typed, idempotent, confirmation-gated, and free of credentials. Do not treatelevation_requiredas permission to automate UAC or another shell path.
- For Windows visual UI fallback, reuse the bundled
- Use CLI profiles (
dcc-mcp-cli gateway ...,list/search/describe/call) as the user UX; treatdcc-mcp-servermodes as runtime plumbing. Readdocs/guide/gateway.mdbefore changing daemon, guardian, sentinel, registry, or idle-timeout behavior. Gateway discovery reuses a recent capability snapshot across adjacent queries. Route adapter catalog changes through the existing load/reload/unload contracts that force a refresh; never depend on every search polling the full backend catalog.gateway://instancesis agent-safe by default and returns only live, routable rows. Use?include_stale=true,?include_dead=true, or?view=allonly for explicit diagnosis; never route a call from those expanded operator views without re-validating live readiness. Once an instance is selected, reusegateway://instances/{instance_id}orGET /v1/instances/{instance_id}/contextfor live process/machine performance, scene/documents, loaded skills, and canonical follow-up routes. These reads fetch the backend context on demand, but scene freshness remains adapter-owned: publish changes from a host event/main-thread callback withDccServerBase.update_gateway_metadata(...), and publish rich snapshots withset_scene_resource(...). Never claim scene awareness when the adapter has not installed a publisher;scene=null/no_scene_publishedis explicit. For agent observability, readgateway://experiments/{experiment_id}for runs, Session DAG links, metrics, and Judge evidence; readgateway://governancefor the effective policy boundary. Keep Admin memory deletion controls out of agent-readable resources. - Use
dcc_mcp_core.install_lifecycle.build_sidecar_command(...)/launch_sidecar(...)for sidecar startup and readiness. Readdocs/guide/adapter-install-lifecycle.mdbefore changing host RPC, dispatch readiness, launch stdio,watch_pid, orinstance_idhandling.- The sidecar MCP listener is dispatch-only. A py37-lite factory can expose local skill metadata, but it cannot advertise or activate declarative skills through the gateway. Require a native py37 wheel for that path, or provide a separate discovery MCP URL; never report lite
load_skillsuccess without an executable catalog. - Wrap the outer adapter import/start block with
capture_bootstrap_errors(...); it is stdlib-only, records pre-MCP failures, and re-raises for the DCC's native error UI.DccServerBasealready captures Python error logs and uncaught exceptions into the shared log plusoutput:///events://. Forward host-native console callbacks withserver.report_host_error(...); do not replace global stdout/stderr or add an adapter-local error store.
- The sidecar MCP listener is dispatch-only. A py37-lite factory can expose local skill metadata, but it cannot advertise or activate declarative skills through the gateway. Require a native py37 wheel for that path, or provide a separate discovery MCP URL; never report lite
- Pass
instance_idto sidecar launch helpers only when it is a real UUID for the DCC service. During early startup, omit it or passNone;build_sidecar_command()rejects cosmetic values such as"unknown"withsuccess=falseandreason="invalid_instance_id"so adapters do not spawn a child that can only fail with a CLI argument error. AfterDccServerBase.start(), useserver.instance_idwhen adapter UI or sidecar wiring needs the canonical FileRegistry identity. It is the exact registered UUID and isNonebefore start, after stop, or when gateway registration is disabled/unavailable; never inspect private handles or generate a replacement UUID. - Adapter supervisors that must stop the sidecar on plugin unload should call
launch_sidecar(..., return_process=True, detached=False)instead of reimplementingsubprocess.Popen; keepreturn_process=Falsefor CLI/JSON paths because the process handle is not serializable. - If the adapter cannot share the gateway
FileRegistry, register remotely throughPOST /v1/instances/register, refresh with/heartbeat, and deregister on shutdown; the gateway will expose the row assource: "http"ingateway://instances/GET /v1/instances, preserveinstance_shortandmcp_url, and route it through the samelive_instancescontract. - Keep the gateway's secondary listener on its default loopback host. Opt into LAN access only with an explicit
--remote-host 0.0.0.0or concrete LAN IP; for same-LAN convenience discovery, build withmdnsand pair adapter-side--advertise-mdnswith gateway-side--discover-mdns. Treat mDNS as a multicast discovery hint only, keep auth/TLS policy explicit, and prefer HTTP registration or relay for routed/subnet-crossing production deployments. - For NAT or routed-subnet deployments, run the tunnel agent with stable
instance_id,capabilities_fingerprint,adapter_version, andscenemetadata, then configure the standalone gateway with--relay-source ADMIN_URL=PUBLIC_BASE_URL; the gateway will expose active tunnels assource: "relay"rows with relay details insource_metaafter probing/v1/healthzthrough<PUBLIC_BASE_URL>/tunnel/<tunnel_id>/mcp. - Preserve gateway caller attribution when adding adapter wrappers or admin/debug routes: let MCP
initialize.params.clientInfo, MCP_meta.agent_context, RESTmeta.agent_context,x-dcc-mcp-*headers, and safeUser-Agentfallbacks flow through core rather than logging raw prompts or local machine data. - For lifecycle/memory/telemetry policy, use
register_lifecycle_hooks(...),search_skills(..., session_id=...),dispatch_session_start(...),dispatch_before_tool_call(...),dispatch_after_tool_call(...), anddispatch_session_end(...); pairMemoryRecorder(InMemoryMemoryStore()).install(hooks)with those hooks when adapters need bounded memory summaries, failed-pattern avoidance, or session compaction. Memory injection is conservative and budgeted by default: search receives compact ranking hints, tool calls receive memory only when it matches the currenttool_name, and session-start injection is opt-in. UseSqliteMemoryStore()only when longterm patterns should be durable, operator-managed in the Admin Memory tab, and included in memory hit-rate observability; disable the recorder for privacy-sensitive deployments. Open a focused core issue/RFC only when those public hooks cannot express the adapter boundary. - Add one executable smoke path: unit tests for construction plus either headless DCC, mock dispatcher MCP calls, gateway REST replay, mDNS same-LAN discovery smoke, relay-source smoke, the open-source MCP Inspector for a loopback internal service, or
just idle-memory-smokefor standalone server idle/regression checks. - For gateway/admin observability, surface explicit state instead of silent zeroes: traffic panels should report disabled, unavailable, filtered, or genuine no-traffic states; skill panels should distinguish discovered, loaded, searched, selected, called, failed, and low-adoption skills; and admin-facing frames/paths should stay metadata-only or aliased unless an operator explicitly configures a private raw sink. Keep
ServiceEntry.versionas the DCC application version; use core-publisheddcc_mcp_server_versionanddcc_mcp_instance_type=gui|standalonemetadata for server regression and runtime-shape diagnostics instead of overloading DCC or adapter versions. - Preserve workflow observability: adapter calls should carry request, parent, trace, session, DCC, transport, and artifact/validation metadata so the Admin workflow graph can show Intent → Discovery → Skill Load → Tool Calls → Fallbacks → Artifacts → Validation → Report without raw log reading.
- Preserve bounded
agent_contexttask/session/turn metadata and artifact/validation-friendly tool names so Admin task outcomes can group workflows, calls, deliverables, and checks without reading raw payloads or local paths. - Preserve record-replay ownership boundaries: forward server-derived
agent_context.session_id, keep UI Control logical ids connection/caller scoped, and write only redacted recording projections to existingsession_events. Do not add adapter-local recorder state, a second database, or a replay authority flag. Generated workflows re-resolve current tools and schemas; semantic UI replay resolves fresh control ids; raw/visual fallback requires exact-window calibration and drift guards. - Record reproducible experiment definitions, run states, Session DAG links,
metrics, and judge evidence through the gateway
/v1/experimentsAPIs. Reusesession_events, workflow/recording identifiers, and artifact references; do not add adapter-local experiment storage or treat judge output as approval authority.
Chunked Main-Thread Jobs
Use the shared chunked path when a main-affinity operation cannot finish within one host UI tick. The adapter owns scheduling; skill code only defines bounded steps:
from dcc_mcp_core import chunked_job
@chunked_job(total=100)
def bake_frames():
for frame in range(100):
yield lambda frame=frame: bake_one_frame(frame)
# A declarative in-process tool returns this runner. HostExecutionBridge
# detects and submits it to HostUiDispatcherBase automatically.
return bake_frames()
- Declare
execution: async,affinity: main, andjob_strategy: chunked. The bridge rejects a declared chunked tool that returns a monolithic value. - Yield one bounded host-API callable per step. A returned string becomes the progress message.
submit_chunked_runner()advances at most one step per host pump tick, so unrelated UI work can run between steps.cancel(request_id)requests cancellation. The runner publishescancelledonly after the next checkpoint observes it; a running native DCC call or monolithic callback is not pre-empted.- Do not add adapter-local generator pumps, timer loops, worker threads, or a second job registry.
- Test pending cancellation, cancellation during a step, monotonic progress, failure, exactly one terminal result, unrelated pump work, and at least two host labels.
Do not label an indivisible native call as chunked. Use
job_strategy: monolithic when the host API cannot yield, or
job_strategy: isolated when a process/service-owned operation can return a
durable job id. Isolated status must remain queryable after transport loss;
cancellation may remain process-owner scoped when reconstructing ownership
would be unsafe.
Liveness and Crash Recovery
- Keep registry heartbeat and HTTP readiness independent of the DCC main
thread. A readiness/transport timeout marks the instance
unreachable; it must not erase a row whose owner lock/PID or remote TTL is still valid. - Treat owner lock/PID death or remote TTL expiry as crash evidence. After a crash, the adapter cannot reconnect until the DCC or sidecar starts again.
- Preserve stable
dcc_type, scene/project metadata, and adapter identity so agents can rediscover a replacement instance. Never reuse an old tool slug or direct MCP URL after the instance id changes. - Enable core job persistence. On restart, in-flight core jobs become
interruptedand remain queryable through the replacement instance'sjobs_get_status; adapter-owned isolated jobs need their own durable status tool when they outlive the request transport. If the worker can outlive the DCC/sidecar process, that status tool must be owned by the worker/service or another independently live control process; gateway restart alone cannot recreate an API whose owner exited.
Failure Analysis and Bug Routing
Reproduce through dcc-mcp and keep one gateway session id. Run
dcc-mcp-cli doctor, then dcc-mcp-cli stats --status failure --session-id <session-id>; preserve the failed call's request_id, trace/job ids, adapter
version, DCC version, readiness fields, and the smallest safe reproduction.
Use /v1/debug/issue-reports/<request_id> for the public-safe issue body and
review any ?mode=raw export locally before sharing it.
Report adapter-owned dispatch, host-thread, readiness, packaging, or install
bugs in the adapter repository. Escalate shared CLI, gateway, protocol, or core
contract failures to dcc-mcp-core. Tool schema/script/workflow defects belong
to the owning Skill and dcc-mcp-skills-creator. Record runtime feedback with
the CLI-discovered dcc_feedback__report tool; open an external issue only
with user authorization.
Example: New Nuke Adapter
When asked to create a Nuke MCP adapter, start by mapping the host lifecycle: how Python is loaded, how the UI/main thread must be entered, what headless mode is available, how plugins are installed, and which operations should be bundled as default skills. Then scaffold the adapter around core primitives:
DccServerBasefor MCP/HTTP and skill catalog behavior.DccServerOptions.from_env("NUKE")or an adapter-specific equivalent for env-driven configuration.HostExecutionBridgeplus a Nuke dispatcher for all Nuke API calls.- Core project, readiness, resource, diagnostics, and gateway helpers before adapter-local glue.
dcc-mcp-skills-creatorfor the firstnuke-*skill packages.
Example: Private Non-DCC Service
When asked to expose an internal asset, render-farm, review, or production
service, stay in the supplied private project and start with
examples/remote-server. It is a standalone
service despite the historical directory name: it binds to loopback for local
development, discovers a bundled example Skill, and needs no DCC process or GitHub
repository.
- Use a stable custom identifier such as
studio-assets; do not pretend it is Maya or another cataloged DCC. - Pass
instance_type="standalone", leavedcc_pidunset, and use inline execution unless a real external host boundary exists. - Validate the Skill, start the service, then exercise
tools/list,tools/call, resources, and errors with the official open-source MCP Inspector before testing gateway discovery. - Keep development on loopback. Intranet exposure requires operator-owned TLS, authentication, firewall policy, secret storage, and audit controls.
- Package through the owner's existing wheel, archive, container, Rez, or private registry workflow. Do not create or publish a public repository unless the user explicitly requests it.
Non-Negotiables
- Do not touch a DCC API from a Tokio/HTTP worker thread.
- Do not parse or rewrite
SKILL.md,tools.yaml,groups.yaml, or prompt/workflow files in adapter runtime code when core exposes a typed object or catalog API. - Do not reach into
server._serverunless no public core API exists; if you must, file a core issue and keep the adapter shim small. - Do not create Maya-only abstractions in shared core or adapter templates.
- Do not expose raw script execution as the primary user workflow when a typed skill can cover the task.
- Do not require GitHub, a public catalog entry, or public issue tracking for a private internal service.
- Do not publish local paths, private machine names, or source-attribution markers in public issues or PR text.