Skip to main content
Glama

add_graph_node

Creates a single node in a Blueprint, material, MetaSound, PCG, or Control Rig graph and returns its node ID and pins so you can wire it immediately.

Instructions

Create one node in a graph and return it with its node_id and pins, so connect_pins and set_pin_default_value can wire it without another read.

Works in a Blueprint graph (Animation and Widget Blueprints included) and in the graph of a material, material function, sound cue, MetaSound Source, PCG graph or Control Rig. To create and wire several Blueprint nodes in one undo step use build_blueprint_graph. Every call adds a new node, except event and custom_event, which give back the one already there; remove_graph_node takes a spare node out.

Each value comes from a read: event_name from list_overridable_functions, function_name from get_class_functions (an engine library's list is long enough to come back as a file: get_mcp_audit_report reads its report_path), variable_name from get_blueprint_variables, struct_type from list_structs, enum_path from list_enums, and graph_name from get_blueprint_functions; get_function_pins previews a node's pins before it exists. When a call_function names both, function_library wins over target_class, and node_position wins over position_x and position_y. node_type keywords ignore case. Example: {"asset_path": "/Game/Blueprints/BP_Door", "node_type": "call_function", "function_name": "PrintString", "function_library": "KismetSystemLibrary"}.

In another asset, node_type is its editor's own node: a material expression class (/Script/Engine.MaterialExpressionConstant), a sound node type (WavePlayer with sound_wave_path, Mixer, Random...), a MetaSound class path from list_metasound_node_types (UE.Sine.Audio, with major_version), a PCG settings class from list_pcg_node_types (PCGSubgraphSettings with subgraph_path embeds a graph), or a Control Rig unit (SetTransform, TwoBoneIKSimple..., with node_name). Those assets are saved by their editor, and a Control Rig is compiled.

A Blueprint is compiled only with compile=true and never saved, and the call is refused during Play-in-Editor (see force). event creates a real override, finding the interface or parent class itself; a name that is not an overridable event is an error, and an interface function with a return value needs add_blueprint_function with override=true. custom_event takes no parameters, so an RPC or anything with arguments must be a function. get_component_by_class makes a node already typed to target_class, so its ReturnValue connects without a cast. Check class in the reply: an async or latent node that comes back as K2Node_CallFunction does nothing, though it compiles clean.

Returns: { node_id, class, title, pos_x, pos_y, comment, pins: [{ name, direction, type, linked_to, default }], blueprint_name, graph_name, compiled, plus the fields of its node_type } -- event: event_name, is_override (true for a live override), already_exists; custom_event: event_name, node_title, already_existed; cast: cast_to; call_function: function_library, function; make_struct and break_struct: struct_type; select: index_pin, return_value_pin, option_pins, option_count, index_enum; macro_instance: input_pins, output_pins; get_component_by_class: component_class, return_pin_type (when it does not name the class, the pin stayed generic).

Input Schema

NameRequiredDescriptionDefault
casesNoOptional string array of case pins for switch_int/switch_string/switch_name
forceNoOptional. This command is REFUSED while a Play-in-Editor session is running: it either compiles a Blueprint (the reinstancer can retain a world, and CheckForWorldGCLeaks is Fatal -- it KILLS the editor) or writes to disk (Editor.AllowSavingAssetsDuringPIE=0 makes the engine refuse the write, so it would report success without writing a byte). Stop PIE and retry instead; force=true runs it anyway, at your own risk.
scopeNoOptional scope hint for variable_get/variable_set: 'auto' (default; a function-local variable declared in the target graph wins, else a self/member variable), 'local' (function-local variable ONLY), or 'member' (member variable only -- self, or on target_class when supplied). Ignored by other node types.
compileNoOptional bool, default false: compile the Blueprint after placing the node. Ignored inside build_blueprint_graph, which never compiles its steps.
argumentsNoOptional string array of argument names for format_text
enum_pathNoEnum path or name; required for switch_enum and enum_literal nodes. Optional for select: the enum then drives the Index pin and one option pin is generated per enum entry.
node_nameNoControl Rig only: the name to give the node (a taken name gets a suffix; the reply's node_id is the real one).
node_typeYesIn a Blueprint, one of event, custom_event, call_function, print_string, variable_get, variable_set, branch, sequence, self, cast, spawn_actor (alias spawn_actor_from_class), create_widget, make_struct, break_struct, get_array_item, select, make_array, make_set, make_map, switch_int, switch_string, switch_name, switch_enum, enum_literal, format_text, foreach, foreach_with_break, do_once, gate, flipflop, for_loop, while_loop, is_valid, add_delegate, macro_instance, get_component_by_class, or a graph node class (AnimGraphNode_Slot, /Script/AnimGraph.AnimGraphNode_SequencePlayer); for another asset, see the description
asset_pathNoThe graph asset: a Blueprint by name (resolved under /Game/Blueprints) or full path, or the path of a material, material function, sound cue, MetaSound Source, PCG graph or Control Rig. Pass the FULL path when a Blueprint short name is ambiguous: a bare name that matches two assets resolves to one of them silently.
dispatcherNoEvent-dispatcher (multicast delegate) name; required for add_delegate node type. Must already exist in the COMPILED class (add_event_dispatcher + compile_blueprint), and it binds on self only -- for a dispatcher on another class use add_object_bound_event.
event_nameNoEvent name; required for event and custom_event node types (e.g. "ReceiveActorBeginOverlap", "ReceiveBeginPlay" for event)
graph_nameNoTarget graph name; defaults to the Blueprint's event graph when omitted
index_typeNoOptional alias of enum_path for node_type=select.
num_inputsNoOptional input-pin count for make_array/make_set/make_map (added after spawn)
position_xNoNode X position on the graph canvas (ignored when node_position is set)
position_yNoNode Y position on the graph canvas (ignored when node_position is set)
struct_typeNoStruct type; required for make_struct and break_struct nodes: a UScriptStruct path (/Game/.../S_Foo.S_Foo), bare name, or engine alias (Vector/Rotator/Transform...)
macro_sourceNoSet to "standard_macros" to skip this Blueprint's own MacroGraphs and resolve macro_graph_name only in the engine StandardMacros library. Only read for node_type=macro_instance.
option_countNoOptional, select only: total number of option pins to end up with (default the built-in 2; ignored when an enum drives the index).
target_classNoClass owning the function or cast/spawn target class; required for cast, create_widget and get_component_by_class. For call_function it is searched STRICTLY: a function that is not on that class is an error, never a silent fallback to another library; it also resolves a user BlueprintFunctionLibrary by asset path ("/Game/Dir/BFL_X"). For get_component_by_class it is the component class to fetch (a UActorComponent subclass). For variable_get/variable_set it names the class that owns the variable, producing a non-self member-access node (with a 'target' pin) instead of a self-context node. For create_widget it names the widget class to construct (e.g. WBP_Foo_C, a full asset path, or the widget Blueprint short name); the node exposes that widget's Expose-On-Spawn pins.
function_nameNoFunction to call; required for call_function node type
macro_libraryNoOptional, macro_instance only: asset path of a macro LIBRARY Blueprint to resolve macro_graph_name in -- the only way to reach a third-party or project macro library.
major_versionNoMetaSound only: the node class's major version (default 1), as list_metasound_node_types gives it.
node_positionNoNode canvas position as [x, y]; takes precedence over position_x/position_y
subgraph_pathNoPCG only, with node_type=PCGSubgraphSettings: the PCG graph to embed.
variable_nameNoVariable to get/set; required for variable_get and variable_set
blueprint_nameNoOlder name of asset_path, still accepted.
blueprint_pathNoAlias of `blueprint_name` (same value, same meaning). Accepted because sibling tools spell this parameter differently; prefer `blueprint_name`.
sound_wave_pathNoSound cue, WavePlayer only: the sound wave it plays.
function_libraryNoOptional, call_function only: the library class owning function_name, used instead of target_class -- an engine library by name ("KismetMathLibrary", "KismetSystemLibrary", "GameplayStatics", "KismetStringLibrary", with or without the U prefix, or any /Script/Engine class) or a user BlueprintFunctionLibrary asset path ("/Game/Dir/BFL_X", "/Game/Dir/BFL_X.BFL_X" or the "..._C" class). Searched strictly, like target_class.
macro_graph_nameNoMacro graph name; required for node_type=macro_instance. Resolved against this Blueprint's own MacroGraphs first, then the engine StandardMacros; "<library-path>:<MacroGraphName>" (e.g. "/Game/Lib/ML_X.ML_X:MyMacro") resolves it in that macro library instead.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed7 schema fields changedv2.5.0
    • addedInput schema / properties / asset_path
      Added value: +{
      +  "description": "The graph asset: a Blueprint by name (resolved under /Game/Blueprints) or full path, or the path of a material, material function, sound cue, MetaSound Source, PCG graph or Control Rig. Pass the FULL path when a Blueprint short name is ambiguous: a bare name that matches two assets resolves to one of them silently.",
      +  "type": "string"
      +}
    • changedInput schema / properties / blueprint_name / description
      Previous value: -"Blueprint name (resolved under /Game/Blueprints) or full asset path. Pass the FULL path when the short name is ambiguous: a bare name that matches two assets resolves to one of them silently."New value: +"Older name of asset_path, still accepted."
    • addedInput schema / properties / major_version
      Added value: +{
      +  "description": "MetaSound only: the node class's major version (default 1), as list_metasound_node_types gives it.",
      +  "type": "number"
      +}
    • addedInput schema / properties / node_name
      Added value: +{
      +  "description": "Control Rig only: the name to give the node (a taken name gets a suffix; the reply's node_id is the real one).",
      +  "type": "string"
      +}
    • changedInput schema / properties / node_type / description
      Previous value: -"One of event, custom_event, call_function, print_string, variable_get, variable_set, branch, sequence, self, cast, spawn_actor (alias spawn_actor_from_class), create_widget, make_struct, break_struct, get_array_item, select, make_array, make_set, make_map, switch_int, switch_string, switch_name, switch_enum, enum_literal, format_text, foreach, foreach_with_break, do_once, gate, flipflop, for_loop, while_loop, is_valid, add_delegate, macro_instance, get_component_by_class"New value: +"In a Blueprint, one of event, custom_event, call_function, print_string, variable_get, variable_set, branch, sequence, self, cast, spawn_actor (alias spawn_actor_from_class), create_widget, make_struct, break_struct, get_array_item, select, make_array, make_set, make_map, switch_int, switch_string, switch_name, switch_enum, enum_literal, format_text, foreach, foreach_with_break, do_once, gate, flipflop, for_loop, while_loop, is_valid, add_delegate, macro_instance, get_component_by_class, or a graph node class (AnimGraphNode_Slot, /Script/AnimGraph.AnimGraphNode_SequencePlayer); for another asset, see the description"
    • addedInput schema / properties / sound_wave_path
      Added value: +{
      +  "description": "Sound cue, WavePlayer only: the sound wave it plays.",
      +  "type": "string"
      +}
    • addedInput schema / properties / subgraph_path
      Added value: +{
      +  "description": "PCG only, with node_type=PCGSubgraphSettings: the PCG graph to embed.",
      +  "type": "string"
      +}
  2. Changed11 schema fields changedv2.0.0
    • addedInput schema / properties / compile
      Added value: +{
      +  "description": "Optional bool, default false: compile the Blueprint after placing the node. Ignored inside build_blueprint_graph, which never compiles its steps.",
      +  "type": "boolean"
      +}
    • changedInput schema / properties / enum_path / description
      Previous value: -"Enum path or name; required for switch_enum and enum_literal nodes"New value: +"Enum path or name; required for switch_enum and enum_literal nodes. Optional for select: the enum then drives the Index pin and one option pin is generated per enum entry."
    • changedInput schema / properties / event_name / description
      Previous value: -"Event name; required for event and custom_event node types"New value: +"Event name; required for event and custom_event node types (e.g. \"ReceiveActorBeginOverlap\", \"ReceiveBeginPlay\" for event)"
    • addedInput schema / properties / function_library
      Added value: +{
      +  "description": "Optional, call_function only: the library class owning function_name, used instead of target_class -- an engine library by name (\"KismetMathLibrary\", \"KismetSystemLibrary\", \"GameplayStatics\", \"KismetStringLibrary\", with or without the U prefix, or any /Script/Engine class) or a user BlueprintFunctionLibrary asset path (\"/Game/Dir/BFL_X\", \"/Game/Dir/BFL_X.BFL_X\" or the \"..._C\" class). Searched strictly, like target_class.",
      +  "type": "string"
      +}
    • addedInput schema / properties / index_type
      Added value: +{
      +  "description": "Optional alias of enum_path for node_type=select.",
      +  "type": "string"
      +}
    • changedInput schema / properties / macro_graph_name / description
      Previous value: -"Macro graph name; required for node_type=macro_instance. Resolved against this Blueprint's own MacroGraphs first, then the engine StandardMacros."New value: +"Macro graph name; required for node_type=macro_instance. Resolved against this Blueprint's own MacroGraphs first, then the engine StandardMacros; \"<library-path>:<MacroGraphName>\" (e.g. \"/Game/Lib/ML_X.ML_X:MyMacro\") resolves it in that macro library instead."
    • addedInput schema / properties / macro_library
      Added value: +{
      +  "description": "Optional, macro_instance only: asset path of a macro LIBRARY Blueprint to resolve macro_graph_name in -- the only way to reach a third-party or project macro library.",
      +  "type": "string"
      +}
    • changedInput schema / properties / node_type / description
      Previous value: -"One of event, custom_event, call_function, print_string, variable_get, variable_set, branch, sequence, self, cast, spawn_actor (alias spawn_actor_from_class), create_widget, make_struct, break_struct, get_array_item, select, make_array, make_set, make_map, switch_int, switch_string, switch_name, switch_enum, enum_literal, format_text, foreach, foreach_with_break, do_once, gate, flipflop, for_loop, while_loop, is_valid, add_delegate, macro_instance"New value: +"One of event, custom_event, call_function, print_string, variable_get, variable_set, branch, sequence, self, cast, spawn_actor (alias spawn_actor_from_class), create_widget, make_struct, break_struct, get_array_item, select, make_array, make_set, make_map, switch_int, switch_string, switch_name, switch_enum, enum_literal, format_text, foreach, foreach_with_break, do_once, gate, flipflop, for_loop, while_loop, is_valid, add_delegate, macro_instance, get_component_by_class"
    • addedInput schema / properties / option_count
      Added value: +{
      +  "description": "Optional, select only: total number of option pins to end up with (default the built-in 2; ignored when an enum drives the index).",
      +  "type": "number"
      +}
    • changedInput schema / properties / struct_type / description
      Previous value: -"Struct type; required for make_struct and break_struct nodes"New value: +"Struct type; required for make_struct and break_struct nodes: a UScriptStruct path (/Game/.../S_Foo.S_Foo), bare name, or engine alias (Vector/Rotator/Transform...)"
    • changedInput schema / properties / target_class / description
      Previous value: -"Class owning the function or cast/spawn target class; required for cast and create_widget. For variable_get/variable_set it names the class that owns the variable, producing a non-self member-access node (with a 'target' pin) instead of a self-context node. For create_widget it names the widget class to construct (e.g. WBP_Foo_C, a full asset path, or the widget Blueprint short name); the node exposes that widget's Expose-On-Spawn pins."New value: +"Class owning the function or cast/spawn target class; required for cast, create_widget and get_component_by_class. For call_function it is searched STRICTLY: a function that is not on that class is an error, never a silent fallback to another library; it also resolves a user BlueprintFunctionLibrary by asset path (\"/Game/Dir/BFL_X\"). For get_component_by_class it is the component class to fetch (a UActorComponent subclass). For variable_get/variable_set it names the class that owns the variable, producing a non-self member-access node (with a 'target' pin) instead of a self-context node. For create_widget it names the widget class to construct (e.g. WBP_Foo_C, a full asset path, or the widget Blueprint short name); the node exposes that widget's Expose-On-Spawn pins."
  3. Changed2 schema fields changedv1.2.10
    • changedInput schema / properties / target_class / description
      Previous value: -"Class owning the function or cast/spawn target class. For variable_get/variable_set it names the class that owns the variable, producing a non-self member-access node (with a 'target' pin) instead of a self-context node. For create_widget it names the widget class to construct (e.g. WBP_Foo_C, a full asset path, or the widget Blueprint short name); the node exposes that widget's Expose-On-Spawn pins."New value: +"Class owning the function or cast/spawn target class; required for cast and create_widget. For variable_get/variable_set it names the class that owns the variable, producing a non-self member-access node (with a 'target' pin) instead of a self-context node. For create_widget it names the widget class to construct (e.g. WBP_Foo_C, a full asset path, or the widget Blueprint short name); the node exposes that widget's Expose-On-Spawn pins."
    • changedInput schema / required
      Previous value: -[
      -  "node_type",
      -  "event_name",
      -  "function_name",
      -  "target_class",
      -  "variable_name",
      -  "struct_type",
      -  "enum_path",
      -  "dispatcher",
      -  "macro_graph_name"
      -]New value: +[
      +  "node_type"
      +]
  4. First observedv1.1.0

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the annotations: every call adds a node (non-idempotent, consistent with annotations), event/custom_event reuse existing nodes, Blueprints compile only with compile=true and are never saved, calls are refused during PIE with the force caveat, and it warns that an async/latent node returned as K2Node_CallFunction silently does nothing. That is exactly the behavioral context an agent needs for a mutation tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with purpose and return shape before the per-type details. It is dense and long, but nearly every sentence carries unique operational information (sources, precedence, PIE refusal, return fields); minor deduction for the volume and run-on density that could be organized into tighter sections.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With 31 parameters and no output schema, the description fully covers the return object shape and per-node_type extra fields, the asset-type-specific semantics, and failure modes. Nothing critical for correct invocation is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds real precedence rules beyond the schema: function_library wins over target_class, node_position wins over position_x/position_y, and where each value must be read from. These overrides are described in prose rather than only in schema descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ('Create one node in a graph and return it with node_id and pins') and enumerates the supported asset/graph types. It clearly differentiates itself from build_blueprint_graph, connect_pins, set_pin_default_value and remove_graph_node.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit routing: use build_blueprint_graph for multi-node single-undo wiring, use the listed read tools (list_overridable_functions, get_class_functions, get_blueprint_variables, etc.) to source each value, and stop PIE before calling. It also documents edge cases (event/custom_event do not add new nodes, interface functions with returns need add_blueprint_function).

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.