@uemcp/server 1.6.1 → 1.7.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 +40 -4
- package/dist/index.mjs +18557 -16136
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -141,6 +141,13 @@ If `DefaultGame.ini` cannot be read, if the section is missing, or if the `Proje
|
|
|
141
141
|
|
|
142
142
|
## MCP Tools
|
|
143
143
|
|
|
144
|
+
### `doctor`
|
|
145
|
+
|
|
146
|
+
- Runs every setup check in one pass and returns `checks` with a `pass` / `warn` / `fail` status and, for anything that is not passing, the `fix` that clears it
|
|
147
|
+
- Covers engine installs under `UE_INSTALLS_DIR` and whether UnrealBuildTool resolves in each, the MCPBridge descriptor beside the project or under an engine, the ProjectID in `Config/DefaultGame.ini`, the registry file, a live bridge ping per registered editor, plugin/server version skew — read from what the ping answered, not from what the registration recorded — and whether an MCP client config names this server
|
|
148
|
+
- Runs with no registered project and no engine installed — a setup that is broken everywhere is exactly when it is called, so no check is allowed to be a precondition for the rest
|
|
149
|
+
- `projectId` narrows the bridge and version checks to one editor, and fails when nothing is registered under it; `projectPath` names the project to resolve, falling back to a registration and then to the server working directory
|
|
150
|
+
|
|
144
151
|
### `get_project_id`
|
|
145
152
|
|
|
146
153
|
- Accepts a project path from the MCP caller
|
|
@@ -182,9 +189,11 @@ This is intended to let an MCP client resolve the canonical Unreal project ident
|
|
|
182
189
|
### `wait_for_job`
|
|
183
190
|
|
|
184
191
|
- Blocks server-side until an async job reaches a terminal state, then returns the payload the matching `get_*_status` tool would have returned under `status`
|
|
185
|
-
- Replaces a client-side poll loop for `kind` `compile` (`trigger_live_compile` / `trigger_hot_reload`), `create_class`, `test_run`, `pie`, and `source_control` (`checkout_assets` / `refresh_source_control_status`); `kind` is required because job ids are bare GUIDs
|
|
192
|
+
- Replaces a client-side poll loop for `kind` `compile` (`trigger_live_compile` / `trigger_hot_reload`), `create_class`, `test_run`, `pie`, `package` (`cook_content` / `package_project` / `run_editor_commandlet`), and `source_control` (`checkout_assets` / `refresh_source_control_status`); `kind` is required because job ids are bare GUIDs
|
|
186
193
|
- `outcome` is `completed`, `timed_out` (last observed status still returned), or `unknown_job` (unknown/expired/cancelled id, returned on the first poll)
|
|
187
194
|
- Per-kind default budgets (compile 120s, create_class 60s, pie 30s, source_control 60s, test_run 300s), clamped to 600s; polls back off from 250ms (1s for test runs) and a transient bridge read timeout or dropped socket is retried rather than failing the wait
|
|
195
|
+
- `package` is a server-side child process, so waiting on one needs no registered editor — every other kind does
|
|
196
|
+
- Emits `notifications/progress` on each poll when the request carried a `_meta.progressToken`, and nothing when it did not
|
|
188
197
|
- For `test_run`, `status.results` is the first page — page the rest with `get_test_run_status` and `nextCursor`
|
|
189
198
|
|
|
190
199
|
### `build_target` / `generate_project_files` / `clean_build`
|
|
@@ -605,16 +614,21 @@ This is intended to let an MCP client resolve the canonical Unreal project ident
|
|
|
605
614
|
|
|
606
615
|
## MCP Resources
|
|
607
616
|
|
|
608
|
-
Resources carry context a client can attach without spending a tool call and a model turn.
|
|
617
|
+
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.
|
|
609
618
|
|
|
610
|
-
All resources use the `uemcp://` URI scheme, are `application/json`, and are capped at 64 KB (`MAX_RESOURCE_PAYLOAD_BYTES`). A read that hits the cap drops entries from the end of the list and sets `truncated: true` while `totalCount` stays authoritative — the same convention the paged tools use. The authority segment (`registry`, `engines`, `workspace`) is the type discriminator.
|
|
619
|
+
All resources use the `uemcp://` URI scheme, are `application/json`, and are capped at 64 KB (`MAX_RESOURCE_PAYLOAD_BYTES`). A read that hits the cap drops entries from the end of the list and sets `truncated: true` while `totalCount` stays authoritative — the same convention the paged tools use. The authority segment (`registry`, `engines`, `workspace`, `project`) is the type discriminator.
|
|
611
620
|
|
|
612
621
|
| URI | Contents |
|
|
613
622
|
| --- | --- |
|
|
614
623
|
| `uemcp://registry` | Every registered Unreal Editor: `projectId`, `projectName`, `projectPath`, `port`, `pid`, `registeredAt`, `lastSeenAt`, plus `totalCount` and `truncated` |
|
|
615
624
|
| `uemcp://registry/{projectId}` | One registration, addressed by canonical ProjectID. Enumerable — the template's `list` callback returns the current registry, and `projectId` offers completions from it |
|
|
616
625
|
| `uemcp://engines` | Unreal installs found under `UE_INSTALLS_DIR`, ascending by version, each with `engineVersion`, `engineRoot`, and `unrealBuildToolResolved`. Source builds and GUID engine associations are excluded, matching `resolveEngine` |
|
|
617
|
-
| `uemcp://workspace/project` | The Unreal project identity of the server's working directory,
|
|
626
|
+
| `uemcp://workspace/project` | The Unreal project identity of the server's working directory, plus a `context` block: modules with their `Build.cs` dependencies, enabled plugins, target platforms, engine association, and the default game mode, game instance and startup map |
|
|
627
|
+
| `uemcp://project/{projectId}/asset/{+assetPath}` | Asset metadata for one content path — the payload `get_asset_metadata` returns |
|
|
628
|
+
| `uemcp://project/{projectId}/class/{className}` | UClass reflection for one class — the payload `get_class_reflection` returns |
|
|
629
|
+
| `uemcp://project/{projectId}/blueprint/{+assetPath}/graph` | A Blueprint's `EventGraph` nodes and connections — the payload `get_blueprint_graph` returns. Use the tool for any other graph or to page past the node cap |
|
|
630
|
+
|
|
631
|
+
The asset and blueprint templates use reserved expansion (`{+var}`) so an Unreal content path keeps its slashes. Both forms of the path resolve: `uemcp://project/<id>/asset/Game/Meshes/SM_Rock` and `uemcp://project/<id>/asset//Game/Meshes/SM_Rock` reach the same asset, because the template segment already follows a `/`.
|
|
618
632
|
|
|
619
633
|
`uemcp://registry/{projectId}` reports `found: false` with a `reason` for an unknown or malformed ProjectID, and `uemcp://engines` / `uemcp://workspace/project` report a `reason` when `UE_INSTALLS_DIR` is unset or the directory is not an Unreal project — none of them fail the read.
|
|
620
634
|
|
|
@@ -630,15 +644,37 @@ Prompts ship the workflows this server knows about as discoverable entry points
|
|
|
630
644
|
| `diagnose_bridge_disconnect` | `projectPath` (optional) | Which leg of the bridge is broken: registry state, `get_project_id` cross-check, `ping_project`, plugin-side log evidence |
|
|
631
645
|
| `smoke_test_bridge` | `projectId` | Green-path proof: registration, `ping_project`, `get_editor_state`, and a full log subscribe-emit-drain cycle |
|
|
632
646
|
| `add_gameplay_feature` | `projectId`, `className`, `parentClass`, `moduleName` (optional) | `create_cpp_class` → `wait_for_job` → implement → `trigger_live_compile` → `run_automation_tests` → `save_dirty_packages` |
|
|
647
|
+
| `fix_blueprint_compile_errors` | `projectId`, `blueprintPath` (optional) | Read the graph before editing it: `get_blueprint_compile_errors` → `get_blueprint_summary`/`get_blueprint_graph` → targeted authoring edits → `compile_blueprint` until it settles |
|
|
648
|
+
| `profile_hitch` | `projectId`, `tracePath` (optional) | `start_insights_trace` → reproduce → `stop_insights_trace` → `analyze_trace`, then confirm the suspect scope against `get_stat_snapshot` and the project |
|
|
649
|
+
| `setup_gas_character` | `projectId`, `characterName`, `packagePath` (optional) | Bottom-up GAS stack: tags → attribute set → cost/cooldown effects → ability → cue → character Blueprint |
|
|
650
|
+
| `port_blueprint_to_cpp` | `projectId`, `blueprintPath`, `moduleName` (optional) | `get_blueprint_summary`/`find_blueprint_references` → `create_cpp_class` → implement with matching member names → build → reparent → tests |
|
|
633
651
|
|
|
634
652
|
`diagnose_bridge_disconnect` and `smoke_test_bridge` are distilled from the same-named skills in `.agents/skills/`. Those files stay separate on purpose: they are maintainer runbooks that reference `just` recipes, `registry.json` paths, and pino module loggers, and the published package ships `dist` only, so they cannot be read at runtime. Each skill carries a pointer to its prompt counterpart so the two do not silently diverge.
|
|
635
653
|
|
|
654
|
+
## Tool annotations, toolsets and search mode
|
|
655
|
+
|
|
656
|
+
Every tool declares all four MCP annotation hints — `readOnlyHint`, `destructiveHint`, `idempotentHint`, `openWorldHint` — so a client can auto-approve a query and prompt on a delete. `openWorldHint` is true only where the tool reaches past the project directory and the running editor: a target device, or a source file the caller names.
|
|
657
|
+
|
|
658
|
+
The gateway groups the tools into toolsets: `core`, `build`, `test`, `level`, `asset`, `blueprint`, `anim`, `ai`, `gas`, `ui`, `sequence`, `fx`, `audio`, `input`. Two environment variables shape what a client sees:
|
|
659
|
+
|
|
660
|
+
- `UEMCP_TOOLSETS` — a comma-separated selection, or `all`. Unset means every toolset, which is what a client that has never heard of this setting keeps getting. `core` is always included, because `enable_toolset` lives there and it is the way back to the rest of the list. `UEMCP_TOOLSETS=core` fits inside the ~40-tool ceiling clients like Cursor impose; `enable_toolset` loads a further group at runtime and emits `notifications/tools/list_changed`.
|
|
661
|
+
- `UEMCP_TOOL_MODE` — `direct` (the default) advertises the tool list. `search` advertises exactly three meta-tools — `search_tools`, `get_tool_schema`, `call_tool` — for a client that cannot hold a large tool list at all. `search_tools` ranks the catalog with BM25 over names, titles, descriptions and toolset keywords; `call_tool` validates against the same schema a direct call uses, so an invalid payload fails identically. The prompts name tools directly; in search mode each one opens with a line saying to run those names through `call_tool`.
|
|
662
|
+
|
|
663
|
+
A plugin that reports its supported request types (see the plugin's capability list) also shapes the tool list: a tool whose bridge request no registered plugin serves is hidden, and calling one against a plugin that cannot serve it returns a clear unsupported error before a socket is opened. A plugin build that predates capability reporting leaves every tool visible.
|
|
664
|
+
|
|
665
|
+
## Progress notifications
|
|
666
|
+
|
|
667
|
+
`wait_for_job` sends `notifications/progress` as a job advances whenever the request carried a `_meta.progressToken`, and sends nothing when it did not. `progress` is the milliseconds waited against a `total` of the wait budget, so it rises monotonically and a client can render a bar. `kind` covers `build`, `compile`, `create_class`, `import`, `package` (cook, package and commandlet jobs), `pie`, `render`, `source_control` and `test_run`; `package` is server-side and needs no registered editor.
|
|
668
|
+
|
|
636
669
|
## Configuration
|
|
637
670
|
|
|
638
671
|
- Engine toolchain (`build_target`, `generate_project_files`, `clean_build`):
|
|
639
672
|
- `UE_INSTALLS_DIR` — base directory holding installed engines (`UE_<version>`)
|
|
640
673
|
- `run_clang_tidy`:
|
|
641
674
|
- `CLANG_TIDY_PATH` — optional clang-tidy binary override
|
|
675
|
+
- Tool surface:
|
|
676
|
+
- `UEMCP_TOOLSETS`
|
|
677
|
+
- `UEMCP_TOOL_MODE`
|
|
642
678
|
- Local HTTP registry API:
|
|
643
679
|
- `MCP_SERVER_HTTP_HOST`
|
|
644
680
|
- `MCP_SERVER_HTTP_PORT`
|