Editor/Mcp/BridgeComponentTools.cs

Editor tool wrappers for MCP bridge component operations. Provides static async methods that call McpGate.Run to add/configure/inspect/invoke components and their properties on GameObjects in the editor.

Networking
// AUTO-GENERATED by scripts/emit-mcp-wrappers.mjs — DO NOT EDIT.
// Regenerate: node scripts/extract-manifest.mjs && node scripts/emit-mcp-wrappers.mjs
// Source of truth: sbox-mcp-server/src/tools/ (zod schemas) → scripts/tools-manifest.json

using System.Text.Json.Nodes;
using System.Threading.Tasks;
using Editor.Mcp;

/// <summary>
/// Add, configure, inspect and invoke components on GameObjects: set/get properties, wire
/// cross-component references, call methods and editor buttons.
/// </summary>
[McpToolset( "bridge_component", "Add, configure, inspect and invoke components on GameObjects: set/get properties, wire cross-component references, call methods and editor buttons." )]
public static class BridgeComponentTools
{
	/// <summary>
	/// Create a new GameObject, add a component, set its properties, and optionally parent/position/tag
	/// it — all in one atomic call. Collapses the create_gameobject → add_component_with_properties →
	/// set_parent sequence. NOTE: a freshly GENERATED component type only resolves after a
	/// trigger_hotload; generate the script, hotload, THEN call this.
	/// </summary>
	/// <param name="component">Component type name to add (e.g. 'CameraComponent', 'ObjectiveManager'). Use list_available_components to find valid types.</param>
	/// <param name="name">Display name for the new GameObject. Defaults to the component type name.</param>
	/// <param name="properties">Key-value map of property names to values, auto-converted to the right type (same convention as add_component_with_properties). JSON value.</param>
	/// <param name="position">World position. As "x,y,z" (or JSON {x,y,z}).</param>
	/// <param name="rotation">World rotation. As "pitch,yaw,roll" degrees.</param>
	/// <param name="scale">World scale (per-axis). As "x,y,z" (or JSON {x,y,z}).</param>
	/// <param name="parentId">GUID of a parent GameObject. Omit for scene root.</param>
	/// <param name="tags">Tags to add to the new GameObject (e.g. ['player']).</param>
	[McpTool( "add_component_to_new_object" )]
	public static Task<object> AddComponentToNewObject( string component, string name = null, JsonNode properties = null, string position = null, string rotation = null, string scale = null, string parentId = null, string[] tags = null )
		=> McpGate.Run( "add_component_to_new_object", McpGate.Args( ( "component", component ), ( "name", name ), ( "properties", properties ), ( "position", position ), ( "rotation", rotation ), ( "scale", scale ), ( "parentId", parentId ), ( "tags", tags ) ) );

	/// <summary>
	/// Add a component to a GameObject and configure its properties in one call (properties PERSIST
	/// through save+reload). Use list_available_components to find valid types. Returns
	/// appliedProperties + failedProperties so you can see exactly what stuck.
	/// </summary>
	/// <param name="id">GUID of the GameObject.</param>
	/// <param name="component">Component type name (e.g. 'ModelRenderer', 'Rigidbody', 'BoxCollider').</param>
	/// <param name="properties">Key-value map of property names to values, each auto-converted to the property's real type. Primitives '5'/true; Color/Vector3 as comma strings '1,0,0,1'; enum member names; ASSET refs as a path ('Model':'models/dev/box.vmdl', 'MaterialOverride':'materials/x.vmat'); GameObject/Component refs as a target GUID. Best-effort per key — failures are reported in failedProperties, not silently dropped. JSON value.</param>
	[McpTool( "add_component_with_properties" )]
	public static Task<object> AddComponentWithProperties( string id, string component, JsonNode properties = null )
		=> McpGate.Run( "add_component_with_properties", McpGate.Args( ( "id", id ), ( "component", component ), ( "properties", properties ) ) );

