Editor/Commands/Tools/SetParentTool.cs
using System;
using System.Collections.Generic;
using System.Text.Json;
using System.Threading.Tasks;
using Editor;
using Sandbox;
namespace Braxnet.Commands.Tools;
[MCPTool( "set_parent", "Set Parent Tool", "Set the parent of a GameObject in the current scene" )]
public class SetParentTool : IMCPTool
{
public string Name => "set_parent";
public string Title => "Set Parent Tool";
public string Description => "Set the parent of a GameObject in the current scene";
public JsonElement InputSchema => JsonSerializer.SerializeToElement( new
{
type = "object",
properties = new
{
id = new { type = "string", description = "The ID of the GameObject to set the parent for" },
parentId = new { type = "string", description = "The ID of the new parent GameObject" }
},
required = new[] { "id", "parentId" }
} );
public JsonElement OutputSchema => default;
public async Task<CallToolResult> ExecuteAsync( Dictionary<string, object> arguments, string sessionId )
{
var result = new CallToolResult();
if ( !arguments.TryGetValue( "id", out var idObj ) || idObj is not string id ||
!arguments.TryGetValue( "parentId", out var parentIdObj ) || parentIdObj is not string parentId )
{
result.IsError = true;
result.Content.Add( new TextContent { Text = "Invalid or missing 'id' or 'parentId' argument." } );
return result;
}
if ( string.IsNullOrEmpty( id ) || string.IsNullOrEmpty( parentId ) )
{
result.IsError = true;
result.Content.Add( new TextContent { Text = "GameObject ID and Parent ID cannot be empty." } );
return result;
}
if ( !Guid.TryParse( id, out var guid ) || !Guid.TryParse( parentId, out var parentGuid ) )
{
result.IsError = true;
result.Content.Add( new TextContent { Text = "Invalid GameObject ID or Parent ID format." } );
return result;
}
var gameObject = Game.ActiveScene.Directory.FindByGuid( guid );
var parentGameObject = Game.ActiveScene.Directory.FindByGuid( parentGuid );
if ( gameObject == null )
{
result.IsError = true;
result.Content.Add( new TextContent { Text = $"GameObject with ID '{id}' not found." } );
return result;
}
if ( parentGameObject == null )
{
result.IsError = true;
result.Content.Add( new TextContent { Text = $"Parent GameObject with ID '{parentId}' not found." } );
return result;
}
await GameTask.MainThread(); // Ensure this runs on the main thread
using ( SceneEditorSession.Active.UndoScope( "Set Parent" )
.WithGameObjectChanges( gameObject, GameObjectUndoFlags.All ).Push() )
{
gameObject.SetParent( parentGameObject );
}
result.Content.Add( new TextContent
{
Text = $"GameObject with ID '{id}' has been set to have parent '{parentId}'."
} );
return result;
}
}