# dcc-mcp-zbrush

> Agent entry point. Read `AGENTS.md` for full navigation map.

## Supported modes

|Mode|When to use|Stack|
|---|---|---|
|**Sidecar + socket plugin (recommended)**|Production GUI and CI clients|External Python → TCP :9876 → receipt-managed dedicated bridge → zbrush.commands|
|**Embedded (advanced)**|Pure-Python experiments only|Python plugin inside ZBrush → zbrush.commands|

## Distribution artifacts

There are three independent distribution channels. Each covers a different scope:

|Artifact|Scope|Install command|
|---|---|---|
|**PyPI wheel** (`dcc-mcp-zbrush`)|MCP server, skills, bridge client, and lifecycle CLI|`python -m pip install "dcc-mcp-zbrush==<version>"`|
|**Plugin ZIP**|Fixed-version ZBrush host payload with SHA-256 provenance|`Resolved and verified by dcc-mcp-zbrush install`|
|**Repo source**|Everything above + bridge/plugin/ raw sources + tests + tools|`git clone https://github.com/dcc-mcp/dcc-mcp-zbrush.git`|

Use the receipt-driven lifecycle; never copy a bridge over the shared Python/init.py file.

## Install steps (recommended sidecar)

### Recommended receipt-driven sidecar install

1. python -m pip install "dcc-mcp-zbrush==<version>"
2. Set ZBRUSH_USER_ASSETS_DIR to the explicit Asset Directory
3. Plan with dcc-mcp-zbrush install --version <version> --dcc-path <ZBrush-path> --python python --dry-run --json
4. Apply the reviewed plan with --yes --json
5. Restart ZBrush and run dcc-mcp-zbrush verify with the same path flags
6. Run dcc-mcp-zbrush --mode sidecar

### Sidecar from source checkout

1. pip install -e ".[dev]"
2. Build the plugin ZIP and exercise it through the same lifecycle
3. Never overwrite the shared Python/init.py file
4. Restart ZBrush and run verify

MCP endpoint: `http://127.0.0.1:9765/mcp`

## MCP config snippets

### Cursor / Claude Desktop

```json
{
  "mcpServers": {
    "dcc-mcp-zbrush": {
      "url": "http://127.0.0.1:9765/mcp"
    }
  }
}
```

### With gateway (multi-DCC)

```json
{
  "mcpServers": {
    "dcc-mcp-zbrush": {
      "url": "http://127.0.0.1:9765/mcp"
    }
  }
}
```

## Environment variables

|Variable|Default|Purpose|
|---|---|---|
|DCC_MCP_ZBRUSH_PORT|`OS-assigned`|Optional fixed MCP instance port|
|DCC_MCP_ZBRUSH_MODE|`auto`|sidecar by default; embedded is advanced and pure-Python only|
|DCC_MCP_ZBRUSH_AUTOSTART|`1`|Auto-start embedded server from plugin|
|DCC_MCP_ZBRUSH_SOCKET_PORT|`9876`|Socket bridge port (sidecar)|
|DCC_MCP_GATEWAY_PORT|`9765`|Gateway election port|
|DCC_MCP_MINIMAL|`1`|Progressive skill loading|

## Bundled skills

|Skill|Tools|
|---|---|
|zbrush-scripting|execute_python, get_session_info|
|zbrush-scene|get_scene_info, list_subtools|
|zbrush-subtool|—|
|zbrush-brush|create_wrinkle_brush, load_wrinkle_brush|
|zbrush-viewport|capture_turntable|
|zbrush-interchange|—|
|zbrush-import-to-scene|import_to_scene|

## Health check

```bash
dcc-mcp-zbrush verify --version <version> --dcc-path <ZBrush-path> --python python --json
```

```bash
dcc-mcp-cli list  # discovers the exact OS-assigned instance URL
```

```bash
call_tool("get_session_info")  # reads version + active tool + subtool count
```

```bash
SocketBridge.connect()  # sends JSON-RPC ping → expects {"ok": true}
```

## Common failure modes

|Problem|Likely cause|Fix|
|---|---|---|
|Connection refused|ZBrush not running|Start ZBrush|
|MCP endpoint unreachable|Wrong mode or stale direct URL|Start dcc-mcp-zbrush --mode sidecar, then run dcc-mcp-cli list; socket bridge remains on 9876|
|ZBrushNotAvailableError|Socket bridge is not ready|Run lifecycle status, restart ZBrush, then run verify|
|partial install|Receipt or managed payload drift|Fail closed; inspect the receipt and backup before retrying|
|checksum mismatch|Payload is not the fixed official release asset|Do not bypass; select a fixed official version and retry|
|subprocess fails|ZBrush Python VM does not support subprocess|Use execute_python skill instead|
|ZBrush version < 2026.1|No Python SDK available|Upgrade to ZBrush 2026.1+|
