Editor tool wrapper for bridge_character MCP tools. It exposes async methods that call McpGate.Run to spawn and outfit citizens, play animations, set animgraph parameters, ragdolls, lipsync, attachments, expressions and look targets.
// 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>
/// Spawn and outfit citizen characters, pose and animate them, play animations, set animgraph
/// parameters, ragdolls, lipsync, and attachments.
/// </summary>
[McpToolset( "bridge_character", "Spawn and outfit citizen characters, pose and animate them, play animations, set animgraph parameters, ragdolls, lipsync, and attachments." )]
public static class BridgeCharacterTools
{
/// <summary>
/// Add + wire s&box's LipSync component (new in the 2026-07 engine update): drives a
/// SkinnedModelRenderer's facial morphs (visemes) from a playing sound. Wires the renderer on the
/// target GameObject (or rendererId) and, if soundEvent is given, a SoundPointComponent bound to
/// that .sound asset (see list_sounds / create_sound_event). Morphs animate at RUNTIME while the
/// sound plays — verify in play mode with capture_view, not the static editor pose.
/// </summary>
/// <param name="id">GUID of the GameObject to add LipSync to (e.g. a spawn_citizen).</param>
/// <param name="rendererId">GUID of a different GameObject holding the SkinnedModelRenderer (default: same as id).</param>
/// <param name="soundEvent">Path to a .sound event to speak, e.g. 'sounds/dialogue/hello.sound' — creates/reuses a SoundPointComponent. Omit to wire an existing sound component on the GameObject (or wire audio later).</param>
/// <param name="playOnStart">Play the sound on scene start (default true; only with soundEvent).</param>
/// <param name="volume">SoundPointComponent volume (only with soundEvent).</param>
/// <param name="morphScale">LipSync.MorphScale — exaggerate/dampen mouth movement (engine default when omitted).</param>
/// <param name="morphSmoothTime">LipSync.MorphSmoothTime — morph smoothing seconds (engine default when omitted).</param>
[McpTool( "add_lipsync" )]
public static Task<object> AddLipsync( string id, string rendererId = null, string soundEvent = null, bool? playOnStart = null, double? volume = null, double? morphScale = null, double? morphSmoothTime = null )
=> McpGate.Run( "add_lipsync", McpGate.Args( ( "id", id ), ( "rendererId", rendererId ), ( "soundEvent", soundEvent ), ( "playOnStart", playOnStart ), ( "volume", volume ), ( "morphScale", morphScale ), ( "morphSmoothTime", morphSmoothTime ) ) );
/// <summary>
/// Add ModelPhysics to a skinned model so it becomes a ragdoll (physics-driven bones). NOTE: the
/// ragdoll only flops in PLAY mode — it won't move in the static editor view, so this one is
/// verified structurally, not by screenshot. Returns { ragdoll, note, gameObject } — check
/// gameObject.components for ModelPhysics, then verify at runtime with start_play + capture_view.
/// </summary>
/// <param name="id">GUID of the GameObject with a SkinnedModelRenderer.</param>
/// <param name="motionEnabled">Whether physics bodies start with motion enabled.</param>
[McpTool( "add_ragdoll" )]
public static Task<object> AddRagdoll( string id, bool? motionEnabled = null )
=> McpGate.Run( "add_ragdoll", McpGate.Args( ( "id", id ), ( "motionEnabled", motionEnabled ) ) );
/// <summary>
/// Dress a spawned Citizen (or any GameObject with a SkinnedModelRenderer) by applying .clothing
/// resources. Pass an array of clothing resource paths; they're loaded, added to a
/// ClothingContainer, and applied to the body. Returns which paths applied vs were not found.
/// </summary>
/// <param name="id">GUID of the Citizen GameObject.</param>
/// <param name="clothing">Clothing resource paths, e.g. ['models/citizen_clothes/jacket/jacket.clothing'].</param>
/// <param name="tint">ClothingContainer tint position 0-1 (skin/clothing colour variation).</param>
[McpTool( "dress_citizen" )]
public static Task<object> DressCitizen( string id, string[] clothing, double? tint = null )
=> McpGate.Run( "dress_citizen", McpGate.Args( ( "id", id ), ( "clothing", clothing ), ( "tint", tint ) ) );
/// <summary>
/// Attach a prop model (weapon, hat, tool) to a Citizen's bone or attachment point — the prop is
/// parented so it follows that point. Tries the point as an attachment (hand_R, hand_L, eyes, hat)
/// then as a bone. Great for arming NPCs or adding accessories.
/// </summary>
/// <param name="id">GUID of the GameObject with a SkinnedModelRenderer.</param>
/// <param name="model">Prop model path, e.g. 'models/dev/box.vmdl'.</param>
/// <param name="point">Attachment or bone name (default 'hand_R'; try hand_L, eyes, hat, head).</param>
/// <param name="offset">Local position offset from the point. As "x,y,z" (or JSON {x,y,z}).</param>
/// <param name="rotation">Local rotation offset. As "pitch,yaw,roll" degrees.</param>
/// <param name="tint">Prop tint colour. As "r,g,b[,a]" (0-1 floats).</param>
/// <param name="name">Name for the prop GameObject.</param>
[McpTool( "equip_model" )]
public static Task<object> EquipModel( string id, string model, string point = null, string offset = null, string rotation = null, string tint = null, string name = null )
=> McpGate.Run( "equip_model", McpGate.Args( ( "id", id ), ( "model", model ), ( "point", point ), ( "offset", offset ), ( "rotation", rotation ), ( "tint", tint ), ( "name", name ) ) );
/// <summary>
/// List the animation sequences available on a GameObject's SkinnedModelRenderer (a spawned Citizen
/// or animated model), plus whether it's driven by an AnimationGraph. Call this before
/// play_animation or set_animgraph_param to see valid names.
/// </summary>
/// <param name="id">GUID of the GameObject with a SkinnedModelRenderer.</param>
[McpTool.ReadOnly( "list_animations" )]
public static Task<object> ListAnimations( string id )
=> McpGate.Run( "list_animations", McpGate.Args( ( "id", id ) ) );
/// <summary>
/// Play a named animation sequence on a GameObject's SkinnedModelRenderer (sets the Sequence). Best
/// for models with raw sequences; for AnimationGraph characters (Citizen) prefer
/// set_animgraph_param. The renderer needs PlayAnimationsInEditorScene = true to animate in-editor
/// — then screenshot to verify. Use list_animations for valid names.
/// </summary>
/// <param name="id">GUID of the GameObject with a SkinnedModelRenderer.</param>
/// <param name="animation">Sequence name to play (see list_animations).</param>
/// <param name="looping">Loop the sequence (default: the model's setting).</param>
/// <param name="speed">Playback rate multiplier (default 1).</param>
[McpTool( "play_animation" )]
public static Task<object> PlayAnimation( string id, string animation, bool? looping = null, double? speed = null )
=> McpGate.Run( "play_animation", McpGate.Args( ( "id", id ), ( "animation", animation ), ( "looping", looping ), ( "speed", speed ) ) );
/// <summary>
/// Pose a Citizen by setting CitizenAnimationHelper params (enables PlayAnimationsInEditorScene so
/// the pose shows in-editor). Set holdType (None/Pistol/Rifle/Shotgun/HoldItem/Punch/Swing),
/// moveStyle (Auto/Walk/Run), specialMove, sitting (bool), and/or duckLevel (0-1). Returns { posed,
/// changed:[...], gameObject } — changed lists which helper params were applied; take_screenshot to
/// verify the pose.
/// </summary>
/// <param name="id">GUID of the Citizen GameObject (must have a CitizenAnimationHelper).</param>
/// <param name="holdType">Hold pose, e.g. None, Pistol, Rifle, Shotgun, HoldItem.</param>
/// <param name="moveStyle">Movement style, e.g. Auto, Walk, Run.</param>
/// <param name="specialMove">Special move style, e.g. None, LedgeGrab, Roll.</param>
/// <param name="sitting">Sit the character (IsSitting).</param>
/// <param name="duckLevel">Crouch amount, 0-1.</param>
[McpTool( "pose_citizen" )]
public static Task<object> PoseCitizen( string id, string holdType = null, string moveStyle = null, string specialMove = null, bool? sitting = null, double? duckLevel = null )
=> McpGate.Run( "pose_citizen", McpGate.Args( ( "id", id ), ( "holdType", holdType ), ( "moveStyle", moveStyle ), ( "specialMove", specialMove ), ( "sitting", sitting ), ( "duckLevel", duckLevel ) ) );
/// <summary>
/// Set an AnimationGraph parameter on a GameObject's SkinnedModelRenderer (calls Set). This drives
/// Citizen/animgraph motion — e.g. 'move_x'/'move_y' (float), 'b_grounded'/'b_ducked' (bool), or a
/// Vector3. Pose previews in-editor when PlayAnimationsInEditorScene is on; screenshot to verify.
/// Param names are defined by the model's animation graph — use list_animations to check whether
/// the model is animgraph-driven. Returns { set, param, kind, note } — kind is the type actually
/// applied (float/int/bool/vector).
/// </summary>
/// <param name="id">GUID of the GameObject with a SkinnedModelRenderer.</param>
/// <param name="param">Animgraph parameter name, e.g. 'move_x', 'b_grounded'.</param>
/// <param name="value">Value: number (float), boolean, or a vector as {x,y,z} OR a comma string "x,y,z". As "x,y,z" (or JSON {x,y,z}).</param>
/// <param name="type">Force the parameter type (default: inferred from value). One of: float | int | bool | vector.</param>
[McpTool( "set_animgraph_param" )]
public static Task<object> SetAnimgraphParam( string id, string param, string value, string type = null )
=> McpGate.Run( "set_animgraph_param", McpGate.Args( ( "id", id ), ( "param", param ), ( "value", value ), ( "type", type ) ) );
/// <summary>
/// Show/hide a bodygroup on a SkinnedModelRenderer (e.g. hide hands when holding a tool, swap head
/// variants). Provide value (int index) or choice (string name). Returns { set, bodygroup } on
/// success (errors if the object has no SkinnedModelRenderer or neither value nor choice is given);
/// take_screenshot to verify the visual change.
/// </summary>
/// <param name="id">GUID of the GameObject with a SkinnedModelRenderer.</param>
/// <param name="name">Bodygroup name.</param>
/// <param name="value">Bodygroup choice index.</param>
/// <param name="choice">Bodygroup choice by name (alternative to value).</param>
[McpTool( "set_bodygroup" )]
public static Task<object> SetBodygroup( string id, string name, int? value = null, string choice = null )
=> McpGate.Run( "set_bodygroup", McpGate.Args( ( "id", id ), ( "name", name ), ( "value", value ), ( "choice", choice ) ) );
/// <summary>
/// Set a facial morph (blendshape) on a skinned model — e.g. smile, frown, blink. Call with NO
/// morph to list the model's available morph names (returned as availableMorphs). weight is
/// typically 0-1. Returns { set, morph, weight, availableMorphs } — availableMorphs is included in
/// every response, so a wrong name can be corrected without an extra listing call.
/// </summary>
/// <param name="id">GUID of the GameObject with a SkinnedModelRenderer.</param>
/// <param name="morph">Morph/blendshape name (omit to list available morphs).</param>
/// <param name="weight">Morph weight, typically 0-1 (default 1).</param>
[McpTool( "set_expression" )]
public static Task<object> SetExpression( string id, string morph = null, double? weight = null )
=> McpGate.Run( "set_expression", McpGate.Args( ( "id", id ), ( "morph", morph ), ( "weight", weight ) ) );
/// <summary>
/// Aim a Citizen's gaze. Pass target {x,y,z} (spawns a LookTarget) or targetId (existing
/// GameObject) and the head/eyes track it. Pass enabled:false to turn gaze tracking off. Tune
/// eyesWeight/headWeight/bodyWeight (0-1).
/// </summary>
/// <param name="id">GUID of the Citizen (must have a CitizenAnimationHelper).</param>
/// <param name="target">World point to look at. As "x,y,z" (or JSON {x,y,z}).</param>
/// <param name="targetId">GUID of a GameObject to look at (overrides target).</param>
/// <param name="enabled">false to disable gaze tracking.</param>
/// <param name="eyesWeight">Eye look weight 0-1.</param>
/// <param name="headWeight">Head turn weight 0-1.</param>
/// <param name="bodyWeight">Body turn weight 0-1.</param>
[McpTool( "set_look_at" )]
public static Task<object> SetLookAt( string id, string target = null, string targetId = null, bool? enabled = null, double? eyesWeight = null, double? headWeight = null, double? bodyWeight = null )
=> McpGate.Run( "set_look_at", McpGate.Args( ( "id", id ), ( "target", target ), ( "targetId", targetId ), ( "enabled", enabled ), ( "eyesWeight", eyesWeight ), ( "headWeight", headWeight ), ( "bodyWeight", bodyWeight ) ) );
/// <summary>
/// Spawn an animated Citizen character: a SkinnedModelRenderer with the Citizen model, plus (by
/// default) a CitizenAnimationHelper so it idles. PlayAnimationsInEditorScene is enabled so the
/// idle pose shows in the editor view (screenshot-verifiable). Returns { created, hasAnimator,
/// gameObject:{ id, name, position, components, ... } } — pass gameObject.id to the follow-ups:
/// dress_citizen, pose_citizen, set_expression, equip_model.
/// </summary>
/// <param name="name">GameObject name (default 'Citizen').</param>
/// <param name="model">Override the skinned model (default 'models/citizen/citizen.vmdl').</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 (default 1,1,1). As "x,y,z" (or JSON {x,y,z}).</param>
/// <param name="tint">Body tint colour. As "r,g,b[,a]" (0-1 floats).</param>
/// <param name="animator">Add a CitizenAnimationHelper for idle/pose (default true).</param>
/// <param name="holdType">Initial hold pose, e.g. None, Pistol, Rifle, Shotgun, HoldItem, Punch, Swing.</param>
/// <param name="moveStyle">Movement style, e.g. Auto, Walk, Run.</param>
/// <param name="parentId">GUID of a parent GameObject.</param>
[McpTool( "spawn_citizen" )]
public static Task<object> SpawnCitizen( string name = null, string model = null, string position = null, string rotation = null, string scale = null, string tint = null, bool? animator = null, string holdType = null, string moveStyle = null, string parentId = null )
=> McpGate.Run( "spawn_citizen", McpGate.Args( ( "name", name ), ( "model", model ), ( "position", position ), ( "rotation", rotation ), ( "scale", scale ), ( "tint", tint ), ( "animator", animator ), ( "holdType", holdType ), ( "moveStyle", moveStyle ), ( "parentId", parentId ) ) );
}