ue-mcp 0.5.0 → 0.5.2
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 +9 -2
- package/dist/bridge.d.ts +7 -1
- package/dist/bridge.js +8 -7
- package/dist/bridge.js.map +1 -1
- package/dist/errors.d.ts +19 -0
- package/dist/errors.js +25 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/project.js +3 -2
- package/dist/project.js.map +1 -1
- package/dist/schemas.d.ts +59 -0
- package/dist/schemas.js +8 -0
- package/dist/schemas.js.map +1 -0
- package/dist/tools/animation.js +4 -3
- package/dist/tools/animation.js.map +1 -1
- package/dist/tools/asset.js +4 -3
- package/dist/tools/asset.js.map +1 -1
- package/dist/tools/audio.js +2 -1
- package/dist/tools/audio.js.map +1 -1
- package/dist/tools/editor.js +3 -2
- package/dist/tools/editor.js.map +1 -1
- package/dist/tools/foliage.js +2 -1
- package/dist/tools/foliage.js.map +1 -1
- package/dist/tools/gameplay.js +3 -2
- package/dist/tools/gameplay.js.map +1 -1
- package/dist/tools/level.js +7 -6
- package/dist/tools/level.js.map +1 -1
- package/dist/tools/material.js +2 -1
- package/dist/tools/material.js.map +1 -1
- package/dist/tools/niagara.js +3 -2
- package/dist/tools/niagara.js.map +1 -1
- package/dist/tools/pcg.js +3 -2
- package/dist/tools/pcg.js.map +1 -1
- package/dist/types.d.ts +2 -2
- package/dist/types.js +3 -2
- package/dist/types.js.map +1 -1
- package/package.json +1 -1
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/BridgeServer.cpp +8 -9
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/HandlerRegistry.cpp +1 -1
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/HandlerUtils.h +155 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AnimationHandlers.cpp +217 -657
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AssetHandlers.cpp +200 -461
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AudioHandlers.cpp +27 -80
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/BlueprintHandlers.cpp +222 -755
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/DemoHandlers.cpp +21 -24
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/DialogHandlers.cpp +23 -42
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/EditorHandlers.cpp +215 -558
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/FoliageHandlers.cpp +59 -150
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/GameplayHandlers.cpp +254 -730
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/GasHandlers.cpp +74 -219
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LandscapeHandlers.cpp +72 -229
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LevelHandlers.cpp +127 -422
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/MaterialHandlers.cpp +240 -506
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/NetworkingHandlers.cpp +71 -151
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/NiagaraHandlers.cpp +80 -220
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/PCGHandlers.cpp +78 -251
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/PhysicsHandlers.cpp +25 -94
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/ReflectionHandlers.cpp +28 -61
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/SequencerHandlers.cpp +30 -92
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/SplineHandlers.cpp +22 -67
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/WidgetHandlers.cpp +98 -316
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/UE_MCP_Bridge.Build.cs +8 -19
package/dist/tools/level.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { categoryTool, bp } from "../types.js";
|
|
3
|
+
import { Vec3, Rotator, Color } from "../schemas.js";
|
|
3
4
|
export const levelTool = categoryTool("level", "Level actors, selection, components, level management, volumes, lights, and splines.", {
|
|
4
5
|
get_outliner: bp("get_world_outliner"),
|
|
5
6
|
place_actor: bp("place_actor"),
|
|
@@ -47,9 +48,9 @@ export const levelTool = categoryTool("level", "Level actors, selection, compone
|
|
|
47
48
|
- set_world_settings: Set world settings. Params: defaultGameMode?, killZ?, globalGravityZ?, enableWorldBoundsChecks?`, {
|
|
48
49
|
actorLabel: z.string().optional(), actorLabels: z.array(z.string()).optional(),
|
|
49
50
|
actorClass: z.string().optional(), label: z.string().optional(),
|
|
50
|
-
location:
|
|
51
|
-
rotation:
|
|
52
|
-
scale:
|
|
51
|
+
location: Vec3.optional(),
|
|
52
|
+
rotation: Rotator.optional(),
|
|
53
|
+
scale: Vec3.optional(),
|
|
53
54
|
properties: z.record(z.unknown()).optional(),
|
|
54
55
|
classFilter: z.string().optional(), nameFilter: z.string().optional(),
|
|
55
56
|
componentClass: z.string().optional(), componentName: z.string().optional(),
|
|
@@ -57,14 +58,14 @@ export const levelTool = categoryTool("level", "Level actors, selection, compone
|
|
|
57
58
|
levelPath: z.string().optional(), templateLevel: z.string().optional(),
|
|
58
59
|
directory: z.string().optional(), recursive: z.boolean().optional(),
|
|
59
60
|
volumeType: z.string().optional(),
|
|
60
|
-
extent:
|
|
61
|
+
extent: Vec3.optional(),
|
|
61
62
|
lightType: z.string().optional(), intensity: z.number().optional(),
|
|
62
|
-
color:
|
|
63
|
+
color: Color.optional(),
|
|
63
64
|
temperature: z.number().optional(), castShadows: z.boolean().optional(),
|
|
64
65
|
attenuationRadius: z.number().optional(),
|
|
65
66
|
innerConeAngle: z.number().optional(), outerConeAngle: z.number().optional(),
|
|
66
67
|
quality: z.string().optional(),
|
|
67
|
-
points: z.array(
|
|
68
|
+
points: z.array(Vec3).optional(),
|
|
68
69
|
closedLoop: z.boolean().optional(),
|
|
69
70
|
defaultGameMode: z.string().optional(),
|
|
70
71
|
killZ: z.number().optional(),
|
package/dist/tools/level.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"level.js","sourceRoot":"","sources":["../../src/tools/level.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,YAAY,EAAE,EAAE,EAAgB,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"level.js","sourceRoot":"","sources":["../../src/tools/level.ts"],"names":[],"mappings":"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"}
|
package/dist/tools/material.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { categoryTool, bp } from "../types.js";
|
|
3
|
+
import { Color } from "../schemas.js";
|
|
3
4
|
export const materialTool = categoryTool("material", "Materials: create, read, parameters, shading, textures, and graph authoring (expression nodes, connections).", {
|
|
4
5
|
read: bp("read_material", (p) => ({ assetPath: p.assetPath })),
|
|
5
6
|
list_parameters: bp("list_material_parameters", (p) => ({ assetPath: p.assetPath })),
|
|
@@ -48,7 +49,7 @@ export const materialTool = categoryTool("material", "Materials: create, read, p
|
|
|
48
49
|
packagePath: z.string().optional(),
|
|
49
50
|
shadingModel: z.string().optional(),
|
|
50
51
|
blendMode: z.string().optional().describe("Blend mode: Opaque, Masked, Translucent, Additive, Modulate, AlphaComposite, AlphaHoldout"),
|
|
51
|
-
color:
|
|
52
|
+
color: Color.optional(),
|
|
52
53
|
materialPath: z.string().optional(),
|
|
53
54
|
texturePath: z.string().optional(),
|
|
54
55
|
property: z.string().optional().describe("Material property: BaseColor, Normal, Roughness, Metallic, EmissiveColor, etc."),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"material.js","sourceRoot":"","sources":["../../src/tools/material.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,YAAY,EAAE,EAAE,EAAgB,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"material.js","sourceRoot":"","sources":["../../src/tools/material.ts"],"names":[],"mappings":"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"}
|
package/dist/tools/niagara.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { categoryTool, bp } from "../types.js";
|
|
3
|
+
import { Vec3, Rotator } from "../schemas.js";
|
|
3
4
|
export const niagaraTool = categoryTool("niagara", "Niagara VFX: systems, emitters, spawning, parameters, and graph authoring.", {
|
|
4
5
|
list: bp("list_niagara_systems"),
|
|
5
6
|
get_info: bp("get_niagara_info"),
|
|
@@ -27,8 +28,8 @@ export const niagaraTool = categoryTool("niagara", "Niagara VFX: systems, emitte
|
|
|
27
28
|
assetPath: z.string().optional(), actorLabel: z.string().optional(),
|
|
28
29
|
directory: z.string().optional(), recursive: z.boolean().optional(),
|
|
29
30
|
systemPath: z.string().optional(), emitterPath: z.string().optional(),
|
|
30
|
-
location:
|
|
31
|
-
rotation:
|
|
31
|
+
location: Vec3.optional(),
|
|
32
|
+
rotation: Rotator.optional(),
|
|
32
33
|
label: z.string().optional(),
|
|
33
34
|
parameterName: z.string().optional(),
|
|
34
35
|
value: z.unknown().optional(),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"niagara.js","sourceRoot":"","sources":["../../src/tools/niagara.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,YAAY,EAAE,EAAE,EAAgB,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"niagara.js","sourceRoot":"","sources":["../../src/tools/niagara.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,YAAY,EAAE,EAAE,EAAgB,MAAM,aAAa,CAAC;AAC7D,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAE9C,MAAM,CAAC,MAAM,WAAW,GAAY,YAAY,CAC9C,SAAS,EACT,4EAA4E,EAC5E;IACE,IAAI,EAAY,EAAE,CAAC,sBAAsB,CAAC;IAC1C,QAAQ,EAAQ,EAAE,CAAC,kBAAkB,CAAC;IACtC,KAAK,EAAW,EAAE,CAAC,2BAA2B,CAAC;IAC/C,aAAa,EAAG,EAAE,CAAC,uBAAuB,CAAC;IAC3C,MAAM,EAAU,EAAE,CAAC,uBAAuB,CAAC;IAC3C,kBAAkB;IAClB,cAAc,EAAE,EAAE,CAAC,wBAAwB,CAAC;IAC5C,WAAW,EAAK,EAAE,CAAC,uBAAuB,CAAC;IAC3C,aAAa,EAAG,EAAE,CAAC,yBAAyB,CAAC;IAC7C,oBAAoB,EAAE,EAAE,CAAC,sBAAsB,CAAC;IAChD,YAAY,EAAI,EAAE,CAAC,sBAAsB,CAAC;IAC1C,gBAAgB,EAAE,EAAE,CAAC,kBAAkB,CAAC;CACzC,EACD;;;;;;;;;;uDAUqD,EACrD;IACE,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACnE,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IACnE,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACrE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE;IACzB,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE;IAC5B,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC5B,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACpC,KAAK,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IAC7B,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACpC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC3B,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAClC,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACnC,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAClC,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CACpC,CACF,CAAC"}
|
package/dist/tools/pcg.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { categoryTool, bp } from "../types.js";
|
|
3
|
+
import { Vec3 } from "../schemas.js";
|
|
3
4
|
export const pcgTool = categoryTool("pcg", "Procedural Content Generation: graphs, nodes, connections, execution, volumes.", {
|
|
4
5
|
list_graphs: bp("list_pcg_graphs"),
|
|
5
6
|
read_graph: bp("read_pcg_graph"),
|
|
@@ -33,7 +34,7 @@ export const pcgTool = categoryTool("pcg", "Procedural Content Generation: graph
|
|
|
33
34
|
targetNode: z.string().optional(), targetPin: z.string().optional(),
|
|
34
35
|
settings: z.record(z.unknown()).optional(),
|
|
35
36
|
graphPath: z.string().optional(),
|
|
36
|
-
location:
|
|
37
|
-
extent:
|
|
37
|
+
location: Vec3.optional(),
|
|
38
|
+
extent: Vec3.optional(),
|
|
38
39
|
});
|
|
39
40
|
//# sourceMappingURL=pcg.js.map
|
package/dist/tools/pcg.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pcg.js","sourceRoot":"","sources":["../../src/tools/pcg.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,YAAY,EAAE,EAAE,EAAgB,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"pcg.js","sourceRoot":"","sources":["../../src/tools/pcg.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,YAAY,EAAE,EAAE,EAAgB,MAAM,aAAa,CAAC;AAC7D,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAErC,MAAM,CAAC,MAAM,OAAO,GAAY,YAAY,CAC1C,KAAK,EACL,gFAAgF,EAChF;IACE,WAAW,EAAW,EAAE,CAAC,iBAAiB,CAAC;IAC3C,UAAU,EAAY,EAAE,CAAC,gBAAgB,CAAC;IAC1C,kBAAkB,EAAI,EAAE,CAAC,wBAAwB,CAAC;IAClD,cAAc,EAAQ,EAAE,CAAC,oBAAoB,CAAC;IAC9C,qBAAqB,EAAE,EAAE,CAAC,2BAA2B,CAAC;IACtD,YAAY,EAAU,EAAE,CAAC,kBAAkB,CAAC;IAC5C,QAAQ,EAAc,EAAE,CAAC,cAAc,CAAC;IACxC,aAAa,EAAS,EAAE,CAAC,mBAAmB,CAAC;IAC7C,iBAAiB,EAAK,EAAE,CAAC,uBAAuB,CAAC;IACjD,WAAW,EAAW,EAAE,CAAC,iBAAiB,CAAC;IAC3C,OAAO,EAAe,EAAE,CAAC,mBAAmB,CAAC;IAC7C,UAAU,EAAY,EAAE,CAAC,gBAAgB,CAAC;CAC3C,EACD;;;;;;;;;;;sEAWoE,EACpE;IACE,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACnE,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IACnE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC/D,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAChE,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACnE,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACnE,QAAQ,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,EAAE;IAC1C,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAChC,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE;IACzB,MAAM,EAAE,IAAI,CAAC,QAAQ,EAAE;CACxB,CACF,CAAC"}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import type {
|
|
2
|
+
import type { IBridge } from "./bridge.js";
|
|
3
3
|
import type { ProjectContext } from "./project.js";
|
|
4
4
|
export interface ToolContext {
|
|
5
|
-
bridge:
|
|
5
|
+
bridge: IBridge;
|
|
6
6
|
project: ProjectContext;
|
|
7
7
|
}
|
|
8
8
|
export interface ToolDef {
|
package/dist/types.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
+
import { McpError, ErrorCode } from "./errors.js";
|
|
2
3
|
export function categoryTool(name, summary, actions, actionDocs, extraSchema) {
|
|
3
4
|
const actionNames = Object.keys(actions);
|
|
4
5
|
return {
|
|
@@ -12,7 +13,7 @@ export function categoryTool(name, summary, actions, actionDocs, extraSchema) {
|
|
|
12
13
|
const action = params.action;
|
|
13
14
|
const spec = actions[action];
|
|
14
15
|
if (!spec) {
|
|
15
|
-
throw new
|
|
16
|
+
throw new McpError(ErrorCode.UNKNOWN_ACTION, `Unknown action '${action}'. Available: ${actionNames.join(", ")}`);
|
|
16
17
|
}
|
|
17
18
|
if (spec.handler) {
|
|
18
19
|
return spec.handler(ctx, params);
|
|
@@ -21,7 +22,7 @@ export function categoryTool(name, summary, actions, actionDocs, extraSchema) {
|
|
|
21
22
|
const mapped = spec.mapParams ? spec.mapParams(params) : stripAction(params);
|
|
22
23
|
return ctx.bridge.call(spec.bridge, mapped);
|
|
23
24
|
}
|
|
24
|
-
throw new
|
|
25
|
+
throw new McpError(ErrorCode.NO_HANDLER, `Action '${action}' has no handler or bridge method`);
|
|
25
26
|
},
|
|
26
27
|
};
|
|
27
28
|
}
|
package/dist/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAoBlD,MAAM,UAAU,YAAY,CAC1B,IAAY,EACZ,OAAe,EACf,OAAmC,EACnC,UAAkB,EAClB,WAAuC;IAEvC,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAA0B,CAAC;IAClE,OAAO;QACL,IAAI;QACJ,WAAW,EAAE,GAAG,OAAO,iBAAiB,UAAU,EAAE;QACpD,MAAM,EAAE;YACN,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,QAAQ,CAAC,mBAAmB,CAAC;YACzD,GAAG,WAAW;SACf;QACD,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE;YAC7B,MAAM,MAAM,GAAG,MAAM,CAAC,MAAgB,CAAC;YACvC,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;YAC7B,IAAI,CAAC,IAAI,EAAE,CAAC;gBACV,MAAM,IAAI,QAAQ,CAAC,SAAS,CAAC,cAAc,EAAE,mBAAmB,MAAM,iBAAiB,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACnH,CAAC;YACD,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;gBACjB,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YACnC,CAAC;YACD,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;gBAChB,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;gBAC7E,OAAO,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YAC9C,CAAC;YACD,MAAM,IAAI,QAAQ,CAAC,SAAS,CAAC,UAAU,EAAE,WAAW,MAAM,mCAAmC,CAAC,CAAC;QACjG,CAAC;KACF,CAAC;AACJ,CAAC;AAED,SAAS,WAAW,CAAC,MAA+B;IAClD,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,GAAG,MAAM,CAAC;IACtC,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,EAAE,CAAC,MAAc,EAAE,SAAmE;IACpG,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;AAC/B,CAAC;AAED,MAAM,UAAU,MAAM;IACpB,OAAO,EAAE,CAAC;AACZ,CAAC;AAcD,MAAM,UAAU,SAAS,CAAC,IAAY,EAAE,MAAe;IACrD,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;AACxD,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,CAAU;IAC5C,OAAO,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,IAAK,CAA6B,CAAC,WAAW,KAAK,IAAI,CAAC;AACpG,CAAC"}
|
package/package.json
CHANGED
|
@@ -40,6 +40,7 @@
|
|
|
40
40
|
#elif PLATFORM_LINUX || PLATFORM_MAC
|
|
41
41
|
#include <sys/socket.h>
|
|
42
42
|
#include <netinet/in.h>
|
|
43
|
+
#include <netinet/tcp.h>
|
|
43
44
|
#include <arpa/inet.h>
|
|
44
45
|
#include <unistd.h>
|
|
45
46
|
#include <sys/select.h>
|
|
@@ -551,10 +552,10 @@ FString FMCPBridgeServer::CreateWebSocketAcceptKey(const FString& ClientKey)
|
|
|
551
552
|
FString MagicString = TEXT("258EAFA5-E914-47DA-95CA-C5AB0DC85B11");
|
|
552
553
|
FString Combined = ClientKey + MagicString;
|
|
553
554
|
|
|
554
|
-
// Compute SHA1 hash (20 bytes)
|
|
555
|
+
// Compute SHA1 hash (20 bytes)
|
|
555
556
|
FTCHARToUTF8 UTF8String(*Combined);
|
|
556
557
|
uint8 HashBytes[20];
|
|
557
|
-
|
|
558
|
+
|
|
558
559
|
#if PLATFORM_WINDOWS
|
|
559
560
|
HCRYPTPROV hProv = 0;
|
|
560
561
|
HCRYPTHASH hHash = 0;
|
|
@@ -570,13 +571,11 @@ FString FMCPBridgeServer::CreateWebSocketAcceptKey(const FString& ClientKey)
|
|
|
570
571
|
CryptReleaseContext(hProv, 0);
|
|
571
572
|
}
|
|
572
573
|
#else
|
|
573
|
-
//
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
}
|
|
579
|
-
FMemory::Memcpy(HashBytes, &Hash, 20);
|
|
574
|
+
// UE's cross-platform SHA1
|
|
575
|
+
FSHA1 Sha1;
|
|
576
|
+
Sha1.Update((const uint8*)UTF8String.Get(), UTF8String.Length());
|
|
577
|
+
Sha1.Final();
|
|
578
|
+
Sha1.GetHash(HashBytes);
|
|
580
579
|
#endif
|
|
581
580
|
|
|
582
581
|
// Base64 encode
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include "CoreMinimal.h"
|
|
4
|
+
#include "Dom/JsonValue.h"
|
|
5
|
+
#include "Dom/JsonObject.h"
|
|
6
|
+
#include "UObject/UObjectIterator.h"
|
|
7
|
+
|
|
8
|
+
// ── Quick result builders ────────────────────────────────────────────────────
|
|
9
|
+
|
|
10
|
+
/** Return an error response: { success: false, error: "..." } */
|
|
11
|
+
inline TSharedPtr<FJsonValue> MCPError(const FString& Message)
|
|
12
|
+
{
|
|
13
|
+
TSharedPtr<FJsonObject> Obj = MakeShared<FJsonObject>();
|
|
14
|
+
Obj->SetBoolField(TEXT("success"), false);
|
|
15
|
+
Obj->SetStringField(TEXT("error"), Message);
|
|
16
|
+
return MakeShared<FJsonValueObject>(Obj);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** Return a formatted error. Usage: MCPError(FString::Printf(TEXT("Not found: %s"), *Path)) */
|
|
20
|
+
// NOTE: Do not use a variadic template wrapper — UE 5.7's consteval format
|
|
21
|
+
// string validation requires TEXT() literals passed directly to FString::Printf.
|
|
22
|
+
|
|
23
|
+
/** Wrap a populated FJsonObject as a FJsonValue (the common return). */
|
|
24
|
+
inline TSharedPtr<FJsonValue> MCPResult(TSharedPtr<FJsonObject> Obj)
|
|
25
|
+
{
|
|
26
|
+
return MakeShared<FJsonValueObject>(Obj);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** Create a fresh result object with success=true pre-set. */
|
|
30
|
+
inline TSharedPtr<FJsonObject> MCPSuccess()
|
|
31
|
+
{
|
|
32
|
+
TSharedPtr<FJsonObject> Obj = MakeShared<FJsonObject>();
|
|
33
|
+
Obj->SetBoolField(TEXT("success"), true);
|
|
34
|
+
return Obj;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// ── Parameter extraction ─────────────────────────────────────────────────────
|
|
38
|
+
|
|
39
|
+
/** Extract a required string parameter. Returns error JSON on failure, nullptr on success. */
|
|
40
|
+
inline TSharedPtr<FJsonValue> RequireString(
|
|
41
|
+
const TSharedPtr<FJsonObject>& Params,
|
|
42
|
+
const TCHAR* Key,
|
|
43
|
+
FString& OutValue)
|
|
44
|
+
{
|
|
45
|
+
if (Params->TryGetStringField(Key, OutValue) && !OutValue.IsEmpty())
|
|
46
|
+
return nullptr;
|
|
47
|
+
return MCPError(FString::Printf(TEXT("Missing required parameter '%s'"), Key));
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** Extract a required string from either of two keys (e.g. "path" or "assetPath"). */
|
|
51
|
+
inline TSharedPtr<FJsonValue> RequireStringAlt(
|
|
52
|
+
const TSharedPtr<FJsonObject>& Params,
|
|
53
|
+
const TCHAR* Key1,
|
|
54
|
+
const TCHAR* Key2,
|
|
55
|
+
FString& OutValue)
|
|
56
|
+
{
|
|
57
|
+
if (Params->TryGetStringField(Key1, OutValue) && !OutValue.IsEmpty())
|
|
58
|
+
return nullptr;
|
|
59
|
+
if (Params->TryGetStringField(Key2, OutValue) && !OutValue.IsEmpty())
|
|
60
|
+
return nullptr;
|
|
61
|
+
return MCPError(FString::Printf(TEXT("Missing required parameter '%s' (or '%s')"), Key1, Key2));
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** Extract an optional string, returning DefaultValue if absent. */
|
|
65
|
+
inline FString OptionalString(
|
|
66
|
+
const TSharedPtr<FJsonObject>& Params,
|
|
67
|
+
const TCHAR* Key,
|
|
68
|
+
const FString& DefaultValue = TEXT(""))
|
|
69
|
+
{
|
|
70
|
+
FString Value;
|
|
71
|
+
return Params->TryGetStringField(Key, Value) ? Value : DefaultValue;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/** Extract an optional int32, returning DefaultValue if absent. */
|
|
75
|
+
inline int32 OptionalInt(
|
|
76
|
+
const TSharedPtr<FJsonObject>& Params,
|
|
77
|
+
const TCHAR* Key,
|
|
78
|
+
int32 DefaultValue = 0)
|
|
79
|
+
{
|
|
80
|
+
int32 Value;
|
|
81
|
+
return Params->TryGetNumberField(Key, Value) ? Value : DefaultValue;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/** Extract an optional double, returning DefaultValue if absent. */
|
|
85
|
+
inline double OptionalNumber(
|
|
86
|
+
const TSharedPtr<FJsonObject>& Params,
|
|
87
|
+
const TCHAR* Key,
|
|
88
|
+
double DefaultValue = 0.0)
|
|
89
|
+
{
|
|
90
|
+
double Value;
|
|
91
|
+
return Params->TryGetNumberField(Key, Value) ? Value : DefaultValue;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/** Extract an optional bool, returning DefaultValue if absent. */
|
|
95
|
+
inline bool OptionalBool(
|
|
96
|
+
const TSharedPtr<FJsonObject>& Params,
|
|
97
|
+
const TCHAR* Key,
|
|
98
|
+
bool DefaultValue = false)
|
|
99
|
+
{
|
|
100
|
+
bool Value;
|
|
101
|
+
return Params->TryGetBoolField(Key, Value) ? Value : DefaultValue;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// ── Common helpers ───────────────────────────────────────────────────────────
|
|
105
|
+
|
|
106
|
+
/** Find a UClass by short name, handling A/U prefix resolution.
|
|
107
|
+
* e.g. "StaticMeshActor" finds AStaticMeshActor, "AnimInstance" finds UAnimInstance. */
|
|
108
|
+
inline UClass* FindClassByShortName(const FString& ClassName)
|
|
109
|
+
{
|
|
110
|
+
UClass* PrefixedMatch = nullptr;
|
|
111
|
+
for (TObjectIterator<UClass> It; It; ++It)
|
|
112
|
+
{
|
|
113
|
+
const FString& Name = It->GetName();
|
|
114
|
+
if (Name == ClassName) return *It;
|
|
115
|
+
if (!PrefixedMatch && (Name == TEXT("U") + ClassName || Name == TEXT("A") + ClassName))
|
|
116
|
+
{
|
|
117
|
+
PrefixedMatch = *It;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return PrefixedMatch;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/** Get the editor world, or nullptr if not available. */
|
|
124
|
+
inline UWorld* GetEditorWorld()
|
|
125
|
+
{
|
|
126
|
+
if (!GEditor) return nullptr;
|
|
127
|
+
return GEditor->GetEditorWorldContext().World();
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/** Get the editor world or return an error response. */
|
|
131
|
+
#define REQUIRE_EDITOR_WORLD(WorldVar) \
|
|
132
|
+
UWorld* WorldVar = GetEditorWorld(); \
|
|
133
|
+
if (!WorldVar) return MCPError(TEXT("Editor world not available"));
|
|
134
|
+
|
|
135
|
+
/** Load an asset by path with fallback to ObjectPath format. Returns nullptr if not found. */
|
|
136
|
+
template <typename T>
|
|
137
|
+
T* LoadAssetByPath(const FString& AssetPath)
|
|
138
|
+
{
|
|
139
|
+
T* Asset = LoadObject<T>(nullptr, *AssetPath);
|
|
140
|
+
if (Asset) return Asset;
|
|
141
|
+
|
|
142
|
+
// Try ObjectPath format: "/Game/Foo/Bar" → "/Game/Foo/Bar.Bar"
|
|
143
|
+
if (!AssetPath.Contains(TEXT(".")))
|
|
144
|
+
{
|
|
145
|
+
FString AssetName;
|
|
146
|
+
AssetPath.Split(TEXT("/"), nullptr, &AssetName, ESearchCase::CaseSensitive, ESearchDir::FromEnd);
|
|
147
|
+
Asset = LoadObject<T>(nullptr, *(AssetPath + TEXT(".") + AssetName));
|
|
148
|
+
}
|
|
149
|
+
return Asset;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/** Load an asset or return an error response. Assigns to OutVar. */
|
|
153
|
+
#define REQUIRE_ASSET(Type, OutVar, AssetPath) \
|
|
154
|
+
Type* OutVar = LoadAssetByPath<Type>(AssetPath); \
|
|
155
|
+
if (!OutVar) return MCPError(FString::Printf(TEXT("%s not found: %s"), TEXT(#Type), *AssetPath));
|