skills/isaac-scripting/SKILL.md
This skill should be used when the user asks to "execute a script in Isaac Sim", "run Python in Isaac", "write a custom Isaac Sim script", "use the omni API", "use the pxr API", "use the isaacsim API", "execute_isaac_script", or needs to perform operations not covered by the granular MCP tools.
npx skillsauth add kickthemoon0817/simul isaac-scriptingInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Prefer granular MCP tools first. The simul plugin exposes purpose-built tools for the most common operations:
| Need | Use Instead |
|------|-------------|
| Create a prim | create_isaac_prim |
| Move/rotate/scale | set_isaac_prim_transform |
| Set an attribute | set_isaac_prim_attribute |
| Add rigid body | add_isaac_rigid_body |
| Add collision | add_isaac_collision |
| Physics material | set_isaac_physics_material |
| Start/stop sim | start_isaac_simulation, stop_isaac_simulation |
| Query scene | get_isaac_scene_summary, get_isaac_prim_info |
Use execute_isaac_script when:
pxr.*, omni.*, or isaacsim.* API accessScripts are sent over TCP to port 8226 (the stock isaacsim.code_editor.vscode extension). The executor runs your code with compile() inside Kit's Python process, giving full access to the global namespace including omni.*, pxr.*, and isaacsim.*.
Key rules:
stdout is captured and returned — use print() for all outputprint(json.dumps({...})) as the final lineawait is supported — the executor detects coroutines automaticallyimport everything at the top of each script; do not rely on state from previous executionstime.sleep() calls that block the Kit main threadEvery script should follow the error-safe template:
import json
import traceback
try:
# --- your logic here ---
import omni.usd
stage = omni.usd.get_context().get_stage()
prim_count = len(list(stage.Traverse()))
result = {"success": True, "prim_count": prim_count}
except Exception as e:
result = {"success": False, "error": str(e), "traceback": traceback.format_exc()}
print(json.dumps(result))
Always wrap in try/except. Always end with print(json.dumps(result)). This ensures the tool always returns parseable JSON even when the script raises an exception.
Isaac Sim 5.1.0 migrated the core package namespace. Use the new names — the old omni.isaac.* imports will fail:
| Old (pre-5.1) | New (5.1.0+) |
|---------------|--------------|
| omni.isaac.core | isaacsim.core.api |
| omni.isaac.core.utils | isaacsim.core.utils |
| omni.isaac.core.utils.prims | isaacsim.core.utils.prims |
| omni.isaac.core.utils.stage | isaacsim.core.utils.stage |
| omni.isaac.core.utils.xforms | isaacsim.core.utils.xforms |
| omni.isaac.core.utils.bounds | isaacsim.core.utils.bounds |
| omni.isaac.core.utils.rotations | isaacsim.core.utils.rotations |
| omni.isaac.core.utils.collisions | isaacsim.core.utils.collisions |
| omni.isaac.core.utils.viewports | isaacsim.core.utils.viewports |
Kit-level APIs are unchanged: omni.usd, omni.timeline, pxr.* (Usd, UsdGeom, UsdPhysics, UsdShade, UsdLux, Gf, Sdf, etc.) all import normally.
import json, omni.timeline
tl = omni.timeline.get_timeline_interface()
print(json.dumps({
"playing": tl.is_playing(),
"stopped": tl.is_stopped(),
"current_time": tl.get_current_time(),
}))
import json, omni.usd
stage = omni.usd.get_context().get_stage()
prims = [
{"path": str(p.GetPath()), "type": p.GetTypeName()}
for p in stage.Traverse()
if p.GetTypeName() # skip pseudoroot and untyped
]
print(json.dumps({"prims": prims, "count": len(prims)}))
import json, omni.usd
stage = omni.usd.get_context().get_stage()
meshes = [str(p.GetPath()) for p in stage.Traverse() if p.GetTypeName() == "Mesh"]
print(json.dumps({"meshes": meshes, "count": len(meshes)}))
import json, traceback
try:
from isaacsim.core.utils.prims import set_prim_attribute_value
from pxr import Gf
set_prim_attribute_value("/World/Box", "xformOp:translate", Gf.Vec3d(1.0, 2.0, 0.5))
set_prim_attribute_value("/World/Box", "xformOp:scale", Gf.Vec3d(2.0, 2.0, 2.0))
result = {"success": True}
except Exception as e:
import traceback
result = {"success": False, "error": str(e), "traceback": traceback.format_exc()}
print(json.dumps(result))
import json, traceback
try:
from isaacsim.core.utils.xforms import get_world_pose
pos, quat = get_world_pose("/World/Robot")
result = {"success": True, "position": pos.tolist(), "orientation_wxyz": quat.tolist()}
except Exception as e:
result = {"success": False, "error": str(e), "traceback": traceback.format_exc()}
print(json.dumps(result))
import json, traceback
try:
from isaacsim.core.utils.bounds import create_bbox_cache, compute_aabb
import numpy as np
cache = create_bbox_cache()
aabb = compute_aabb(cache, "/World/Robot")
center = ((aabb[:3] + aabb[3:]) / 2).tolist()
size = (aabb[3:] - aabb[:3]).tolist()
result = {"success": True, "center": center, "size": size, "aabb": aabb.tolist()}
except Exception as e:
result = {"success": False, "error": str(e), "traceback": traceback.format_exc()}
print(json.dumps(result))
Do not reuse state between executions. Each execute_isaac_script call is isolated. Variables, imports, and objects from a previous call are not available. Always re-import.
Do not block the main thread. Never use while True, time.sleep(), or any blocking wait inside a script. For physics stepping, use world.step(render=True) in a bounded loop (e.g. for _ in range(10)), not an infinite one.
Use World.instance() not World() when the world already exists. Calling World() a second time raises an error. Always check:
from isaacsim.core.api import World
world = World.instance()
if world is None:
world = World(physics_dt=1/60, rendering_dt=1/60)
JSON-serialise everything. pxr.Gf.Vec3d, numpy arrays, and USD types are not JSON-serialisable. Convert with .tolist() or list(v) before passing to json.dumps.
Attribute access requires the prim to be valid. Always check prim.IsValid() before calling methods on it. A prim retrieved from a path that does not exist returns an invalid prim that will raise on method calls.
references/api-quick-reference.md — full API task-to-module lookup tablereferences/namespace-migration.md — complete old-to-new namespace mappingreferences/script-templates.md — copy-paste templates for common patternstools
This skill should be used when the user asks to "analyze a USD file", "load a USD file", "inspect USD", "headless USD", "prim info", "search prims", "mesh info", "scene summary", "bounding box", or needs to work with USD files without a running Isaac Sim instance.
testing
This skill should be used when the user asks to "start the simulation", "stop the simulation", "pause simulation", "step the simulation", "reset simulation", "play simulation", "check simulation state", "run the simulation", or needs to control simulation playback in Isaac Sim.
development
This skill should be used when the user asks to "set up simul", "install simul", "configure simul", "get started", "which backend", "how to install", or needs help choosing and installing the right backends for their simulation workflow.
development
This skill should be used when the user asks to "set up a scene", "create a new scene", "add a ground plane", "add lighting", "create a basic scene", "scene from scratch", "empty scene", "new stage", or needs to build a complete 3D scene in Isaac Sim from the ground up.