@uemcp/server 1.7.0 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +50 -0
- package/dist/index.mjs +1676 -10
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -125,6 +125,12 @@ The MCP tool surface currently exposes:
|
|
|
125
125
|
- `create_sound_cue`
|
|
126
126
|
- `create_metasound`
|
|
127
127
|
- `set_metasound_graph`
|
|
128
|
+
- `find_symbol`
|
|
129
|
+
- `export_blueprint_cpp`
|
|
130
|
+
- `add_reflected_member`
|
|
131
|
+
- `scaffold_class_template`
|
|
132
|
+
- `get_live_compile_details`
|
|
133
|
+
- `run_editor_python`
|
|
128
134
|
|
|
129
135
|
## Project Identity
|
|
130
136
|
|
|
@@ -612,6 +618,50 @@ This is intended to let an MCP client resolve the canonical Unreal project ident
|
|
|
612
618
|
- `restartProperties` names the settings the engine reads once at startup. They are written correctly and still inert until the editor restarts, which is worth saying rather than leaving the caller to wonder
|
|
613
619
|
- `set_default_gamemode` writes the project default through `GameMapsSettings`, or a level override through that level's world settings. The pawn, controller, state and HUD classes are not settings — they live on the game mode class — so they are written onto its defaults and the Blueprint is recompiled. A **C++ game mode refuses them**: its class defaults are rebuilt from its constructor on every start, so the write would live only until the editor closed
|
|
614
620
|
|
|
621
|
+
### `find_symbol`
|
|
622
|
+
|
|
623
|
+
- Answers "where is this type declared" across the engine and the project without a running editor: it scans headers for `UCLASS` / `UINTERFACE` / `USTRUCT` / `UENUM` / `UFUNCTION` / `UPROPERTY` and reports the header path, the owning module, and the `#include` path to write
|
|
624
|
+
- The include path is derived from the nearest `Public/` or `Classes/` directory, which is what UBT puts on the include path — a header under `Private/` is reported without one, because there is no include that reaches it from another module
|
|
625
|
+
- The module name comes from the nearest `*.Build.cs` walking up from the header, so it is the module a caller has to add to `PrivateDependencyModuleNames`, not a guess from the directory name
|
|
626
|
+
- Matching is exact first, then prefix, then substring, so a full type name never loses to a longer one that happens to contain it. `kind` narrows to one symbol kind, and results page with `maxResults` / `totalCount` / `truncated`
|
|
627
|
+
- The index is cached on disk per root set (hashed engine + project roots) beside the registry file, and rebuilt incrementally: a file whose size and mtime are unchanged reuses its cached records, so a rescan after a build touches only what the build touched
|
|
628
|
+
- `Binaries`, `Intermediate`, `Saved`, `DerivedDataCache`, `ThirdParty` and VCS directories are skipped, and the walk stops at `maxFiles` (default 80,000) rather than running unbounded over an engine source tree
|
|
629
|
+
- Cost is real and worth planning around: a cold UE 5.8 engine scan reads about 45,000 headers and takes a couple of minutes, after which a warm call re-stats them and answers in seconds. Call it once per engine rather than per question
|
|
630
|
+
|
|
631
|
+
### `export_blueprint_cpp`
|
|
632
|
+
|
|
633
|
+
- Turns a `get_blueprint_graph` payload into something readable: pseudo-code for each graph, and a C++ header skeleton for the class
|
|
634
|
+
- Pure server-side transform — no plugin change of its own. The editor still owns the graph; this only renders what it hands back
|
|
635
|
+
- The walk follows exec pins from each entry node, so `K2Node_IfThenElse` becomes `if`/`else`, `K2Node_ExecutionSequence` becomes sequential statements, and the For / While / For Each macro instances become the matching loop. A node reached twice emits a `goto` and sets `truncated` rather than looping forever
|
|
636
|
+
- Roots are sorted by graph title then node id, so the same graph renders byte-identical on every call — the output is diffable
|
|
637
|
+
- The skeleton maps Blueprint variables to `UPROPERTY` (including `ReplicatedUsing` for a variable with a RepNotify) and Blueprint functions to `UFUNCTION`, with out parameters as references. It is a starting point for a hand port, **not** a compilable nativization
|
|
638
|
+
|
|
639
|
+
### `add_reflected_member` / `scaffold_class_template`
|
|
640
|
+
|
|
641
|
+
- The authoring half of the C++ surface: `add_reflected_member` inserts a `UPROPERTY` or `UFUNCTION` into an existing class, `scaffold_class_template` writes a new pair of files for one of the shapes UE has no simple template for
|
|
642
|
+
- Members are inserted directly after the class's own `GENERATED_BODY()` under a fresh `public:`. That is this tool's policy, not a UHT rule — UHT reflects `private:` and `protected:` members too, and `meta = (AllowPrivateAccess = "true")` only governs whether Blueprints can reach a private `UPROPERTY`. Opening a section makes the insertion point deterministic instead of inheriting whatever section the cursor happened to land in, at the cost of every generated member being public; move it afterwards if it belongs elsewhere. A member that is already declared is reported rather than duplicated
|
|
643
|
+
- **Specifiers are validated before anything is written.** Rejected combinations include more than one Edit or Visible specifier, `BlueprintReadOnly` with `BlueprintReadWrite`, `Replicated` with `ReplicatedUsing`, a bare `ReplicatedUsing` with no handler, `BlueprintPure` with `BlueprintCallable`, `BlueprintImplementableEvent` with `BlueprintNativeEvent`, more than one RPC target, an RPC with no reliability specifier, and an RPC with a non-void return. An unknown specifier is rejected too — a typo UHT would catch minutes later at build time fails here in milliseconds
|
|
644
|
+
- A function also gets a `.cpp` stub (header `Public/X.h` → source `Private/X.cpp`), except for `BlueprintImplementableEvent`, which has no native body by definition. A `BlueprintNativeEvent` gets its stub named `Name_Implementation`, which is the symbol UHT's dispatcher calls and the one that fails to link if it is missing
|
|
645
|
+
- `scaffold_class_template` covers `interface` (the `UInterface` + `IInterface` pair, the shape that is got wrong most often) and the `game_instance_subsystem` / `world_subsystem` / `editor_subsystem` trio. It refuses to overwrite existing files and returns the module dependencies the new files need
|
|
646
|
+
- Both are filesystem-only and need no editor. Run project-file generation and a build — or `trigger_live_compile` for a body-only change — afterwards
|
|
647
|
+
|
|
648
|
+
### `get_live_compile_details`
|
|
649
|
+
|
|
650
|
+
- Reports what Live Coding actually did with the last patch: the modules it patched, and, when it refused, why
|
|
651
|
+
- The restart case is the one worth naming. A change to a reflected type's layout — a new `UPROPERTY`, a reordered member — patches into the running editor, but the editor is then running against types its loaded assets no longer match, and the engine says so only as a warning on the completion line. That warning comes back as `restartRequired` with the engine's own wording, instead of leaving a caller to wonder why their change behaved oddly
|
|
652
|
+
- The two halves come from two places, because neither alone is enough: `ILiveCodingModule` reports counts only, the editor's `LogLiveCoding` carries just the completion line, and which modules were patched is printed by the separate `LiveCodingConsole` process into its own log. That log is read on demand, filtered to the compile's own time window, and to modules this editor has actually loaded — one console serves every editor in its process group
|
|
653
|
+
- Bounded: at most 64 entries per kind and 512 characters per entry, with `truncated` set when either cap is hit
|
|
654
|
+
- Windows-only in practice — Live Coding ships only where the engine supports it. Elsewhere the compile job carries no details rather than failing
|
|
655
|
+
|
|
656
|
+
### `run_editor_python`
|
|
657
|
+
|
|
658
|
+
- Executes Python inside the running editor through `IPythonScriptPlugin` and returns the log output, the error lines, and the evaluated result. The `py` console command exec path cannot return any of that
|
|
659
|
+
- A failed run reports its traceback in `errors` and leaves `result` unset, so `result` always means "the value the script produced" rather than sometimes meaning "why it did not"
|
|
660
|
+
- **Off by default.** It hands a caller the editor's entire Python API with no sandbox around it, so it stays disabled until a human enables `Allow run_editor_python` under Project Settings → Plugins → MCP Bridge (`MCPBridgeSettings.bAllowEditorPython`). With the setting off the tool returns `state: 'disabled'` naming that setting rather than failing opaquely
|
|
661
|
+
- An editor whose Python Script Plugin is absent or disabled returns `state: 'unsupported'` with the reason, which is a different answer from a script that ran and failed
|
|
662
|
+
- The whole script runs inside one `FScopedTransaction`, so a successful run is a single editor undo; a failed run cancels the transaction rather than leaving half its effects behind
|
|
663
|
+
- `executionMode` is `script` (default: a whole block of Python, or a `.py` path with arguments), `statement` (exactly one statement) or `evaluate` (one expression, whose value comes back in `result`). `script` is the default because the engine reports a traceback line by line only in that mode; the two statement modes put it in `result` instead. Commands are capped at 16,384 characters, and output and error lines at 200 lines each, with `truncated` set
|
|
664
|
+
|
|
615
665
|
## MCP Resources
|
|
616
666
|
|
|
617
667
|
Resources carry context a client can attach without spending a tool call and a model turn. The `registry`, `engines` and `workspace` resources are served from in-memory state or the local filesystem: **those reads never open a bridge socket and never wait on the editor**, so an unreachable or absent editor produces a structured payload rather than a timeout. The `project` resources are the exception — they are the editor-backed reads, and they report `found: false` with a `reason` instead of throwing when the editor is gone.
|