ultimate-unreal-engine-mcp 0.1.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 +729 -0
- package/dist/build/error-parser.js +51 -0
- package/dist/build/fix-suggester.js +84 -0
- package/dist/build/ubt-runner.js +146 -0
- package/dist/cli.js +13 -0
- package/dist/config.js +8 -0
- package/dist/docs/data/ue57-api.js +228 -0
- package/dist/docs/doc-index.js +110 -0
- package/dist/docs/types.js +4 -0
- package/dist/generators/class-generator.js +363 -0
- package/dist/generators/file-modifier.js +276 -0
- package/dist/generators/uht-validator.js +177 -0
- package/dist/index.js +89 -0
- package/dist/parsers/cpp-class-index.js +230 -0
- package/dist/parsers/cpp-parser.js +369 -0
- package/dist/parsers/ini-parser.js +216 -0
- package/dist/parsers/uproject-parser.js +130 -0
- package/dist/plugin-bridge/client.js +217 -0
- package/dist/plugin-bridge/protocol.js +6 -0
- package/dist/plugin-bridge/retry.js +23 -0
- package/dist/setup.js +209 -0
- package/dist/tools/ai-systems/index.js +247 -0
- package/dist/tools/ai-systems/types.js +4 -0
- package/dist/tools/animation/index.js +241 -0
- package/dist/tools/animation/types.js +4 -0
- package/dist/tools/audio/index.js +204 -0
- package/dist/tools/audio/types.js +4 -0
- package/dist/tools/blueprint/index.js +495 -0
- package/dist/tools/blueprint/types.js +4 -0
- package/dist/tools/build/index.js +163 -0
- package/dist/tools/chaos/index.js +230 -0
- package/dist/tools/chaos/types.js +4 -0
- package/dist/tools/collision-physics/index.js +211 -0
- package/dist/tools/config/index.js +288 -0
- package/dist/tools/cpp/index.js +305 -0
- package/dist/tools/docs/index.js +251 -0
- package/dist/tools/editor/index.js +242 -0
- package/dist/tools/gas/index.js +222 -0
- package/dist/tools/gas/types.js +5 -0
- package/dist/tools/import-export/index.js +218 -0
- package/dist/tools/input/index.js +146 -0
- package/dist/tools/known-issues/index.js +88 -0
- package/dist/tools/known-issues/middleware.js +55 -0
- package/dist/tools/known-issues/store.js +125 -0
- package/dist/tools/livelink/index.js +203 -0
- package/dist/tools/livelink/types.js +4 -0
- package/dist/tools/material/index.js +190 -0
- package/dist/tools/motion-design/index.js +251 -0
- package/dist/tools/motion-design/types.js +6 -0
- package/dist/tools/movie-render/index.js +220 -0
- package/dist/tools/networking/index.js +149 -0
- package/dist/tools/pcg/index.js +164 -0
- package/dist/tools/selection/index.js +180 -0
- package/dist/tools/sequencer/index.js +218 -0
- package/dist/tools/validation/index.js +183 -0
- package/dist/tools/validation/types.js +4 -0
- package/dist/tools/viewport/index.js +310 -0
- package/dist/tools/worldpartition/index.js +226 -0
- package/dist/tools/worldpartition/types.js +4 -0
- package/dist/utils/execFileNoThrow.js +40 -0
- package/dist/utils/logger.js +27 -0
- package/dist/utils/path-guard.js +26 -0
- package/package.json +40 -0
- package/unreal-plugin/MCPBridge/MCPBridge.uplugin +29 -0
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/MCPBridgeEditor.Build.cs +68 -0
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/MCPAICommands.cpp +919 -0
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/MCPAICommands.h +23 -0
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/MCPActorCommands.cpp +415 -0
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/MCPActorCommands.h +16 -0
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/MCPAnimationCommands.cpp +653 -0
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/MCPAnimationCommands.h +24 -0
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/MCPAssetCommands.cpp +290 -0
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/MCPAssetCommands.h +17 -0
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/MCPAudioCommands.cpp +624 -0
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/MCPAudioCommands.h +22 -0
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/MCPBlueprintHandlers.cpp +616 -0
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/MCPBlueprintHandlers.h +25 -0
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/MCPBlueprintWriteHandlers.cpp +744 -0
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/MCPBlueprintWriteHandlers.h +24 -0
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/MCPBridgeEditor.cpp +23 -0
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/MCPBridgeSubsystem.cpp +149 -0
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/MCPBridgeSubsystem.h +38 -0
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/MCPChaosCommands.cpp +771 -0
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/MCPChaosCommands.h +22 -0
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/MCPCollisionPhysicsCommands.cpp +749 -0
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/MCPCollisionPhysicsCommands.h +22 -0
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/MCPEditorStateCommands.cpp +172 -0
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/MCPEditorStateCommands.h +16 -0
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/MCPGASCommands.cpp +715 -0
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/MCPGASCommands.h +22 -0
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/MCPImportExportCommands.cpp +679 -0
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/MCPImportExportCommands.h +22 -0
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/MCPInputHandlers.cpp +381 -0
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/MCPInputHandlers.h +24 -0
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/MCPLiveLinkCommands.cpp +504 -0
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/MCPLiveLinkCommands.h +22 -0
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/MCPMaterialCommands.cpp +511 -0
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/MCPMaterialCommands.h +22 -0
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/MCPMotionDesignCommands.cpp +1110 -0
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/MCPMotionDesignCommands.h +28 -0
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/MCPMovieRenderCommands.cpp +590 -0
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/MCPMovieRenderCommands.h +16 -0
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/MCPNetworkingCommands.cpp +482 -0
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/MCPNetworkingCommands.h +16 -0
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/MCPPieCommands.cpp +338 -0
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/MCPPieCommands.h +16 -0
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/MCPSelectionCommands.cpp +677 -0
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/MCPSelectionCommands.h +22 -0
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/MCPSequencerCommands.cpp +721 -0
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/MCPSequencerCommands.h +16 -0
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/MCPValidationCommands.cpp +368 -0
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/MCPValidationCommands.h +22 -0
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/MCPViewportCommands.cpp +1208 -0
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/MCPViewportCommands.h +29 -0
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/MCPWorldPartitionCommands.cpp +822 -0
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Private/MCPWorldPartitionCommands.h +23 -0
- package/unreal-plugin/MCPBridge/Source/MCPBridgeEditor/Public/MCPBridgeEditor.h +14 -0
- package/unreal-plugin/MCPBridge/Source/MCPBridgeRuntime/MCPBridgeRuntime.Build.cs +28 -0
- package/unreal-plugin/MCPBridge/Source/MCPBridgeRuntime/Private/MCPBridgeRuntime.cpp +22 -0
- package/unreal-plugin/MCPBridge/Source/MCPBridgeRuntime/Private/MCPCommandRouter.cpp +118 -0
- package/unreal-plugin/MCPBridge/Source/MCPBridgeRuntime/Private/MCPTcpServer.cpp +196 -0
- package/unreal-plugin/MCPBridge/Source/MCPBridgeRuntime/Public/MCPBridgeRuntime.h +15 -0
- package/unreal-plugin/MCPBridge/Source/MCPBridgeRuntime/Public/MCPCommandRouter.h +55 -0
- package/unreal-plugin/MCPBridge/Source/MCPBridgeRuntime/Public/MCPTcpServer.h +59 -0
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
// src/tools/animation/index.ts
|
|
2
|
+
// MCP tool implementations for animation asset inspection (Phase 17).
|
|
3
|
+
// All tools route commands through PluginBridgeClient to the C++ MCPBridge handlers.
|
|
4
|
+
// Returns structured plugin_not_connected errors when the plugin is absent.
|
|
5
|
+
//
|
|
6
|
+
// Tools registered (Phase 17 — ANIM-01 through ANIM-05):
|
|
7
|
+
// ue_list_animation_assets — List all animation assets, optionally filtered by type
|
|
8
|
+
// ue_inspect_anim_blueprint — Inspect AnimBP state machines, states, and transitions
|
|
9
|
+
// ue_inspect_montage — Read montage sections, notifies, and slot assignments
|
|
10
|
+
// ue_inspect_blend_space — Inspect blend space axes, samples, and grid config
|
|
11
|
+
// ue_read_retarget_mappings — Read IK Retargeter source/target rig and chain mappings
|
|
12
|
+
//
|
|
13
|
+
// All tools require MCPBridge plugin (Phase 17 — ANIM-01 through ANIM-05).
|
|
14
|
+
import { z } from 'zod';
|
|
15
|
+
import { withKnownIssues } from '../known-issues/middleware.js';
|
|
16
|
+
import { PluginBridgeClient, PluginNotConnectedError } from '../../plugin-bridge/client.js';
|
|
17
|
+
// Module-level bridge instance — injected in tests via exported handler signatures.
|
|
18
|
+
const bridge = new PluginBridgeClient();
|
|
19
|
+
// ---------------------------------------------------------------------------
|
|
20
|
+
// sendOrDisconnect helper
|
|
21
|
+
// ---------------------------------------------------------------------------
|
|
22
|
+
/**
|
|
23
|
+
* Sends a command to the bridge and returns a ToolResult.
|
|
24
|
+
*
|
|
25
|
+
* - On success (response.success true): returns data as JSON text.
|
|
26
|
+
* - On command-level failure (response.success false): returns isError:true with error JSON.
|
|
27
|
+
* - On PluginNotConnectedError: returns isError:true with plugin_not_connected JSON.
|
|
28
|
+
* - On other errors: rethrows (withKnownIssues catches and formats).
|
|
29
|
+
*
|
|
30
|
+
* NOTE: sendCommand() overwrites correlationId with crypto.randomUUID() internally;
|
|
31
|
+
* passing an empty string is safe and correct (per STATE.md decision).
|
|
32
|
+
*/
|
|
33
|
+
async function sendOrDisconnect(b, cmd) {
|
|
34
|
+
try {
|
|
35
|
+
const response = await b.sendCommand({ ...cmd, correlationId: '' });
|
|
36
|
+
if (!response.success) {
|
|
37
|
+
return {
|
|
38
|
+
isError: true,
|
|
39
|
+
content: [{ type: 'text', text: JSON.stringify({ error: response.error }) }],
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
return {
|
|
43
|
+
content: [{ type: 'text', text: JSON.stringify(response.data ?? {}) }],
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
catch (err) {
|
|
47
|
+
if (err instanceof PluginNotConnectedError) {
|
|
48
|
+
return {
|
|
49
|
+
isError: true,
|
|
50
|
+
content: [{ type: 'text', text: JSON.stringify(err.bridgeError) }],
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
throw err; // withKnownIssues catches unexpected errors
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
// ---------------------------------------------------------------------------
|
|
57
|
+
// Exported handler functions (for direct unit testing via bridge injection)
|
|
58
|
+
// ---------------------------------------------------------------------------
|
|
59
|
+
/**
|
|
60
|
+
* ue_list_animation_assets handler — satisfies ANIM-01.
|
|
61
|
+
* Sends animation.list to the plugin; returns all animation assets, optionally filtered by type.
|
|
62
|
+
*
|
|
63
|
+
* @param args Tool arguments including optional type_filter.
|
|
64
|
+
* @param b PluginBridgeClient instance (defaults to module-level singleton).
|
|
65
|
+
*/
|
|
66
|
+
export async function handleListAnimationAssets(args, b = bridge) {
|
|
67
|
+
// Response data shape: AnimationListResult
|
|
68
|
+
const payload = {};
|
|
69
|
+
if (args.type_filter !== undefined) {
|
|
70
|
+
payload['type_filter'] = args.type_filter;
|
|
71
|
+
}
|
|
72
|
+
return sendOrDisconnect(b, {
|
|
73
|
+
type: 'animation.list',
|
|
74
|
+
payload,
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* ue_inspect_anim_blueprint handler — satisfies ANIM-02.
|
|
79
|
+
* Sends animation.inspectAnimBP to the plugin; returns state machines, states, transitions, and skeleton.
|
|
80
|
+
*
|
|
81
|
+
* @param args Tool arguments including asset_path.
|
|
82
|
+
* @param b PluginBridgeClient instance (defaults to module-level singleton).
|
|
83
|
+
*/
|
|
84
|
+
export async function handleInspectAnimBlueprint(args, b = bridge) {
|
|
85
|
+
// Response data shape: AnimBlueprintInspectResult
|
|
86
|
+
return sendOrDisconnect(b, {
|
|
87
|
+
type: 'animation.inspectAnimBP',
|
|
88
|
+
payload: { asset_path: args.asset_path },
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* ue_inspect_montage handler — satisfies ANIM-03.
|
|
93
|
+
* Sends animation.inspectMontage to the plugin; returns sections, notifies, and slot assignments.
|
|
94
|
+
*
|
|
95
|
+
* @param args Tool arguments including asset_path.
|
|
96
|
+
* @param b PluginBridgeClient instance (defaults to module-level singleton).
|
|
97
|
+
*/
|
|
98
|
+
export async function handleInspectMontage(args, b = bridge) {
|
|
99
|
+
// Response data shape: MontageInspectResult
|
|
100
|
+
return sendOrDisconnect(b, {
|
|
101
|
+
type: 'animation.inspectMontage',
|
|
102
|
+
payload: { asset_path: args.asset_path },
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* ue_inspect_blend_space handler — satisfies ANIM-04.
|
|
107
|
+
* Sends animation.inspectBlendSpace to the plugin; returns axes, samples, and grid configuration.
|
|
108
|
+
*
|
|
109
|
+
* @param args Tool arguments including asset_path.
|
|
110
|
+
* @param b PluginBridgeClient instance (defaults to module-level singleton).
|
|
111
|
+
*/
|
|
112
|
+
export async function handleInspectBlendSpace(args, b = bridge) {
|
|
113
|
+
// Response data shape: BlendSpaceInspectResult
|
|
114
|
+
return sendOrDisconnect(b, {
|
|
115
|
+
type: 'animation.inspectBlendSpace',
|
|
116
|
+
payload: { asset_path: args.asset_path },
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* ue_read_retarget_mappings handler — satisfies ANIM-05.
|
|
121
|
+
* Sends animation.retargetMappings to the plugin; returns source/target rigs and chain mappings.
|
|
122
|
+
*
|
|
123
|
+
* @param args Tool arguments including asset_path.
|
|
124
|
+
* @param b PluginBridgeClient instance (defaults to module-level singleton).
|
|
125
|
+
*/
|
|
126
|
+
export async function handleReadRetargetMappings(args, b = bridge) {
|
|
127
|
+
// Response data shape: RetargetMappingsResult
|
|
128
|
+
return sendOrDisconnect(b, {
|
|
129
|
+
type: 'animation.retargetMappings',
|
|
130
|
+
payload: { asset_path: args.asset_path },
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
// ---------------------------------------------------------------------------
|
|
134
|
+
// registerAnimationTools
|
|
135
|
+
// ---------------------------------------------------------------------------
|
|
136
|
+
/**
|
|
137
|
+
* Register UE animation asset inspection tools on the MCP server.
|
|
138
|
+
*
|
|
139
|
+
* All tools in this domain require the MCPBridge editor plugin.
|
|
140
|
+
* When the plugin is not connected, each handler returns:
|
|
141
|
+
* { isError: true, content: [{ type: 'text', text: <plugin_not_connected JSON> }] }
|
|
142
|
+
*
|
|
143
|
+
* Tools registered (Phase 17):
|
|
144
|
+
* ue_list_animation_assets — ANIM-01: List animation assets filtered by type
|
|
145
|
+
* ue_inspect_anim_blueprint — ANIM-02: Inspect AnimBP state machines and transitions
|
|
146
|
+
* ue_inspect_montage — ANIM-03: Read montage sections, notifies, slots
|
|
147
|
+
* ue_inspect_blend_space — ANIM-04: Inspect blend space axes and sample points
|
|
148
|
+
* ue_read_retarget_mappings — ANIM-05: Read IK Retargeter chain mappings
|
|
149
|
+
*
|
|
150
|
+
* @param server The McpServer instance to register tools on.
|
|
151
|
+
* @param _bridge Optional PluginBridgeClient for testing (not used directly — handlers
|
|
152
|
+
* accept bridge injection via their exported function signatures).
|
|
153
|
+
*/
|
|
154
|
+
export function registerAnimationTools(server, _bridge) {
|
|
155
|
+
const b = _bridge ?? new PluginBridgeClient();
|
|
156
|
+
// --------------------------------------------------------------------------
|
|
157
|
+
// ue_list_animation_assets (ANIM-01)
|
|
158
|
+
// --------------------------------------------------------------------------
|
|
159
|
+
server.registerTool('ue_list_animation_assets', {
|
|
160
|
+
title: 'List Animation Assets',
|
|
161
|
+
description: '[requires_plugin] List all animation assets in the project, optionally filtered by type (AnimBlueprint, AnimMontage, BlendSpace, BlendSpace1D, AnimSequence).',
|
|
162
|
+
inputSchema: z.object({
|
|
163
|
+
type_filter: z
|
|
164
|
+
.string()
|
|
165
|
+
.optional()
|
|
166
|
+
.describe('Optional asset class filter: AnimBlueprint | AnimMontage | BlendSpace | BlendSpace1D | AnimSequence'),
|
|
167
|
+
}),
|
|
168
|
+
annotations: {
|
|
169
|
+
readOnlyHint: true,
|
|
170
|
+
destructiveHint: false,
|
|
171
|
+
},
|
|
172
|
+
}, withKnownIssues('ue_list_animation_assets', async (args) => handleListAnimationAssets(args, b)));
|
|
173
|
+
// --------------------------------------------------------------------------
|
|
174
|
+
// ue_inspect_anim_blueprint (ANIM-02)
|
|
175
|
+
// --------------------------------------------------------------------------
|
|
176
|
+
server.registerTool('ue_inspect_anim_blueprint', {
|
|
177
|
+
title: 'Inspect Animation Blueprint',
|
|
178
|
+
description: "[requires_plugin] Inspect an Animation Blueprint's state machines, states, transitions, and skeleton.",
|
|
179
|
+
inputSchema: z.object({
|
|
180
|
+
asset_path: z
|
|
181
|
+
.string()
|
|
182
|
+
.min(1)
|
|
183
|
+
.describe('UE long package path to the Animation Blueprint asset, e.g. /Game/Animations/ABP_Character'),
|
|
184
|
+
}),
|
|
185
|
+
annotations: {
|
|
186
|
+
readOnlyHint: true,
|
|
187
|
+
destructiveHint: false,
|
|
188
|
+
},
|
|
189
|
+
}, withKnownIssues('ue_inspect_anim_blueprint', async (args) => handleInspectAnimBlueprint(args, b)));
|
|
190
|
+
// --------------------------------------------------------------------------
|
|
191
|
+
// ue_inspect_montage (ANIM-03)
|
|
192
|
+
// --------------------------------------------------------------------------
|
|
193
|
+
server.registerTool('ue_inspect_montage', {
|
|
194
|
+
title: 'Inspect Montage',
|
|
195
|
+
description: '[requires_plugin] Read montage sections, notifies (with trigger times), and slot assignments.',
|
|
196
|
+
inputSchema: z.object({
|
|
197
|
+
asset_path: z
|
|
198
|
+
.string()
|
|
199
|
+
.min(1)
|
|
200
|
+
.describe('UE long package path to the Animation Montage asset, e.g. /Game/Animations/AM_Attack'),
|
|
201
|
+
}),
|
|
202
|
+
annotations: {
|
|
203
|
+
readOnlyHint: true,
|
|
204
|
+
destructiveHint: false,
|
|
205
|
+
},
|
|
206
|
+
}, withKnownIssues('ue_inspect_montage', async (args) => handleInspectMontage(args, b)));
|
|
207
|
+
// --------------------------------------------------------------------------
|
|
208
|
+
// ue_inspect_blend_space (ANIM-04)
|
|
209
|
+
// --------------------------------------------------------------------------
|
|
210
|
+
server.registerTool('ue_inspect_blend_space', {
|
|
211
|
+
title: 'Inspect Blend Space',
|
|
212
|
+
description: '[requires_plugin] Inspect blend space axes, sample points, and grid configuration.',
|
|
213
|
+
inputSchema: z.object({
|
|
214
|
+
asset_path: z
|
|
215
|
+
.string()
|
|
216
|
+
.min(1)
|
|
217
|
+
.describe('UE long package path to the BlendSpace or BlendSpace1D asset, e.g. /Game/Animations/BS_Movement'),
|
|
218
|
+
}),
|
|
219
|
+
annotations: {
|
|
220
|
+
readOnlyHint: true,
|
|
221
|
+
destructiveHint: false,
|
|
222
|
+
},
|
|
223
|
+
}, withKnownIssues('ue_inspect_blend_space', async (args) => handleInspectBlendSpace(args, b)));
|
|
224
|
+
// --------------------------------------------------------------------------
|
|
225
|
+
// ue_read_retarget_mappings (ANIM-05)
|
|
226
|
+
// --------------------------------------------------------------------------
|
|
227
|
+
server.registerTool('ue_read_retarget_mappings', {
|
|
228
|
+
title: 'Read Retarget Mappings',
|
|
229
|
+
description: '[requires_plugin] Read IK Retargeter source/target skeleton rigs and chain mappings.',
|
|
230
|
+
inputSchema: z.object({
|
|
231
|
+
asset_path: z
|
|
232
|
+
.string()
|
|
233
|
+
.min(1)
|
|
234
|
+
.describe('UE long package path to the IK Retargeter asset, e.g. /Game/Animations/RTG_CharacterRetarget'),
|
|
235
|
+
}),
|
|
236
|
+
annotations: {
|
|
237
|
+
readOnlyHint: true,
|
|
238
|
+
destructiveHint: false,
|
|
239
|
+
},
|
|
240
|
+
}, withKnownIssues('ue_read_retarget_mappings', async (args) => handleReadRetargetMappings(args, b)));
|
|
241
|
+
}
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
// src/tools/audio/index.ts
|
|
2
|
+
// MCP tool implementations for audio asset inspection (Phase 23).
|
|
3
|
+
// All tools route commands through PluginBridgeClient to the C++ MCPBridge handlers.
|
|
4
|
+
// Returns structured plugin_not_connected errors when the plugin is absent.
|
|
5
|
+
//
|
|
6
|
+
// Tools registered (Phase 23 — AUD-01 through AUD-04):
|
|
7
|
+
// ue_list_sound_assets — List all sound assets, optionally filtered by type
|
|
8
|
+
// ue_inspect_metasound — Inspect MetaSound patch graph nodes, edges, inputs, outputs
|
|
9
|
+
// ue_inspect_sound_cue — Read SoundCue node graph structure and attenuation settings
|
|
10
|
+
// ue_query_audio_insights — Query Audio Insights monitoring data (active sounds, events)
|
|
11
|
+
//
|
|
12
|
+
// All tools require MCPBridge plugin (Phase 23 — AUD-01 through AUD-04).
|
|
13
|
+
import { z } from 'zod';
|
|
14
|
+
import { withKnownIssues } from '../known-issues/middleware.js';
|
|
15
|
+
import { PluginBridgeClient, PluginNotConnectedError } from '../../plugin-bridge/client.js';
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
// sendOrDisconnect helper
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
/**
|
|
20
|
+
* Sends a command to the bridge and returns a ToolResult.
|
|
21
|
+
*
|
|
22
|
+
* - On success (response.success true): returns data as JSON text.
|
|
23
|
+
* - On command-level failure (response.success false): returns isError:true with error JSON.
|
|
24
|
+
* - On PluginNotConnectedError: returns isError:true with plugin_not_connected JSON.
|
|
25
|
+
* - On other errors: rethrows (withKnownIssues catches and formats).
|
|
26
|
+
*
|
|
27
|
+
* NOTE: sendCommand() overwrites correlationId with crypto.randomUUID() internally;
|
|
28
|
+
* passing an empty string is safe and correct (per STATE.md decision).
|
|
29
|
+
*/
|
|
30
|
+
async function sendOrDisconnect(b, cmd) {
|
|
31
|
+
try {
|
|
32
|
+
const response = await b.sendCommand({ ...cmd, correlationId: '' });
|
|
33
|
+
if (!response.success) {
|
|
34
|
+
return {
|
|
35
|
+
isError: true,
|
|
36
|
+
content: [{ type: 'text', text: JSON.stringify({ error: response.error }) }],
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
return {
|
|
40
|
+
content: [{ type: 'text', text: JSON.stringify(response.data ?? {}) }],
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
catch (err) {
|
|
44
|
+
if (err instanceof PluginNotConnectedError) {
|
|
45
|
+
return {
|
|
46
|
+
isError: true,
|
|
47
|
+
content: [{ type: 'text', text: JSON.stringify(err.bridgeError) }],
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
throw err; // withKnownIssues catches unexpected errors
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
// ---------------------------------------------------------------------------
|
|
54
|
+
// Exported handler functions (for direct unit testing via bridge injection)
|
|
55
|
+
// ---------------------------------------------------------------------------
|
|
56
|
+
/**
|
|
57
|
+
* ue_list_sound_assets handler — satisfies AUD-01.
|
|
58
|
+
* Sends audio.list to the plugin; returns all sound assets, optionally filtered by type.
|
|
59
|
+
*
|
|
60
|
+
* @param args Tool arguments including optional type_filter.
|
|
61
|
+
* @param b PluginBridgeClient instance (defaults to bridge created in registerAudioTools).
|
|
62
|
+
*/
|
|
63
|
+
export async function handleListSoundAssets(args, b) {
|
|
64
|
+
const bridge = b ?? new PluginBridgeClient();
|
|
65
|
+
// Response data shape: SoundAssetListResult
|
|
66
|
+
const payload = {};
|
|
67
|
+
if (args.type_filter !== undefined) {
|
|
68
|
+
payload['type_filter'] = args.type_filter;
|
|
69
|
+
}
|
|
70
|
+
return sendOrDisconnect(bridge, {
|
|
71
|
+
type: 'audio.list',
|
|
72
|
+
payload,
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* ue_inspect_metasound handler — satisfies AUD-02.
|
|
77
|
+
* Sends audio.metasound to the plugin; returns graph nodes, edges, inputs, and outputs.
|
|
78
|
+
*
|
|
79
|
+
* @param args Tool arguments including asset_path.
|
|
80
|
+
* @param b PluginBridgeClient instance (defaults to bridge created in registerAudioTools).
|
|
81
|
+
*/
|
|
82
|
+
export async function handleInspectMetasound(args, b) {
|
|
83
|
+
const bridge = b ?? new PluginBridgeClient();
|
|
84
|
+
// Response data shape: MetaSoundInspectResult
|
|
85
|
+
return sendOrDisconnect(bridge, {
|
|
86
|
+
type: 'audio.metasound',
|
|
87
|
+
payload: { asset_path: args.asset_path },
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* ue_inspect_sound_cue handler — satisfies AUD-03.
|
|
92
|
+
* Sends audio.soundcue to the plugin; returns recursive node tree and attenuation settings.
|
|
93
|
+
*
|
|
94
|
+
* @param args Tool arguments including asset_path.
|
|
95
|
+
* @param b PluginBridgeClient instance (defaults to bridge created in registerAudioTools).
|
|
96
|
+
*/
|
|
97
|
+
export async function handleInspectSoundCue(args, b) {
|
|
98
|
+
const bridge = b ?? new PluginBridgeClient();
|
|
99
|
+
// Response data shape: SoundCueInspectResult
|
|
100
|
+
return sendOrDisconnect(bridge, {
|
|
101
|
+
type: 'audio.soundcue',
|
|
102
|
+
payload: { asset_path: args.asset_path },
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* ue_query_audio_insights handler — satisfies AUD-04.
|
|
107
|
+
* Sends audio.insights to the plugin; returns monitoring data or informative unavailable message.
|
|
108
|
+
*
|
|
109
|
+
* @param args No required parameters (empty object).
|
|
110
|
+
* @param b PluginBridgeClient instance (defaults to bridge created in registerAudioTools).
|
|
111
|
+
*/
|
|
112
|
+
export async function handleQueryAudioInsights(args, b) {
|
|
113
|
+
const bridge = b ?? new PluginBridgeClient();
|
|
114
|
+
// Response data shape: AudioInsightsResult
|
|
115
|
+
return sendOrDisconnect(bridge, {
|
|
116
|
+
type: 'audio.insights',
|
|
117
|
+
payload: {},
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
// ---------------------------------------------------------------------------
|
|
121
|
+
// registerAudioTools
|
|
122
|
+
// ---------------------------------------------------------------------------
|
|
123
|
+
/**
|
|
124
|
+
* Register UE audio asset inspection and monitoring tools on the MCP server.
|
|
125
|
+
*
|
|
126
|
+
* All tools in this domain require the MCPBridge editor plugin.
|
|
127
|
+
* When the plugin is not connected, each handler returns:
|
|
128
|
+
* { isError: true, content: [{ type: 'text', text: <plugin_not_connected JSON> }] }
|
|
129
|
+
*
|
|
130
|
+
* Tools registered (Phase 23):
|
|
131
|
+
* ue_list_sound_assets — AUD-01: List sound assets filtered by type
|
|
132
|
+
* ue_inspect_metasound — AUD-02: Inspect MetaSound patch graph nodes and connections
|
|
133
|
+
* ue_inspect_sound_cue — AUD-03: Read SoundCue node graph and attenuation settings
|
|
134
|
+
* ue_query_audio_insights — AUD-04: Query Audio Insights monitoring data
|
|
135
|
+
*
|
|
136
|
+
* @param server The McpServer instance to register tools on.
|
|
137
|
+
* @param bridge Optional PluginBridgeClient for testing (injected into handler calls).
|
|
138
|
+
*/
|
|
139
|
+
export function registerAudioTools(server, bridge) {
|
|
140
|
+
const b = bridge ?? new PluginBridgeClient();
|
|
141
|
+
// --------------------------------------------------------------------------
|
|
142
|
+
// ue_list_sound_assets (AUD-01)
|
|
143
|
+
// --------------------------------------------------------------------------
|
|
144
|
+
server.registerTool('ue_list_sound_assets', {
|
|
145
|
+
title: 'List Sound Assets',
|
|
146
|
+
description: '[requires_plugin] List all sound assets in the project, optionally filtered by type (SoundWave, SoundCue, MetaSound). Returns asset paths, names, types, and audio properties.',
|
|
147
|
+
inputSchema: z.object({
|
|
148
|
+
type_filter: z
|
|
149
|
+
.enum(['SoundWave', 'SoundCue', 'MetaSound'])
|
|
150
|
+
.optional()
|
|
151
|
+
.describe('Filter by sound asset type. Omit to list all types.'),
|
|
152
|
+
}),
|
|
153
|
+
annotations: {
|
|
154
|
+
readOnlyHint: true,
|
|
155
|
+
destructiveHint: false,
|
|
156
|
+
},
|
|
157
|
+
}, withKnownIssues('ue_list_sound_assets', async (args) => handleListSoundAssets(args, b)));
|
|
158
|
+
// --------------------------------------------------------------------------
|
|
159
|
+
// ue_inspect_metasound (AUD-02)
|
|
160
|
+
// --------------------------------------------------------------------------
|
|
161
|
+
server.registerTool('ue_inspect_metasound', {
|
|
162
|
+
title: 'Inspect MetaSound Patch',
|
|
163
|
+
description: "[requires_plugin] Inspect a MetaSound patch's graph nodes, connections, input pins, and output pins.",
|
|
164
|
+
inputSchema: z.object({
|
|
165
|
+
asset_path: z
|
|
166
|
+
.string()
|
|
167
|
+
.min(1)
|
|
168
|
+
.describe('UE content path to the MetaSound asset, e.g. /Game/Audio/MS_Ambience'),
|
|
169
|
+
}),
|
|
170
|
+
annotations: {
|
|
171
|
+
readOnlyHint: true,
|
|
172
|
+
destructiveHint: false,
|
|
173
|
+
},
|
|
174
|
+
}, withKnownIssues('ue_inspect_metasound', async (args) => handleInspectMetasound(args, b)));
|
|
175
|
+
// --------------------------------------------------------------------------
|
|
176
|
+
// ue_inspect_sound_cue (AUD-03)
|
|
177
|
+
// --------------------------------------------------------------------------
|
|
178
|
+
server.registerTool('ue_inspect_sound_cue', {
|
|
179
|
+
title: 'Inspect Sound Cue',
|
|
180
|
+
description: "[requires_plugin] Read a SoundCue's node graph structure, configured parameters (volume, pitch), and attenuation settings.",
|
|
181
|
+
inputSchema: z.object({
|
|
182
|
+
asset_path: z
|
|
183
|
+
.string()
|
|
184
|
+
.min(1)
|
|
185
|
+
.describe('UE content path to the SoundCue asset, e.g. /Game/Audio/SC_Footstep'),
|
|
186
|
+
}),
|
|
187
|
+
annotations: {
|
|
188
|
+
readOnlyHint: true,
|
|
189
|
+
destructiveHint: false,
|
|
190
|
+
},
|
|
191
|
+
}, withKnownIssues('ue_inspect_sound_cue', async (args) => handleInspectSoundCue(args, b)));
|
|
192
|
+
// --------------------------------------------------------------------------
|
|
193
|
+
// ue_query_audio_insights (AUD-04)
|
|
194
|
+
// --------------------------------------------------------------------------
|
|
195
|
+
server.registerTool('ue_query_audio_insights', {
|
|
196
|
+
title: 'Query Audio Insights',
|
|
197
|
+
description: '[requires_plugin] Query Audio Insights monitoring data including active sound count, max channels, and recent audio events. Returns informative message if Audio Insights plugin is not enabled.',
|
|
198
|
+
inputSchema: z.object({}),
|
|
199
|
+
annotations: {
|
|
200
|
+
readOnlyHint: true,
|
|
201
|
+
destructiveHint: false,
|
|
202
|
+
},
|
|
203
|
+
}, withKnownIssues('ue_query_audio_insights', async (args) => handleQueryAudioInsights(args, b)));
|
|
204
|
+
}
|