Unity MCP Server for OTT-Labs components
  • C# 98.5%
  • Python 1.5%
Find a file
Cyrus Otter 313f07bb48
All checks were successful
Release / release (push) Successful in 5s
Release v1.8.0: asset/scene-view/physics tools + kill_import_workers (192 tools)
- assets/size_report, assets/set_labels, assets/apply_preset
- scene_view/get + scene_view/set (aim the Scene view camera for screenshots)
- physics/settle (edit-mode global physics settle with Undo)
- vrchat/setup_layers
- editor/kill_import_workers: shut down AssetImportWorker child processes
  whose hidden container windows turn into white not-responding ghost
  windows; graceful ForceToDesiredWorkerCount first, then kill, parent-PID
  scoped to this editor instance
- terrain: lean default detail/alpha/base map resolutions; drop
  Undo.RecordObject on TerrainData (froze the editor serializing all maps)
- bridge: send tools/list_changed so hosts pick up new tools without restart
2026-07-30 08:15:36 +02:00
.forgejo/workflows ci: fix VPM listing update aborting on the dirty package.json 2026-07-08 21:08:37 +02:00
bridge Release v1.8.0: asset/scene-view/physics tools + kill_import_workers (192 tools) 2026-07-30 08:15:36 +02:00
docs Release v1.8.0: asset/scene-view/physics tools + kill_import_workers (192 tools) 2026-07-30 08:15:36 +02:00
.gitignore OTTLabs MCP Server v1.4.0 2026-06-12 16:35:45 +02:00
CLAUDE.md Release v1.8.0: asset/scene-view/physics tools + kill_import_workers (192 tools) 2026-07-30 08:15:36 +02:00
LICENSE Add MIT LICENSE file and refresh README 2026-06-12 21:05:49 +02:00
OttLabs.OTTLabsMCP.Editor.asmdef OTTLabs MCP Server v1.4.0 2026-06-12 16:35:45 +02:00
OttLabs.OTTLabsMCP.Editor.asmdef.meta OTTLabs MCP Server v1.4.0 2026-06-12 16:35:45 +02:00
OTTLabsMCPAnimationHandlers.cs Minimal-file-access + feature-area audit waves: 119 -> 178 tools 2026-07-25 16:09:15 +02:00
OTTLabsMCPAnimationHandlers.cs.meta Minimal-file-access + feature-area audit waves: 119 -> 178 tools 2026-07-25 16:09:15 +02:00
OTTLabsMCPAssetHandlers.cs Release v1.8.0: asset/scene-view/physics tools + kill_import_workers (192 tools) 2026-07-30 08:15:36 +02:00
OTTLabsMCPAssetHandlers.cs.meta Minimal-file-access + feature-area audit waves: 119 -> 178 tools 2026-07-25 16:09:15 +02:00
OTTLabsMCPAvatarOptHandlers.cs OTTLabs MCP Server v1.4.0 2026-06-12 16:35:45 +02:00
OTTLabsMCPAvatarOptHandlers.cs.meta OTTLabs MCP Server v1.4.0 2026-06-12 16:35:45 +02:00
OTTLabsMCPEditorOpsHandlers.cs Release v1.8.0: asset/scene-view/physics tools + kill_import_workers (192 tools) 2026-07-30 08:15:36 +02:00
OTTLabsMCPEditorOpsHandlers.cs.meta Minimal-file-access + feature-area audit waves: 119 -> 178 tools 2026-07-25 16:09:15 +02:00
OTTLabsMCPEvalHandlers.cs Minimal-file-access + feature-area audit waves: 119 -> 178 tools 2026-07-25 16:09:15 +02:00
OTTLabsMCPEvalHandlers.cs.meta OTTLabs MCP Server v1.4.0 2026-06-12 16:35:45 +02:00
OTTLabsMCPHandlers.cs Release v1.8.0: asset/scene-view/physics tools + kill_import_workers (192 tools) 2026-07-30 08:15:36 +02:00
OTTLabsMCPHandlers.cs.meta OTTLabs MCP Server v1.4.0 2026-06-12 16:35:45 +02:00
OTTLabsMCPMeshHandlers.cs OTTLabs MCP Server v1.4.0 2026-06-12 16:35:45 +02:00
OTTLabsMCPMeshHandlers.cs.meta OTTLabs MCP Server v1.4.0 2026-06-12 16:35:45 +02:00
OTTLabsMCPOTTHandlers.cs Minimal-file-access + feature-area audit waves: 119 -> 178 tools 2026-07-25 16:09:15 +02:00
OTTLabsMCPOTTHandlers.cs.meta OTTLabs MCP Server v1.4.0 2026-06-12 16:35:45 +02:00
OTTLabsMCPPrefabHandlers.cs Minimal-file-access + feature-area audit waves: 119 -> 178 tools 2026-07-25 16:09:15 +02:00
OTTLabsMCPPrefabHandlers.cs.meta Minimal-file-access + feature-area audit waves: 119 -> 178 tools 2026-07-25 16:09:15 +02:00
OTTLabsMCPServer.cs Release v1.7.0: agent-ergonomics batch (184 tools) 2026-07-25 16:39:22 +02:00
OTTLabsMCPServer.cs.meta OTTLabs MCP Server v1.4.0 2026-06-12 16:35:45 +02:00
OTTLabsMCPSettings.cs OTTLabs MCP Server v1.4.0 2026-06-12 16:35:45 +02:00
OTTLabsMCPSettings.cs.meta OTTLabs MCP Server v1.4.0 2026-06-12 16:35:45 +02:00
OTTLabsMCPSettingsProvider.cs OTTLabs MCP Server v1.4.0 2026-06-12 16:35:45 +02:00
OTTLabsMCPSettingsProvider.cs.meta OTTLabs MCP Server v1.4.0 2026-06-12 16:35:45 +02:00
OTTLabsMCPTerrainHandlers.cs Release v1.8.0: asset/scene-view/physics tools + kill_import_workers (192 tools) 2026-07-30 08:15:36 +02:00
OTTLabsMCPTerrainHandlers.cs.meta OTTLabs MCP Server v1.4.0 2026-06-12 16:35:45 +02:00
OTTLabsMCPTextureHandlers.cs Minimal-file-access + feature-area audit waves: 119 -> 178 tools 2026-07-25 16:09:15 +02:00
OTTLabsMCPTextureHandlers.cs.meta OTTLabs MCP Server v1.4.0 2026-06-12 16:35:45 +02:00
OTTLabsMCPToolsRegistry.cs Release v1.8.0: asset/scene-view/physics tools + kill_import_workers (192 tools) 2026-07-30 08:15:36 +02:00
OTTLabsMCPValueConverter.cs Minimal-file-access + feature-area audit waves: 119 -> 178 tools 2026-07-25 16:09:15 +02:00
OTTLabsMCPValueConverter.cs.meta OTTLabs MCP Server v1.4.0 2026-06-12 16:35:45 +02:00
OTTLabsMCPVRCFuryHandlers.cs Minimal-file-access + feature-area audit waves: 119 -> 178 tools 2026-07-25 16:09:15 +02:00
OTTLabsMCPVRCFuryHandlers.cs.meta OTTLabs MCP Server v1.4.0 2026-06-12 16:35:45 +02:00
OTTLabsMCPWindowHandlers.cs OTTLabs MCP Server v1.4.0 2026-06-12 16:35:45 +02:00
OTTLabsMCPWindowHandlers.cs.meta OTTLabs MCP Server v1.4.0 2026-06-12 16:35:45 +02:00
package.json Release v1.8.0: asset/scene-view/physics tools + kill_import_workers (192 tools) 2026-07-30 08:15:36 +02:00
README.md Release v1.8.0: asset/scene-view/physics tools + kill_import_workers (192 tools) 2026-07-30 08:15:36 +02:00

