Skip to content

Transports & Bridges ProOnly

Logic Driver Assist registers its operations in one editor-side registry. A transport (also called a bridge or provider) is a thin adapter that exposes that registry to a caller: the built-in console, an MCP bridge, a third-party copilot, or something you write yourself. The operation set and every operation's behavior are the same no matter which transport carries the call. Only the call mechanics and the result envelope differ.

This page collects the provider-specific details so they stay out of the generic setup story. Read the generic contract first, then the section for the transport you actually use. Anything below a provider heading (Monolith, ToolsetRegistry, Ultimate Engine Co-Pilot) applies to that provider only; if you drive Assist another way, only the generic contract applies to you.

Pick by engine version and client, not by capability

Transport Use it when Server / entry point
Console Smoke-testing, or scripting one-off calls without an MCP client LDAssist.Exec in the editor console (always available)
Monolith bridge You want an MCP client driving Assist today, on any supported engine Monolith HTTP server, default http://localhost:9316/mcp
Engine ToolsetRegistry You are on UE 5.8+ and want Epic's built-in MCP server Stock ModelContextProtocol plugin, default http://localhost:8000/mcp
Ultimate Engine Co-Pilot You already use UECP's in-editor chat, its MCP server, or its ACP agents, and want Assist's operations as UECP tools Third-party plugin by BlueprintsLab; enable its Logic Driver extension (see below)

The generic contract

Everything provider-specific on this page is a wrapper around one editor subsystem, USMAssistSubsystem. That subsystem is the registry: operations self-register into it at editor startup, each carrying a name, a description, a JSON input schema, and an impact classification. A transport does three things against it, and nothing more:

  1. Discover. Enumerate the registered operations to advertise them to the caller (name, description, schema, impact).
  2. Dispatch. Take an operation name plus a JSON argument object and invoke it.
  3. Relay. Return the operation's structured result: a success flag, an error message on failure, and a JSON payload on success.

Because every transport funnels through the same dispatch, an operation produces identical results whether it was called from the console, an MCP client, or your own adapter. What each transport adds is purely the shape of the call and the reply on the wire, described per provider below.

The impact classification is for permission gating. Each operation is either read_only (it reads without changing anything the user would recognize as their work) or destructive (it changes asset, project, or filesystem state in any way). The split is deliberately coarse and describes the operation's worst case across all of its arguments, so a purely additive edit and an operation with a dry-run flag are both destructive. An unclassified operation defaults to destructive, so it fails safe. In MCP terms read_only is readOnlyHint and destructive is destructiveHint. What You Can Author lists the ten read-only operations.

Operation names are namespace.action (for example ld.add_state). The dot is meaningful to some transports (Monolith splits on it to form a tool namespace); keep it in mind when a provider section refers to the namespace and the action separately.

Console (always available)

The console transport ships in the core module and needs no server. It is the quickest way to confirm the registry is live and to sanity-check an operation's arguments before a client calls it.

LDAssist.List
LDAssist.Describe [operation]
LDAssist.Exec <operation> [json_args]

LDAssist.List prints one name description line per registered operation. LDAssist.Describe prints one condensed JSON object per line carrying name, description, impact (read_only or destructive), and input_schema, for one operation or for all of them when called with no argument. That gives a client driving Assist over the console the full typed surface without linking against the plugin:

> LDAssist.Describe ld.create_blueprint
Operations (1):
  {"name":"ld.create_blueprint","description":"Create a new state machine blueprint asset.","impact":"destructive","input_schema":{"type":"object","properties":{...},"required":["name"]}}

LDAssist.Exec runs one operation:

LDAssist.Exec ld.create_blueprint {"name":"SM_Door","path":"/Game/StateMachines"}
LDAssist.Exec ld.add_state {"asset_path":"/Game/StateMachines/SM_Door.SM_Door","state_name":"Closed","position_x":200}
LDAssist.Exec ld.get_asset {"asset_path":"/Game/StateMachines/SM_Door.SM_Door"}

Success prints [op] ok: <json payload>. Failure prints [op] error: <message>. The console is also the reference adapter: it is the smallest possible implementation of the generic contract, so anything it can call, an MCP client or a custom bridge can call the same way.

Monolith MCP bridge

Monolith is an HTTP MCP server for Unreal. When it is present in the project, the bridge module registers each operation with it as namespace.action (the dot splits the operation name into a tool namespace and an action), so an MCP client sees the ld namespace's operations. Registration is tracked live, so operations appear without an editor restart.

Point your MCP client at the Monolith HTTP server (default port 9316). When you run several editors at once, give each its own port so the bridges do not collide: set ServerPort= under [/Script/MonolithCore.MonolithSettings] in Config/DefaultMonolith.ini.

