flockbay 0.10.15

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.
Files changed (80) hide show
  1. package/README.md +56 -0
  2. package/bin/flockbay-mcp.mjs +56 -0
  3. package/bin/flockbay.mjs +78 -0
  4. package/dist/codex/flockbayMcpStdioBridge.cjs +383 -0
  5. package/dist/codex/flockbayMcpStdioBridge.d.cts +2 -0
  6. package/dist/codex/flockbayMcpStdioBridge.d.mts +2 -0
  7. package/dist/codex/flockbayMcpStdioBridge.mjs +381 -0
  8. package/dist/flockbayScreenshotGate-DJX3Is5d.mjs +136 -0
  9. package/dist/flockbayScreenshotGate-DkxU24cR.cjs +138 -0
  10. package/dist/index--o4BPz5o.cjs +10311 -0
  11. package/dist/index-CUp3juDS.mjs +10268 -0
  12. package/dist/index.cjs +43 -0
  13. package/dist/index.d.cts +1 -0
  14. package/dist/index.d.mts +1 -0
  15. package/dist/index.mjs +40 -0
  16. package/dist/lib.cjs +33 -0
  17. package/dist/lib.d.cts +957 -0
  18. package/dist/lib.d.mts +957 -0
  19. package/dist/lib.mjs +23 -0
  20. package/dist/runCodex-D3eT-TvB.cjs +3449 -0
  21. package/dist/runCodex-o6PCbHQ7.mjs +3446 -0
  22. package/dist/runGemini-Bt0oEj_g.mjs +3183 -0
  23. package/dist/runGemini-CBxZp6I7.cjs +3185 -0
  24. package/dist/types-C-jnUdn_.cjs +4498 -0
  25. package/dist/types-DGd6ea2Z.mjs +4450 -0
  26. package/kits/kit.open_world/kit.json +59 -0
  27. package/package.json +130 -0
  28. package/scripts/claude_local_launcher.cjs +73 -0
  29. package/scripts/claude_remote_launcher.cjs +16 -0
  30. package/scripts/claude_version_utils.cjs +391 -0
  31. package/scripts/ripgrep_launcher.cjs +33 -0
  32. package/scripts/session_hook_forwarder.cjs +49 -0
  33. package/scripts/test-codex-abort-history.mjs +77 -0
  34. package/scripts/unpack-tools.cjs +222 -0
  35. package/tools/licenses/difftastic-LICENSE +21 -0
  36. package/tools/licenses/ripgrep-LICENSE +3 -0
  37. package/tools/unreal-mcp/UPSTREAM_VERSION.md +8 -0
  38. package/tools/unreal-mcp/upstream/Docs/README.md +8 -0
  39. package/tools/unreal-mcp/upstream/Docs/Tools/README.md +7 -0
  40. package/tools/unreal-mcp/upstream/Docs/Tools/actor_tools.md +184 -0
  41. package/tools/unreal-mcp/upstream/Docs/Tools/blueprint_tools.md +268 -0
  42. package/tools/unreal-mcp/upstream/Docs/Tools/editor_tools.md +104 -0
  43. package/tools/unreal-mcp/upstream/Docs/Tools/node_tools.md +274 -0
  44. package/tools/unreal-mcp/upstream/MCPGameProject/Plugins/UnrealMCP/Config/FilterPlugin.ini +8 -0
  45. package/tools/unreal-mcp/upstream/MCPGameProject/Plugins/UnrealMCP/Source/UnrealMCP/Private/Commands/UnrealMCPBlueprintCommands.cpp +1160 -0
  46. package/tools/unreal-mcp/upstream/MCPGameProject/Plugins/UnrealMCP/Source/UnrealMCP/Private/Commands/UnrealMCPBlueprintNodeCommands.cpp +924 -0
  47. package/tools/unreal-mcp/upstream/MCPGameProject/Plugins/UnrealMCP/Source/UnrealMCP/Private/Commands/UnrealMCPCommonUtils.cpp +709 -0
  48. package/tools/unreal-mcp/upstream/MCPGameProject/Plugins/UnrealMCP/Source/UnrealMCP/Private/Commands/UnrealMCPEditorCommands.cpp +896 -0
  49. package/tools/unreal-mcp/upstream/MCPGameProject/Plugins/UnrealMCP/Source/UnrealMCP/Private/Commands/UnrealMCPProjectCommands.cpp +72 -0
  50. package/tools/unreal-mcp/upstream/MCPGameProject/Plugins/UnrealMCP/Source/UnrealMCP/Private/Commands/UnrealMCPUMGCommands.cpp +544 -0
  51. package/tools/unreal-mcp/upstream/MCPGameProject/Plugins/UnrealMCP/Source/UnrealMCP/Private/MCPServerRunnable.cpp +321 -0
  52. package/tools/unreal-mcp/upstream/MCPGameProject/Plugins/UnrealMCP/Source/UnrealMCP/Private/UnrealMCPBridge.cpp +419 -0
  53. package/tools/unreal-mcp/upstream/MCPGameProject/Plugins/UnrealMCP/Source/UnrealMCP/Private/UnrealMCPModule.cpp +21 -0
  54. package/tools/unreal-mcp/upstream/MCPGameProject/Plugins/UnrealMCP/Source/UnrealMCP/Public/Commands/UnrealMCPBlueprintCommands.h +34 -0
  55. package/tools/unreal-mcp/upstream/MCPGameProject/Plugins/UnrealMCP/Source/UnrealMCP/Public/Commands/UnrealMCPBlueprintNodeCommands.h +27 -0
  56. package/tools/unreal-mcp/upstream/MCPGameProject/Plugins/UnrealMCP/Source/UnrealMCP/Public/Commands/UnrealMCPCommonUtils.h +59 -0
  57. package/tools/unreal-mcp/upstream/MCPGameProject/Plugins/UnrealMCP/Source/UnrealMCP/Public/Commands/UnrealMCPEditorCommands.h +40 -0
  58. package/tools/unreal-mcp/upstream/MCPGameProject/Plugins/UnrealMCP/Source/UnrealMCP/Public/Commands/UnrealMCPProjectCommands.h +20 -0
  59. package/tools/unreal-mcp/upstream/MCPGameProject/Plugins/UnrealMCP/Source/UnrealMCP/Public/Commands/UnrealMCPUMGCommands.h +82 -0
  60. package/tools/unreal-mcp/upstream/MCPGameProject/Plugins/UnrealMCP/Source/UnrealMCP/Public/MCPServerRunnable.h +34 -0
  61. package/tools/unreal-mcp/upstream/MCPGameProject/Plugins/UnrealMCP/Source/UnrealMCP/Public/UnrealMCPBridge.h +64 -0
  62. package/tools/unreal-mcp/upstream/MCPGameProject/Plugins/UnrealMCP/Source/UnrealMCP/Public/UnrealMCPModule.h +22 -0
  63. package/tools/unreal-mcp/upstream/MCPGameProject/Plugins/UnrealMCP/Source/UnrealMCP/UnrealMCP.Build.cs +78 -0
  64. package/tools/unreal-mcp/upstream/MCPGameProject/Plugins/UnrealMCP/UnrealMCP.uplugin +36 -0
  65. package/tools/unreal-mcp/upstream/Python/README.md +40 -0
  66. package/tools/unreal-mcp/upstream/Python/pyproject.toml +22 -0
  67. package/tools/unreal-mcp/upstream/Python/scripts/actors/test_cube.py +203 -0
  68. package/tools/unreal-mcp/upstream/Python/scripts/blueprints/test_create_and_spawn_blueprints_with_different_components.py +497 -0
  69. package/tools/unreal-mcp/upstream/Python/scripts/blueprints/test_create_and_spawn_cube_blueprint.py +194 -0
  70. package/tools/unreal-mcp/upstream/Python/scripts/node/test_component_reference.py +267 -0
  71. package/tools/unreal-mcp/upstream/Python/scripts/node/test_create_bird_blueprint_with_input_and_camera.py +618 -0
  72. package/tools/unreal-mcp/upstream/Python/scripts/node/test_input_mapping.py +366 -0
  73. package/tools/unreal-mcp/upstream/Python/scripts/node/test_physics_variables.py +390 -0
  74. package/tools/unreal-mcp/upstream/Python/tools/blueprint_tools.py +420 -0
  75. package/tools/unreal-mcp/upstream/Python/tools/editor_tools.py +369 -0
  76. package/tools/unreal-mcp/upstream/Python/tools/node_tools.py +430 -0
  77. package/tools/unreal-mcp/upstream/Python/tools/project_tools.py +64 -0
  78. package/tools/unreal-mcp/upstream/Python/tools/umg_tools.py +333 -0
  79. package/tools/unreal-mcp/upstream/Python/unreal_mcp_server.py +398 -0
  80. package/tools/unreal-mcp/upstream/Python/uv.lock +521 -0