OTTLabs MCP Server

Gives any MCP-compatible AI assistant (Claude Code, Cursor, etc.) direct access to the Unity Editor. The assistant can inspect the scene hierarchy, move objects, create materials, bake lighting, manage VRCFury components, and much more -- all without leaving the chat.

How it works

AI assistant  <--- MCP (stdio) ---->  Python bridge  <--- HTTP/JSON ---->  Unity Editor
(Claude Code)                        bridge/unity_bridge.py              this package
  1. Unity Editor runs an HTTP server on a per-project port (a sticky random port in the 20000-60000 range, chosen once and kept for that project). The server only runs in the interactive editor process — batch-mode processes (AssetImportWorkers, CI) never bind a port or touch the port file.
  2. Python bridge (bridge/unity_bridge.py) is a tiny MCP server that reads the port file and forwards tool calls.
  3. AI assistant talks to the bridge over stdio using the standard MCP protocol.

The port (and a few other options) are configurable under Project Settings → OTT Labs → MCP Server.


Installation

Step 1 -- Install the Unity package

Via VCC / VPM (recommended for VRChat projects): add the OT&T Labs repository to the VRChat Creator Companion (or ALCOM), then add OTTLabs MCP Server to your project:

https://ott-labs.pages.ott-labs.de/vpm/index.json

Via Unity Package Manager: use Add package from git URL:

https://git.ott-labs.de/OTT-Labs/OTTLabsMCP.git

Or add it manually to Packages/manifest.json:

