Audio & MetaSound
11 tools — 0 typed MCP · 11 via cu CLI.
- Audio — Creation & Playback — 11 tools
Audio — Creation & Playback
Section titled “Audio — Creation & Playback”add_audio_component CLI
Section titled “add_audio_component ”Attach an AudioComponent to an actor or Blueprint
@mcp.tool()@showcase( "Attach an AudioComponent to an actor or Blueprint", featured=True,)def add_audio_component( ctx: Context, target: str, sound: str, component_name: str = "AudioComponent", auto_activate: bool = False, attenuation: str = None, sound_class: str = None,) -> ToolResult: """[Audio] Add a UAudioComponent to an actor or Blueprint with a sound assigned.
Anti-patterns: - Do not pass ``sound`` to an asset that is not a ``USoundBase`` subclass (SoundWave/SoundCue/MetaSoundSource) — handler rejects with "Asset is not a USoundBase". - Do not pass ``attenuation`` or ``sound_class`` paths that don't resolve to ``USoundAttenuation``/``USoundClass`` — handler rejects with "asset not found". - Do not pass ``target`` that is neither a scene actor nor a Blueprint under ``/Game/Blueprints/`` — only those two locations are searched.
Args: ctx: The MCP context target: Name of a scene actor OR Blueprint name under /Game/Blueprints sound: Path to a SoundBase asset (SoundWave, SoundCue, MetaSoundSource) e.g. "/Game/Audio/MySound" component_name: Component name (default "AudioComponent") auto_activate: Whether the component should auto-play on spawn (default False) attenuation: Optional Sound Attenuation asset path for spatial falloff sound_class: Optional Sound Class asset path for mix grouping """ from claude_unreal_server import get_unreal_connection
try: unreal = get_unreal_connection() if not unreal: return err("Failed to add AudioComponent: no connection to Unreal Engine")
params: Dict[str, object] = { "target": target, "sound": sound, "component_name": component_name, "auto_activate": auto_activate, } if attenuation is not None: params["attenuation"] = attenuation if sound_class is not None: params["sound_class"] = sound_class
response = unreal.send_command("add_audio_component", params) if not response: return err("Failed to add AudioComponent: no response from Unreal Engine") if response.get("status") == "error": return err("Failed to add AudioComponent", error=response.get("error", "Unknown error"))
result = response.get("result", response) return ok( f"Added AudioComponent '{component_name}' to {target}", target=result.get("target", target), target_type=result.get("target_type", ""), component_name=result.get("component_name", component_name), sound=result.get("sound", sound), auto_activate=result.get("auto_activate", auto_activate), ) except Exception as e: logger.error(f"Error adding AudioComponent: {e}") return err("Failed to add AudioComponent", error=str(e))add_metasound_input CLI
Section titled “add_metasound_input ”Add a graph input to a MetaSound asset
@mcp.tool()@showcase( "Add a graph input to a MetaSound asset", featured=False,)def add_metasound_input( ctx: Context, metasound: str, input_name: str, data_type: str = "Float", default_value: str = None,) -> ToolResult: """[Audio] Add a graph input (exposed parameter) to a MetaSound asset.
Creates an input node on the MetaSound graph so the exposed parameter can be read inside the graph and driven from BP / AudioComponent via set_metasound_parameter.
Anti-patterns: - Do not pass ``data_type`` outside the supported set (``Float``, ``Bool``, ``Int``/``Int32``, ``String``, ``Trigger``, ``Audio``, ``Time``, ``Double``) — unknown types are passed through verbatim and the underlying builder will reject them. - Do not pass a ``default_value`` whose JSON type does not match ``data_type`` (e.g. ``"hello"`` for ``Float``) — only matching types are applied; ``Trigger``/``Audio`` ignore ``default_value`` entirely. - Do not call before ``create_metasound`` — handler rejects with "MetaSound asset not found".
Args: ctx: The MCP context metasound: MetaSound asset reference — short name (resolved under /Game/Audio) or full path (e.g. "/Game/Audio/MS_Drone") input_name: Name of the input parameter (e.g. "Intensity") data_type: MetaSound data type. Supported: "Float", "Bool", "Int", "String", "Trigger", "Audio", "Time" (default "Float") default_value: JSON-encoded default value matching the data type. Examples: "0.5" (float), "true" (bool), "42" (int), "\\"hello\\"" (string). Ignored for Trigger/Audio. """ from claude_unreal_server import get_unreal_connection import json as _json
try: unreal = get_unreal_connection() if not unreal: return err("Failed to add MetaSound input: no connection to Unreal Engine")
params: Dict[str, object] = { "metasound": metasound, "input_name": input_name, "data_type": data_type, } if default_value is not None: try: params["default_value"] = _json.loads(default_value) except (ValueError, TypeError): params["default_value"] = default_value
response = unreal.send_command("add_metasound_input", params) if not response: return err("Failed to add MetaSound input: no response from Unreal Engine") if response.get("status") == "error": return err("Failed to add MetaSound input", error=response.get("error", "Unknown error"))
result = response.get("result", response) return ok( f"Added input '{input_name}' ({data_type}) to {metasound}", metasound=result.get("metasound", metasound), input_name=result.get("input_name", input_name), data_type=result.get("data_type", data_type), node_id=result.get("node_id", ""), ) except Exception as e: logger.error(f"Error adding MetaSound input: {e}") return err("Failed to add MetaSound input", error=str(e))add_metasound_node CLI
Section titled “add_metasound_node ”Add a node (oscillator, math op, etc.) to a MetaSound graph
@mcp.tool()@showcase( "Add a node (oscillator, math op, etc.) to a MetaSound graph", featured=False,)def add_metasound_node( ctx: Context, metasound: str, class_name: str, major_version: int = 1,) -> ToolResult: """[Audio] Add a node instance to a MetaSound graph by its registered class name.
Anti-patterns: - Do not pass ``class_name`` for a class that is not registered in the MetaSound Frontend — handler rejects with "class may not be registered". Use a verified ``Namespace.Name`` like ``UE.Sine`` or ``UE.Add.Float``. - Do not pass ``major_version`` that does not exist for the given class — same registration check.
Args: ctx: The MCP context metasound: MetaSound asset reference (short name or full path) class_name: Dot-separated class name. Accepts: "Name", "Namespace.Name", or "Namespace.Name.Variant". Examples: "UE.Sine", "UE.Add.Float", "UE.Multiply.Audio" major_version: Major version of the class to instantiate (default 1) """ from claude_unreal_server import get_unreal_connection
try: unreal = get_unreal_connection() if not unreal: return err("Failed to add MetaSound node: no connection to Unreal Engine")
params: Dict[str, object] = { "metasound": metasound, "class_name": class_name, "major_version": major_version, }
response = unreal.send_command("add_metasound_node", params) if not response: return err("Failed to add MetaSound node: no response from Unreal Engine") if response.get("status") == "error": return err("Failed to add MetaSound node", error=response.get("error", "Unknown error"))
result = response.get("result", response) return ok( f"Added node '{class_name}' to {metasound}", metasound=result.get("metasound", metasound), class_name=result.get("class_name", class_name), major_version=result.get("major_version", major_version), node_id=result.get("node_id", ""), ) except Exception as e: logger.error(f"Error adding MetaSound node: {e}") return err("Failed to add MetaSound node", error=str(e))connect_metasound_nodes CLI
Section titled “connect_metasound_nodes ”Connect two nodes in a MetaSound graph
@mcp.tool()@showcase( "Connect two nodes in a MetaSound graph", featured=False,)def connect_metasound_nodes( ctx: Context, metasound: str, from_node_id: str, from_output: str, to_node_id: str, to_input: str,) -> ToolResult: """[Audio] Connect an output pin of one MetaSound node to an input pin of another.
Use node_id values returned from add_metasound_input / add_metasound_node, or discovered via get_metasound_info.
Anti-patterns: - Do not pass ``from_node_id`` / ``to_node_id`` that are not valid GUIDs — handler rejects with "Invalid 'from_node_id' guid". - Do not pass ``from_output`` / ``to_input`` pin names that don't exist on the respective nodes — handler rejects with "Output … not found" / "Input … not found". - Do not connect mismatched data types (e.g. ``Audio`` -> ``Float``) — underlying ``ConnectNodes`` rejects with "data types may not match".
Args: ctx: The MCP context metasound: MetaSound asset reference (short name or full path) from_node_id: Source node GUID (from add_metasound_* results) from_output: Source output pin name (e.g. "Audio", "Out") to_node_id: Destination node GUID to_input: Destination input pin name (e.g. "Frequency", "In") """ from claude_unreal_server import get_unreal_connection
try: unreal = get_unreal_connection() if not unreal: return err("Failed to connect MetaSound nodes: no connection to Unreal Engine")
params: Dict[str, object] = { "metasound": metasound, "from_node_id": from_node_id, "from_output": from_output, "to_node_id": to_node_id, "to_input": to_input, }
response = unreal.send_command("connect_metasound_nodes", params) if not response: return err("Failed to connect MetaSound nodes: no response from Unreal Engine") if response.get("status") == "error": return err("Failed to connect MetaSound nodes", error=response.get("error", "Unknown error"))
result = response.get("result", response) return ok( f"Connected {from_node_id[:8]}.{from_output} → {to_node_id[:8]}.{to_input}", metasound=result.get("metasound", metasound), from_node_id=result.get("from_node_id", from_node_id), from_output=result.get("from_output", from_output), to_node_id=result.get("to_node_id", to_node_id), to_input=result.get("to_input", to_input), ) except Exception as e: logger.error(f"Error connecting MetaSound nodes: {e}") return err("Failed to connect MetaSound nodes", error=str(e))create_metasound CLI
Section titled “create_metasound ”Create a MetaSound Source or Patch asset
@mcp.tool()@showcase( "Create a MetaSound Source or Patch asset", featured=True,)def create_metasound( ctx: Context, name: str, path: str = "/Game/Audio", type: str = "Source",) -> ToolResult: """[Audio] Create a new MetaSound asset.
Anti-patterns: - Do not pass ``type`` outside ``Source`` or ``Patch`` — anything else silently falls back to ``Source``. Use ``Patch`` for reusable subgraphs, ``Source`` for playable assets. - Do not pass ``path`` outside ``/Game/`` — handler rejects with "Invalid package path". - Requires the ``MetaSoundEngine`` plugin to be enabled.
Args: ctx: The MCP context name: Asset name (e.g. "MS_AmbientDrone") path: Content path (default "/Game/Audio") type: MetaSound type — "Source" (playable) or "Patch" (reusable graph) """ from claude_unreal_server import get_unreal_connection
try: unreal = get_unreal_connection() if not unreal: return err("Failed to create MetaSound: no connection to Unreal Engine")
params: Dict[str, object] = { "name": name, "path": path, "type": type, }
response = unreal.send_command("create_metasound", params) if not response: return err("Failed to create MetaSound: no response from Unreal Engine") if response.get("status") == "error": return err("Failed to create MetaSound", error=response.get("error", "Unknown error"))
result = response.get("result", response) return ok( f"Created MetaSound {result.get('type', type)} '{name}' at {result.get('path', path)}", name=result.get("name", name), path=result.get("path", ""), type=result.get("type", type), ) except Exception as e: logger.error(f"Error creating MetaSound: {e}") return err("Failed to create MetaSound", error=str(e))create_sound_attenuation CLI
Section titled “create_sound_attenuation ”Create a Sound Attenuation asset for spatial audio falloff
@mcp.tool()@showcase( "Create a Sound Attenuation asset for spatial audio falloff", featured=False,)def create_sound_attenuation( ctx: Context, name: str, path: str = "/Game/Audio", falloff_distance: float = None, attenuation_distance: float = None,) -> ToolResult: """[Audio] Create a Sound Attenuation asset.
Args: ctx: The MCP context name: Asset name (e.g. "Att_3DFalloff") path: Content path (default "/Game/Audio") falloff_distance: Optional falloff distance in cm (distance over which attenuation happens from inner radius to silence) attenuation_distance: Optional inner attenuation radius in cm """ from claude_unreal_server import get_unreal_connection
try: unreal = get_unreal_connection() if not unreal: return err("Failed to create Sound Attenuation: no connection to Unreal Engine")
params: Dict[str, object] = {"name": name, "path": path} if falloff_distance is not None: params["falloff_distance"] = falloff_distance if attenuation_distance is not None: params["attenuation_distance"] = attenuation_distance
response = unreal.send_command("create_sound_attenuation", params) if not response: return err("Failed to create Sound Attenuation: no response from Unreal Engine") if response.get("status") == "error": return err("Failed to create Sound Attenuation", error=response.get("error", "Unknown error"))
result = response.get("result", response) return ok( f"Created Sound Attenuation '{name}' at {result.get('path', path)}", name=result.get("name", name), path=result.get("path", ""), falloff_distance=result.get("falloff_distance", 0.0), ) except Exception as e: logger.error(f"Error creating Sound Attenuation: {e}") return err("Failed to create Sound Attenuation", error=str(e))create_sound_class CLI
Section titled “create_sound_class ”Create a Sound Class asset for mix grouping
@mcp.tool()@showcase( "Create a Sound Class asset for mix grouping", featured=False,)def create_sound_class( ctx: Context, name: str, path: str = "/Game/Audio", volume: float = None, pitch: float = None,) -> ToolResult: """[Audio] Create a Sound Class asset used to group sounds for mixing.
Args: ctx: The MCP context name: Asset name (e.g. "SC_Ambient") path: Content path (default "/Game/Audio") volume: Optional default class volume multiplier pitch: Optional default class pitch multiplier """ from claude_unreal_server import get_unreal_connection
try: unreal = get_unreal_connection() if not unreal: return err("Failed to create Sound Class: no connection to Unreal Engine")
params: Dict[str, object] = {"name": name, "path": path} if volume is not None: params["volume"] = volume if pitch is not None: params["pitch"] = pitch
response = unreal.send_command("create_sound_class", params) if not response: return err("Failed to create Sound Class: no response from Unreal Engine") if response.get("status") == "error": return err("Failed to create Sound Class", error=response.get("error", "Unknown error"))
result = response.get("result", response) return ok( f"Created Sound Class '{name}' at {result.get('path', path)}", name=result.get("name", name), path=result.get("path", ""), volume=result.get("volume", 1.0), pitch=result.get("pitch", 1.0), ) except Exception as e: logger.error(f"Error creating Sound Class: {e}") return err("Failed to create Sound Class", error=str(e))create_sound_mix CLI
Section titled “create_sound_mix ”Create a Sound Mix with per-SoundClass adjusters
@mcp.tool()@showcase( "Create a Sound Mix with per-SoundClass adjusters", featured=False,)def create_sound_mix( ctx: Context, name: str, path: str = "/Game/Audio", class_adjusters: List[Dict[str, str]] = None,) -> ToolResult: """[Audio] Create a Sound Mix asset with optional per-SoundClass adjusters.
Args: ctx: The MCP context name: Asset name (e.g. "SM_Duck") path: Content path (default "/Game/Audio") class_adjusters: Optional list of dicts describing per-class adjustments. Each dict accepts: sound_class (asset path, required), volume (float), pitch (float). Example: [{"sound_class": "/Game/Audio/SC_Music", "volume": 0.3, "pitch": 1.0}] """ from claude_unreal_server import get_unreal_connection
try: unreal = get_unreal_connection() if not unreal: return err("Failed to create Sound Mix: no connection to Unreal Engine")
params: Dict[str, object] = {"name": name, "path": path} if class_adjusters is not None: params["class_adjusters"] = class_adjusters
response = unreal.send_command("create_sound_mix", params) if not response: return err("Failed to create Sound Mix: no response from Unreal Engine") if response.get("status") == "error": return err("Failed to create Sound Mix", error=response.get("error", "Unknown error"))
result = response.get("result", response) return ok( f"Created Sound Mix '{name}' at {result.get('path', path)}", name=result.get("name", name), path=result.get("path", ""), num_class_adjusters=result.get("num_class_adjusters", 0), ) except Exception as e: logger.error(f"Error creating Sound Mix: {e}") return err("Failed to create Sound Mix", error=str(e))get_metasound_info CLI
Section titled “get_metasound_info ”Inspect a MetaSound graph — list inputs, outputs, and nodes
@mcp.tool()@showcase( "Inspect a MetaSound graph — list inputs, outputs, and nodes", featured=False,)def get_metasound_info( ctx: Context, metasound: str,) -> ToolResult: """[Audio] Get the inputs, outputs, and node list of a MetaSound asset.
Useful for discovering existing node IDs and pin names before calling connect_metasound_nodes.
Args: ctx: The MCP context metasound: MetaSound asset reference (short name or full path) """ from claude_unreal_server import get_unreal_connection
try: unreal = get_unreal_connection() if not unreal: return err("Failed to get MetaSound info: no connection to Unreal Engine")
params: Dict[str, object] = {"metasound": metasound}
response = unreal.send_command("get_metasound_info", params) if not response: return err("Failed to get MetaSound info: no response from Unreal Engine") if response.get("status") == "error": return err("Failed to get MetaSound info", error=response.get("error", "Unknown error"))
result = response.get("result", response) return ok( f"MetaSound {metasound}: {result.get('num_nodes', 0)} nodes, " f"{result.get('num_inputs', 0)} inputs, {result.get('num_outputs', 0)} outputs", metasound=result.get("metasound", metasound), inputs=result.get("inputs", []), outputs=result.get("outputs", []), nodes=result.get("nodes", []), num_inputs=result.get("num_inputs", 0), num_outputs=result.get("num_outputs", 0), num_nodes=result.get("num_nodes", 0), ) except Exception as e: logger.error(f"Error getting MetaSound info: {e}") return err("Failed to get MetaSound info", error=str(e))set_audio_parameter CLI
Section titled “set_audio_parameter ”Adjust runtime audio parameters on a placed AudioComponent
@mcp.tool()@showcase( "Adjust runtime audio parameters on a placed AudioComponent", featured=False,)def set_audio_parameter( ctx: Context, actor_name: str, component_name: str = "", volume: float = None, pitch: float = None, low_pass_frequency: float = None,) -> ToolResult: """[Audio] Set runtime audio parameters on an AudioComponent attached to an actor.
Anti-patterns: - Do not call this against an actor with no ``UAudioComponent`` — handler rejects with "Actor … has no AudioComponent". Add one via ``add_audio_component`` first. - Do not call with all of ``volume``/``pitch``/``low_pass_frequency`` unset — the call succeeds but applies nothing.
Args: ctx: The MCP context actor_name: Name of the actor carrying the AudioComponent component_name: Optional specific component name (defaults to the first AudioComponent on the actor if empty) volume: Optional volume multiplier (0.0 - 1.0 typical, can go higher) pitch: Optional pitch multiplier (0.5 - 2.0 typical range) low_pass_frequency: Optional low-pass filter cutoff in Hz (e.g. 2000). Enables the filter when set. """ from claude_unreal_server import get_unreal_connection
try: unreal = get_unreal_connection() if not unreal: return err("Failed to set audio parameter: no connection to Unreal Engine")
params: Dict[str, object] = {"actor_name": actor_name} if component_name: params["component_name"] = component_name if volume is not None: params["volume"] = volume if pitch is not None: params["pitch"] = pitch if low_pass_frequency is not None: params["low_pass_frequency"] = low_pass_frequency
response = unreal.send_command("set_audio_parameter", params) if not response: return err("Failed to set audio parameter: no response from Unreal Engine") if response.get("status") == "error": return err("Failed to set audio parameter", error=response.get("error", "Unknown error"))
result = response.get("result", response) return ok( f"Updated audio parameters on '{actor_name}'", actor_name=result.get("actor_name", actor_name), component_name=result.get("component_name", component_name), applied=result.get("applied", {}), ) except Exception as e: logger.error(f"Error setting audio parameter: {e}") return err("Failed to set audio parameter", error=str(e))set_metasound_parameter CLI
Section titled “set_metasound_parameter ”Set a MetaSound input parameter on a playing AudioComponent
@mcp.tool()@showcase( "Set a MetaSound input parameter on a playing AudioComponent", featured=False,)def set_metasound_parameter( ctx: Context, actor_name: str, parameter_name: str, value: str, component_name: str = "",) -> ToolResult: """[Audio] Set a MetaSound input parameter on an AudioComponent playing a MetaSound.
The value type is auto-detected: numbers map to float, "true"/"false" map to bool. Runs against a live AudioComponent so the MetaSound must be playing (e.g. during PIE) for the value to take effect immediately.
Anti-patterns: - Do not pass a JSON-encoded string ``value`` — ``UAudioComponent`` exposes no ``SetStringParameter``, handler rejects with "String parameters not supported … (use float/int/bool)". - Do not call this when no AudioComponent is on the actor — handler rejects with "no AudioComponent". - Do not pass ``parameter_name`` that does not match a graph input on the playing MetaSound — the underlying call silently no-ops. - Do not call outside PIE expecting an immediate audible change — the MetaSound must be actively playing.
Args: ctx: The MCP context actor_name: Name of the actor carrying the AudioComponent parameter_name: MetaSound input name (e.g. "Intensity", "Pitch") value: JSON-encoded value. Examples: "0.75" (float), "true" (bool), "42" (int mapped to float) component_name: Optional specific AudioComponent name """ from claude_unreal_server import get_unreal_connection import json as _json
try: unreal = get_unreal_connection() if not unreal: return err("Failed to set MetaSound parameter: no connection to Unreal Engine")
try: parsed_value = _json.loads(value) except (ValueError, TypeError): parsed_value = value
params: Dict[str, object] = { "actor_name": actor_name, "parameter_name": parameter_name, "value": parsed_value, } if component_name: params["component_name"] = component_name
response = unreal.send_command("set_metasound_parameter", params) if not response: return err("Failed to set MetaSound parameter: no response from Unreal Engine") if response.get("status") == "error": return err("Failed to set MetaSound parameter", error=response.get("error", "Unknown error"))
result = response.get("result", response) return ok( f"Set '{parameter_name}' on '{actor_name}'", actor_name=result.get("actor_name", actor_name), component_name=result.get("component_name", component_name), parameter_name=result.get("parameter_name", parameter_name), parameter_type=result.get("parameter_type", ""), ) except Exception as e: logger.error(f"Error setting MetaSound parameter: {e}") return err("Failed to set MetaSound parameter", error=str(e))