	/// <summary>
	/// Dump all public properties of every component on a GameObject. Returns { id, components } where
	/// each entry is { component, properties: [{ name, type, value }] } — values are stringified
	/// (unreadable ones show '&lt;error&gt;'). Use the exact component/property names it reports with
	/// set_property or get_property; can be large on component-heavy objects.
	/// </summary>
	/// <param name="id">GUID of the GameObject.</param>
	[McpTool.ReadOnly( "get_all_properties" )]
	public static Task<object> GetAllProperties( string id )
		=> McpGate.Run( "get_all_properties", McpGate.Args( ( "id", id ) ) );

	/// <summary>
	/// Read a single property value from a component on a GameObject.
	/// </summary>
	/// <param name="id">GUID of the GameObject.</param>
	/// <param name="component">Component type name (e.g. 'ModelRenderer', 'PlayerController').</param>
	/// <param name="property">Property name to read.</param>
	[McpTool.ReadOnly( "get_property" )]
	public static Task<object> GetProperty( string id, string component, string property )
		=> McpGate.Run( "get_property", McpGate.Args( ( "id", id ), ( "component", component ), ( "property", property ) ) );

	/// <summary>
	/// Call a public method on a component. Matching is tried in order: (1) a [Button] attribute label,
	/// (2) the exact method NAME, (3) case-insensitive name with spaces stripped. Calls ANY public
	/// method, not only [Button]-attributed ones (e.g. 'StartGame'). Pass `args` to call methods that
	/// take parameters — the arg count must match and each value is coerced to the parameter type
	/// (primitives: string/number/bool work; complex types like Vector3 may not coerce). Omit args (or
	/// []) for parameterless methods. (list_component_buttons only lists [Button] methods, so a plain
	/// method may be invokable yet not appear there.).
	/// </summary>
	/// <param name="component">Component type name (e.g. 'MapBuilder', 'SasquatchedGame').</param>
	/// <param name="button">A [Button] label OR a public method name (e.g. 'Build Terrain', 'StartGame'); case- and space-insensitive.</param>
	/// <param name="id">Optional GameObject GUID — if omitted, finds first matching component in scene.</param>
	/// <param name="args">Arguments to pass (must match the method's parameter count); coerced to each parameter type. JSON array.</param>
	[McpTool( "invoke_button" )]
	public static Task<object> InvokeButton( string component, string button, string id = null, JsonNode args = null )
		=> McpGate.Run( "invoke_button", McpGate.Args( ( "component", component ), ( "button", button ), ( "id", id ), ( "args", args ) ) );

	/// <summary>
	/// Call a public method BY NAME on a component of a live scene GameObject, passing ARGUMENTS. The
	/// with-args sibling of invoke_button (which only calls parameterless [Button]/methods on a scene
	/// component). Finds a public method matching name + arg-count, coerces each JSON arg to the
	/// parameter type (primitives/enums; Color/Vector3 as comma strings '1,0,0,1'; asset refs as a
	/// path; GameObject/Component refs as a target GUID), invokes it, and returns the method's return
	/// value as a string (null for void). Returns success=false with a clear error on
	/// resolve/coerce/throw.
	/// </summary>
	/// <param name="id">GUID of the GameObject.</param>
	/// <param name="method">Name of the public method to call (e.g. 'TakeDamage', 'AddGold').</param>
	/// <param name="component">Component type name to target (e.g. 'Health', 'PlayerController'). Omit to search all components on the object for a method matching name + arg-count.</param>
	/// <param name="args">Ordered arguments, each coerced to the matching parameter's type. Numbers/bools/strings pass through; Color/Vector3/Rotation as comma strings '1,0,0,1'; enum member names; ASSET refs as a path ('models/dev/box.vmdl'); GameObject/Component refs as a target GUID. Omit (or []) for a no-arg method. JSON array.</param>
	[McpTool( "invoke_method" )]
	public static Task<object> InvokeMethod( string id, string method, string component = null, JsonNode args = null )
		=> McpGate.Run( "invoke_method", McpGate.Args( ( "id", id ), ( "method", method ), ( "component", component ), ( "args", args ) ) );