{
  "dependencies": {
    "de.ott-labs.ottlabs-mcp": "https://git.ott-labs.de/OTT-Labs/OTTLabsMCP.git"
  }
}

Open or restart the Unity Editor. The server starts automatically and logs its port:

[OTTLabsMCP] Listening on http://localhost:41485/

(The port is per-project — see Configuration.)

Use OTT Labs -> OTTLabs MCP -> Server Status to confirm it is running.

Step 2 -- Install the Python bridge

Requires Python 3.11+.

# with pip
pip install mcp httpx

# or with uv (recommended)
uv pip install mcp httpx

Step 3 -- Configure your MCP client

Claude Code

Register the bridge with the claude mcp CLI:

claude mcp add unity --env UNITY_PROJECT_PATH=/absolute/path/to/your/unity/project \
  -- python /absolute/path/to/OTTLabsMCP/bridge/unity_bridge.py

Or create a .mcp.json at the root of the workspace you run Claude Code from:

{
  "mcpServers": {
    "unity": {
      "command": "python",
      "args": ["/absolute/path/to/OTTLabsMCP/bridge/unity_bridge.py"],
      "env": {
        "UNITY_PROJECT_PATH": "/absolute/path/to/your/unity/project"
      }
    }
  }
}

Replace both paths with the real absolute paths on your machine.

Other MCP clients

Configure a stdio MCP server with:

  • Command: python /path/to/bridge/unity_bridge.py
  • Environment: UNITY_PROJECT_PATH=/path/to/your/unity/project

Verification

With Unity running and the bridge configured, ask Claude Code:

"Show me the scene hierarchy."

Claude will call the scene_hierarchy tool and return the full tree.


Environment variables

Variable Required Description
UNITY_PROJECT_PATH Yes Absolute path to the Unity project root. The bridge reads Temp/OTTLabsMCPPort.txt from here.

Configuration

Open Project Settings → OTT Labs → MCP Server (or edit ProjectSettings/OTTLabsMCP.json directly):

Option Default Description
Port random 20000-60000, sticky TCP port for this project. Chosen once on first run and reused every session. Use Randomize to pick a new one. If the port is busy the server scans upward a few and warns.
Auto-start true Start the server automatically when the editor loads.
Loopback only true Bind localhost/127.0.0.1 only (recommended).
Require auth token false Generate a per-session bearer token and require it on every request.
Allow C# eval false Allow the editor_eval endpoint to compile and run one-shot C# snippets (via the editor's bundled compiler). editor_invoke_static is always available.
Verbose logging false Log every handled request path to the Console.

ProjectSettings/OTTLabsMCP.json is machine-local — add it to your project's .gitignore so two checkouts on one machine don't fight over the same port.

Security

The server only binds to localhost and never accepts remote connections (unless you explicitly turn off Loopback only).

When Require auth token is enabled, a fresh random token is generated each time the server starts and written alongside the port to Temp/OTTLabsMCPPort.txt as {port}:{token}. The bridge reads it automatically and sends it as an Authorization: Bearer <token> header; requests without a valid token receive a 401. The discovery endpoints (/openapi.json, /swagger, /editor/ping) stay reachable without a token. The token rotates on every restart, so restart the bridge (restart your MCP client) after toggling auth or restarting Unity.

OpenAPI / Swagger

The same tool catalogue is exposed as an OpenAPI 3.0 document for REST/Swagger clients:

  • GET http://localhost:<port>/openapi.json — the spec
  • GET http://localhost:<port>/swagger — a browsable Swagger UI page

Every endpoint is a POST with a JSON body and returns the standard {success, result} / {success, error} envelope.


Troubleshooting

Bridge says "OTTLabs MCP server not found"

  • Make sure the Unity Editor is open.
  • Check that the OTTLabs MCP package is installed (Package Manager -> In Project).
  • Confirm UNITY_PROJECT_PATH points to the correct project folder.
  • Look in Temp/OTTLabsMCPPort.txt -- it should contain a port:token pair.

"Unauthorized" errors

  • The token rotates on every Unity restart. Restart the bridge (restart Claude Code / your MCP client) so it re-reads the port file.

Port binding failed in Unity

  • Check the Unity Console for [OTTLabsMCP] log lines.
  • Use OTT Labs -> OTTLabs MCP -> Restart Server to retry.

Long operations time out (lighting bake, VRC build)

  • The default HTTP timeout in the bridge is 90 seconds. These operations can take longer. Use the cancel endpoint (lighting_bake_cancel) to abort, or increase timeout in _post() inside unity_bridge.py.

