Editor/Mcp/BridgePhysicsTools.cs

Editor toolset wrapper for bridge_physics MCP tools. It exposes async methods to add colliders, joints, rigidbodies, run overlap queries and raycasts by forwarding calls to McpGate.Run with typed arguments.

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>
/// Rigidbodies, colliders, joints, raycasts and overlap queries in the open scene.
/// </summary>
[McpToolset( "bridge_physics", "Rigidbodies, colliders, joints, raycasts and overlap queries in the open scene." )]
public static class BridgePhysicsTools
{
	/// <summary>
	/// Add a specific collider component to a GameObject (no Rigidbody — use add_physics for a dynamic
	/// body). Can be configured as a trigger. Returns { added, id, collider, isTrigger } where collider
	/// is the actual component type added — note 'mesh' maps to HullCollider (s&amp;box has no
	/// MeshCollider) and unrecognized types fall back to BoxCollider.
	/// </summary>
	/// <param name="id">GUID of the GameObject.</param>
	/// <param name="type">Type of collider to add. One of: box | sphere | capsule | mesh | hull.</param>
	/// <param name="isTrigger">If true, the collider acts as a trigger (no physics collision). Defaults to false.</param>
	/// <param name="size">Size for BoxCollider (x, y, z dimensions) — object {x,y,z} or comma string "x,y,z". As "x,y,z" (or JSON {x,y,z}).</param>
	/// <param name="radius">Radius for SphereCollider or CapsuleCollider.</param>
	/// <param name="height">Height/length for CapsuleCollider.</param>
	[McpTool( "add_collider" )]
	public static Task<object> AddCollider( string id, string type, bool? isTrigger = null, string size = null, double? radius = null, double? height = null )
		=> McpGate.Run( "add_collider", McpGate.Args( ( "id", id ), ( "type", type ), ( "isTrigger", isTrigger ), ( "size", size ), ( "radius", radius ), ( "height", height ) ) );

	/// <summary>
	/// Add a physics joint/constraint component to a GameObject, optionally connected to a target body
	/// (targetId). Returns { added, id, joint, targetId } — joint is the component type added
	/// (FixedJoint/SpringJoint/SliderJoint). If targetId is omitted the joint is added unconnected;
	/// wire it later via set_property. Both objects need physics (add_physics) for the constraint to
	/// simulate in play mode.
	/// </summary>
	/// <param name="id">GUID of the GameObject to add the joint to.</param>
	/// <param name="type">Type of joint to create. One of: fixed | spring | slider.</param>
	/// <param name="targetId">GUID of the target GameObject to connect to.</param>
	/// <param name="frequency">Spring frequency (spring joints only).</param>
	/// <param name="damping">Damping ratio (spring joints only). 0 = no damping, 1 = critical.</param>
	[McpTool( "add_joint" )]
	public static Task<object> AddJoint( string id, string type, string targetId = null, double? frequency = null, double? damping = null )
		=> McpGate.Run( "add_joint", McpGate.Args( ( "id", id ), ( "type", type ), ( "targetId", targetId ), ( "frequency", frequency ), ( "damping", damping ) ) );

	/// <summary>
	/// Add a Rigidbody and collider to a GameObject, making it a dynamic physics object. Auto-selects
	/// BoxCollider if no collider type specified. Returns { physicsAdded, id, components } listing
	/// exactly which components were added (e.g. Rigidbody + BoxCollider) — enter play mode
	/// (start_play) to see it simulate.
	/// </summary>
	/// <param name="id">GUID of the GameObject.</param>
	/// <param name="collider">Collider type to add. Defaults to 'box'. One of: box | sphere | capsule | mesh.</param>
	/// <param name="mass">Mass of the physics body in kg.</param>
	/// <param name="gravity">Whether gravity affects this object. Defaults to true.</param>
	[McpTool( "add_physics" )]
	public static Task<object> AddPhysics( string id, string collider = null, double? mass = null, bool? gravity = null )
		=> McpGate.Run( "add_physics", McpGate.Args( ( "id", id ), ( "collider", collider ), ( "mass", mass ), ( "gravity", gravity ) ) );

	/// <summary>
	/// Spatial volume query: return the GameObjects whose colliders intersect a SPHERE (center +
	/// radius) or a BOX (center + size) — the volume counterpart to raycast's ray. Use it for 'what's
	/// near this point' / 'what's inside this trigger volume' checks (proximity, blast radius,
	/// spawn-clearance). Read-only.
	/// </summary>
	/// <param name="center">Center of the query volume (world space) — object {x,y,z} or comma string "x,y,z". As "x,y,z" (or JSON {x,y,z}).</param>
	/// <param name="radius">Sphere radius. Provide this OR size (box), not both.</param>
	/// <param name="size">Full box size (not half-extents). Provide this OR radius. As "x,y,z" (or JSON {x,y,z}).</param>
	[McpTool.ReadOnly( "physics_overlap" )]
	public static Task<object> PhysicsOverlap( string center, double? radius = null, string size = null )
		=> McpGate.Run( "physics_overlap", McpGate.Args( ( "center", center ), ( "radius", radius ), ( "size", size ) ) );

	/// <summary>
	/// Perform a physics raycast (Scene.Trace.Ray) from start to end — pass both; the handler traces
	/// the start→end segment. Useful for line-of-sight checks, object placement, and collision
	/// detection. Returns { hit, hitPosition, normal, distance, gameObjectId, gameObjectName } — feed
	/// gameObjectId into get_all_properties/set_transform, or visualize the result with debug_draw_ray.
	/// A 'Default Surface not found' error is a known transient; call restart_editor and retry.
	/// </summary>
	/// <param name="start">Ray start position (world space) — object {x,y,z} or comma string "x,y,z". As "x,y,z" (or JSON {x,y,z}).</param>
	/// <param name="end">Ray end position. Use either end or direction+maxDistance. As "x,y,z" (or JSON {x,y,z}).</param>
	/// <param name="direction">Ray direction (normalized). Used with maxDistance instead of end. As "x,y,z" (or JSON {x,y,z}).</param>
	/// <param name="maxDistance">Maximum ray distance when using direction. Defaults to 10000.</param>
	/// <param name="radius">Sphere/box trace radius. 0 = thin ray (default).</param>
	/// <param name="ignoreIds">GUIDs of GameObjects to ignore.</param>
	/// <param name="all">If true, returns all hits along the ray. Defaults to false (first hit only).</param>
	[McpTool.ReadOnly( "raycast" )]
	public static Task<object> Raycast( string start, string end = null, string direction = null, double? maxDistance = null, double? radius = null, string[] ignoreIds = null, bool? all = null )
		=> McpGate.Run( "raycast", McpGate.Args( ( "start", start ), ( "end", end ), ( "direction", direction ), ( "maxDistance", maxDistance ), ( "radius", radius ), ( "ignoreIds", ignoreIds ), ( "all", all ) ) );
}