MCP Unity exposes Unity Editor capabilities to MCP-enabled clients by running:
- Unity-side “client” (C# Editor scripts): a WebSocket server inside the Unity Editor that executes tools/resources.
- Node-side “server” (TypeScript): an MCP stdio server that registers MCP tools/resources and forwards requests to Unity over WebSocket.
- MCP client ⇄ (stdio / MCP SDK) ⇄ Node server (
Server~/src/index.ts) - Node server ⇄ (WebSocket JSON-RPC-ish) ⇄ Unity Editor (
Editor/UnityBridge/McpUnityServer.cs+McpUnitySocketHandler.cs) - Tool/Resource names must match exactly across Node and Unity (typically
lower_snake_case).
- Unity WebSocket endpoint:
ws://localhost:8090/McpUnityby default. - Config file:
ProjectSettings/McpUnitySettings.json(written/read by Unity; read opportunistically by Node). - Authentication token:
Library/McpUnity/bridge-token(256-bit hex secret; never commit or copy into project settings). - Handshake security: clients authenticate as
mcp-unity:<token>with HTTP Basic and must omitOrigin; every supplied Origin is rejected. - Execution thread: Tool/resource execution is dispatched via
EditorCoroutineUtilityand runs on the Unity main thread. Keep synchronous work short; use async patterns for long work.
/
├── Editor/ # Unity Editor package code (C#)
│ ├── Tools/ # Tools (inherit McpToolBase)
│ ├── Resources/ # Resources (inherit McpResourceBase)
│ ├── UnityBridge/ # WebSocket server + message routing
│ ├── Services/ # Test/log services used by tools/resources
│ └── Utils/ # Shared helpers (config, logging, workspace integration)
├── Server~/ # Node MCP server (TypeScript, ESM)
│ ├── src/index.ts # Registers tools/resources/prompts with MCP SDK
│ ├── src/tools/ # MCP tool definitions (zod schema + handler)
│ ├── src/resources/ # MCP resource definitions
│ └── src/unity/mcpUnity.ts # WebSocket client that talks to Unity
-
Unity side
- Open the Unity project that has this package installed.
- Ensure the server is running (auto-start is controlled by
McpUnitySettings.AutoStartServer). - Settings persist in
ProjectSettings/McpUnitySettings.json.
-
Node side (build)
cd Server~ && npm run build- The MCP entrypoint is
Server~/build/index.js(published as an MCP stdio server).
-
Node side (debug/inspect)
cd Server~ && npm run inspectorto use the MCP Inspector.
The Unity settings file is the shared contract:
- Path:
ProjectSettings/McpUnitySettings.json - Fields
- Port (default 8090): Unity WebSocket server port.
- RequestTimeoutSeconds (default 10): Node request timeout.
- AllowBatchModeServer (default false): permits a persistent MCP host in Unity
-batchmode; package installation remains disabled in batch mode. - AllowRemoteConnections (default false): Unity binds to
0.0.0.0when enabled; otherwiselocalhost. - AllowPackageInstallation (default false): permits
add_package; keep disabled unless both client and package source are trusted. - EnableInfoLogs: Unity console logging verbosity.
- NpmExecutablePath: optional npm path for Unity-driven install/build.
Node resolves bridge configuration in this order:
- explicit environment values:
UNITY_PORT,UNITY_HOST,UNITY_REQUEST_TIMEOUT; MCP_UNITY_SETTINGS_PATHwhen set;ProjectSettings/McpUnitySettings.jsondiscovered above the installed Node module, then above the current working directory.
Node resolves authentication separately and fails closed in this order:
MCP_UNITY_AUTH_TOKEN;- the file named by
MCP_UNITY_AUTH_TOKEN_PATH; Library/McpUnity/bridge-tokenbeside the discovered Unity project.
An explicitly configured missing, empty, or malformed token never falls back. Generated client configs set both MCP_UNITY_SETTINGS_PATH and MCP_UNITY_AUTH_TOKEN_PATH.
If no valid setting is found, Node falls back to:
- host:
localhost - port:
8090 - timeout:
10s
Remote connection note:
- If Unity is on another machine, set
AllowRemoteConnections=truein Unity and setUNITY_HOST=<unity_machine_ip_or_hostname>for the Node process. - Remote transport is plaintext
ws://; restrict it to a trusted network, VPN, or SSH tunnel. UseMCP_UNITY_AUTH_TOKENwhen the remote bridge cannot read the project token file.
Persistent headless host note:
- Batch mode is disabled by default. Enable
AllowBatchModeServeror launch Unity withMCP_UNITY_ALLOW_BATCH_MODE=truefor a long-lived headless MCP host; npm installation/build remains skipped in batch mode.
-
Unity (C#)
- Add
Editor/Tools/<YourTool>Tool.csinheritingMcpToolBase. - Set
Nameto the MCP tool name (recommended:lower_snake_case). - Implement:
Execute(JObject parameters)for synchronous work, or- set
IsAsync = trueand implementExecuteAsync(JObject parameters, TaskCompletionSource<JObject> tcs)for long-running operations.
- Register it in
Editor/UnityBridge/McpUnityServer.cs(RegisterTools()).
- Add
-
Node (TypeScript)
- Add
Server~/src/tools/<yourTool>Tool.ts. - Register the tool in
Server~/src/index.ts. - Use a zod schema for params; forward to Unity using the same
methodstring:mcpUnity.sendRequest({ method: toolName, params: {...} })
- Add
-
Build
cd Server~ && npm run build
-
Unity (C#)
- Add
Editor/Resources/<YourResource>Resource.csinheritingMcpResourceBase. - Set
Name(method string) andUri(e.g.unity://...). - Implement
Fetch(...)orFetchAsync(...). - Register in
Editor/UnityBridge/McpUnityServer.cs(RegisterResources()).
- Add
-
Node (TypeScript)
- Add
Server~/src/resources/<yourResource>.ts, register inServer~/src/index.ts. - Forward to Unity via
mcpUnity.sendRequest({ method: resourceName, params: {} }).
- Add
-
Unity
- Uses
McpUnity.Utils.McpLogger(info logs gated byEnableInfoLogs). - Connection lifecycle is managed in
Editor/UnityBridge/McpUnityServer.cs(domain reload & playmode transitions stop/restart the server).
- Uses
-
Node
- Logging is controlled by env vars:
LOGGING=trueenables console logging.LOGGING_FILE=truewriteslog.txtin the Node process working directory.
- Logging is controlled by env vars:
- Port mismatch: Unity default is 8090; update docs/config if you change it.
- Name mismatch: Node
toolName/resourceNamemust equal UnityNameexactly, or Unity respondsunknown_method. - Long main-thread work: synchronous
Execute()blocks the Unity editor; use async patterns for heavy operations. - Remote connections: Unity must bind
0.0.0.0(AllowRemoteConnections=true) and Node must target the correct host (UNITY_HOST). - Unity domain reload: the server stops during script reloads and may restart; avoid relying on persistent in-memory state across reloads.
- Multiplayer Play Mode: Clone instances automatically skip server startup; only the main editor hosts the MCP server.
- Schema compatibility across clients: avoid reusing the same nested Zod object instance for multiple sibling fields (for example
position,rotation,scale). Some MCP clients fail on local refs like#/properties/position; prefer creating a fresh nested schema per field.
- Update versions consistently:
- Unity package
package.json(version) - Node server
Server~/package.json(version) - Node lockfile, MCP protocol metadata, dashboard metadata, and
McpUnitySettings.ServerVersion
- Unity package
- Rebuild Node output:
cd Server~ && npm run build
execute_menu_item— Execute Unity menu itemsselect_gameobject— Select GameObjects in hierarchyupdate_gameobject— Update or create GameObject propertiesupdate_component— Update or add components on GameObjectsadd_package— Install packages via Package Manager (disabled by default; requiresAllowPackageInstallation=true)run_tests— Run Unity Test Runner testssend_console_log— Send logs to Unity consoleadd_asset_to_scene— Add assets to scenecreate_prefab— Create prefabs with optional scriptscreate_scene— Create and save new scenesload_scene— Load scenes (single or additive)delete_scene— Delete scenes and remove from Build Settingssave_scene— Save current scene (with optional Save As)get_scene_info— Get active scene info and loaded scenes listget_play_mode_status— Get Unity play mode status (isPlaying, isPaused)set_play_mode_status— Control Unity play mode (play, pause, stop, step)unload_scene— Unload scene from hierarchyget_gameobject— Get detailed GameObject infoget_console_logs— Retrieve Unity console logsrecompile_scripts— Recompile all project scriptsduplicate_gameobject— Duplicate GameObjects with optional rename/reparentdelete_gameobject— Delete GameObjects from scenereparent_gameobject— Change GameObject parent in hierarchycreate_material— Create materials with specified shaderassign_material— Assign materials to Renderer componentsmodify_material— Modify material properties (colors, floats, textures)get_material_info— Get material details including all properties
show_unity_dashboard— Open the Unity dashboard MCP App in VS Code
unity://menu-items— List of available menu itemsunity://scenes-hierarchy— Current scene hierarchyunity://gameobject/{id}— GameObject details by ID or pathunity://logs— Unity console logsunity://packages— Installed and available packagesunity://assets— Asset database informationunity://tests/{testMode}— Test Runner test informationui://unity-dashboard— Unity dashboard MCP App UI
unity_dashboard— Opens Unity dashboard MCP app with guided information about featuresgameobject_handling_strategy— Provides structured workflow for GameObject operations
- Update this file when:
- tools/resources/prompts are added/removed/renamed,
- config shape or default ports/paths change,
- the bridge protocol changes (request/response contract).
- Keep it high-signal: where to edit code, how to run/build/debug, and the invariants that prevent subtle breakage.
AGENTS.mdis the single source of project guidance. Its siblingCLAUDE.mdmust contain the exact bytes@AGENTS.md\n; never duplicate these rules there.- If project skills are added, keep their content only in
.agents/skills/<skill>/and expose each to Claude Code through a relative.claude/skills/<skill>symlink targeting../../.agents/skills/<skill>. Never use copied content or absolute links, so clones and worktrees remain self-contained.