ProjectM QA MCP
Provides tools for interacting with Unity Editor via a command bridge, enabling AI agents to execute editor commands, run Unity tests, capture screenshots, and retrieve Unity status.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@ProjectM QA MCPRun all tests and show failure counts."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
NX3 Unity MCP
NX3 Unity MCP is a Unity Package Manager package that installs a small Unity Editor command bridge and ships a bundled Node MCP server.
The package is intentionally ProjectM-focused. It avoids the long-lived
WebSocket bridge used by general Unity MCP packages and uses request/response
JSON files under .codex/unity-commands.
Install in Unity
Use Unity Package Manager with Add package from git URL....
The URL must include the .git suffix:
https://github.com/chdnl0420-svg/UnityMCP.gitYou can also edit Packages/manifest.json directly:
{
"dependencies": {
"com.nx3games.unity-mcp": "https://github.com/chdnl0420-svg/UnityMCP.git"
}
}For local development, add this folder as a local package:
{
"dependencies": {
"com.nx3games.unity-mcp": "file:D:/Project/UnityMCP"
}
}Related MCP server: Unity-MCP
Codex MCP Registration
Add a server entry to C:\Users\NX3GAMES\.codex\config.toml.
Adjust the args path to the installed package location.
[mcp_servers.nx3-unity-mcp]
command = "node"
args = ['D:\Project\UnityMCP\Server~\build\index.js']
startup_timeout_sec = 120
[mcp_servers.nx3-unity-mcp.env]
PROJECTM_UNITY_PATH = 'C:\Program Files\Unity\Hub\Editor\2022.3.76f1\Editor\Unity.exe'
PROJECTM_DEFAULT_PROJECT_PATH = 'C:\Project\CLIENT_KSH_ASIA_L\client\ProjectM'
PROJECTM_COMMAND_ROOT = 'C:\Project\CLIENT_KSH_ASIA_L\client\ProjectM\.codex\unity-commands'Build and Test
cd D:\Project\UnityMCP\Server~
npm install
npm test
npm run buildThe generated MCP server entrypoint is:
Server~/build/index.jsEditor-tool automation and in-editor tests
Editor tools (EditorWindow) cannot be driven by the runtime NGUI commands: those go through
NguiRaycast and UICamera.Notify, a path an editor window never takes, and IMGUI keeps no retained
widget tree to walk instead.
unity_editor_* tools cover that: open a window by type or menu path, dump its instance fields, its
callable methods and its IMGUI layout rects, set fields by dotted/indexed path with a before/after
readback, inject real clicks and keystrokes, run menu items, read the Console, and read or write
EditorPrefs/PlayerPrefs.
unity_run_tests_in_editor, unity_get_test_results and unity_list_tests run Unity Test Framework
tests inside the already-open editor via TestRunnerApi. The older CLI test tools spawn a second Unity
in batch mode, which cannot work while an editor holds the project lock.
See Documentation~/projectm-qa-mcp.md for the mechanisms, the coordinate-space gotchas, and the
current limitation on window pixel capture.
Testing hover: unity_editor_move
unity_editor_drag cannot test hover. Its moves are MouseDrag events, and the MouseDown that opens
the gesture registers a pressed button, so UI Toolkit delivers them as a MouseMoveEvent with
pressedButtons != 0. Everything that reacts to a bare cursor — GraphView highlighting the edge under
the mouse, a rollover tint, a hover tooltip — sits on the other branch and never runs.
unity_editor_move sends one MouseMove with no button held, and nothing else: no MouseDown,
MouseDrag or MouseUp, so it cannot move a node, change the selection, start a marquee, pan the view
or open a context menu. Coordinates follow unity_editor_drag — content-local by default with the dock
tab strip added automatically, coordinateSpace: "host" for the raw host-view space unity_editor_click
uses. Consecutive calls on the same window carry the delta between the two points, and every window
keeps its own last position, so one window's hover path never depends on another's.
// hover the middle of a GraphView, then photograph the result
{ "tool": "unity_editor_move",
"arguments": { "windowType": "MoveProbeWindow", "x": 300, "y": 160 } }
{ "tool": "unity_editor_window_capture",
"arguments": { "windowType": "MoveProbeWindow", "outputPath": "C:/tmp/hover.png" } }The response reports what was sent — target window, resolved x/y, deltaX/deltaY,
pressedButtons: 0, eventType: MouseMove and the raw sendEventReturned. None of that is proof the
UI reacted, exactly as with click and drag: verify with unity_editor_window_capture right after the
move, or by reading the tool's own state with unity_editor_get_field.
IMGUI is a special case worth knowing: OnGUI only receives EventType.MouseMove in a window that set
EditorWindow.wantsMouseMove, which is Unity's rule for a real mouse too. unity_editor_move turns
that flag on for the send and puts it straight back, and reports both the window's original setting and
whether it did so. Pass ensureWantsMouseMove: false for strict production fidelity.
Window/NX3 MCP/Move Probe (plus (Floating) and (Docked)) opens a window built for checking all of
this, and Tests/Editor/EditorMoveTests.cs asserts it. Package tests only compile in a project that
lists the package under testables in Packages/manifest.json:
{ "testables": ["com.nx3games.unity-mcp"] }Opening a context menu: unity_editor_context_click
What unity_editor_click with button: 1 misses is one event, not the button. Measured on 2022.3.62,
Windows, against MoveProbeWindow:
Path | Right |
|
UI Toolkit | already worked — it listens on | works |
GraphView | already worked — same manipulator path | works |
IMGUI | never fired | works |
So the gap is IMGUI: OnGUI code builds its menu by testing Event.current.type against
EventType.ContextClick, and unity_editor_click delivers no such event, leaving that branch dead.
Unity's native input layer synthesises ContextClick for a real right-click; EditorWindow.SendEvent
does not, so the bridge sends it itself — which reaches IMGUI menu code and makes the gesture what a
real right-click is, rather than only what UI Toolkit happens to accept.
unity_editor_context_click sends three events in order — MouseDown (button 1), MouseUp (button 1),
then ContextClick at the same point — and reports mouseDownReturned, mouseUpReturned and
contextClickReturned separately. The press pair still goes first because a menu is a gesture, not a
lone event: handlers that track which button is down, dismiss an open popup, or take the menu's anchor
from the press would otherwise see a ContextClick arrive out of nowhere.
// right-click a GraphView, then check what opened
{ "tool": "unity_editor_context_click",
"arguments": { "windowType": "MoveProbeWindow", "targetMode": "element", "elementName": "graph-area" } }
{ "tool": "unity_editor_window_capture",
"arguments": { "windowType": "MoveProbeWindow", "outputPath": "C:/tmp/menu.png" } }Targeting is the same resolver unity_editor_click uses — a point, an entryIndex, or targetMode: "element" with the element filters — so a right-click can aim at exactly the pixel a left click just
hit. Coordinates therefore follow click, not drag: x/y are host-view by default, the space
unity_editor_element_query reports. Pass coordinateSpace: "content" for the content-corner
convention unity_editor_drag and unity_editor_move default to. There is no button or clickCount
parameter, because a context click is one right-button gesture by definition.
The three *Returned values are raw SendEvent returns, not proof a menu opened — the same caveat as
click, drag and move. One case looks identical from the outside and is worth knowing: a menu whose
BuildContextualMenu appends no items is built and then displays nothing at all.
A menu that does display blocks the editor until it is dismissed. Unity shows it from inside
SendEvent, so the main thread and this bridge are held for the duration — 4s, 24s and 123s measured
for the same click, differing only in how long the menu stayed up. contextClickBlockedMs reports it.
Because nothing else can run meanwhile, the popup cannot be inspected while it is up; confirm the menu
afterwards by reading the tool's own state with unity_editor_get_field.
Window/NX3 MCP/Move Probe carries a GraphView with a BuildContextualMenu override that always
appends an item, named graph-area, alongside hover-area and imgui-strip; _graphContextMenuCount
and _contextMenuCount are readable with unity_editor_get_field.
Tests/Editor/EditorContextClickTests.cs asserts the event sequence, and deliberately aims away from
the GraphView so no popup is left on screen mid-run.
Aiming, scrolling, selecting, compiling
unity_editor_element_queryfinds UI Toolkit elements by name, USS class, type or text and returns where each one is, withenabled,visibleandpickable.unity_editor_click,unity_editor_moveandunity_editor_scrolltake the same filters withtargetMode: "element", so input can aim at "the button named Build" instead of a pixel that a resize invalidates.unity_editor_context_clickopens a context menu, whichunity_editor_clickwithbutton: 1never did — see below.unity_editor_scrollturns the wheel at a point: ScrollViews, long inspectors and GraphView zoom.unity_editor_selection_get/unity_editor_selection_setread and set the editor selection, which is how an inspector-driven tool is put in front of the asset it should act on.unity_editor_refreshreimports, recompiles and waits for the verdict;unity_editor_compile_statusreads the last one.errorCountis Unity's own compiler output, so this is usable as a gate, and the result is stored on disk so it survives the domain reload a recompile causes.unity_editor_wait_for_fieldpolls a field until it reaches an expected value instead of sleeping a fixed amount after triggering slow work.
Tool Success Criteria
unity_status must return real JSON data, not just a connection signal.
Editor commands must write response JSON with success, command,
elapsedMs, logs, outputs, and error.
unity_enter_play_mode and unity_exit_play_mode must wait for
editor_status to report the requested isPlaying value before returning
success.
unity_click_ui_text must resolve a visible NGUI label to its clickable target
instead of requiring manual dump_ui coordinate transfer.
When a label has no direct clickable target, text-click and dump_ui fallback
to a nearby clickable UI object and mark it with clickResolution=nearest.
dump_ui omits off-screen UI by default to keep QA responses small; pass
includeOffscreen=true when scroll-buffered or hidden coordinates are needed.
unity_wait_ui_text must poll dump_ui until expected text appears or return a
timed-out response with the last observed UI dump.
unity_click_ui_text_and_wait must click a visible label and return the
post-click matched UI text in one response.
unity_run_ui_text_qa_flow must enter PlayMode, wait for initial text, capture
before/after screenshots, click text, wait for expected text, and return every
step in one response.
Test tools parse Unity Test Framework XML and expose failure counts.
Screenshot tools verify that a PNG exists and has non-zero size, and that its pixels are not a single
flat colour — a blank capture is reported as a failure rather than handed back as an image.
Screenshot responses also report requested dimensions, actual dimensions, and
matchesRequestedSize; set requireRequestedSize=true when dimension mismatch
should fail the tool call.
Frame-sequence recording (fast motion)
For fast motion that a single unity_capture_screenshot round-trip misses,
record the game view as a PNG frame sequence:
unity_start_frame_capture— starts capturing the game view camera on every editor update into a frames folder and returns immediately. Run the fast action next. Bounded bymaxFramesandmaxDurationSeconds(auto-stops).unity_stop_frame_capture— stops recording and returnsframesDir,frameCount, andfps. Read theframe_NNNNN.pngfiles in order to inspect the motion.
Use recording only when a single screenshot cannot catch the change; a normal screenshot is cheaper for static checks.
Code, QA, and UI Tools
Beyond PlayMode/screenshot/click tools, the server exposes code-iteration, QA
inspection, and UI mutation tools. See Documentation~/nx3-unity-mcp.md for the
full list. Highlights:
unity_editor_refresh— reimport assets and recompile scripts, wait for the domain reload to settle, and return the compiler's own verdict. Use this after editing C# so the next QA step runs against fresh code. Scripts only compile in Edit mode, so exit PlayMode first.unity_editor_compile_status/unity_editor_console_read/unity_editor_console_clear— inspect compilation state and the Editor console for errors and warnings.unity_inspect_object/unity_find_objects/unity_scene_info/unity_get_hierarchy— discover and inspect scene objects for QA.unity_set_active/unity_set_label_text/unity_set_input_text/unity_set_sprite— mutate existing NGUI widgets for UI checks.
New typed tools appear after the MCP server is reconnected. The underlying bridge
commands are usable immediately through unity_execute_editor_command.
Recovery Notes
If Unity does not answer a command, inspect:
<ProjectM>/.codex/unity-commands/requests
<ProjectM>/.codex/unity-commands/responses
<ProjectM>/.codex/unity-commands/processed
%LOCALAPPDATA%/Unity/Editor/Editor.logUse unity_kill_stale without kill=true first. It reports candidates and
reasons before termination is requested.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- Alicense-qualityAmaintenanceA bridge enabling seamless communication between Unity and Large Language Models via the Model Context Protocol, allowing developers to automate workflows, manipulate assets, and control the Unity Editor programmatically.Last updated13,107MIT
- AlicenseBqualityCmaintenanceA bridge between Unity and AI assistants that enables AI to interact with Unity game environments through a standardized interface for code execution, scene analysis, and runtime debugging.Last updated3587MIT
- Flicense-qualityCmaintenanceA bridge that enables controlling Unity Editor through natural language commands via AI assistants, allowing users to create materials, build projects, manage scenes, and configure settings without manual interaction.Last updated93
- Alicense-qualityAmaintenanceUnity Editor automation bridge for AI agents and MCP clients, enabling inspection, control, and diagnostics of the Editor.Last updatedMIT
Related MCP Connectors
Control Unreal Engine to browse assets, import content, and manage levels and sequences. Automate…
A paid remote MCP for Unity-MCP, built to return verdicts, receipts, usage logs, and audit-ready JSO
Drive a live Cinevva game session: edit game files, import CC0 assets, preview changes.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/chdnl0420-svg/UnityMCP'
If you have feedback or need assistance with the MCP directory API, please join our Discord server