omniverse-mcp 0.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (131) hide show
  1. omniverse_mcp-0.2.0/.claude-plugin/marketplace.json +17 -0
  2. omniverse_mcp-0.2.0/.gitignore +47 -0
  3. omniverse_mcp-0.2.0/CHANGELOG.md +115 -0
  4. omniverse_mcp-0.2.0/LICENSE +21 -0
  5. omniverse_mcp-0.2.0/PKG-INFO +264 -0
  6. omniverse_mcp-0.2.0/README.md +237 -0
  7. omniverse_mcp-0.2.0/docs/AI_GUIDE.md +36 -0
  8. omniverse_mcp-0.2.0/docs/ARCHITECTURE.md +332 -0
  9. omniverse_mcp-0.2.0/docs/TOOLS.md +778 -0
  10. omniverse_mcp-0.2.0/docs/images/README.md +27 -0
  11. omniverse_mcp-0.2.0/docs/images/hero-segmentation.png +0 -0
  12. omniverse_mcp-0.2.0/docs/images/hero-viewport.jpg +0 -0
  13. omniverse_mcp-0.2.0/docs/images/inspect-orbit.jpg +0 -0
  14. omniverse_mcp-0.2.0/docs/images/logo.svg +5 -0
  15. omniverse_mcp-0.2.0/docs/images/social-preview.png +0 -0
  16. omniverse_mcp-0.2.0/docs/plans/2026-10-28-modernization.md +507 -0
  17. omniverse_mcp-0.2.0/docs/plans/README.md +67 -0
  18. omniverse_mcp-0.2.0/docs/releasing.md +53 -0
  19. omniverse_mcp-0.2.0/docs/reviews/2026-10-28-dependabot-auto-merge-code.md +60 -0
  20. omniverse_mcp-0.2.0/docs/reviews/2026-10-28-exact-allows-code.md +84 -0
  21. omniverse_mcp-0.2.0/docs/reviews/2026-10-28-gate-holes-code.md +82 -0
  22. omniverse_mcp-0.2.0/docs/reviews/2026-10-28-log-levels-code.md +50 -0
  23. omniverse_mcp-0.2.0/docs/reviews/2026-10-28-s1-bridge-token-code.md +76 -0
  24. omniverse_mcp-0.2.0/docs/reviews/2026-10-28-s2-rename-code.md +45 -0
  25. omniverse_mcp-0.2.0/docs/reviews/2026-10-28-s4-harness-code.md +52 -0
  26. omniverse_mcp-0.2.0/docs/reviews/2026-10-28-s5-ci-code.md +168 -0
  27. omniverse_mcp-0.2.0/docs/reviews/2026-10-28-s6-testability-code.md +85 -0
  28. omniverse_mcp-0.2.0/docs/reviews/2026-10-28-s7a-sdk-v2-code.md +71 -0
  29. omniverse_mcp-0.2.0/docs/reviews/2026-10-28-s7b-tool-contract-code.md +79 -0
  30. omniverse_mcp-0.2.0/docs/reviews/2026-10-28-s7c-tool-tests-code.md +70 -0
  31. omniverse_mcp-0.2.0/docs/reviews/2026-10-28-s8-extension-install-code.md +84 -0
  32. omniverse_mcp-0.2.0/docs/reviews/2026-10-28-s8-plugin-code.md +123 -0
  33. omniverse_mcp-0.2.0/docs/reviews/2026-10-28-set-material-mdl-code.md +66 -0
  34. omniverse_mcp-0.2.0/docs/reviews/2026-10-28-wip-camera-lighting-code.md +128 -0
  35. omniverse_mcp-0.2.0/docs/reviews/2026-10-29-capture-fresh-file-code.md +63 -0
  36. omniverse_mcp-0.2.0/docs/reviews/2026-10-29-release-0.2.0-code.md +63 -0
  37. omniverse_mcp-0.2.0/docs/reviews/2026-10-29-s8b-presentation-code.md +46 -0
  38. omniverse_mcp-0.2.0/docs/reviews/2026-10-29-s9-release-workflow-code.md +67 -0
  39. omniverse_mcp-0.2.0/docs/reviews/README.md +51 -0
  40. omniverse_mcp-0.2.0/extension/ovmcp.bridge/config/extension.toml +21 -0
  41. omniverse_mcp-0.2.0/extension/ovmcp.bridge/docs/README.md +31 -0
  42. omniverse_mcp-0.2.0/extension/ovmcp.bridge/ovmcp/__init__.py +0 -0
  43. omniverse_mcp-0.2.0/extension/ovmcp.bridge/ovmcp/bridge/__init__.py +4 -0
  44. omniverse_mcp-0.2.0/extension/ovmcp.bridge/ovmcp/bridge/extension.py +226 -0
  45. omniverse_mcp-0.2.0/extension/ovmcp.bridge/ovmcp/bridge/handlers/__init__.py +133 -0
  46. omniverse_mcp-0.2.0/extension/ovmcp.bridge/ovmcp/bridge/handlers/_mcp_bridge.py +164 -0
  47. omniverse_mcp-0.2.0/extension/ovmcp.bridge/ovmcp/bridge/handlers/_utils.py +338 -0
  48. omniverse_mcp-0.2.0/extension/ovmcp.bridge/ovmcp/bridge/handlers/camera.py +833 -0
  49. omniverse_mcp-0.2.0/extension/ovmcp.bridge/ovmcp/bridge/handlers/logging.py +64 -0
  50. omniverse_mcp-0.2.0/extension/ovmcp.bridge/ovmcp/bridge/handlers/misc.py +301 -0
  51. omniverse_mcp-0.2.0/extension/ovmcp.bridge/ovmcp/bridge/handlers/recording.py +318 -0
  52. omniverse_mcp-0.2.0/extension/ovmcp.bridge/ovmcp/bridge/handlers/robot.py +330 -0
  53. omniverse_mcp-0.2.0/extension/ovmcp.bridge/ovmcp/bridge/handlers/scene.py +654 -0
  54. omniverse_mcp-0.2.0/extension/ovmcp.bridge/ovmcp/bridge/handlers/simulation.py +285 -0
  55. omniverse_mcp-0.2.0/extension/ovmcp.bridge/ovmcp/bridge/handlers/usd_advanced.py +472 -0
  56. omniverse_mcp-0.2.0/extension/ovmcp.bridge/ovmcp/core/__init__.py +6 -0
  57. omniverse_mcp-0.2.0/extension/ovmcp.bridge/ovmcp/core/bounds.py +69 -0
  58. omniverse_mcp-0.2.0/extension/ovmcp.bridge/ovmcp/core/formatter.py +239 -0
  59. omniverse_mcp-0.2.0/extension/ovmcp.bridge/ovmcp/core/framing.py +147 -0
  60. omniverse_mcp-0.2.0/extension/ovmcp.bridge/ovmcp/core/http.py +262 -0
  61. omniverse_mcp-0.2.0/extension/ovmcp.bridge/ovmcp/core/isolation.py +144 -0
  62. omniverse_mcp-0.2.0/extension/ovmcp.bridge/ovmcp/core/lighting.py +20 -0
  63. omniverse_mcp-0.2.0/extension/ovmcp.bridge/ovmcp/core/logs.py +93 -0
  64. omniverse_mcp-0.2.0/extension/ovmcp.bridge/ovmcp/core/material.py +39 -0
  65. omniverse_mcp-0.2.0/extension/ovmcp.bridge/ovmcp/core/png.py +45 -0
  66. omniverse_mcp-0.2.0/extension/ovmcp.bridge/ovmcp/core/protocol.py +24 -0
  67. omniverse_mcp-0.2.0/extension/ovmcp.bridge/ovmcp/core/serial.py +41 -0
  68. omniverse_mcp-0.2.0/extension/ovmcp.bridge/ovmcp/core/token.py +57 -0
  69. omniverse_mcp-0.2.0/extension/ovmcp.bridge/ovmcp/core/usd.py +53 -0
  70. omniverse_mcp-0.2.0/plugin/.claude-plugin/icon.png +0 -0
  71. omniverse_mcp-0.2.0/plugin/.claude-plugin/plugin.json +13 -0
  72. omniverse_mcp-0.2.0/plugin/.mcp.json +13 -0
  73. omniverse_mcp-0.2.0/plugin/README.md +45 -0
  74. omniverse_mcp-0.2.0/plugin/skills/geometry/SKILL.md +43 -0
  75. omniverse_mcp-0.2.0/plugin/skills/scene/SKILL.md +61 -0
  76. omniverse_mcp-0.2.0/plugin/skills/script/SKILL.md +45 -0
  77. omniverse_mcp-0.2.0/plugin/skills/setup/SKILL.md +69 -0
  78. omniverse_mcp-0.2.0/plugin/skills/simulate/SKILL.md +44 -0
  79. omniverse_mcp-0.2.0/pyproject.toml +246 -0
  80. omniverse_mcp-0.2.0/src/omniverse_mcp/__init__.py +0 -0
  81. omniverse_mcp-0.2.0/src/omniverse_mcp/__main__.py +5 -0
  82. omniverse_mcp-0.2.0/src/omniverse_mcp/bridge_token.py +39 -0
  83. omniverse_mcp-0.2.0/src/omniverse_mcp/client.py +619 -0
  84. omniverse_mcp-0.2.0/src/omniverse_mcp/config.py +62 -0
  85. omniverse_mcp-0.2.0/src/omniverse_mcp/kit_extension.py +166 -0
  86. omniverse_mcp-0.2.0/src/omniverse_mcp/py.typed +0 -0
  87. omniverse_mcp-0.2.0/src/omniverse_mcp/server.py +165 -0
  88. omniverse_mcp-0.2.0/src/omniverse_mcp/tools/__init__.py +27 -0
  89. omniverse_mcp-0.2.0/src/omniverse_mcp/tools/_annotations.py +15 -0
  90. omniverse_mcp-0.2.0/src/omniverse_mcp/tools/_bridge.py +30 -0
  91. omniverse_mcp-0.2.0/src/omniverse_mcp/tools/_params.py +12 -0
  92. omniverse_mcp-0.2.0/src/omniverse_mcp/tools/camera.py +293 -0
  93. omniverse_mcp-0.2.0/src/omniverse_mcp/tools/misc.py +121 -0
  94. omniverse_mcp-0.2.0/src/omniverse_mcp/tools/recording.py +95 -0
  95. omniverse_mcp-0.2.0/src/omniverse_mcp/tools/robot.py +108 -0
  96. omniverse_mcp-0.2.0/src/omniverse_mcp/tools/scene.py +212 -0
  97. omniverse_mcp-0.2.0/src/omniverse_mcp/tools/simulation.py +155 -0
  98. omniverse_mcp-0.2.0/src/omniverse_mcp/tools/usd_advanced.py +188 -0
  99. omniverse_mcp-0.2.0/tests/__init__.py +0 -0
  100. omniverse_mcp-0.2.0/tests/conftest.py +41 -0
  101. omniverse_mcp-0.2.0/tests/fixtures/mcp-tools.json +1838 -0
  102. omniverse_mcp-0.2.0/tests/mock_bridge.py +97 -0
  103. omniverse_mcp-0.2.0/tests/test_bounds.py +83 -0
  104. omniverse_mcp-0.2.0/tests/test_bridge_http.py +426 -0
  105. omniverse_mcp-0.2.0/tests/test_bridge_token.py +104 -0
  106. omniverse_mcp-0.2.0/tests/test_client.py +963 -0
  107. omniverse_mcp-0.2.0/tests/test_config.py +77 -0
  108. omniverse_mcp-0.2.0/tests/test_contract.py +112 -0
  109. omniverse_mcp-0.2.0/tests/test_formatter.py +151 -0
  110. omniverse_mcp-0.2.0/tests/test_framing.py +135 -0
  111. omniverse_mcp-0.2.0/tests/test_gate.py +1201 -0
  112. omniverse_mcp-0.2.0/tests/test_integration.py +430 -0
  113. omniverse_mcp-0.2.0/tests/test_isolation.py +190 -0
  114. omniverse_mcp-0.2.0/tests/test_kit_extension.py +187 -0
  115. omniverse_mcp-0.2.0/tests/test_lighting.py +40 -0
  116. omniverse_mcp-0.2.0/tests/test_logs.py +140 -0
  117. omniverse_mcp-0.2.0/tests/test_material.py +47 -0
  118. omniverse_mcp-0.2.0/tests/test_mcp_bridge.py +19 -0
  119. omniverse_mcp-0.2.0/tests/test_png.py +86 -0
  120. omniverse_mcp-0.2.0/tests/test_release.py +163 -0
  121. omniverse_mcp-0.2.0/tests/test_scenarios.py +1329 -0
  122. omniverse_mcp-0.2.0/tests/test_serial.py +79 -0
  123. omniverse_mcp-0.2.0/tests/test_server.py +228 -0
  124. omniverse_mcp-0.2.0/tests/test_tools.py +559 -0
  125. omniverse_mcp-0.2.0/tests/test_tools_camera.py +181 -0
  126. omniverse_mcp-0.2.0/tests/test_usd.py +58 -0
  127. omniverse_mcp-0.2.0/tools/gate.py +925 -0
  128. omniverse_mcp-0.2.0/tools/golden.py +86 -0
  129. omniverse_mcp-0.2.0/tools/hooks.py +190 -0
  130. omniverse_mcp-0.2.0/tools/release.py +160 -0
  131. omniverse_mcp-0.2.0/tools/setup.py +190 -0