@@ -0,0 +1,82 @@
1
+ #pragma once
2
+
3
+ #include "CoreMinimal.h"
4
+ #include "Json.h"
5
+
6
+ /**
7
+ * Handles UMG (Widget Blueprint) related MCP commands
8
+ * Responsible for creating and modifying UMG Widget Blueprints,
9
+ * adding widget components, and managing widget instances in the viewport.
10
+ */
11
+ class UNREALMCP_API FUnrealMCPUMGCommands
12
+ {
13
+ public:
14
+ FUnrealMCPUMGCommands();
15
+
16
+ /**
17
+ * Handle UMG-related commands
18
+ * @param CommandType - The type of command to handle
19
+ * @param Params - JSON parameters for the command
20
+ * @return JSON response with results or error
21
+ */
22
+ TSharedPtr<FJsonObject> HandleCommand(const FString& CommandType, const TSharedPtr<FJsonObject>& Params);
23
+
24
+ private:
25
+ /**
26
+ * Create a new UMG Widget Blueprint
27
+ * @param Params - Must include "name" for the blueprint name
28
+ * @return JSON response with the created blueprint details
29
+ */
30
+ TSharedPtr<FJsonObject> HandleCreateUMGWidgetBlueprint(const TSharedPtr<FJsonObject>& Params);
31
+
32
+ /**
33
+ * Add a Text Block widget to a UMG Widget Blueprint
34
+ * @param Params - Must include:
35
+ * "blueprint_name" - Name of the target Widget Blueprint
36
+ * "widget_name" - Name for the new Text Block
37
+ * "text" - Initial text content (optional)
38
+ * "position" - [X, Y] position in the canvas (optional)
39
+ * @return JSON response with the added widget details
40
+ */
41
+ TSharedPtr<FJsonObject> HandleAddTextBlockToWidget(const TSharedPtr<FJsonObject>& Params);
42
+
43
+ /**
44
+ * Add a widget instance to the game viewport
45
+ * @param Params - Must include:
46
+ * "blueprint_name" - Name of the Widget Blueprint to instantiate
47
+ * "z_order" - Z-order for widget display (optional)
48
+ * @return JSON response with the widget instance details
49
+ */
50
+ TSharedPtr<FJsonObject> HandleAddWidgetToViewport(const TSharedPtr<FJsonObject>& Params);
51
+
52
+ /**
53
+ * Add a Button widget to a UMG Widget Blueprint
54
+ * @param Params - Must include:
55
+ * "blueprint_name" - Name of the target Widget Blueprint
56
+ * "widget_name" - Name for the new Button
57
+ * "text" - Button text
58
+ * "position" - [X, Y] position in the canvas
59
+ * @return JSON response with the added widget details
60
+ */
61
+ TSharedPtr<FJsonObject> HandleAddButtonToWidget(const TSharedPtr<FJsonObject>& Params);
62
+
63
+ /**
64
+ * Bind an event to a widget (e.g. button click)
65
+ * @param Params - Must include:
66
+ * "blueprint_name" - Name of the target Widget Blueprint
67
+ * "widget_name" - Name of the widget to bind
68
+ * "event_name" - Name of the event to bind
69
+ * @return JSON response with the binding details
70
+ */
71
+ TSharedPtr<FJsonObject> HandleBindWidgetEvent(const TSharedPtr<FJsonObject>& Params);
72
+
73
+ /**
74
+ * Set up text block binding for dynamic updates
75
+ * @param Params - Must include:
76
+ * "blueprint_name" - Name of the target Widget Blueprint
77
+ * "widget_name" - Name of the widget to bind
78
+ * "binding_name" - Name of the binding to set up
79
+ * @return JSON response with the binding details
80
+ */
81
+ TSharedPtr<FJsonObject> HandleSetTextBlockBinding(const TSharedPtr<FJsonObject>& Params);
82
+ };
@@ -0,0 +1,34 @@
1
+ #pragma once
2
+
3
+ #include "CoreMinimal.h"
4
+ #include "HAL/Runnable.h"
5
+ #include "Sockets.h"
6
+ #include "Interfaces/IPv4/IPv4Address.h"
7
+
8
+ class UUnrealMCPBridge;
9
+
10
+ /**
11
+ * Runnable class for the MCP server thread
12
+ */
13
+ class FMCPServerRunnable : public FRunnable
14
+ {
15
+ public:
16
+ FMCPServerRunnable(UUnrealMCPBridge* InBridge, TSharedPtr<FSocket> InListenerSocket);
17
+ virtual ~FMCPServerRunnable();
18
+
19
+ // FRunnable interface
20
+ virtual bool Init() override;
21
+ virtual uint32 Run() override;
22
+ virtual void Stop() override;
23
+ virtual void Exit() override;
24
+
25
+ protected:
26
+ void HandleClientConnection(TSharedPtr<FSocket> ClientSocket);
27
+ void ProcessMessage(TSharedPtr<FSocket> Client, const FString& Message);
28
+
29
+ private:
30
+ UUnrealMCPBridge* Bridge;
31
+ TSharedPtr<FSocket> ListenerSocket;
32
+ TSharedPtr<FSocket> ClientSocket;
33
+ bool bRunning;
34
+ };
@@ -0,0 +1,64 @@
1
+ #pragma once
2
+
3
+ #include "CoreMinimal.h"
4
+ #include "EditorSubsystem.h"
5
+ #include "Sockets.h"
6
+ #include "SocketSubsystem.h"
7
+ #include "Http.h"
8
+ #include "Json.h"
9
+ #include "Interfaces/IPv4/IPv4Address.h"
10
+ #include "Interfaces/IPv4/IPv4Endpoint.h"
11
+ #include "Commands/UnrealMCPEditorCommands.h"
12
+ #include "Commands/UnrealMCPBlueprintCommands.h"
13
+ #include "Commands/UnrealMCPBlueprintNodeCommands.h"
14
+ #include "Commands/UnrealMCPProjectCommands.h"
15
+ #include "Commands/UnrealMCPUMGCommands.h"
16
+ #include "UnrealMCPBridge.generated.h"
17
+
18
+ class FMCPServerRunnable;
19
+
20
+ /**
21
+ * Editor subsystem for MCP Bridge
22
+ * Handles communication between external tools and the Unreal Editor
23
+ * through a TCP socket connection. Commands are received as JSON and
24
+ * routed to appropriate command handlers.
25
+ */
26
+ UCLASS()
27
+ class UNREALMCP_API UUnrealMCPBridge : public UEditorSubsystem
28
+ {
29
+ GENERATED_BODY()
30
+
31
+ public:
32
+ UUnrealMCPBridge();
33
+ virtual ~UUnrealMCPBridge();
34
+
35
+ // UEditorSubsystem implementation
36
+ virtual void Initialize(FSubsystemCollectionBase& Collection) override;
37
+ virtual void Deinitialize() override;
38
+
39
+ // Server functions
40
+ void StartServer();
41
+ void StopServer();
42
+ bool IsRunning() const { return bIsRunning; }
43
+
44
+ // Command execution
45
+ FString ExecuteCommand(const FString& CommandType, const TSharedPtr<FJsonObject>& Params);
46
+
47
+ private:
48
+ // Server state
49
+ bool bIsRunning;
50
+ TSharedPtr<FSocket> ListenerSocket;
51
+ TSharedPtr<FSocket> ConnectionSocket;
52
+ FRunnableThread* ServerThread;
53
+
54
+ // Server configuration
55
+ FIPv4Address ServerAddress;
56
+ uint16 Port;
57
+
58
+ // Command handler instances
59
+ TSharedPtr<FUnrealMCPEditorCommands> EditorCommands;
60
+ TSharedPtr<FUnrealMCPBlueprintCommands> BlueprintCommands;
61
+ TSharedPtr<FUnrealMCPBlueprintNodeCommands> BlueprintNodeCommands;
62
+ TSharedPtr<FUnrealMCPProjectCommands> ProjectCommands;
63
+ TSharedPtr<FUnrealMCPUMGCommands> UMGCommands;
64
+ };
@@ -0,0 +1,22 @@
1
+ #pragma once
2
+
3
+ #include "CoreMinimal.h"
4
+ #include "Modules/ModuleManager.h"
5
+
6
+ class FUnrealMCPModule : public IModuleInterface
7
+ {
8
+ public:
9
+ /** IModuleInterface implementation */
10
+ virtual void StartupModule() override;
11
+ virtual void ShutdownModule() override;
12
+
13
+ static inline FUnrealMCPModule& Get()
14
+ {
15
+ return FModuleManager::LoadModuleChecked<FUnrealMCPModule>("UnrealMCP");
16
+ }
17
+
18
+ static inline bool IsAvailable()
19
+ {
20
+ return FModuleManager::Get().IsModuleLoaded("UnrealMCP");
21
+ }
22
+ };
@@ -0,0 +1,78 @@
1
+ // Copyright Epic Games, Inc. All Rights Reserved.
2
+
3
+ using UnrealBuildTool;
4
+
5
+ public class UnrealMCP : ModuleRules
6
+ {
7
+ public UnrealMCP(ReadOnlyTargetRules Target) : base(Target)
8
+ {
9
+ PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs;
10
+ // Use IWYUSupport instead of the deprecated bEnforceIWYU in UE5.5
11
+ IWYUSupport = IWYUSupport.Full;
12
+
13
+ PublicIncludePaths.AddRange(
14
+ new string[] {
15
+ // ... add public include paths required here ...
16
+ }
17
+ );
18
+
19
+ PrivateIncludePaths.AddRange(
20
+ new string[] {
21
+ // ... add other private include paths required here ...
22
+ }
23
+ );
24
+
25
+ PublicDependencyModuleNames.AddRange(
26
+ new string[]
27
+ {
28
+ "Core",
29
+ "CoreUObject",
30
+ "Engine",
31
+ "InputCore",
32
+ "Networking",
33
+ "Sockets",
34
+ "HTTP",
35
+ "Json",
36
+ "JsonUtilities",
37
+ "DeveloperSettings"
38
+ }
39
+ );
40
+
41
+ PrivateDependencyModuleNames.AddRange(
42
+ new string[]
43
+ {
44
+ "UnrealEd",
45
+ "EditorScriptingUtilities",
46
+ "EditorSubsystem",
47
+ "Slate",
48
+ "SlateCore",
49
+ "UMG",
50
+ "Kismet",
51
+ "KismetCompiler",
52
+ "BlueprintGraph",
53
+ "Projects",
54
+ "AssetRegistry"
55
+ }
56
+ );
57
+
58
+ if (Target.bBuildEditor == true)
59
+ {
60
+ PrivateDependencyModuleNames.AddRange(
61
+ new string[]
62
+ {
63
+ "PropertyEditor", // For widget property editing
64
+ "ToolMenus", // For editor UI
65
+ "BlueprintEditorLibrary", // For Blueprint utilities
66
+ "UMGEditor" // For WidgetBlueprint.h and other UMG editor functionality
67
+ }
68
+ );
69
+ }
70
+
71
+ DynamicallyLoadedModuleNames.AddRange(
72
+ new string[]
73
+ {
74
+ // ... add any modules that your module loads dynamically here ...
75
+ }
76
+ );
77
+ }
78
+ }
@@ -0,0 +1,36 @@
1
+ {
2
+ "FileVersion": 3,
3
+ "Version": 1,
4
+ "VersionName": "1.0",
5
+ "FriendlyName": "Flockbay MCP",
6
+ "Description": "Flockbay bridge for Unreal Editor via Model Context Protocol (MCP)",
7
+ "Category": "Editor",
8
+ "CreatedBy": "Respaced Inc.",
9
+ "CreatedByURL": "",
10
+ "DocsURL": "",
11
+ "MarketplaceURL": "",
12
+ "SupportURL": "",
13
+ "CanContainContent": true,
14
+ "IsBetaVersion": false,
15
+ "IsExperimentalVersion": false,
16
+ "EnabledByDefault": false,
17
+ "Installed": false,
18
+ "Modules": [
19
+ {
20
+ "Name": "UnrealMCP",
21
+ "Type": "Editor",
22
+ "LoadingPhase": "Default",
23
+ "WhitelistPlatforms": [
24
+ "Win64",
25
+ "Mac",
26
+ "Linux"
27
+ ]
28
+ }
29
+ ],
30
+ "Plugins": [
31
+ {
32
+ "Name": "EditorScriptingUtilities",
33
+ "Enabled": true
34
+ }
35
+ ]
36
+ }
@@ -0,0 +1,40 @@
1
+ # Unreal MCP
2
+
3
+ Python bridge for interacting with Unreal Engine 5.5 using the Model Context Protocol (MCP).
4
+
5
+ ## Setup
6
+
7
+ 1. Make sure Python 3.10+ is installed
8
+ 2. Install `uv` if you haven't already:
9
+ ```bash
10
+ curl -LsSf https://astral.sh/uv/install.sh | sh
11
+ ```
12
+ 3. Create and activate a virtual environment:
13
+ ```bash
14
+ uv venv
15
+ source .venv/bin/activate # On Unix/macOS
16
+ # or
17
+ .venv\Scripts\activate # On Windows
18
+ ```
19
+ 4. Install dependencies:
20
+ ```bash
21
+ uv pip install -e .
22
+ ```
23
+
24
+ At this point, you can configure your MCP Client (Claude Desktop, Cursor, Windsurf) to use the Unreal MCP Server as per the [Configuring your MCP Client](README.md#configuring-your-mcp-client).
25
+
26
+ ## Testing Scripts
27
+
28
+ There are several scripts in the [scripts](./scripts) folder. They are useful for testing the tools and the Unreal Bridge via a direct connection. This means that you do not need to have an MCP Server running.
29
+
30
+ You should make sure you have installed dependencies and/or are running in the `uv` virtual environment in order for the scripts to work.
31
+
32
+
33
+ ## Troubleshooting
34
+
35
+ - Make sure Unreal Engine editor is loaded loaded and running before running the server.
36
+ - Check logs in `unreal_mcp.log` for detailed error information
37
+
38
+ ## Development
39
+
40
+ To add new tools, modify the `UnrealMCPBridge.py` file to add new command handlers, and update the `unreal_mcp_server.py` file to expose them through the HTTP API.
@@ -0,0 +1,22 @@
1
+ [project]
2
+ name = "unreal-mcp"
3
+ version = "0.1.0"
4
+ description = "Unreal MCP Server: A server for Unreal Engine integration via the Model Context Protocol (MCP)."
5
+ readme = "README.md"
6
+ requires-python = ">=3.10"
7
+ dependencies = [
8
+ "mcp[cli]>=1.4.1",
9
+ "fastmcp>=0.2.0",
10
+ "uvicorn",
11
+ "fastapi",
12
+ "pydantic>=2.6.1",
13
+ "requests"
14
+ ]
15
+
16
+ [build-system]
17
+ requires = ["setuptools>=42", "wheel"]
18
+ build-backend = "setuptools.build_meta"
19
+
20
+ [tool.setuptools]
21
+ # The main server script is a single-file module
22
+ py-modules = ["unreal_mcp_server"]
@@ -0,0 +1,203 @@
1
+ #!/usr/bin/env python
2
+ """
3
+ Test script for creating and manipulating actors in Unreal Engine via MCP.
4
+
5
+ This script demonstrates the basic actor manipulation capabilities of the MCP system:
6
+ - Creating actors with specific names and transforms
7
+ - Getting actor properties
8
+ - Modifying actor transforms
9
+ - Error handling and validation
10
+ """
11
+
12
+ import sys
13
+ import os
14
+ import time
15
+ import socket
16
+ import json
17
+ import logging
18
+ from typing import Dict, Any, Optional
19
+
20
+ # Add the parent directory to the path so we can import the server module
21
+ sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
22
+
23
+ # Set up logging
24
+ logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
25
+ logger = logging.getLogger("TestCube")
26
+
27
+ def send_command(command: str, params: Dict[str, Any]) -> Optional[Dict[str, Any]]:
28
+ """Send a command to the Unreal MCP server and get the response.
29
+
30
+ Args:
31
+ command: The command type to send
32
+ params: Dictionary of parameters for the command
33
+
34
+ Returns:
35
+ Optional[Dict[str, Any]]: The response from the server, or None if there was an error
36
+ """
37
+ try:
38
+ # Create new socket connection
39
+ sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
40
+ sock.connect(("127.0.0.1", 55557))
41
+
42
+ try:
43
+ # Create command object
44
+ command_obj = {
45
+ "type": command,
46
+ "params": params
47
+ }
48
+
49
+ # Convert to JSON and send
50
+ command_json = json.dumps(command_obj)
51
+ logger.info(f"Sending command: {command_json}")
52
+ sock.sendall(command_json.encode('utf-8'))
53
+
54
+ # Receive response
55
+ chunks = []
56
+ while True:
57
+ chunk = sock.recv(4096)
58
+ if not chunk:
59
+ break
60
+ chunks.append(chunk)
61
+
62
+ # Try parsing to see if we have a complete response
63
+ try:
64
+ data = b''.join(chunks)
65
+ json.loads(data.decode('utf-8'))
66
+ # If we can parse it, we have the complete response
67
+ break
68
+ except json.JSONDecodeError:
69
+ # Not a complete JSON object yet, continue receiving
70
+ continue
71
+
72
+ # Parse response
73
+ data = b''.join(chunks)
74
+ response = json.loads(data.decode('utf-8'))
75
+ logger.info(f"Received response: {response}")
76
+ return response
77
+
78
+ finally:
79
+ # Always close the socket
80
+ sock.close()
81
+
82
+ except Exception as e:
83
+ logger.error(f"Error sending command: {e}")
84
+ return None
85
+
86
+ def create_test_cube(name: str, location: list[float]) -> Optional[Dict[str, Any]]:
87
+ """Create a test cube actor with the specified name and location.
88
+
89
+ Args:
90
+ name: The name to give the cube actor
91
+ location: The [x, y, z] world location to spawn at
92
+
93
+ Returns:
94
+ Optional[Dict[str, Any]]: The response from the create command, or None if failed
95
+ """
96
+ cube_params = {
97
+ "name": name,
98
+ "type": "StaticMeshActor",
99
+ "location": location,
100
+ "rotation": [0.0, 0.0, 0.0],
101
+ "scale": [1.0, 1.0, 1.0]
102
+ }
103
+
104
+ response = send_command("create_actor", cube_params)
105
+ if not response or response.get("status") != "success":
106
+ logger.error(f"Failed to create cube: {response}")
107
+ return None
108
+
109
+ logger.info(f"Created cube '{name}' successfully at location {location}")
110
+ return response
111
+
112
+ def get_actor_properties(name: str) -> Optional[Dict[str, Any]]:
113
+ """Get the properties of an actor by name.
114
+
115
+ Args:
116
+ name: The name of the actor to get properties for
117
+
118
+ Returns:
119
+ Optional[Dict[str, Any]]: The actor properties, or None if not found/error
120
+ """
121
+ response = send_command("get_actor_properties", {"name": name})
122
+ if not response or response.get("status") != "success":
123
+ logger.error(f"Failed to get properties for actor '{name}': {response}")
124
+ return None
125
+
126
+ logger.info(f"Got properties for actor '{name}' successfully")
127
+ return response
128
+
129
+ def set_actor_transform(
130
+ name: str,
131
+ location: Optional[list[float]] = None,
132
+ rotation: Optional[list[float]] = None,
133
+ scale: Optional[list[float]] = None
134
+ ) -> Optional[Dict[str, Any]]:
135
+ """Set the transform of an actor.
136
+
137
+ Args:
138
+ name: The name of the actor to modify
139
+ location: Optional new [x, y, z] location
140
+ rotation: Optional new [pitch, yaw, roll] rotation in degrees
141
+ scale: Optional new [x, y, z] scale
142
+
143
+ Returns:
144
+ Optional[Dict[str, Any]]: The updated actor properties, or None if failed
145
+ """
146
+ transform_params = {"name": name}
147
+ if location is not None:
148
+ transform_params["location"] = location
149
+ if rotation is not None:
150
+ transform_params["rotation"] = rotation
151
+ if scale is not None:
152
+ transform_params["scale"] = scale
153
+
154
+ response = send_command("set_actor_transform", transform_params)
155
+ if not response or response.get("status") != "success":
156
+ logger.error(f"Failed to set transform for actor '{name}': {response}")
157
+ return None
158
+
159
+ logger.info(f"Modified transform for actor '{name}' successfully")
160
+ return response
161
+
162
+ def main():
163
+ """Main function to test actor creation and manipulation."""
164
+ try:
165
+ # Create first test cube
166
+ cube1_name = "TestCube_001"
167
+ cube1 = create_test_cube(cube1_name, [0.0, 0.0, 100.0])
168
+ if not cube1:
169
+ logger.error("Failed to create first test cube")
170
+ return
171
+
172
+ # Get its properties to verify creation
173
+ props = get_actor_properties(cube1_name)
174
+ if not props:
175
+ logger.error("Failed to verify first test cube properties")
176
+ return
177
+
178
+ # Modify its transform
179
+ result = set_actor_transform(
180
+ cube1_name,
181
+ location=[0.0, 0.0, 200.0],
182
+ rotation=[0.0, 45.0, 0.0],
183
+ scale=[2.0, 2.0, 2.0]
184
+ )
185
+ if not result:
186
+ logger.error("Failed to modify first test cube transform")
187
+ return
188
+
189
+ # Create a second test cube at a different location
190
+ cube2_name = "TestCube_002"
191
+ cube2 = create_test_cube(cube2_name, [100.0, 100.0, 100.0])
192
+ if not cube2:
193
+ logger.error("Failed to create second test cube")
194
+ return
195
+
196
+ logger.info("All test operations completed successfully!")
197
+
198
+ except Exception as e:
199
+ logger.error(f"Error in main: {e}")
200
+ sys.exit(1)
201
+
202
+ if __name__ == "__main__":
203
+ main()