Tool calls fail right after a recompile

  • A domain reload tears the HTTP listener down for a few seconds. The bridge keeps the last-known tool registry and transparently retries connection-refused for up to 30 s; if the editor is still restarting it returns a structured {"retryable": true, "error": "editor restarting..."} response — just retry the call.

New tools after a package upgrade don't appear

  • The bridge polls Unity's registry every ~10 s and emits the MCP tools/list_changed notification when the tool set changes, so hosts that honor it (Claude Code does) pick up new tools without a restart. If your host ignores the notification, restart it once.

Available tools

Tools are discovered dynamically from Unity via tools/list -- no hard-coding in the bridge. The full list is always up-to-date with the installed package version.

Category Tools
Meta tools_list, openapi
Scene query scene_hierarchy (subtree + depth params), scene_object, scene_find, scene_info
Scene files scene_open, scene_save_as, scene_close, scene_list_loaded, scene_set_active (object paths resolve across all loaded scenes)
Prefabs prefab_get, prefab_create, prefab_overrides, prefab_apply_overrides, prefab_revert_overrides, prefab_unpack
Scene modify scene_create, scene_delete, scene_set_transform, scene_set_field, scene_set_field_reference, component_set_serialized_property, component_get_serialized_property, scene_add_component, scene_remove_component, scene_instantiate, scene_reparent, scene_rename, scene_invoke_method, component_copy, scene_set_static_flags, scene_find_missing_scripts, scene_find_missing_references, scene_find_asset_usage
Udon udon_add_behaviour (UdonSharp-aware, no focus dance)
Settings settings_get, settings_set (tags/layers, physics, quality, graphics, player, ...)
Animation animator_get, animator_create, animator_add_layer, animator_add_parameter, animator_remove_parameter, animator_add_state, animator_set_state, animator_remove_state, animator_add_transition, animator_add_blend_tree, animation_get, animation_create, animation_set_curve
Meta ops batch (up to 100 calls per round trip), packages_list
Assets assets_list, assets_find (name/type/label), assets_create_material, asset_read_material, assets_move, assets_rename, assets_delete, assets_duplicate, assets_create_folder, assets_guid_lookup, assets_dependencies, assets_references, assets_create_instance, asset_get_object, asset_get_importer, asset_set_importer, assets_size_report, assets_set_labels, assets_apply_preset
Materials renderer_materials, renderer_validate, renderer_blendshapes, renderer_set_blendshape, material_poiyomi_status, material_set_locked, shader_get, asset_set_material, texture_export
Editor editor_save, editor_refresh, editor_select, editor_get_selection, editor_ping, editor_play_start, editor_play_stop (both with wait), editor_play_status, editor_logs, editor_logs_clear, editor_wait_for_log, editor_recompile, editor_compile_status, editor_wait_idle, editor_invoke_static, editor_eval, editor_reflect, editor_screenshot, editor_undo, editor_redo, editor_undo_snapshot, editor_undo_revert_to, editor_undo_collapse, editor_stats, editor_focus, scene_view_get, scene_view_set, physics_settle
Windows editor_window_open, editor_window_close, editor_window_list, editor_execute_menu, ott_window_list, ott_window_open
Lighting lighting_get, lighting_set, lighting_bake, lighting_bake_cancel, lighting_clear
Occlusion occlusion_bake, occlusion_cancel, occlusion_clear, occlusion_status
VRChat SDK vrchat_info, vrchat_validate, vrchat_descriptor_get, vrchat_descriptor_set, vrchat_setup_layers
Build build_settings, build_switch_platform
Avatar avatar_strip_unused_bones, avatar_build_test_copy, avatar_perf_report
Texture texture_create (6 generation modes)
Mesh mesh_create (5 modes), mesh_get, mesh_modify
Terrain terrain_create, terrain_get, terrain_resize, terrain_set_heights, terrain_apply_craters, terrain_add_layer, terrain_to_mesh, terrain_bake_height_texture
VRCFury vrcfury_list, vrcfury_get, vrcfury_list_feature_types, vrcfury_add_toggle, vrcfury_add_feature, vrcfury_remove, vrcfury_set_field, vrcfury_add_object_action, vrcfury_add_blendshape_action
OT&T MQTT ott_mqtt_manager_status/inject/refresh, ott_mqtt_driver_status/connect/disconnect/publish/fault
OT&T VR Phone ott_vrphone_* (22 tools for layout editing, atlas baking, canvas build)
OT&T ScribanGen ott_scriban_generate_all, ott_scriban_generate_asset, ott_scriban_list_bindings

Note: This package deliberately does not include VRChat build or upload automation. Automating SDK builds/uploads violates the VRChat Terms of Service, so no such tools have been added. Building and uploading worlds or avatars must be done manually through the VRChat SDK control panel.


License

MIT -- see LICENSE.