A Claude Code .mcp.json pointing at the bridge:

{
  "mcpServers": {
    "monolith": {
      "type": "http",
      "url": "http://localhost:9316/mcp"
    }
  }
}

Most clients abstract the wire calls. If you drive the server directly over HTTP, Monolith surfaces each namespace as a single <namespace>_query tool. Call tools/call with tool name ld_query and an action plus params, where action is the bare action name with no namespace prefix:

{"name":"ld_query","arguments":{"action":"add_state","params":{"asset_path":"...","state_name":"Red"}}}

Passing the full ld.add_state as action double-prefixes it to ld.ld.add_state and fails. The reply is also double-wrapped: the payload arrives as a JSON string inside result.content[0].text, which you parse again to get the operation's JSON.

The bridge forwards each operation's impact classification to Monolith as the action's readOnlyHint and destructiveHint annotations. Monolith serializes per-action hints only for its own namespace, and a bridged namespace reaches the client as the single ld_query tool, so an MCP client does not see the hints per action yet. Until that transport adds per-action annotations, read the classification from LDAssist.Describe or from the registry in process.

Monolith ships its own Logic Driver surface, so prefer ld.*

This overlap is specific to Monolith. Monolith has a native logicdriver.* namespace (the logicdriver_query tool: scaffold helpers and opinionated readers), which auto-enables under the same condition Assist installs under. So an MCP client on the Monolith bridge typically sees both the ld_query and logicdriver_query tools.

Prefer the ld.* surface. It is maintained alongside this plugin, tracks the editor internals, and is the generic primitive set Assist exists to provide. Treat logicdriver.* as a fallback only.

Two ways to keep an agent on ld.*:

  • Silence the native namespace with bEnableLogicDriver=false under [/Script/MonolithCore.MonolithSettings] (the "Enable Logic Driver Integration" project setting). The rest of Monolith is unaffected. This removes the overlap entirely.
  • Add an instruction-layer rule if you keep both surfaces live, so the agent stays on ld.*. A name-level rule reliably disambiguates the overlap; tool descriptions alone do not. See Authoring with an AI Agent.

Neither of these applies to the ToolsetRegistry transport or to a bridge you write yourself, because neither surfaces a second Logic Driver namespace.

Engine ToolsetRegistry (UE 5.8+)

When the engine ships ToolsetRegistry, the toolset exposes each operation as a typed, AICallable function. A marshaling layer converts the typed arguments into the same JSON envelope the subsystem expects. Only the call mechanics and the outer envelope differ:

  • Server. UE 5.8's stock ModelContextProtocol plugin, default http://localhost:8000/mcp. Enable it in the editor for this transport to be reachable.
  • Call mechanics. In the default tool-search mode the server advertises three meta-tools: list_toolsets, describe_toolset, and call_tool. Invoke an operation with call_tool, passing the toolset name, the operation's function name, and its arguments. tools/call returns an SSE stream, so parse the last data: line.
  • Every parameter is required at the schema layer (the dispatcher rejects omitted fields regardless of C++ defaults). Sentinel values (empty string, -1, -1.0) mean "use the default"; the marshaling layer strips them.
  • Object arguments take a full object path such as /Game/Path/SM_Foo.SM_Foo (the asset_path that create_blueprint and get_asset return), not the bare package path.
  • Result envelope. Success returns the payload as a JSON string on the reply's returnValue field; there is no separate success flag. Failure surfaces as a tool-level MCP error carrying the Assist error text.

There is no logicdriver.* overlap on this transport, so the namespace-preference rule from the Monolith section does not apply here. The toolset does not carry the impact classification onto its functions, so a client that gates on it reads the classification from LDAssist.Describe instead.

Ultimate Engine Co-Pilot

Ultimate Engine Co-Pilot (UECP) is a third-party AI copilot for Unreal Engine 5, developed by BlueprintsLab. It runs inside the editor and exposes over 1,400 native editor operations as tools an agent can call against your project. Those tools are reachable from three surfaces at once: UECP's own in-editor chat, external MCP clients (Claude Code, Cursor, Cline, Codex, and others), and ACP command-line agents.

UECP ships a Logic Driver extension that bridges Assist into that tool surface. With the extension enabled, an agent driving UECP can author a state machine end to end using Assist's own operations. It can create the blueprint, add states, transitions, and conduits, write the logic inside a transition's graph, lay the graph out, compile, and read a running PIE instance's state. The bridge lives entirely on the UECP side and is maintained by BlueprintsLab. It needs no change to Logic Driver or to Assist, and it adds no build-time dependency in either direction.