@@ -0,0 +1,17 @@
1
+ {
2
+ "name": "omniverse-mcp",
3
+ "owner": {
4
+ "name": "Soma Osvay",
5
+ "url": "https://github.com/serionist"
6
+ },
7
+ "metadata": {
8
+ "description": "The Omniverse MCP plugin for Claude Code."
9
+ },
10
+ "plugins": [
11
+ {
12
+ "name": "omniverse-mcp",
13
+ "source": "./plugin",
14
+ "description": "Drive NVIDIA Omniverse Kit apps (Isaac Sim, USD Composer) from Claude Code: look at the stage, edit it, run physics, drive robots and record what happens."
15
+ }
16
+ ]
17
+ }
@@ -0,0 +1,47 @@
1
+ # Python
2
+ __pycache__/
3
+ *.pyc
4
+ *.pyo
5
+ *.egg-info/
6
+ dist/
7
+ build/
8
+ .eggs/
9
+ *.egg
10
+
11
+ # Virtual environments
12
+ .venv/
13
+ venv/
14
+ env/
15
+
16
+ # MCP output (generated at runtime)
17
+ mcp_output/
18
+
19
+ # Test results (generated during testing)
20
+ .pytest_cache/
21
+ .coverage
22
+ .coverage.*
23
+ htmlcov/
24
+ test_project/results/
25
+
26
+ # IDE
27
+ .idea/
28
+ .vscode/
29
+ *.swp
30
+ *.swo
31
+ *~
32
+
33
+ # OS
34
+ .DS_Store
35
+ Thumbs.db
36
+
37
+ # Local overrides
38
+ test_project/.mcp.json
39
+ test_project/.claude/
40
+
41
+ # Claude Code local state: machine-specific settings and keys.
42
+ .claude/settings.local.json
43
+ .claude/worktrees/
44
+ CLAUDE.local.md
45
+
46
+ # Scratch files the skills write: review packs, issue and PR bodies.
47
+ .local/
@@ -0,0 +1,115 @@
1
+ # Changelog
2
+
3
+ What changed for people who use omniverse-mcp, newest first. A change users notice adds its line under Unreleased in
4
+ the same PR. The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
5
+
6
+ ## Unreleased
7
+
8
+ ## 0.2.0 (2026-10-29)
9
+
10
+ The first release on PyPI: `uvx omniverse-mcp`, or the Claude Code plugin. The breaking changes below concern a clone
11
+ of this repo from before it.
12
+
13
+ ### Security
14
+
15
+ - **The bridge answers only the MCP server that holds its token.** Before this, any program on the machine, and any
16
+ web page open in a browser, could send `/execute` to the extension and run Python inside the Kit app. The extension
17
+ now writes a new random token to a file only your user can read, every request must carry it, and requests from web
18
+ pages are refused.
19
+
20
+ ### Breaking changes
21
+
22
+ - **Update the MCP server and the Kit extension together.** A new server refuses an old extension, and an old server
23
+ gets 401 from a new one. `git pull` in your checkout updates both; then restart Kit and your MCP client.
24
+ - **A remote Kit app needs the token by hand:** set the extension's `token` setting and the server's
25
+ `OMNIVERSE_MCP_TOKEN` to the same value.
26
+ - **`inspect_prim` no longer takes `distance`.** It fits the distance itself; use `zoom_offset` to move closer or
27
+ further.
28
+ - **`viewport_light("get")` reports `lighting_mode`** and the available modes, in place of `camera_light_on`.
29
+ - **The Python package is `omniverse_mcp`.** In `.mcp.json`, `python -m isaac_sim_mcp` becomes the `omniverse-mcp`
30
+ command (or `uv run --no-sync --project <clone> omniverse-mcp`; the README shows both). An install from before
31
+ the rename still points `omniverse-mcp` at the deleted `isaac_sim_mcp`: reinstall it with
32
+ `pip uninstall omniverse-mcp` then `pip install .` (or `pip install -e .`), or switch to `uv sync`.
33
+ - **The Kit extension is `ovmcp.bridge`, in `extension/ovmcp.bridge/`.** It was `isaacsim.mcp.bridge`, in a folder
34
+ named with its version. To move over:
35
+ 1. In Kit's Extension Manager, turn `isaacsim.mcp.bridge` off and its autoload off.
36
+ 2. Remove its search path if it pointed inside `extension/isaacsim.mcp.bridge-1.0.0`; the repo's `extension/` folder
37
+ stays the search path.
38
+ 3. Turn on `ovmcp.bridge` with autoload.
39
+ 4. Move a custom port or token from `exts."isaacsim.mcp.bridge"` to `exts."ovmcp.bridge"`. The
40
+ `scene_tree_max_depth` setting is gone; nothing read it.
41
+ - **The server's flags are `--host` and `--port`,** in place of `--isaac-host` and `--isaac-port`, which now stop
42
+ the server with a message naming the new flag; any other unknown flag is an error too. `--host`, `--port` and
43
+ `--output-dir` default to `OMNIVERSE_MCP_HOST`, `OMNIVERSE_MCP_PORT` and `OMNIVERSE_MCP_OUTPUT_DIR`; an empty
44
+ variable counts as unset.
45
+ - **The MCP resources are `omniverse://scene/tree` and `omniverse://sim/state`,** and the server calls itself
46
+ `omniverse`. Scene dumps and recording state files start with `# Omniverse MCP`, and their `# format` line
47
+ reads `omniverse-mcp-v1`.
48
+ - **Python 3.11 or newer** for the server.
49
+ - **A tool that fails returns an error result, not `ERROR:` text.** The MCP result has `isError` set, with the
50
+ bridge's message and the last lines of its traceback, or why the Kit app couldn't be reached; its text no
51
+ longer starts `ERROR:`. A script that looked for `ERROR:` in a tool's text reads `isError` instead, or it
52
+ takes every failure for a success. A failed resource read is a resource error.
53
+ - **A tool refuses a value out of its range, or not one of its choices,** before it reaches Kit: a width, height,
54
+ count or `fps` below 1; a negative `max_depth`, `frame_index`, mass, density or friction; a distance, duration,
55
+ radius or point size not above 0; a `zoom_offset` of -1 or less; an opacity, roughness, metallic or restitution
56
+ outside 0 to 1; a `max_depth` above 15 in `get_scene_tree`, which used to cut it to 15 quietly. `sim_control`,
57
+ `viewport_light`, `manage_extensions` and `draw_debug` take only their listed actions and shapes, in lower case
58
+ (`"Play"` used to work), and `get_logs` only `verbose`, `info`, `warn`, `error`, `fatal` or `""` as `min_level`,
59
+ where an unknown level used to filter nothing.
60
+ - **`clone_prim` refuses a target path that already holds a prim,** and `create_prim` one that holds a prim of
61
+ another type. Both used to overwrite it: a clone replaced the prim there and its children, and a create turned a
62
+ Cube into an Xform.
63
+
64
+ ### Fixed
65
+
66
+ - **A capture shows the view it was asked for.** Every capture went through one temporary file, which Kit 110
67
+ writes after it reports the capture done, so a capture could return the previous one's image: each of
68
+ `inspect_prim`'s angles showed the angle before it, its first the view from before the call, and `capture_viewport`
69
+ and recording frames could be a step behind too. On Kit apps that wrote the file in time this didn't show.
70
+ - **`set_material`'s colours show.** Its OmniPBR shader named only an id, which some Kit apps don't resolve
71
+ (Isaac Sim 6.2 headless among them): every material rendered as Kit's red error material, while the tool reported
72
+ success. The shader now names its MDL source, `OmniPBR.mdl`, and a material made before this gets it the next time
73
+ `set_material` uses it.
74
+ - **`draw_debug`'s `size` defaults to 0.05, what it draws,** where its schema said 5.0; asking for 5.0 drew 0.05.
75
+ - **`get_logs` names Kit's log levels right, and `min_level` keeps the right ones.** A warning was labelled
76
+ `verbose` and an error `info`, and `min_level="warn"` kept only fatal messages.
77
+
78
+ ### Changed
79
+
80
+ - **The server runs on MCP SDK v2** (`mcp` 2.3.0), and its tools reach Kit one request at a time.
81
+ - **A black capture is no longer relit behind your back.** The bridge used to turn the camera light on and capture
82
+ again; now the capture comes back as it is, with a warning that says how to light the scene (`viewport_light`).
83
+ - **`inspect_prim` refuses what it cannot do instead of guessing:** an unknown angle name (it used to be skipped),
84
+ a non-numeric `width`, `height` or `zoom_offset`, and an orthographic viewport camera, where distance frames
85
+ nothing.
86
+
87
+ ### Added
88
+
89
+ - **A Claude Code plugin,** with this repo as its marketplace: `/plugin marketplace add serionist/omniverse-mcp`,
90
+ then `/plugin install omniverse-mcp@omniverse-mcp`. It starts the server of its release with `uvx`, and brings
91
+ skills: `/omniverse-mcp:setup` installs the Kit extension and checks the connection; `scene`, `geometry`,
92
+ `simulate` and `script` hold the workflows and traps `docs/AI_GUIDE.md` used to. A skill pre-approves read-only
93
+ tools only.
94
+ - **`get_sim_state` reports the Kit extension's release beside the server's,** and when they differ, the command
95
+ that installs the server's extension. A different release on the same bridge protocol works, so nothing else would
96
+ show that Kit still runs the old extension after an update.
97
+ - **`docs/AI_GUIDE.md` is short:** the context every client needs, and links to the skills for the workflows.
98
+ - **`omniverse-mcp extension install`** copies the Kit extension of the server's own release to your user data
99
+ folder, in place of an older one, and prints the folder Kit's extension search paths need; `omniverse-mcp extension
100
+ path` prints it again. When the server and the extension speak different bridge protocols, the server's message
101
+ names the command for its release, `uvx omniverse-mcp==X.Y.Z extension install` (from a checkout,
102
+ `uv run --project <checkout> omniverse-mcp extension install`), and says which side is older.
103
+ - **Each tool says what it does to the Kit app,** as MCP annotations a client may use to ask before it runs one:
104
+ read-only (queries and captures), not destructive (edits), destructive (deletes and overwrites, prims or files), or
105
+ destructive and open world (`execute_script`, `manage_extensions`). `docs/TOOLS.md` lists them. They are hints,
106
+ never security.
107
+ - **Every parameter is described in the tool's schema,** with its range or choices, so a client shows them without
108
+ the docs.
109
+ - **`inspect_prim` frames the prim for you.** The camera stands where the prim's bounding sphere fills the captured
110
+ frame with a small margin; `zoom_offset` moves it closer (`-0.3`) or further (`0.5`). `isolate=True` hides everything
111
+ but the prim while it captures, keeps the scene's lights on, and puts every prim's visibility back exactly as it was;
112
+ what it cannot hide (inside an instance, or with time-sampled visibility) it names in `isolate_warnings`.
113
+ - **`viewport_light(action="set", mode=...)` switches the lighting mode:** `"off"`, `"camera"`, `"stage"`, or a light
114
+ rig such as `"Default"`, the quickest fix for black captures. It returns an error when the mode did not change, for
115
+ example a light rig in a Kit app without the viewport's lighting menu.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Soma Osvay
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,264 @@
1
+ Metadata-Version: 2.5
2
+ Name: omniverse-mcp
3
+ Version: 0.2.0
4
+ Summary: MCP server for AI control of NVIDIA Omniverse applications (Isaac Sim 5.x and up, USD Composer, and more)
5
+ Project-URL: Homepage, https://github.com/serionist/omniverse-mcp
6
+ Project-URL: Repository, https://github.com/serionist/omniverse-mcp
7
+ Project-URL: Documentation, https://github.com/serionist/omniverse-mcp/tree/main/docs
8
+ Project-URL: Issues, https://github.com/serionist/omniverse-mcp/issues
9
+ Author: Soma Osvay
10
+ License-Expression: MIT
11
+ License-File: LICENSE
12
+ Keywords: ai,isaac-sim,mcp,model-context-protocol,nvidia,omniverse,robotics,simulation,usd
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Intended Audience :: Science/Research
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Programming Language :: Python :: 3.14
21
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
22
+ Classifier: Topic :: Scientific/Engineering :: Physics
23
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
24
+ Requires-Python: >=3.11
25
+ Requires-Dist: mcp==2.3.0
26
+ Description-Content-Type: text/markdown
27
+
28
+ <p align="center">
29
+ <img src="https://raw.githubusercontent.com/serionist/omniverse-mcp/main/docs/images/logo.svg" width="96" alt="">
30
+ </p>
31
+
32
+ <h1 align="center">Omniverse MCP</h1>
33
+
34
+ <p align="center">
35
+ Drive NVIDIA Omniverse Kit apps (Isaac Sim, USD Composer) from Claude Code and any MCP client:<br>
36
+ look at the stage, edit it, run physics, drive robots and record what happens.
37
+ </p>
38
+
39
+ <p align="center">
40
+ <a href="https://github.com/serionist/omniverse-mcp/actions/workflows/ci.yml"><img alt="CI" src="https://github.com/serionist/omniverse-mcp/actions/workflows/ci.yml/badge.svg?branch=main"></a>
41
+ <a href="https://github.com/serionist/omniverse-mcp/actions/workflows/codeql.yml"><img alt="CodeQL" src="https://github.com/serionist/omniverse-mcp/actions/workflows/codeql.yml/badge.svg?branch=main"></a>
42
+ <a href="https://github.com/serionist/omniverse-mcp/blob/main/LICENSE"><img alt="Licence: MIT" src="https://img.shields.io/badge/licence-MIT-blue"></a>
43
+ <a href="https://www.python.org/downloads/"><img alt="Python 3.11 | 3.12 | 3.13 | 3.14" src="https://img.shields.io/badge/python-3.11%20%7C%203.12%20%7C%203.13%20%7C%203.14-blue"></a>
44
+ </p>
45
+
46
+ <p align="center">
47
+ <img src="https://raw.githubusercontent.com/serionist/omniverse-mcp/main/docs/images/hero-viewport.jpg" width="49%" alt="A Franka arm on a table with a red, a green and a blue block and a yellow ball, as capture_viewport returns it from Isaac Sim">
48
+ <img src="https://raw.githubusercontent.com/serionist/omniverse-mcp/main/docs/images/hero-segmentation.png" width="49%" alt="The same view's instance segmentation: each link of the arm, the table, each block and the ball in its own colour">
49
+ </p>
50
+ <p align="center">
51
+ <sub>One <code>capture_viewport</code> call in Isaac Sim 6.2: the frame, and every prim in its own colour, with the legend and the
52
+ screen boxes that tell the assistant what it sees.</sub>
53
+ </p>
54
+
55
+ An [MCP](https://modelcontextprotocol.io/) (Model Context Protocol) server that gives AI assistants full control over NVIDIA Omniverse applications -- including **Isaac Sim 5.x and up**, USD Composer, and any Omniverse Kit-based app. Inspect scenes, manipulate objects, control robots, run physics simulations, capture viewports, record sessions, and manage extensions.
56
+
57
+ ```
58
+ AI Assistant <--MCP/stdio--> MCP Server <--HTTP/REST--> Omniverse Extension
59
+ (any MCP client) (Python) (runs inside Kit app)
60
+ ```
61
+
62
+ ## What Can It Do?
63
+
64
+ The tools, by area:
65
+
66
+ | Category | Tools | Description |
67
+ |----------|-------|-------------|
68
+ | **Scene** | `get_scene_tree`, `dump_scene`, `get_prim_properties`, `get_prim_bounds`, `set_prim_transform`, `create_prim`, `delete_prim`, `clone_prim`, `set_visibility`, `save_scene`, `new_scene` | Full scene graph control -- create, query, transform, and manage USD prims |
69
+ | **Geometry & Mesh** | `get_mesh_stats`, `get_prim_face_count_tree`, `compare_prims` | Face/vertex/triangle counts, hierarchical face count trees, compare two prims or variants |
70
+ | **USD Operations** | `flatten_usd`, `export_prim_as_file` | Flatten references into a single file, export prim subtrees as self-contained USD |
71
+ | **Variants** | `create_variant_structure`, `set_variant_selection` | Create variant sets, switch variants with automatic FSD/Hydra handling |
72
+ | **Materials** | `set_material`, `update_material_paths` | Create and bind PBR materials, bulk-fix material binding paths |
73
+ | **Robot** | `create_robot`, `get_robot_info`, `get_joint_states`, `set_joint_targets` | Spawn robots from the asset library (Franka, G1, Spot, etc.), query joints, drive positions |
74
+ | **Camera** | `set_camera`, `look_at_prim`, `inspect_prim`, `capture_viewport`, `viewport_light` | Position cameras, orbit-capture from multiple angles, capture viewport with instance segmentation + screen-space bounding boxes, manage viewport lighting |
75
+ | **Simulation** | `sim_control`, `get_sim_state` | Play/pause/stop/step simulation, query state (time, FPS, up axis) |
76
+ | **Recording** | `start_recording`, `stop_recording`, `get_recording_frame` | Capture simulation frames + prim state over time for analysis |
77
+ | **Physics** | `set_physics_properties`, `apply_force`, `raycast` | Set mass/friction/restitution, apply forces, cast rays for spatial queries |
78
+ | **Debug** | `draw_debug` | Draw lines, spheres, and points in the viewport for visualisation |
79
+ | **Logging** | `get_logs` | Query Omniverse log entries (errors, warnings) for diagnosing tool failures |
80
+ | **Scripting** | `execute_script` | Run Python inside the sim with `mcp` bridge for async MCP handler access |
81
+ | **Extensions** | `manage_extensions` | List, enable, and disable Omniverse extensions |
82
+
83
+ **Key capabilities:**
84
+ - **Scene understanding** -- `capture_viewport` outputs a screenshot, screen-space bounding boxes, and instance segmentation (a unique colour per prim) so the AI knows what it sees
85
+ - **Simulation recording** -- capture frames + prim state during physics, review any frame after
86
+ - **File-based output** -- large scene dumps in grep-friendly text format, images saved as PNGs
87
+ - **Arbitrary scripting** -- run any Python code inside the sim via `execute_script`; also serves as a fallback if any tool fails
88
+ - **10 built-in robots** -- franka, ur10, carter, jetbot, g1, go1, go2, h1, spot, anymal
89
+
90
+ <p align="center">
91
+ <img src="https://raw.githubusercontent.com/serionist/omniverse-mcp/main/docs/images/inspect-orbit.jpg" width="100%" alt="The workcell from four corners, as inspect_prim frames it with everything else hidden">
92
+ </p>
93
+ <p align="center">
94
+ <sub><code>inspect_prim(prim_path="/World/Workcell", angles=[the four top corners], isolate=True)</code>: one call, every side,
95
+ framed to fit, the rest of the stage hidden.</sub>
96
+ </p>
97
+
98
+ ## Install
99
+
100
+ You need a Kit app of Kit 107 or later (Isaac Sim 5.x and up, USD Composer) and [uv](https://docs.astral.sh/uv/getting-started/installation/),
101
+ which runs the server. Two parts: the MCP server your AI client starts, and the Kit extension `ovmcp.bridge` inside
102
+ the Kit app, both from the same release.
103
+
104
+ ### Claude Code: the plugin
105
+
106
+ ```
107
+ /plugin marketplace add serionist/omniverse-mcp
108
+ /plugin install omniverse-mcp@omniverse-mcp
109
+ ```
110
+
111
+ Then run `/omniverse-mcp:setup`: it installs the Kit extension of the plugin's release, walks you through turning it on
112
+ in Kit, and checks the connection. The plugin also brings skills for working on scenes, geometry, simulation and
113
+ scripts, which Claude uses when a request fits ([the plugin](https://github.com/serionist/omniverse-mcp/blob/main/plugin/README.md)).
114
+
115
+ ### Other MCP clients: uvx
116
+
117
+ Add the server to your client's MCP configuration, such as a project's `.mcp.json`:
118
+
119
+ ```json
120
+ {
121
+ "mcpServers": {
122
+ "omniverse": { "command": "uvx", "args": ["omniverse-mcp"] }
123
+ }
124
+ }
125
+ ```
126
+
127
+ Install the extension of the same release and turn it on in Kit (below). `uvx` fetches the newest release the first
128
+ time and keeps it until its cache is refreshed; `uvx omniverse-mcp@latest extension install` fetches the newest server
129
+ and installs its extension. Copy [`docs/AI_GUIDE.md`](https://github.com/serionist/omniverse-mcp/blob/main/docs/AI_GUIDE.md) into
130
+ your client's instruction file (`AGENTS.md`, `.cursorrules`): the context every session needs, with links to the
131
+ skills that hold the workflows and traps; copy the ones your work needs too.
132
+
133
+ ### The Kit extension
134
+
135
+ ```bash
136
+ uvx omniverse-mcp extension install
137
+ ```
138
+
139
+ It copies `ovmcp.bridge` into your user data folder and prints that folder. Then, once, in the Kit app:
140
+
141
+ 1. **Window > Extensions**, the menu (☰) at the top right, **Settings**.
142
+ 2. Under **Extension Search Paths**, the green **+**, then paste the folder it printed. The **+** adds an empty row:
143
+ click it to type.
144
+ 3. Search for `ovmcp` under **THIRD PARTY**, and turn **Omniverse MCP Bridge** on, with **Autoload**.
145
+ 4. Quit with **File > Exit**, which is when Kit saves these settings, and start it again. The console shows
146
+ `[ext: ovmcp.bridge-<version>] startup`.
147
+
148
+ A headless or scripted Kit takes `--ext-folder <that folder> --enable ovmcp.bridge` instead. `omniverse-mcp extension
149
+ path` prints the folder again.
150
+
151
+ > **Updating:** install the extension again after each server update, and restart Kit and your client. On Windows a
152
+ > running Kit holds the folder: quit it first. With the plugin, `/omniverse-mcp:setup` does this.
153
+
154
+ > **Used the extension before?** Before 0.2.0 it came from a clone of this repo, and before that it was
155
+ > `isaacsim.mcp.bridge`. Turn the old one off and remove its search path, so Kit loads one copy. See the
156
+ > [changelog](https://github.com/serionist/omniverse-mcp/blob/main/CHANGELOG.md).
157
+
158
+ ### From a clone
159
+
160
+ For working on omniverse-mcp itself:
161
+
162
+ ```bash
163
+ git clone https://github.com/serionist/omniverse-mcp.git
164
+ cd omniverse-mcp
165
+ uv sync
166
+ ```
167
+
168
+ The client starts the server from the clone, and the Kit extension search path takes the clone's `extension/`
169
+ folder, so a `git pull` updates both (restart Kit and the client after it):
170
+
171
+ ```json
172
+ {
173
+ "mcpServers": {
174
+ "omniverse": { "command": "uv", "args": ["run", "--no-sync", "--project", "<REPO_PATH>", "omniverse-mcp"] }
175
+ }
176
+ }
177
+ ```
178
+
179
+ `--no-sync` starts the server from the environment `uv sync` built, so a client never waits on a download at start,
180
+ and the server still writes its files under your project's `mcp_output/`. [CONTRIBUTING](https://github.com/serionist/omniverse-mcp/blob/main/CONTRIBUTING.md) has the rest.
181
+
182
+ ### Go
183
+
184
+ With the Kit app running, open your AI client in the project and ask: *"What's in the scene right now?"*
185
+
186
+ ## Context7 for scripts
187
+
188
+ Models are not trained on Omniverse and Isaac Sim APIs, and guess their names. With [Context7](https://context7.com)
189
+ as a second MCP server, the assistant looks the API up (library `isaac-sim/isaacsim`) before writing `execute_script`
190
+ code; the server's instructions and the `script` skill ask it to.
191
+
192
+ ## Examples
193
+
194
+ > "Create a table with a red cube on top of it, and point a spotlight at it."
195
+
196
+ > "Spawn a Franka arm at the origin, then move its joints to a pick-ready pose."
197
+
198
+ > "Start recording, play the sim for 3 seconds, then show me what happened to the robot."
199
+
200
+ > "Move the apple so it's sitting on top of the desk. Use bounding boxes to compute the correct position."
201
+
202
+ > "Inspect the G1 robot from all angles so I can see its current pose."
203
+
204
+ ## Configuration
205
+
206
+ ### The server
207
+
208
+ ```
209
+ omniverse-mcp [--host HOST] [--port PORT] [--output-dir DIR] the MCP server, over stdio
210
+ omniverse-mcp extension install install the Kit extension of this release
211
+ omniverse-mcp extension path print the folder Kit's search paths need
212
+
213
+ --host Kit extension host (default: OMNIVERSE_MCP_HOST, else 127.0.0.1)
214
+ --port Kit extension port (default: OMNIVERSE_MCP_PORT, else 8211)
215
+ --output-dir Directory for file outputs (default: OMNIVERSE_MCP_OUTPUT_DIR, else ./mcp_output/)
216
+ ```
217
+
218
+ The plugin's server takes the same variables from the environment Claude Code starts in.
219
+
220
+ ### The extension's settings
221
+
222
+ Kit settings, in the extension's `config/extension.toml` or on Kit's command line (`--/exts/ovmcp.bridge/port=8212`):
223
+ ```toml
224
+ [settings]
225
+ exts."ovmcp.bridge".host = "127.0.0.1"
226
+ exts."ovmcp.bridge".port = 8211
227
+ exts."ovmcp.bridge".token = ""
228
+ ```
229
+
230
+ ### The bridge token
231
+
232
+ The extension runs any Python the MCP server sends, so it answers only a server that holds its token. At every start
233
+ it writes a new token to a file only your user can read, and the MCP server on the same machine picks it up: nothing
234
+ to set up. Requests from web pages are refused. See [Architecture](https://github.com/serionist/omniverse-mcp/blob/main/docs/ARCHITECTURE.md#the-bridge-token) for where the
235
+ file lives.
236
+
237
+ For a remote setup, set the extension's `token` to a long random value and give the MCP server the same value in the
238
+ `OMNIVERSE_MCP_TOKEN` environment variable. Anyone with the token can run code in your Kit app.
239
+
240
+ ## Troubleshooting
241
+
242
+ **"Missing or wrong bridge token"** -- Is Kit running the extension on this machine, as your user? If Kit runs as another user, in a container or on another machine, use the `token` setting and `OMNIVERSE_MCP_TOKEN` (above).
243
+
244
+ **"The Kit extension is older than this MCP server", or "speaks bridge protocol"** -- The server and the extension come from different releases. Run the command the message names (or `git pull` in a clone), then restart Kit so it loads the new extension.
245
+
246
+ **"Kit app connection failed", refused or timed out** -- Is the Kit app running, with the extension on? Its console shows `[ext: ovmcp.bridge-<version>] startup`. The server looks for it on port 8211 unless `OMNIVERSE_MCP_PORT` or `--port` says otherwise.
247
+
248
+ **The plugin's server doesn't start** -- `/mcp` in Claude Code shows its error. Is `uv` on the PATH Claude Code starts with?
249
+
250
+ **Viewport capture returns black** -- The response includes a WARNING with the lighting mode. Use `viewport_light("get")` to see the mode and whether the scene has lights, then `viewport_light(action="set", mode="Default")` for a light rig, or `mode="camera"` for a light that follows the camera, and recapture. Kit 105.1+ has no default stage light, so scenes without explicitly added lights will render black.
251
+
252
+ **Tools return errors** -- Check the Omniverse console for tracebacks. Some tools need the sim to have played once (`get_joint_states`, `raycast`). Robot tools require Isaac Sim specifically.
253
+
254
+ ## Documentation
255
+
256
+ - [Tool Reference](https://github.com/serionist/omniverse-mcp/blob/main/docs/TOOLS.md) -- Every tool, with its parameters, hints and examples
257
+ - [Architecture](https://github.com/serionist/omniverse-mcp/blob/main/docs/ARCHITECTURE.md) -- How the two-process bridge works
258
+ - [The plugin](https://github.com/serionist/omniverse-mcp/blob/main/plugin/README.md) -- What the Claude Code plugin brings, and its skills
259
+ - [AI Assistant Guide](https://github.com/serionist/omniverse-mcp/blob/main/docs/AI_GUIDE.md) -- For other clients' instruction files
260
+ - [Contributing](https://github.com/serionist/omniverse-mcp/blob/main/CONTRIBUTING.md) -- How to contribute
261
+
262
+ ## Licence
263
+
264
+ [MIT](https://github.com/serionist/omniverse-mcp/blob/main/LICENSE). Not affiliated with or endorsed by NVIDIA; Omniverse and Isaac Sim are NVIDIA's trademarks.