UnityInfoMCP
Unity runtime inspection toolkit for MCP-based modding and localization workflows, with an external MCP server and in-game bridge.
Ask AI about UnityInfoMCP
Powered by Claude ยท Grounded in docs
I know everything about UnityInfoMCP. Ask me about installation, configuration, usage, or troubleshooting.
0/500
Reviews
Documentation
English | ํ๊ตญ์ด
UnityInfoMCP
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-RPC
The split is intentional:
- the MCP server can stay alive while games restart
- AI clients keep a stable MCP endpoint
- the game-side bridge can reconnect whenever the game launches again
Port layout
This is the part that matters most in practice:
- MCP server in default HTTP mode:
http://127.0.0.1:16000/mcp - MCP server in stdio mode: no listening socket; the MCP client launches the process directly
- Game bridge: first free port in
127.0.0.1:16001~16100
These are different connections.
--transport streamable-httpuses the HTTP endpoint above--transport stdioswitches the client-facing transport to stdio--portonly applies to--transport streamable-httpUNITY_INFO_BRIDGE_PORTis only a legacy fallback for bridge connection attempts- bridge auto-discovery still scans
16001~16100 16000is theUnityInfoMCPHTTP port. The in-gameUnityInfoBridgeplugin itself binds the first free port in16001~16100.
There are also two separate transport layers:
- Client ->
UnityInfoMCP: Streamable HTTP or stdio UnityInfoMCP->UnityInfoBridge: TCP
Repository layout
UnityInfoMCPThe Python MCP packageUnityInfoBridgeThe Unity plugin projectUnityInfoBridge/includesReference DLLs used to build the bridgedocsBridge protocol and tool mapping documents
Supported bridge targets
UnityInfoBridge currently targets:
BepInEx BE #754+MonoBepInEx BE #754+IL2CPPMelonLoader 0.7.2MonoMelonLoader 0.7.2IL2CPP
Running the MCP server
Create 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:
- default MCP transport: Streamable HTTP
- optional MCP transport: stdio via
--transport stdio - default HTTP bind:
127.0.0.1:16000 - default HTTP MCP endpoint:
http://127.0.0.1:16000/mcp --portis only valid when--transport streamable-httpis in use- startup failure: prints the error; interactive HTTP launches wait for
Enter, stdio exits immediately
MCP client configuration
UnityInfoMCP 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=16000is only a legacy fallback bridge port- normal bridge discovery still probes
16001~16100 --portonly affects--transport streamable-http--transport stdiodoes not expose/mcp; the client must speak MCP over the launched process stdio
Recommended 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"
}
}
}
}
Direct execution
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.
Environment variables
UNITY_INFO_BRIDGE_TRANSPORTDefault:tcpTransport used betweenUnityInfoMCPand the game-sideUnityInfoBridgeUNITY_INFO_BRIDGE_HOSTDefault:127.0.0.1UNITY_INFO_BRIDGE_PORTDefault:16000Legacy fallback bridge port only. Auto-discovery still probes16001~16100.UNITY_INFO_BRIDGE_TIMEOUT_SECDefault:8.0UNITY_INFO_MCP_NAMEDefault:UnityInfoMCPUNITY_INFO_MCP_LOG_LEVELDefault:INFO
Use .env.example as a starting point if needed.
Building UnityInfoBridge
Build inputs:
- bridge references are resolved from
UnityInfoBridge/includes - the project only uses local reference DLLs under:
UnityInfoBridge/includes/bepinex/monoUnityInfoBridge/includes/bepinex/il2cppUnityInfoBridge/includes/melonloader/monoUnityInfoBridge/includes/melonloader/il2cppUnityInfoBridge/includes/unity/monoUnityInfoBridge/includes/unity/il2cpp UnityInfoBridge/build.ps1builds all supported variants
The 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.
Release assets
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.txt
Package structure:
- MelonLoader Mono zip:
Mods/UnityInfoBridge.dllMods/Newtonsoft.Json.dll - MelonLoader IL2CPP zip:
Mods/UnityInfoBridge.dllMods/Newtonsoft.Json.dllMods/UnityInfoBridge.deps.json - BepInEx Mono zip:
BepInEx/plugins/UnityInfoBridge/UnityInfoBridge.dllBepInEx/plugins/UnityInfoBridge/Newtonsoft.Json.dll - BepInEx IL2CPP zip:
BepInEx/plugins/UnityInfoBridge/UnityInfoBridge.dllBepInEx/plugins/UnityInfoBridge/Newtonsoft.Json.dllBepInEx/plugins/UnityInfoBridge/UnityInfoBridge.deps.json
MCP tool surface
Runtime:
bridge_statuslist_bridge_targetsselect_bridge_targetget_runtime_summary
Scene and hierarchy:
list_scenesget_scene_hierarchyfind_gameobjects_by_nameresolve_instance_idget_gameobjectget_gameobject_by_pathget_gameobject_children
Components and fields:
get_componentsget_componentget_component_fieldssearch_component_fields
Text and localization discovery:
list_text_elementssearch_textget_text_context
Snapshots:
snapshot_gameobjectsnapshot_scene
Write operations:
set_gameobject_activeset_component_memberset_text
Capture:
capture_screenshot
Notes:
- text and hierarchy discovery includes persistent
DontDestroyOnLoadUI when Unity exposes it as a valid runtime scene object capture_screenshotreturns PNG image content to the MCP client- when
output_pathis omitted, the bridge usesGameRoot\UnityInfoBridge\captures\capture_yy-MM-dd-HH-mm-ss-fff.pngas a temporary capture path andUnityInfoMCPremoves the temp file after embedding the image - provide
output_pathif you want the PNG to remain on disk after the MCP response
Example workflow
Find 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:
- scene:
Search - object path:
_root/Canvas2/ScreenScaler2/GameObject/messagewindow/messagearea/text_message (TMP) - component type:
TMPro.TextMeshProUGUI - current TMP font asset:
message#en-font
Move 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:
- target component:
UnityEngine.RectTransform anchoredPosition:(0.0, -358.0)->(0.0, -258.0)- effective change: moved upward by
100px
Runtime 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.
Documentation
- Bridge protocol:
docs/bridge-protocol.md - Tool mapping:
docs/tool-catalog.md
