Batch Command Reference¶
Combine two or more compatible operations into a single MCP call and avoid repeating typed-call envelopes.
Overview¶
Prefer batch() for two or more compatible reads or writes. Direct-only and Python-expanded tools must be called through their typed MCP wrappers.
Instead of:
await create_object("Enemy") # 1 call
await set_property("Enemy", ...) # 2nd call
await manage_component("Enemy", ...) # 3rd call
Use:
await batch("""
create_object name=Enemy
set_property path=Enemy component=Transform prop=position value=0,1,0
manage_component path=Enemy type=Health action=add
""")
batch¶
Execute multiple commands in one call.
Parameters: - commands (string) — Text format: one command per line, cmd key=value key=value - on_error (string, default="continue") — "continue" or "stop" - timeout (float, default=75.0) — Client-side wait budget. Unity's outer batch execution deadline is 65 seconds. - atomic (bool, default=False) — On failure, revert changes recorded in the Unity Undo group. File, process, and other external side effects are not guaranteed to roll back. - validate_aliases (bool, default=False) — Dry-run alias validation before any mutations execute
Command Format:
Example: Simple Batch
result = await batch("""
create_object name=Player
set_property path=Player component=Transform prop=position value=0,1,0
manage_component path=Player type=Health action=add
""")
Supported Commands (35+)¶
| Category | Commands |
|---|---|
| Object CRUD | create_object, delete_object, set_active, set_parent, transfer_object |
| Components | manage_component, wire_event, unwire_event, set_material |
| Properties | set_property, set_property_delta |
| Reads | get_component, get_components_list, get_object_detail, find_objects, inspect |
| Scene | search_scene, get_hierarchy |
| Assets | asset, material, prefab, scriptable_object, project_settings |
| Advanced | object_diff, validate_references, references |
Constraints: - ❌ No async commands (wait_until, move_to, run_tests, test_step, run_playtest) - ❌ No inter-command references (each op is independent) - ❌ No DSL-expansion tools (animator_intent, vfx_intent, ui_intent must be typed MCP calls) - ✅ Tool enable/disable checks apply to each command - ✅ Play Mode guard: mutating ops blocked (BLOCKED response) - ✅ Compile guard: mutations blocked during compilation - ✅ Main thread processing only
Key parameter names: - prop (not property) — for set_property - type (not component) — for manage_component action
Command Reference¶
Object Creation & Deletion¶
create_object:
delete_object:
set_active:
set_parent:
Component Management¶
manage_component:
manage_component path=Player type=Rigidbody action=add
manage_component path=Player type=AudioSource action=remove
wire_event:
wire_event path=UI/Button component=Button event=onClick target=GameManager method=OnClick arg_type=void
unwire_event:
set_material:
Property Modification¶
set_property (Edit Mode; Play Mode writes are lost on stop):
set_property path=Player component=Transform prop=position value=10,5,0
set_property path=Enemy component=Health prop=maxHp value=100
set_property path=Light component=Light prop=intensity value=1.5
set_property_delta:
Reading Data¶
get_component:
inspect:
get_components_list:
get_hierarchy:
search_scene:
find_objects:
Asset Operations¶
asset:
asset action=find type=Material folder=Assets/UI
asset action=move source=Assets/Old.mat dest=Assets/Materials/Old.mat
asset action=delete path=Assets/Temp.prefab
material:
prefab:
prefab action=save path=MyPrefab asset_path=Assets/Prefabs/MyPrefab.prefab
prefab action=edit asset_path=Assets/Prefabs/Player.prefab component=Health prop=MaxHP value=200
scriptable_object:
Advanced Operations¶
object_diff:
validate_references:
See Diagnostics: validate_references.
references:
Real-World Examples¶
Example 1: Setup Scene with Multiple Objects¶
await batch("""
create_object name=Player primitive=Cube
set_property path=Player component=Transform prop=position value=0,1,0
manage_component path=Player type=Rigidbody action=add
set_property path=Player component=Rigidbody prop=mass value=80
create_object name=Enemy primitive=Cube parent=Enemies
set_property path=Enemy component=Transform prop=position value=5,1,0
manage_component path=Enemy type=Health action=add
set_property path=Enemy component=Health prop=maxHp value=50
""")
Example 2: Modify Multiple UI Elements¶
await batch("""
set_active path=UI/MainMenu active=false
set_active path=UI/GameUI active=true
set_property path=UI/HealthBar component=Image prop=fillAmount value=1
wire_event path=UI/PlayButton component=Button event=onClick target=GameManager method=StartGame arg_type=void
""")
Example 3: Inspect Multiple Objects¶
result = await batch("""
inspect paths=Player components=Transform,Health,Rigidbody
inspect paths=Enemy components=Transform,Health
get_components_list id=<boss_instance_id>
""")
Example 4: Asset & Prefab Operations¶
await batch("""
asset action=find type=Material folder=Assets/Materials
material action=set path=Assets/NewMat.mat prop=_Color value=1,0,0,1
prefab action=edit asset_path=Assets/Prefabs/Player.prefab component=Health prop=MaxHP value=200
""")
Batch Behavior¶
Sequential execution: Commands run in order on the Unity main thread.
Error handling: - continue (default) — Skip failed operation, continue to next - stop — Halt batch on first failure (set in tool params)
Atomicity: Entire batch fails if compile in progress or Play Mode guard triggered.
Performance: Single round-trip TCP call, ~5-50ms total (vs 50-500ms for 10 individual calls).
Typed vs. Batch Commands¶
Some tools MUST be called as typed MCP tools (not batch): - batch — Can't batch a batch - do, ask, ask_user — NL intent tools - run_playtest — DSL-based testing - run_tests — NUnit execution - wait_until, move_to, test_step — Async operations - animator_intent, vfx_intent, ui_intent — DSL-expansion tools
All others are batchable (reads, writes, asset ops, etc.)
Common Mistakes¶
❌ WRONG: 10 separate calls
await create_object("Enemy1")
await create_object("Enemy2")
await set_property("Enemy1", ...)
# ... 7 more calls
✅ RIGHT: 1 batch call
await batch("""
create_object name=Enemy1
create_object name=Enemy2
set_property path=Enemy1 component=Transform prop=position value=0,1,0
""")
❌ WRONG: Async in batch
✅ RIGHT: Typed async call
Output Format¶
Success:
ok: 5
[0] create_object "Player" → ok
[1] set_property "Player" → ok
[2] manage_component "Player" → ok
[3] get_component "Player" → Transform { position=(0,1,0), ... }
[4] search_scene "Enemy" → [Enemy $a, Enemy2 $b]
Partial failure (continue mode):
ok: 3, err: 2
[0] create_object "Player" → ok
[1] set_property "Player" → err: Component 'Invalid' not found
[2] manage_component "Player" → ok
[3] get_component "Player" → ok
[4] find_objects "Missing" → err: No objects found
Batch-First Decision Tree¶
1+ operations needed?
├─ YES
│ ├─ All 2+ can be batched? (no async, no intent)
│ │ ├─ YES → use batch()
│ │ └─ NO → split into batch + typed calls
│ └─ Single operation → direct call (ok, no penalty)
└─ NO → single direct call
Patterns & Idioms¶
| Pattern | When | Example |
|---|---|---|
| Inspect All | Snapshot multiple objects | Text DSL: multi-line inspect commands |
| Setup Scene | Initialize with multiple objects | create_object, manage_component, set_property in one batch |
| Bulk Modify | Change same property on many objects | Multiple set_property lines with different paths |
| Read Before/After | Compare state | get_component, mutations, get_component in sequence |
| Asset Organization | Move & create folders | asset commands in one batch |
See also: Token Optimization Skills for usage patterns and the Batch guide index.