Unreal MCP is an AI-powered game development assistant for the Unreal Editor. Connect Claude, Cursor, Copilot, or any MCP-aware agent to Unreal Engine and let it inspect and drive your project — spawn actors, edit levels, author Blueprints, manage assets, edit and compile C++, capture screenshots, and more.
Unreal-MCP is the Unreal Engine counterpart of Unity-MCP and Godot-MCP: a C++ editor plugin that exposes Unreal Editor operations as AI Tools and connects them to an MCP server through the same hosted cloud backend (ai-game.dev) that powers Unity-MCP and Godot-MCP — or your own self-hosted server. The local server is the shared, engine-agnostic GameDev-MCP-Server (binary gamedev-mcp-server) — one server consumed by Unity-MCP, Godot-MCP, and Unreal-MCP; no server source lives in this repo.
Unlike Unity and Godot (C# engines that host the .NET McpPlugin in-process), Unreal's editor is C++ — so the .NET MCP host runs as an auto-managed sidecar process (unreal-mcp-bridge) that the plugin spawns and talks to over a localhost IPC channel. The full design lives in docs/ARCHITECTURE.md (see the §0 system-overview diagram).
Status: beta. The plugin, the .NET sidecar, the
unreal-mcp-cli, the AI Game Developer editor UI, and 62 built-in tools across 8 families have shipped and are exercised by CI. Theunreal-mcp-cliis published on npm — install the plugin with it (Option B below); the Fab / Epic Marketplace listing for the precompiled plugin is coming soon (Option A). Pixel-capture (screenshot) tools need a GPU-backed editor; everything else runs headless.
💬 Join our Discord Server — Ask questions, showcase your work, and connect with other developers!
- ✔️ AI agents — Use the best agents from Anthropic, OpenAI, Google, or any other provider with no vendor lock-in
- ✔️ 62 built-in Tools — A wide range of MCP Tools across 8 families for operating the Unreal Editor
- ✔️ Blueprint authoring — Create, edit, and compile Blueprints with a structured error/warning feedback loop the AI can act on
- ✔️ C++ edit & compile — Read, scaffold, and edit project C++, then compile (Live Coding or UBT) with a structured error report
- ✔️ Visual feedback — Capture viewport, game-view, camera, and isolated-actor screenshots the LLM can inspect directly
- ✔️ Custom Tools, Prompts & Resources — Register your own AI Tools, prompt templates, and resources from any UE plugin with no fork — one public, modular-feature contract (Customize Tools, Prompts & Resources)
- ✔️ Cloud or self-hosted — Connect to
ai-game.devout of the box, or point at your own GameDev-MCP-Server - ✔️ Per-tool enable / disable — Flip any tool on or off from the MCP Tools window; the toggle is enforced at the execution boundary, not just hidden
Table of contents
- Requirements
- Install
- Updating the plugin
- First run
- Tools — all 8 families, 62 tools
- Per-tool enable / disable
unreal-mcp-cli- Customize Tools, Prompts & Resources
- Runtime usage (in-game)
- Configuration & environment variables
- Troubleshooting
- How Unreal MCP Architecture Works
- Repo layout
- Links
- License
Requirements
- Unreal Engine 5.5+ (developed and CI-tested against 5.7, and verified to build & run on 5.8). The plugin deliberately ships no
EngineVersionpin — UE treats that field as an exact-build match, not a floor, and would refuse to load on newer engines. - .NET 9 SDK to build the bridge sidecar from source. (End users of a packaged release do NOT need it — the self-contained sidecar is bundled inside the plugin and auto-spawned, ARCHITECTURE §6. The local MCP server is downloaded as a prebuilt GameDev-MCP-Server release binary, never built here.)
- Node.js
^20.19.0 || >=22.12.0for the optionalunreal-mcp-cli. - A C++ Unreal project (the plugin builds an Editor module, so the host project must be able to compile C++).
Install
There are three ways to install the plugin, in order of preference. Fab / Epic Marketplace is the recommended channel for end users — it ships precompiled, per-engine binaries and the Epic Games Launcher keeps them up to date automatically, so there is zero compile and zero stale-build risk. Source / unreal-mcp-cli installs remain the current path for developers and early adopters until the Fab listing goes live.
Option A — Fab / Epic Marketplace (recommended; coming soon)
Status: not yet live. The Fab listing is operator-gated and tracked separately; until it publishes, use Option B or C below. The framing here is what the end-user flow will be.
- Install Unreal-MCP from Fab (the Epic Marketplace successor) into your engine via the Epic Games Launcher.
- Enable the plugin for your project from Edit → Plugins.
- Open the project — UE loads the precompiled plugin (no C++ build on your machine). On boot the Output Log prints
[Unreal-MCP] plugin loaded.
Because Fab ships precompiled binaries and the Epic Launcher updates them in place, you never compile the plugin and never have to clear a stale build cache — the most robust path for non-developers.
Option B — unreal-mcp-cli (current / advanced)
The CLI is the recommended path today, until the Fab listing is live. Install it from npm — no repo clone, no build step. By default install-plugin / update use a local UnrealMCP/ checkout when one is present; otherwise they download the dedicated unreal-mcp-plugin-source-<version>.zip source asset from the public GitHub Release that matches the CLI version. That source asset keeps the distributed descriptor semantics (no EngineVersion pin) and carries the signed bridge payload under Source/ThirdParty/UnrealMcpBridge/<rid>/; the installer materializes it into Binaries/ThirdParty/... for first-open convenience. --plugin-source <dir> remains the offline / CI / dev override. The CLI copies (or, for dev, junctions) the plugin into your project and, on update, automatically clears the stale UE build cache so you always get a clean recompile of the new code (see Updating the plugin). On desktop platforms (Win64 / Mac / Linux), unreal-mcp-cli open also runs a pre-launch build when the project/plugin state still needs native editor binaries, then auto-dismisses the known Unreal blocker dialogs (Missing ... Modules, UnrealMCP is Incompatible) if they still appear during startup. Linux dialog automation is X11-only; Wayland is detected and warned as unsupported.
# 1. Install unreal-mcp-cli (or use `npx unreal-mcp-cli@latest <command>` for a one-off, no install)
npm install -g unreal-mcp-cli
# 2. Install the UnrealMCP plugin into your project
unreal-mcp-cli install-plugin ./YourProject
# 3. Authorize against the cloud server (ai-game.dev)
unreal-mcp-cli login ./YourProject
# 4. Open the Unreal Editor for the project (wires the MCP connection env vars)
unreal-mcp-cli open ./YourProject
See cli/README.md for the full 16-command reference.
Option C — manual
- Copy
UnrealMCP/into<YourProject>/Plugins/UnrealMCP/(or create a directory junction / symlink to it for live development). - Open the project; UE compiles the
UnrealMcpEditormodule on first launch. - On editor boot the Output Log prints
[Unreal-MCP] plugin loaded— that confirms the plugin and its game-thread dispatcher started.
The sidecar binary (unreal-mcp-bridge) is bundled inside the plugin in a packaged release: a prebuilt, self-contained binary for your platform ships under UnrealMCP/Binaries/ThirdParty/UnrealMcpBridge/<rid>/ and the editor auto-spawns it on startup with zero user action — no .NET install, no env var, no manual launch (ARCHITECTURE §6). The first Cloud OAuth device-code browser approval is the only remaining human step; after that, reconnect on later launches is zero-click (the cloud token is cached in Saved/Config/UnrealMcp/).
When you copy the repo source checkout directly (Option C/manual or a live dev junction), the bundled binary is not present — the plugin then resolves the sidecar from the UNREAL_MCP_BRIDGE_PATH environment variable instead: point that at a locally built sidecar, or run unreal-mcp-cli bootstrap-local to build the bridge from source into <YourProject>/Intermediate/UnrealMCP/ and set the var to the result. With neither a bundled binary nor the env var resolved, the plugin's TCP listener still starts but logs [Unreal-MCP] no sidecar binary resolved for rid <rid> … and spawns nothing.
Updating the plugin
Updating in place must always leave you running the new code. The risk is UE's incremental compiler: if the plugin source changes (new .cpp files, a new module) but the old UnrealMCP/Intermediate/ build cache survives, UE can do a partial recompile against a stale module file-list and silently leave you on old/partial code. Each channel handles this differently:
-
Fab / Epic Marketplace → automatic. The Epic Games Launcher replaces the precompiled binaries in place; nothing to compile, no cache to clear. This is why Fab is the recommended channel.
-
unreal-mcp-cli update→ automatic clean rebuild.updatere-copies the plugin source and, by default, deletes the installed plugin's staleIntermediate/and the C++Binaries/so UE performs a clean compile on the next editor launch — no manual steps. The bundled sidecar bridge underBinaries/ThirdParty/UnrealMcpBridge/<rid>/is kept intact: release-source installs refresh it fromSource/ThirdParty/..., while repo/dev installs preserve the previously bundled copy when needed. Dev junction installs are never cleaned (that would wipe your live source tree's outputs). Pass--no-cleanto opt out of the cache wipe.node bin/unreal-mcp-cli.js update <YourProject> # default: clean rebuild on version change node bin/unreal-mcp-cli.js update <YourProject> --force # re-copy even when versions match node bin/unreal-mcp-cli.js update <YourProject> --no-clean # keep the existing build cache -
Manual copy → clear the cache yourself. If you overwrite
<YourProject>/Plugins/UnrealMCP/by hand, close the editor first, delete<YourProject>/Plugins/UnrealMCP/Intermediate/and the C++Binaries/(keepBinaries/ThirdParty/if a bundled bridge is present), then relaunch so UE recompiles cleanly.
First run
- Open the AI Game Developer main window from the editor's Tools menu (the tab is registered under the Tools menu category).
- Choose a connection mode:
- Cloud (default) — connects to ai-game.dev. Click Authorize to start the OAuth device-code flow: the window shows a verification URL and a short user code; open the URL, enter the code, approve, and the editor finishes authorizing. Use Revoke to clear the stored cloud token.
- Custom — connects to a local
gamedev-mcp-serveryou run (or any compatible server). Enter the server URL and point your AI client at it. (The plugin does not start the local server for you — rununreal-mcp-clior your own process; see Troubleshooting.)
- The Connection section shows a status dot, a status label, and a Connect / Disconnect / Stop button; the bridge status reads
Running (restarts: N)orStopped. Use them to confirm the sidecar is live. - Point your AI client (Claude Code, Cursor, the AI Game Developer app, …) at the server. The AI agents section lists the agents currently connected; to write an MCP client config use
unreal-mcp-cli setup-mcp.
Connection settings persist to <Project>/Saved/Config/UnrealMcp/ai-game-developer-config.json (Saved/ is gitignored by every UE template, so tokens never land in VCS by default).
Pinned MCP client URL.
unreal-mcp-cli setup-mcp <agent>writes an MCP client config that points at the project-pinned cloud URL<base>/mcp/p/<pin>, so the agent routes to this project's editor even when your account drives several. Pass--no-pinto write the bare<base>/mcpURL instead. The pin is a routing path segment only — the OAuth resource stays<base>/mcp, and OAuth-capable clients (Claude Code, Cursor, …) still run their own device-code login against it.
That's it. Ask your AI "Spawn three cubes in a row and a point light above them" and watch it happen. ✨
Tools
Unreal-MCP ships 62 built-in ("core") tools across 8 families. Tool ids are kebab-case (actor-create, blueprint-compile), matching the Unity/Godot naming convention. Extensions can add more (see Customize Tools, Prompts & Resources).
This list is generated from the registration source (
UnrealMCP/Source/UnrealMcpEditor/Private/Tools/UnrealMcp*Tools.cpp). Counts: actor 13, blueprint 11, asset 11, editor/reflection 9, level 7, source 6, screenshot 4, ping 1 = 62.
| Tool id | What it does |
|---|---|
actor-create |
Spawn an actor from a class path (native or Blueprint), with optional name/location/rotation/parent |
actor-destroy |
Destroy an actor |
actor-duplicate |
Duplicate an actor |
actor-find |
Find actors, with scoped reads (paths/viewQuery) |
actor-modify |
Write actor FProperty values (including transform) |
actor-set-parent |
Attach an actor to a parent |
actor-component-add |
Add a component to an actor |
actor-component-destroy |
Destroy a component |
actor-component-get |
Read a component's data |
actor-component-modify |
Modify a component's properties |
actor-component-list-all |
List available UActorComponent classes (paginated) |
object-get-data |
Read any UObject by path |
object-modify |
Modify any UObject by path |
| Tool id | What it does |
|---|---|
blueprint-create |
Create a new Blueprint class from a parent UClass path |
blueprint-get |
Graph summary for LLM inspection (variables, components, functions/events, parent chain) |
blueprint-add-component |
Add a component via the Simple Construction Script |
blueprint-remove-component |
Remove an SCS component |
blueprint-add-variable |
Add a typed member variable |
blueprint-modify-variable |
Modify a member variable |
blueprint-set-default |
Edit a CDO (class-default) property |
blueprint-add-function |
Add a function stub (entry/result nodes wired) |
blueprint-add-event |
Add/bind an event stub (BeginPlay, Tick, input, …) |
blueprint-compile |
Compile the Blueprint and return a structured error/warning list (the AI feedback loop) |
blueprint-spawn |
Instance the Blueprint into the current level |
| Tool id | What it does |
|---|---|
asset-find |
Search the AssetRegistry by name/class/path/tags |
asset-get-data |
Read an asset's data (scoped reads supported) |
asset-create-folder |
Create a Content folder |
asset-copy |
Copy an asset |
asset-move |
Move / rename an asset |
asset-delete |
Delete an asset |
asset-refresh |
Rescan asset paths |
asset-material-create |
Create a Material Instance from a parent material |
asset-material-modify |
Set scalar/vector/texture material-instance parameters |
asset-material-get-data |
Read material graph/parameter info (the "shader" analog) |
asset-import |
Import FBX/textures via AssetImportTask |
| Tool id | What it does |
|---|---|
editor-application-get-state |
Read editor application state (PIE, etc.) |
editor-application-set-state |
Start / stop / pause Play-In-Editor |
editor-selection-get |
Read the current editor selection |
editor-selection-set |
Set the editor selection |
console-get-logs |
Read recent editor logs from the LogCollector ring buffer |
console-clear-logs |
Clear the captured-log ring buffer |
console-run-command |
Run a console command / CVar |
reflection-method-find |
Discover callable UFunctions (returns invocation schemas) |
reflection-method-call |
Invoke a UFunction (static or instance, incl. CallInEditor) |
| Tool id | What it does |
|---|---|
level-create |
Create a new level |
level-open |
Open a level |
level-save |
Save the level (save-as via optional path) |
level-get-data |
Actor-tree snapshot of a level (scoped reads) |
level-list-loaded |
List persistent + streaming sublevels (World-Partition aware, read-only) |
level-set-current |
Set the current/active level |
level-unload-sublevel |
Unload a streaming sublevel |
| Tool id | What it does |
|---|---|
source-read |
Read a project C++ source file (sliced) |
source-create-class |
Scaffold a new C++ class (header + cpp from templates) |
source-update |
Edit a source file |
source-delete |
Delete a source file |
source-list |
List module source files |
source-compile |
Compile project C++ (Live Coding when active, else UBT) with a structured error report |
All file operations are jailed to <Project>/Source/.
| Tool id | What it does |
|---|---|
screenshot-viewport |
Capture the active editor viewport |
screenshot-game-view |
Capture the PIE / game view |
screenshot-camera |
Render from a resolved camera actor via USceneCaptureComponent2D |
screenshot-isolated |
Render an actor in isolation (transient SceneCapture2D + show-only list) |
Captures return a base64 PNG as MCP image content so the LLM can inspect the render directly. Dimensions are clamped (default 1024, hard cap 2048 per side). Pixel capture needs a GPU-backed editor; under headless -nullrhi these tools return a structured error.
| Tool id | What it does |
|---|---|
ping |
Liveness probe — round-trips the plugin ⇄ sidecar ⇄ server chain |
Per-tool enable / disable
Every tool can be individually enabled or disabled from the MCP Tools window — the standalone MCP Tools tab (registered under the editor's Tools menu). The window shows each tool's title, family, and description, plus an "N / M tools enabled" summary line. Disabling a tool:
- removes it from the served manifest entirely — it never appears in the MCP
tools/list; and - is enforced at the execution boundary too — even if a stale
tools/listis dispatched, a disabled tool is rejected atExecute()rather than run.
Two filters combine to decide whether a tool is served (see ARCHITECTURE §7/§8):
- a whitelist (
enabledTools, overridable viaUNREAL_MCP_TOOLS) — when non-empty, only listed tools are served; empty means "no filter"; and - a blocklist (
disabledTools) — the per-tool toggles you flip in the UI.
A tool is served iff it passes the whitelist and is not in the blocklist. Both sets are persisted across editor sessions and survive an extension hot-reload (a re-registered tool inherits the retained toggle, so a rebuild can never silently re-enable a tool you disabled).
All connection settings live in the single AI Game Developer main window's Connection section (there is no separate Settings tab or Project-Settings page — Unity-MCP parity). The MCP Prompts and MCP Resources windows are wired but ship empty in this release — each renders a subdued empty-state message (the "N / M enabled" summary is unique to the Tools window).
unreal-mcp-cli
A cross-platform Node CLI (unreal-mcp-cli) that scaffolds projects, installs the plugin, configures connection settings, drives the local server, and invokes tools over HTTP. It is a port of unity-mcp-cli / godot-cli. Full reference: cli/README.md.
Published on npm — install with
npm install -g unreal-mcp-cli, or run a one-off withnpx unreal-mcp-cli@latest <command>.
The full 16-command surface:
| Command | What it does |
|---|---|
create-project |
Scaffold a minimal Unreal Engine C++ project |
open |
Launch the Unreal Editor for a project, wiring MCP connection env vars |
close |
Terminate the Unreal Editor process running a project |
install-plugin |
Install the UnrealMCP plugin into <project>/Plugins (copy or --junction) from a local checkout or the version-matched GitHub source asset |
remove-plugin |
Remove the UnrealMCP plugin from <project>/Plugins |
configure |
Write UNREAL_MCP_* values into <project>/.env and gitignore .env |
setup-mcp |
Write an MCP client config snippet for an agent |
login |
Authorize against ai-game.dev via the OAuth device-code flow |
status |
Report package, project, plugin, and live connection status |
wait-for-ready |
Block until the project's MCP server responds to a ping |
run-tool |
Invoke an MCP tool via the project's local MCP server (HTTP) |
run-system-tool |
Invoke a system tool via the project's local MCP server (HTTP) |
bootstrap-local |
Build the bridge from source into <project>/Intermediate/UnrealMCP (the server is downloaded by setup-mcp, not built) |
update |
Update the UnrealMCP plugin installed in a project from a local checkout or the version-matched GitHub source asset |
install-engine |
Detect installed Unreal engines; for a missing version, link to the Epic launcher |
setup-skills |
Write a Claude-Code skill stub that drives this project's Unreal MCP server |
Customize Tools, Prompts & Resources
This is the headline extensibility feature. Anyone can register their own AI Tools, prompts, and resources — from any third-party UE plugin — and have them appear in the MCP manifest alongside the built-ins. No fork, no link-time coupling, no load-order assumptions. Your contributions are discovered automatically on editor boot (and on late-load / hot-unload), merged in deterministic order, and exposed to every connected AI agent.
All three kinds use the same small, public, modular-feature-based contract — a provider interface plus a fluent registry builder, both living in the UnrealMcpRuntime module (re-exported by UnrealMcpEditor, so the same contract serves editor and runtime extensions). The full author guide is docs/EXTENSIONS.md.
Tools
Implement IUnrealMcpToolProvider and declare your tools with the fluent FUnrealMcpToolRegistry builder:
#include "IUnrealMcpToolProvider.h"
#include "UnrealMcpToolRegistry.h"
class FMyExtensionProvider : public IUnrealMcpToolProvider
{
public:
virtual FString GetExtensionId() const override { return TEXT("com.foo.my-extension"); }
virtual FText GetDisplayName() const override { return NSLOCTEXT("Foo", "Name", "My Extension"); }
virtual FString GetExtensionVersion() const override { return TEXT("1.0.0"); }
virtual void RegisterTools(FUnrealMcpToolRegistry& Registry) override
{
Registry.Tool(TEXT("hello-extension"))
.Title(TEXT("Hello Extension"))
.Description(TEXT("Returns a friendly greeting."))
.ParamString(TEXT("name"), TEXT("Who to greet. Defaults to 'world'."))
.ReadOnlyHint(true)
.IdempotentHint(true)
.Handle([](const FUnrealMcpToolCall& Call) -> FUnrealMcpToolResult
{
const FString Name = Call.Has(TEXT("name")) ? Call.GetString(TEXT("name")) : TEXT("world");
return FUnrealMcpToolResult::Success(FString::Printf(TEXT("Hello, %s!"), *Name));
});
}
};
Then register the provider as a modular feature in your module's StartupModule (and unregister in ShutdownModule):
// In StartupModule:
IModularFeatures::Get().RegisterModularFeature(
IUnrealMcpToolProvider::GetModularFeatureName(), Provider.Get());
Prompts
Prompts are reusable, parameterized prompt templates the agent fetches via prompts/get. Implement IUnrealMcpPromptProvider and declare prompts with FUnrealMcpPromptRegistry. Prompt arguments reuse the same Param* helpers as the tool builder; a handler returns role-tagged messages:
#include "IUnrealMcpPromptProvider.h"
#include "UnrealMcpPromptRegistry.h"
class FMyPromptProvider : public IUnrealMcpPromptProvider
{
public:
virtual FString GetExtensionId() const override { return TEXT("com.foo.my-extension"); }
virtual FText GetDisplayName() const override { return NSLOCTEXT("Foo", "Name", "My Extension"); }
virtual FString GetExtensionVersion() const override { return TEXT("1.0.0"); }
virtual void RegisterPrompts(FUnrealMcpPromptRegistry& Registry) override
{
Registry.Prompt(TEXT("level-design-brief"))
.Title(TEXT("Level Design Brief"))
.Description(TEXT("Generate a level design brief from a single 'theme' argument."))
.Role(EUnrealMcpPromptRole::User)
.ParamString(TEXT("theme"), TEXT("The level theme (e.g. 'haunted forest')."),
EUnrealMcpParamRequirement::Required)
.Handle([](const FUnrealMcpToolCall& Call) -> FUnrealMcpPromptResult
{
const FString Theme = Call.GetString(TEXT("theme"));
if (Theme.IsEmpty())
return FUnrealMcpPromptResult::Error(TEXT("theme is required."));
const FString Text = FString::Printf(
TEXT("Draft a level design brief for a \"%s\"-themed level."), *Theme);
return FUnrealMcpPromptResult::Success(Text, EUnrealMcpPromptRole::User);
});
}
};
// Register under the prompt modular-feature name (and unregister in ShutdownModule):
IModularFeatures::Get().RegisterModularFeature(
IUnrealMcpPromptProvider::GetModularFeatureName(), PromptProvider.Get());
level-design-brief is the shipped core prompt — see UnrealMCP/Source/UnrealMcpRuntime/Private/Prompts/UnrealMcpCorePrompts.cpp.
Resources
Resources are addressable, readable content the agent fetches via resources/read — the resource's URI is its identity. Implement IUnrealMcpResourceProvider and declare resources with FUnrealMcpResourceRegistry. A read returns content blocks — text XOR a base64 blob + a mime type:
#include "IUnrealMcpResourceProvider.h"
#include "UnrealMcpResourceRegistry.h"
virtual void RegisterResources(FUnrealMcpResourceRegistry& Registry) override
{
Registry.Resource(TEXT("unreal://project/levels")) // JSON (text) resource
.Name(TEXT("Project Levels"))
.Description(TEXT("A JSON snapshot of the active world and its levels."))
.MimeType(TEXT("application/json"))
.Read([](const FString& Uri) -> FUnrealMcpResourceResult
{
return FUnrealMcpResourceResult::Text(Uri, BuildLevelsJson(), TEXT("application/json"));
});
Registry.Resource(TEXT("unreal://project/icon")) // binary (blob) resource
.Name(TEXT("Project Icon"))
.Description(TEXT("A small PNG, returned as a base64 blob."))
.MimeType(TEXT("image/png"))
.Read([](const FString& Uri) -> FUnrealMcpResourceResult
{
const FString Base64 = FBase64::Encode(IconBytes, sizeof(IconBytes));
return FUnrealMcpResourceResult::Blob(Uri, Base64, TEXT("image/png"));
});
}
// Register under the resource modular-feature name (and unregister in ShutdownModule):
IModularFeatures::Get().RegisterModularFeature(
IUnrealMcpResourceProvider::GetModularFeatureName(), ResourceProvider.Get());
unreal://project/levels and unreal://project/icon are the shipped core resources — see UnrealMCP/Source/UnrealMcpRuntime/Private/Resources/UnrealMcpCoreResources.cpp. Only static, fixed-URI resources are supported today (templated / parameterized URIs are deferred). A blob is base64 on the Unreal side and the IPC wire; a known upstream quirk in the shared GameDev-MCP-Server / MCP-Plugin-dotnet can mis-emit blob bytes on the final MCP wire to the client (text resources round-trip cleanly end-to-end) — that is an upstream issue, not the Unreal plugin or bridge.
How it behaves (identical for tools, prompts, and resources):
- Auto-discovery & hot-reload. Unreal-MCP enumerates every registered provider (
UnrealMcpToolProvider/UnrealMcpPromptProvider/UnrealMcpResourceProvider) on boot, and subscribes to register/unregister events — so loading or unloading your plugin at any time triggers a registry rebuild and a manifest revision bump, and the sidecar diffs the new manifest and adds/removes the affected tools / prompts / resources automatically. You never push anything yourself. - Deterministic merge. Providers are merged in ascending
GetExtensionId()order; within one provider, entries register in declaration order. YourGetExtensionId()is stamped onto everything you contribute (don't call.ExtensionId(...)yourself). - Per-extension isolation. Each descriptor is validated (a tool/prompt needs a kebab-case name + well-formed schema + bound handler; a resource needs a non-empty URI + handler). An invalid or duplicate entry (duplicate tool/prompt name, or duplicate resource URI) is dropped/rejected and the reason is recorded on your extension's record — your other valid entries, and every other extension, are unaffected. (UE builds without C++ exceptions, so isolation is descriptor-level, not handler-body-level; validate inputs and fail gracefully with the
Error(...)result helpers.) - Toggles & enable/disable. Extension-contributed tools are toggled in the MCP Tools window like the built-ins; a disabled extension contributes nothing to any manifest. (The MCP Prompts / MCP Resources windows are wired but still render empty in this release — see Per-tool enable / disable — so prompt/resource toggling from the UI is a follow-up; registration and use work today.)
Learn more:
- Full author guide:
docs/EXTENSIONS.md— the contract for tools, prompts, and resources, the builders, lifecycle, ordering, isolation semantics, and versioning. - Design:
docs/ARCHITECTURE.md§5 (tools) + §A (the prompt/resource registration path). - Working samples:
samples/UnrealAITemplate/— a complete, buildable editor extension plugin with ahello-extensiontool and a compile-time switch (UNREAL_AI_TEMPLATE_INVALID_SCHEMA=1) that demonstrates the isolation behaviour first-hand;samples/UnrealAIRuntimeSample/— the runtime (in-game) counterpart, aType=Runtimeplugin whosegame-time-dilationtool reads/sets the live world's time dilation, callable in a running game over a runtime MCP connection (docs/ARCHITECTURE.md§12.9; see EXTENSIONS.md "Runtime usage"). For prompts and resources, the shipped core families ([UnrealMcpCorePrompts.cpp](https://github.com/IvanMurzak/Unreal-MCP/blob/main/UnrealMCP/Source/Unr
No comments yet
Be the first to share your take.