Requirements and setup

You need Logic Driver Pro 2.11 or newer and LogicDriver-Assist (the SMAssist plugin) in the project's Plugins/ folder. You also need UECP with its Logic Driver extension enabled. When Assist is absent, the extension is inert: it registers a single status tool and nothing else changes.

  1. Install Logic Driver Pro 2.11 or newer and LogicDriver-Assist, as described in Setup & Connecting an Agent.
  2. Install UECP, then open Settings > Extensions and enable Logic Driver. The extension ships disabled by default; enabling it loads the bridge.
  3. Restart the editor. On startup the bridge discovers Assist's operations and registers each one as a UECP tool.
  4. Have the agent call get_logic_driver_status. It reports whether Assist was detected and how many operations were bridged. If the ld_* tools are missing, its message says what is needed.

How it works

  • Discovery, not a hard-coded list. The bridge enumerates Assist's registered operations at editor startup and registers whatever that build exposes. Nothing is hard-coded, so the tool surface tracks Assist as operations are added, renamed, or removed. No UECP update is needed.
  • One registration, three surfaces. Each discovered operation is registered once with UECP's tool dispatcher, which makes it reachable from the in-editor chat, external MCP clients, and ACP agents at the same time.
  • Tool naming. Assist names operations with a dot (ld.add_state); UECP tool names use underscores, so each becomes ld_add_state, ld_add_transition, ld_compile, and so on. The bridge dispatches the original dotted name, so the rename never reaches Assist.
  • No direct link. The bridge reaches Assist through the console commands, LDAssist.List and LDAssist.Exec, invoked with an argument array built in code. JSON arguments therefore pass through intact, never tokenized or escaped. This is what lets UECP ship as a precompiled binary and still integrate with a plugin that may or may not be present on your machine.

The extension adds no Logic Driver surface of its own beyond the status tool, so the namespace-preference rule from the Monolith section does not apply here.

Parameters

Each bridged tool carries Assist's own description of the operation, verbatim, including the layout guidance on operations such as ld.add_state. When the installed Assist build exposes per-operation input schemas (2.11 and newer), UECP publishes them as typed parameters. An agent then sees each operation's real argument names, types, and required fields. UECP validates a call against that schema before it reaches Assist. A wrong parameter name is answered with the expected set instead of being passed through malformed.

Permission gating

UECP classifies each tool so MCP clients and its own permission layer know which calls may run without a prompt. The split follows Assist's impact classification:

  • Read-only operations (asset and graph inspection, ld.runtime_get_state, property reads) are marked auto-approvable.
  • Every mutating operation is gated, so the agent's host prompts before it runs. UECP additionally flags the small set of irreversible operations (node and state removal, class replacement, structural merges, property and screenshot resets) as destructive. That finer split is UECP's own. Assist itself classifies every mutating operation as destructive.

Experimental

Assist is experimental, and its operation surface and payload shapes may still change. Because UECP discovers operations at runtime rather than declaring them, the bridge follows those changes automatically. An operation's exact arguments should still be taken from its live description or schema, never assumed.

Getting Ultimate Engine Co-Pilot

UECP is on Fab, and V2 ships from gamedevcore.com. Both include the Logic Driver extension, disabled until you enable it as described above.

Rolling your own bridge

Any adapter that can implement the three-step generic contract can serve Assist, running the same dispatch as the built-in transports. The registry is a public editor subsystem, USMAssistSubsystem (SMASSIST_API), reachable from editor code with GEditor->GetEditorSubsystem<USMAssistSubsystem>(). The console and the Monolith bridge are two reference adapters over it; a custom bridge does the same three things:

  • Discover. Call GetAllOperationInfos() for the current set, and bind OnOperationRegistered() / OnOperationUnregistered() to track additions and removals live. Seed from GetAllOperationInfos() once on bind so you catch operations registered before you connected. Each FSMAssistOperationInfo carries its Impact (ESMAssistOperationImpact::ReadOnly or Destructive); map it onto your transport's permission hints so a client can auto-approve the read-only operations. Operations you register yourself default to destructive unless you classify them.
  • Dispatch. Call ExecuteOperation(Name, Args) with the operation name and a TSharedRef<FJsonObject> of arguments.
  • Relay. Read the returned result's success flag, error message, and JSON payload, and shape them into whatever envelope your transport speaks.

A bridge you write surfaces only the operations you advertise from the registry (both ld.* and the ld_ue.* fallback ops), and it introduces no second Logic Driver namespace, so the Monolith namespace-preference guidance is irrelevant to it. If you want your transport to expose a smaller or renamed surface, filter or remap the operation names as you register them; the dispatch does not care how the caller found the name.