loading…
Search for a command to run...
loading…
A runtime inspection and automation toolkit that enables MCP clients to interact with live Unity game sessions through a dedicated bridge plugin. It allows user
A runtime inspection and automation toolkit that enables MCP clients to interact with live Unity game sessions through a dedicated bridge plugin. It allows users to browse scene hierarchies, inspect component fields, search text elements, and modify game object properties in real-time.
English | 한국어
Unity runtime inspection toolkit for MCP-based automation.
This repository contains two parts:
UnityInfoMCP: an external Python MCP serverUnityInfoBridge: an in-game Unity plugin that exposes runtime data over local JSON-RPCThe split is intentional:
This is the part that matters most in practice:
http://127.0.0.1:16000/mcp127.0.0.1:16001~16100These are different connections.
--transport streamable-http uses the HTTP endpoint above--transport stdio switches the client-facing transport to stdio--port only applies to --transport streamable-httpUNITY_INFO_BRIDGE_PORT is only a legacy fallback for bridge connection attempts16001~1610016000 is the UnityInfoMCP HTTP port. The in-game UnityInfoBridge plugin itself binds the first free port in 16001~16100.There are also two separate transport layers:
UnityInfoMCP: Streamable HTTP or stdioUnityInfoMCP -> UnityInfoBridge: TCPUnityInfoMCP
The Python MCP packageUnityInfoBridge
The Unity plugin projectUnityInfoBridge/includes
Reference DLLs used to build the bridgedocs
Bridge protocol and tool mapping documentsUnityInfoBridge currently targets:
BepInEx BE #754+ MonoBepInEx BE #754+ IL2CPPMelonLoader 0.7.2 MonoMelonLoader 0.7.2 IL2CPPCreate and activate a virtual environment:
python -m venv .venv
. .venv/Scripts/activate
pip install -e .
For PyInstaller or release builds, install the build extra instead:
pip install -e ".[build]"
Run the MCP server on the default transport and port:
unity-info-mcp
That starts the Streamable HTTP transport on 127.0.0.1:16000 and exposes /mcp.
If the unity-info-mcp command is not found on Windows, use:
python -m UnityInfoMCP
That usually means Python's user Scripts directory is not on PATH.
In this environment, the generated launcher is installed at:
C:\Users\USER\AppData\Local\Python\pythoncore-3.12-64\Scripts\unity-info-mcp.exe
Run it on a different port:
unity-info-mcp --port 8080
Run it over stdio instead:
unity-info-mcp --transport stdio
Behavior:
--transport stdio127.0.0.1:16000http://127.0.0.1:16000/mcp--port is only valid when --transport streamable-http is in useEnter, stdio exits immediatelyUnityInfoMCP supports both Streamable HTTP and stdio on the client-facing side.
For URL-based MCP clients, connect to:
http://127.0.0.1:16000/mcp
If you launch the server on a custom port, use the matching endpoint instead:
http://127.0.0.1:8080/mcp
For process-launching MCP clients, launch the server in stdio mode:
unity-info-mcp --transport stdio
Bridge-side environment variables are still useful in both modes:
$env:UNITY_INFO_BRIDGE_HOST = "127.0.0.1"
$env:UNITY_INFO_BRIDGE_PORT = "16000"
unity-info-mcp --transport stdio
Important notes:
UNITY_INFO_BRIDGE_PORT=16000 is only a legacy fallback bridge port16001~16100--port only affects --transport streamable-http--transport stdio does not expose /mcp; the client must speak MCP over the launched process stdioRecommended auto-launch examples:
Codex config.toml:
[mcp_servers.UnityInfoMCP]
command = "C:\\MCP\\UnityInfoMCP_v1.0.2.exe"
args = ["--transport", "stdio"]
startup_timeout_sec = 45
[mcp_servers.UnityInfoMCP.env]
UNITY_INFO_BRIDGE_HOST = "127.0.0.1"
UNITY_INFO_BRIDGE_PORT = "16000"
Claude Desktop claude_desktop_config.json:
{
"mcpServers": {
"UnityInfoMCP": {
"command": "C:\\MCP\\UnityInfoMCP_v1.0.2.exe",
"args": ["--transport", "stdio"],
"env": {
"UNITY_INFO_BRIDGE_HOST": "127.0.0.1",
"UNITY_INFO_BRIDGE_PORT": "16000"
}
}
}
}
You can also run UnityInfoMCP directly outside MCP client configuration.
When unity-info-mcp is available on PATH:
unity-info-mcp
When you prefer stdio transport:
unity-info-mcp --transport stdio
When you prefer to invoke the module directly:
python -m UnityInfoMCP
To run the module in stdio mode:
python -m UnityInfoMCP --transport stdio
To bind HTTP on a different port:
unity-info-mcp --port 8080
If you built the PyInstaller executable, you can launch it directly as well:
& "C:\path\to\UnityInfoMCP_v1.0.2.exe"
Or in stdio mode:
& "C:\path\to\UnityInfoMCP_v1.0.2.exe" --transport stdio
In all of these direct-launch cases, UnityInfoMCP starts the selected client-facing transport. Streamable HTTP exposes /mcp on the selected port, while stdio does not bind an HTTP port.
UNITY_INFO_BRIDGE_TRANSPORT
Default: tcp
Transport used between UnityInfoMCP and the game-side UnityInfoBridgeUNITY_INFO_BRIDGE_HOST
Default: 127.0.0.1UNITY_INFO_BRIDGE_PORT
Default: 16000
Legacy fallback bridge port only. Auto-discovery still probes 16001~16100.UNITY_INFO_BRIDGE_TIMEOUT_SEC
Default: 8.0UNITY_INFO_MCP_NAME
Default: UnityInfoMCPUNITY_INFO_MCP_LOG_LEVEL
Default: INFOUse .env.example as a starting point if needed.
Build inputs:
UnityInfoBridge/includesUnityInfoBridge/includes/bepinex/mono
UnityInfoBridge/includes/bepinex/il2cpp
UnityInfoBridge/includes/melonloader/mono
UnityInfoBridge/includes/melonloader/il2cpp
UnityInfoBridge/includes/unity/mono
UnityInfoBridge/includes/unity/il2cppUnityInfoBridge/build.ps1 builds all supported variantsThe repository already includes the required reference DLLs, so builds do not depend on any extra sync step.
Typical build:
Set-Location UnityInfoBridge
.\build.ps1
Build specific targets:
Set-Location UnityInfoBridge
.\build.ps1 -Configurations Release_BepInEx_IL2CPP
Build outputs:
UnityInfoBridge/Release/UnityInfoBridge.BepInEx.Mono/UnityInfoBridge/Release/UnityInfoBridge.BepInEx.IL2CPP/UnityInfoBridge/Release/UnityInfoBridge.MelonLoader.Mono/UnityInfoBridge/Release/UnityInfoBridge.MelonLoader.IL2CPP/Each output now includes the bridge assembly plus Newtonsoft.Json.dll.
IL2CPP outputs also include UnityInfoBridge.*.deps.json.
The GitHub release workflow produces:
UnityInfoMCP_vx.x.x.exeUnityInfoMCP-vx.x.x.tar.gzUnityInfoMCP-vx.x.x-py3-none-any.whlUnityInfoBridge_vx.x.x_MelonLoader_Mono.zipUnityInfoBridge_vx.x.x_MelonLoader_IL2CPP.zipUnityInfoBridge_vx.x.x_BepInEx_Mono.zipUnityInfoBridge_vx.x.x_BepInEx_IL2CPP.zipSHA256SUMS.txtPackage structure:
Mods/UnityInfoBridge.dll
Mods/Newtonsoft.Json.dllMods/UnityInfoBridge.dll
Mods/Newtonsoft.Json.dll
Mods/UnityInfoBridge.deps.jsonBepInEx/plugins/UnityInfoBridge/UnityInfoBridge.dll
BepInEx/plugins/UnityInfoBridge/Newtonsoft.Json.dllBepInEx/plugins/UnityInfoBridge/UnityInfoBridge.dll
BepInEx/plugins/UnityInfoBridge/Newtonsoft.Json.dll
BepInEx/plugins/UnityInfoBridge/UnityInfoBridge.deps.jsonRuntime:
bridge_statuslist_bridge_targetsselect_bridge_targetget_runtime_summaryScene and hierarchy:
list_scenesget_scene_hierarchyfind_gameobjects_by_nameresolve_instance_idget_gameobjectget_gameobject_by_pathget_gameobject_childrenComponents and fields:
get_componentsget_componentget_component_fieldssearch_component_fieldsText and localization discovery:
list_text_elementssearch_textget_text_contextSnapshots:
snapshot_gameobjectsnapshot_sceneWrite operations:
set_gameobject_activeset_component_memberset_textCapture:
capture_screenshotNotes:
DontDestroyOnLoad UI when Unity exposes it as a valid runtime scene objectcapture_screenshot returns PNG image content to the MCP clientoutput_path is omitted, the bridge uses GameRoot\UnityInfoBridge\captures\capture_yy-MM-dd-HH-mm-ss-fff.png as a temporary capture path and UnityInfoMCP removes the temp file after embedding the imageoutput_path if you want the PNG to remain on disk after the MCP responseFind which font a live dialogue line is using:
User prompt:
"어디까지나 이리스의 의견이니까"라는 텍스트가 어느 폰트를 사용하고 있는지 알려줘.
Primary tool call:
UnityInfoMCP.search_text({
"query": "어디까지나 이리스의 의견이니까",
"include_inactive": true,
"limit": 10
})
Typical result summary:
Search_root/Canvas2/ScreenScaler2/GameObject/messagewindow/messagearea/text_message (TMP)TMPro.TextMeshProUGUImessage#en-fontMove the same text up by 100px:
User prompt:
그 텍스트를 위로 100px 올려줘.
Tool flow:
UnityInfoMCP.get_components({
"gameobject_instance_id": 480506,
"include_fields": true,
"include_non_public": false,
"field_depth": 1
})
UnityInfoMCP.set_component_member({
"component_instance_id": 485632,
"member_name": "anchoredPosition",
"value": { "x": 0.0, "y": -258.0 },
"include_non_public": false
})
Verification:
UnityInfoMCP.get_component_fields({
"component_instance_id": 485632,
"include_non_public": false,
"include_properties": true,
"max_depth": 1
})
Typical result summary:
UnityEngine.RectTransformanchoredPosition: (0.0, -358.0) -> (0.0, -258.0)100pxRuntime object IDs such as 480506 and 485632 are example values and will differ each session.
For common Unity structs, tuple-style strings such as "(0, -258)" also work.
docs/bridge-protocol.mddocs/tool-catalog.mdДобавь это в claude_desktop_config.json и перезапусти Claude Desktop.
{
"mcpServers": {
"unityinfomcp": {
"command": "npx",
"args": []
}
}
}