	/// <summary>
	/// List all instantiable component types in the TypeLibrary — built-in AND your project's custom
	/// components (abstract types excluded); filter does a substring match on the type name. Returns {
	/// count, components } with { name, title, description, fullName } per type, sorted by name — the
	/// unfiltered list is LARGE, so pass filter. Use the returned name with
	/// add_component_with_properties, and describe_type for a type's full property list.
	/// </summary>
	/// <param name="filter">Search filter — matches against component name and title.</param>
	/// <param name="category">Filter by category/group (e.g. 'Rendering', 'Physics', 'Audio').</param>
	[McpTool.ReadOnly( "list_available_components" )]
	public static Task<object> ListAvailableComponents( string filter = null, string category = null )
		=> McpGate.Run( "list_available_components", McpGate.Args( ( "filter", filter ), ( "category", category ) ) );

	/// <summary>
	/// List the [Button]-attributed methods on a component. NOTE: this only finds methods decorated
	/// with [Button]; invoke_button can ALSO call any plain public no-arg method by name, so a method
	/// missing here may still be invokable. Use describe_type / get_method_signature to find non-button
	/// methods.
	/// </summary>
	/// <param name="component">Component type name.</param>
	/// <param name="id">Optional GameObject GUID.</param>
	[McpTool.ReadOnly( "list_component_buttons" )]
	public static Task<object> ListComponentButtons( string component, string id = null )
		=> McpGate.Run( "list_component_buttons", McpGate.Args( ( "component", component ), ( "id", id ) ) );

	/// <summary>
	/// Wire a component's GameObject/Component-typed property to ANOTHER live object in the scene by
	/// GUID (e.g. ObjectiveManager.Player = the player, a camera's follow target, a door's hinge).
	/// Preferred for object/component refs (can pick a specific component type off the target via
	/// targetComponent, and validates). set_property also accepts a GUID for ref props; set_prefab_ref
	/// is for prefab assets. Set clear:true to null the reference.
	/// </summary>
	/// <param name="id">GUID of the GameObject that HOLDS the component you're writing into.</param>
	/// <param name="component">Component type name on that object (e.g. 'ObjectiveManager', 'CameraComponent').</param>
	/// <param name="property">The property to set (must be a GameObject- or Component-typed property).</param>
	/// <param name="targetId">GUID of the GameObject to reference. Required unless clear:true.</param>
	/// <param name="targetComponent">If the property is a Component subtype, the specific component type to pull off the target object. Omit to auto-match by the property's type.</param>
	/// <param name="clear">If true, set the reference to null instead of assigning a target.</param>
	[McpTool( "set_component_reference" )]
	public static Task<object> SetComponentReference( string id, string component, string property, string targetId = null, string targetComponent = null, bool? clear = null )
		=> McpGate.Run( "set_component_reference", McpGate.Args( ( "id", id ), ( "component", component ), ( "property", property ), ( "targetId", targetId ), ( "targetComponent", targetComponent ), ( "clear", clear ) ) );

	/// <summary>
	/// Set a property value on a component (editor mode), and PERSIST it (survives save+reload).
	/// Handles primitives, enums, value types (Color/Vector3 as comma strings), AND references: pass an
	/// asset PATH for Model/Material/Texture/SoundEvent props, or a GameObject GUID for
	/// GameObject/Component-typed props (resolved like set_component_reference). Returns success=false
	/// with a clear error if a path/GUID can't be resolved (no more silent null). For wiring object
	/// refs prefer set_component_reference; for prefab refs use set_prefab_ref.
	/// </summary>
	/// <param name="id">GUID of the GameObject.</param>
	/// <param name="component">Component type name.</param>
	/// <param name="property">Property name to set.</param>
	/// <param name="value">New value. Primitive: '5', 'true'. Color/Vector3: a comma string ('1,0,0,1' / '0,0,200'), an array ([0,0,200]), or an object ({r,g,b,a} / {x,y,z}). Enum: the member name. Asset ref (Model/Material/...): the asset path e.g. 'models/dev/box.vmdl'. GameObject/Component ref: the target GameObject's GUID. Empty/'null' clears the property. JSON value.</param>
	[McpTool( "set_property" )]
	public static Task<object> SetProperty( string id, string component, string property, JsonNode value )
		=> McpGate.Run( "set_property", McpGate.Args( ( "id", id ), ( "component", component ), ( "property", property ), ( "value", value ) ) );
}