VMUnityMCP
Allows interaction with the Unity Editor, providing structured, queue-safe tools for scenes, assets, UI Toolkit, packages, builds, tests, project-defined workflows, and Editor diagnostics.
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., "@VMUnityMCPlist all playmode tests"
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.
VM Unity MCP
VM Unity MCP is an independently maintained Unity Editor bridge for structured, queue-safe MCP automation. It provides route-specific tools for Unity assets, scenes, UI Toolkit, packages, builds, tests, diagnostics, and project-defined workflows.
This project was originally derived from AnkleBreaker Studio's Unity MCP Plugin and retains its license and attribution requirements. Powered by AnkleBreaker MCP.
Installation
VM Unity MCP is the Editor half of the connection. For a first-time setup, follow the companion server's complete installation and MCP host configuration guide. That guide covers Node.js, Codex, the ChatGPT desktop app, Claude Desktop, multiple projects, reconnects, and the final health check. This README covers the Unity package itself.
Requirements
Unity 2021.3.18f1 or newer.
Unity MCP Server 9.x for VM Unity MCP 10.x. The current matching releases are server
9.2.3and package10.1.1.Git available to Unity Package Manager.
The bridge and server negotiate their supported version ranges. A mismatched
major release fails with incompatible_stack; do not work around that error by
switching routes or bypassing the server.
Add the package
In Unity, open Window > Package Manager, choose Add package from git URL..., and enter the current compatible release tag:
https://github.com/VM233/VMUnityMCP.git#v10.1.1For an immutable project pin, resolve that release tag and replace it with the release's full 40-character commit SHA.
Keep this Git URL in Packages/manifest.json and let Package Manager maintain
Packages/packages-lock.json. Do not edit Library/PackageCache or turn the
package into an embedded copy.
Configure and verify the bridge
After package import finishes:
Use Project Settings > Unity MCP for team-owned context and tool defaults.
Use Preferences > Unity MCP for local bridge startup, ports, response limits, histories, and enabled categories.
Leave automatic ports enabled unless a fixed port is required. The bridge listens on
127.0.0.1; its initial automatic range is7890-7899.Configure the companion server with the exact Unity project root in
UNITY_MCP_PROJECT_PATH, then restart or reconnect the MCP host.Call
unity_mcp_healthand confirm the intended project and a compatible server/plugin stack. Then useunity_tools_searchandunity_tools_getto confirm the project-bound typed catalog is available.
Projects using VMFramework can install the optional VMFramework MCP package after this base connection works. It joins the same catalog and does not need a second server entry.
Related MCP server: Agent Bridge for Unity
Capability model
The public MCP surface is generated from live Editor metadata rather than a hand-maintained README list. This prevents installed Unity packages, Unity versions, and the currently selected project from producing stale concrete tools.
The built-in catalog comes from one typed descriptor registry. Each descriptor owns execution, deferred dispatch, description, profile, input schema, and output schema. Optional package assemblies contribute typed providers without making the core assembly depend on those packages, and reading metadata does not initialize the HTTP listener.
Area | Contract |
Discovery |
|
Client binding | One companion-server stdio connection binds to one project and publishes that project's complete typed catalog in its first successful tool list. |
Built-in tools | Every available route has one typed name, full input/output schemas, module/capability/operation metadata, effects, and preconditions. |
Project extensions | Every valid project/package tool is cataloged at |
Multi-instance safety | Each connection has one immutable normalized absolute |
Long work | Builds, tests, workspace refresh/package operations, package tests, snapshots, Addressables builds, execute-code, and long project tools use persistent jobs or tickets; owned cancel routes are cooperative. |
Optional integrations | Localization, Shader Graph, VFX Graph, Addressables, Timeline, Cinemachine, Build Profiles, and Unity 6.4+ Project Auditor publish only when their capability is available. |
Common asset-authoring composition is intentionally available without arbitrary Editor code: create folders, copy assets, and create Prefab Variants; inspect a Prefab hierarchy; apply one atomic Prefab transaction; then create or update framework-owned configuration through a project/package tool. Localization entry upsert and removal are concrete tools when Unity Localization is installed. Project code should not retain one-off Editor builders that mirror checked-in asset values; temporary migrations are removed after asset readback succeeds.
Successful asset/delete operations save asset changes produced by Unity deletion callbacks before
returning. Dependent configuration such as Addressables entries is therefore persisted together with
the deletion instead of remaining only in the current Editor session.
Filename-changing asset/rename and asset/move operations keep Sprite asset
identity coherent as well as preserving the .meta GUID. Single Sprite names
follow the filename. Multiple Sprite names that use the previous filename as
their prefix are migrated to the new prefix while retaining every Sprite ID,
so AnimationClip and Prefab references remain valid.
Major route families include:
scene workspaces, GameObjects, components, Prefabs, materials, importers, and serialized assets;
UI Toolkit authoring, static audits, runtime inspection, screenshots, and visual comparison;
Animator, Audio Mixer, VFX Graph, Shader Graph, Timeline, Cinemachine, Addressables, Localization, Physics 2D/3D, terrain, lighting, and navigation;
Console, compilation, debugger, Profiler, testing, builds, packages, jobs, queue diagnostics, and Editor execution.
Shader Graph inspection treats the graph's GraphData node, property, and edge
references as authoritative. Texture properties report authoring flags that can
change generated shader declarations, while scalar graph-object edits validate
the existing field and type, synchronously import, verify readback, and roll
back on failure.
Use live tool metadata for exact names and schemas. Do not copy a tool list from this README into a client manifest.
Programmatic UI Toolkit audits
Editor integrations can consume the same USS and UXML analysis used by the MCP
tools through the typed UIToolkitAuditor API. This avoids coupling Project
Auditor, CI, or package integrations to MCP request and response dictionaries:
using System;
using UnityMCP.Editor;
UIToolkitAuditReport ussReport = UIToolkitAuditor.AuditUssStyles(
Array.Empty<string>(), includeSuppressed: false,
maxFindings: UIToolkitAuditor.MaximumFindingCount);
UIToolkitAuditReport uxmlReport = UIToolkitAuditor.AuditUxmlLayouts(
Array.Empty<string>(), includeSuppressed: false,
maxFindings: UIToolkitAuditor.MaximumFindingCount);An empty path collection audits every asset in the project-owned scope.
Specific project-relative paths audit only those targets while retaining the
configured UXML, USS, runtime-source, PanelSettings/TSS, and suppression indexes.
Each immutable finding supplies AssetPath, Line, RuleId, Message, and
suppression state. Reports separately expose source/configuration errors and
whether the requested finding limit truncated the result.
Initial-style no-op detection uses Unity's own USS importer and computed initial style instead of a plugin-maintained property list. It therefore covers the engine's current non-inherited longhand and shorthand properties; inherited properties remain parent-cascade owned and are not treated as element-local defaults.
The shared scope and policy remain authoritative in
ProjectSettings/UnityMCPUIToolkitAudit.json; programmatic consumers do not
maintain a second configuration.
Project Auditor reports
On Unity 6.4 or newer, unity_project_auditor_audit starts a new Project
Auditor analysis through Unity's public API and returns the resulting issues.
It uses the saved Project Auditor rule settings, but it does not read the
Project Auditor window's previous report or its current UI filters.
The typed request can restrict analyzed categories and can filter returned
issues by exact descriptor ID or resolved severity. Results are sorted by
asset path, line, descriptor ID, and description before applying offset and
limit; the default page size is 100 and the maximum is 500. Each issue
includes its descriptor ID, category, severity, log level, description, source
location, and optional custom properties. Registered project analyzers and
rules supplied by packages such as com.unity.project-auditor-rules flow
through the same report; that rules package is not required for the tool to be
available.
Project extensions
Project-specific workflows can live in an Editor assembly in the project or in another package:
using System.ComponentModel;
using UnityMCP.Editor;
// Keep each public type in its own source file in production code.
[MCPDataProduct("example.content-ref")]
public sealed class ContentReference
{
[MCPRequired, MCPJsonProperty("id"), MCPMinLength(1)]
[Description("Registered content id.")]
public string Id { get; set; }
}
public sealed class AddContentRequest
{
[MCPRequired, MCPJsonProperty("id"), MCPMinLength(1)]
[Description("Content id to create.")]
public string Id { get; set; }
}
public sealed class AddContentResult
{
[MCPRequired, MCPJsonProperty("content")]
[Description("Authoritative reference to the created content.")]
public ContentReference Content { get; set; }
}
public static class ProjectMcpTools
{
[MCPProjectTool("example/add-content",
Description = "Create and register one example content asset.",
ModuleId = "example",
Capability = "content",
WhenToUse = "Use when the project needs one registered content asset.",
SearchTerms = new[] { "content", "authoring", "register" },
SideEffects = MCPProjectToolSideEffect.WritesAssets,
ErrorCodes = new[] { "content_id_conflict" },
MutatesAssets = true)]
public static AddContentResult AddContent(AddContentRequest request)
{
return new AddContentResult
{
Content = new ContentReference { Id = request.Id }
};
}
}The request and result types are the only schema authority for typed tools. Do
not add InputSchemaJson or OutputSchemaJson to them. A tool that deliberately
uses Dictionary<string, object> must instead declare complete exact input and
output schemas; open or opaque executable contracts are rejected.
Apply the same MCPDataProduct id to the shared reference type returned by a
producer and accepted by a consumer. The companion server validates that every
occurrence has the same structure and reports the exact producer-result and
consumer-input JSON pointers. Both tools are already ordinary advertised tools;
the server does not insert a generic executor between them.
Declare exactly one operation kind: ReadOnly, MutatesAssets,
MutatesRuntime, or MutatesProjectFiles. Use MutatesProjectFiles for writes
to project-owned files outside Unity's Assets database, such as generated
reports or repository configuration; discovery exposes it as the exact
writesProjectFiles side effect. Add RequiresPlayMode, Dangerous,
LongRunning, or
MayReloadDomain when applicable. Strict schemas should describe every
property and reject unknown business arguments. The bridge recursively enforces
the supported JSON Schema subset before invocation, including
allOf/anyOf/oneOf, not, const, nested objects, and array items.
Declared output schemas are also enforced before success. Use SideEffects for
the concrete effect classes, ErrorCodes for domain failures, and
CleanupToolName only when the operation produces a token owned by that cleanup
tool.
These booleans are authoring inputs, not public response fields. Discovery
serializes positive capabilities as a sorted tags array, for example
["dangerous", "longRunning"]; absence means false. Concrete effects such as
writesAssets, writesProjectFiles, changesRuntimeState, or reloadsDomain
are reported once in
sideEffects. Empty tags/effects, empty cleanup names, valid-state aliases, and
standard project-tool error codes are omitted. Canonical descriptors include
only tool-specific extra errorCodes.
LongRunning=true and an explicit runAsJob=true both return a persistent Job.
Class-based tools can implement IMCPPersistentProjectTool to yield a
MCPProjectToolJobStep between Editor updates. Every continuation value must be
returned in the step state; the bridge does not retain the tool instance.
Transaction-capable tools publish one semantically neutral descriptor with
scope, atomicity, isolation, durability, rollbackKind, and
commitEvidence. Project-tool packages set the matching
MCPProjectToolAttribute fields as one complete contract; partial declarations
are rejected. These fields describe framework guarantees and evidence, not
consumer gameplay meaning.
The canonical client workflow is the same for built-in and project tools:
Search the bound project catalog by intent, module, capability, operation kind, effects, or preconditions.
Get one exact typed name to inspect its complete published schema.
Call that typed tool directly with its business arguments.
For the example above, the Editor route remains
project-tools/call/example/add-content; clients never send a generic
toolName + args envelope. A different Unity project uses a different MCP
connection, so one project's tools cannot leak into another project.
Project-tool packages can reuse
MCPSettingsManager.ResolvePrimaryResultLimit(...) for a single primary
collection. It preserves the shared Unity MCP user preference while keeping
explicit values and package-specific hard caps authoritative. Domain-specific
packages should own their own Project Settings and Preferences rather than
adding unrelated fields to Unity MCP.
Configuration
Default precedence is:
explicit tool argument;
team-owned Project Settings;
local Preferences;
built-in default.
Team settings are stored in ProjectSettings/UnityMCPSettings.json and edited
under Project Settings > Unity MCP:
project context;
additional namespaces for
editor/execute-code;default Physics query dimension;
screenshot output directory.
Operator settings are edited under Preferences > Unity MCP:
bridge startup and manual/automatic ports;
MPPM startup;
optional primary-result-limit override;
optional Prefab YAML diff detail;
Action and Job history sizes;
locally enabled tool categories.
Safety caps, paths/selectors, mutation operations, overwrite/save/discard choices, build/test targets, raw diagnostic expansion, and destructive confirmation remain explicit or invariant.
The full ownership matrix and authoritative built-in route audit are in Documentation~/configuration.md.
Response and safety conventions
Tool metadata publishes an
outputSchemafor every route. The companion server exposes the actual result through MCPstructuredContent; the text block remains a short human-readable summary. Shared persistent Job fields include semantic descriptions so clients can compose status, cancellation, and cleanup without relying on route-specific prose.Successful bridge responses may omit redundant
success=true; errors keep a stable error code and retryability.Transported type descriptors keep the complete
fullType,fullTypeName, orfullNameidentifier and omit matching shorttype,component,typeName,name, or fallbacktitlealiases. Distinct names and custom titles remain; request selectors still accept simple or complete names.Project-tool success envelopes are unwrapped without compacting the validated result object. Required empty collections, counts, flags, and nested members therefore retain the exact shape declared by the tool's
outputSchema. The same preservation applies when that envelope is nested in a persistent Job snapshot returned byjobs/get.Published
inputSchemaandoutputSchemaobjects are transported without response compaction. Business properties namedtagsorsideEffectsand JSON Schema keywords such asreadOnlytherefore retain their declared schema shapes.editor/execute-codereports invalid submissions and compiler diagnostics as non-retryable structured errors. Compilation failures useexecute_code_compilation_failedand returnuserCodeExecuted=false, so callers can distinguish invalid C# from bridge or runtime failures.editor/execute-codealways returns a persistent Job. Polljobs/get; usejobs/cancelbefore execution or between incremental steps; and usejobs/cleanuponly when the Job reports an available cleanup contract. Idempotency keys are project-scoped recovery capabilities: an exact retry after an MCP reconnect returns the original Job and access token, while reusing a key with different arguments is rejected.jobs/cancelreports success when the target accepts cancellation, including workflows that reachcanceledimmediately. Read the terminal outcome throughjobs/get; cancellation acceptance is not returned as a command failure.asset/refresh,packages/update-git, andpackages/resolveuse one serialized durable workspace-job state machine. Package targets require a full commit SHA. A terminal success proves exact manifest, lockfile, and registered-package state when applicable, one AssetDatabase refresh invocation, a clean compilation with no compiler errors, and the subsequent assembly reload. Poll byjobId, or use the originalrequestIdplusjobTypeafter a transport response is lost.asset/transactionis also a serialized durable workspace Job. It validates the complete virtual operation sequence, captures every affected asset/meta baseline before mutation, persists prepare/apply/save/publish/rollback phases, and verifies restored or committed bytes after synchronous import. Its only terminal states arecommitted,rolled_back,rollback_failed, andoutcome_uncertain; retained recovery artifacts require explicit cleanup.Unity Undo is not transaction rollback. Each eligible synchronous MCP request owns a distinct Undo group only when Unity records an actual undoable change.
undo/performandundo/redorequire the exact request or action identity;undo/historyreports those records, and reload invalidates unprovable groups. Domain reload resumes this same identity and never reissues the mutation.Durable refresh, build, Test Runner, package-test, memory-snapshot, Addressables, and Unity-package-import Jobs return
jobId,jobType, and a durablejobAccessToken. The originating agent can poll normally; after an MCP reconnect, pass the token tojobs/getorjobs/cancel.jobs/listand public history snapshots never return the token.A domain reload may legitimately change the live catalog revision while the Job remains active. An already negotiated client may still call the built-in
jobs/get,jobs/cancel, andjobs/cleanuplifecycle contracts with its complete prior stack identity; their current input contracts and Job owner capabilities are validated before dispatch. No other stale-catalog command is admitted.jobs/getandtesting/get-jobreport a successful snapshot read independently from the observed job outcome. Inspectstatusanderrorforfailedorcanceledjobs; those outcomes do not turn polling into a queue-command failure or overwrite the business status. Package-test starts returnjobIdplusjobType="package-test"; poll that identity throughjobs/get.testing/get-package-jobis the specialized inspection and terminal-state cleanup route for the current package-test workflow. It accepts the samejobIdand access token, but is not a second public job identity or the normal polling path.Job capability and positive state flags use the same presence-only
tagscontract (incrementalJob,cleanupDeclared,cleanupAvailable,cancellationRequested, andreused). Fields that do not yet have a value are omitted;status, timestamps, progress, results, and errors remain explicit runtime facts.The transport applies that rule uniformly to specialized build, test, package-test, import, refresh, and profiler workflows. Poll-route aliases, status-derived booleans, idle compilation diagnostics, and false lifecycle markers are omitted. Business facts whose false value is meaningful—such as
valid,visible,found, orfileExists—remain explicit.Editor process activity uses presence tags (
playing,paused,compiling,updating,changingPlayMode, andidle). Everyeditor/statesnapshot also carries authoritativeisPlaying,isPaused, andisChangingPlayModebooleans, so clients can safely distinguish Edit, Play, Pause, and a transition without interpreting an omitted tag. The compositeisPlayingOrWillChangePlaymodealias and successful wait-configuration echoes are not sent.Execute-code uses compact Unity value strings by default. Pass
unityStructFormat="structured"for typed objects with stable fields.Completed pagination aliases and exact duplicate counts are removed on the wire. A sole empty primary collection is preserved so a zero-match result cannot disappear from a completed ticket.
Prefab mutations return semantic results without YAML diffs initially. Request
includePrefabFileDiff=trueor enable the personal preference when line detail is needed.prefab-asset/add-componentaccepts an optionalpropertiesmap and applies it before the first save. Success is returned only after serialized readback confirms both the new component and its requested initial values; useprefab-asset/configure-componentfor idempotent ensure/update work or ObjectReference wiring. PasscreatePathIfMissing=truewhen the component's semantic GameObject path does not exist yet; the path and component are then created and configured in one rollback-capable transaction.All Prefab asset mutations use one authoring-session owner. Serialized views close before save, the isolated authoring root unloads before YAML normalization, import, or persistent readback, and only the adopted product can commit. Failures restore the exact original bytes through the same atomic file publisher and synchronously re-adopt them before returning.
When
referenceAssetPathcontains more than one compatible object, Prefab reference routes requirereferenceSubAssetNameor the lossless decimal stringreferenceSubAssetLocalId. Ambiguous paths fail with bounded candidate details instead of silently assigning the first imported subasset.Sprite sheet slicing replaces the complete Sprite name-fileID mapping and reserializes importer metadata. Renaming or shrinking a sheet therefore does not leave stale subasset names or removed frames in the texture
.metafile.The
pixel-spriteimporter preset preserves an existing Single/Multiple Sprite mode. Usetexture/set-import, a reference importer, or a slicing route when changing that structural mode is intentional.Potentially large raw graph, stack, serialized, and metadata diagnostics are opt-in.
Mutating requests validate
expectedProjectPathbefore dispatch; project names never select or reject a target. Stable idempotency keys, non-reused ticket identities, and persistent queue snapshots protect reload-sensitive workflows. The allocator high-water survives even when replay-safe read ticket payloads are intentionally discarded.Ping and queue health publish the Editor-loop pulse and its age separately from focus/application activity. While the bridge listener is alive, queue submission first atomically persists the request identity and payload even if the Editor loop is temporarily stalled;
queueReadyandeditorLoopAdvancingreport when execution can progress. A durable workspace job continues while the Editor is unfocused and waits through imports, compilation, and domain reload. Other MCP mutations remain durably queued until the workspace job reaches a terminal state.MCP-owned durable state uses one path-keyed publication owner. Writers publish complete immutable text or binary snapshots through private files, disk flush, and atomic replacement; target and backup adoption is serialized with readers, deletes, and bounded operating-system lease handoff. Queue, Job, refresh, build, import, package-test, history, Addressables, and instance-registry state therefore share one failure-closed persistence contract.
HTTP listener startup is transactional: partial binds and registrations are rolled back before retry. Shutdown publishes stopped state first, closes the exact listener generation, and tolerates clients disconnecting while a response is in flight. Project paths compare case-insensitively on Windows and preserve casing on Linux and macOS.
Use
unity_wait_editor_idleafter compilation, package changes, refreshes, or domain reloads before issuing dependent work.
Development and validation
The package contains EditMode regression tests for route authority, metadata,
schemas, configuration precedence, queue/reload behavior, response compaction,
and tool families. Use the persistent testing/run-package-tests workflow when
testing a Git package inside a consumer project. With VM Unity MCP and no
testNames, categories, or groupNames, this workflow runs the curated
VMUnityMCP.PackageSmoke category. Request
categories: ["VMUnityMCP.FullRegression"] only when the complete integration
suite is warranted; exact names, fixture groups, and other categories remain
available for focused validation. The start response contains a jobId and
jobType="package-test" plus a jobAccessToken; poll that identity with
jobs/get, supplying the token after an MCP reconnect, until a terminal status
reports manifestRestored or the explicit manifestRestoreFailed outcome. The
workflow refuses to replace a malformed pre-existing testables value and leaves
externally changed manifest bytes untouched during restoration. A modified
manifest is adopted only when the requested test assemblies enter Unity's
loaded or compiled product; restoration completes only after the exact original
bytes are back and every test assembly declared by that package has left both
products. The workflow persists one resolve issuance across reloads and never
overlaps a second void Client.Resolve() operation for the same transition.
Each modified or original manifest publication also requests one clean
compilation after that resolve, so package test assemblies enter or leave the
compiled product even when Package Manager emits no separate update signal.
When tool metadata changes, synchronize and test the companion Node server, then reconnect the MCP client before judging its cached concrete tool list.
License and related projects
See LICENSE for the complete terms and attribution.
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
- AlicenseNot gradedqualityBmaintenanceUnity Editor MCP SDK that exposes Unity Editor capabilities as MCP tools, enabling AI assistants like Claude Code to drive Unity Editor workflows through prefab inspection, asset manipulation, and preview rendering.MIT
- AlicenseNot gradedqualityCmaintenanceEnables AI agents to control the Unity Editor through MCP, allowing scene building, runtime scripting, visual QA, and more.4Apache 2.0
- AlicenseNot gradedqualityAmaintenanceUnity Editor automation bridge for AI agents and MCP clients, enabling inspection, control, and diagnostics of the Editor.MIT
- AlicenseNot gradedqualityAmaintenanceExposes VMFramework-specific editor workflows as first-class Unity MCP project tools.1MIT
Related MCP Connectors
pub.dev MCP — package registry for Dart & Flutter.
A paid remote MCP for Unity-MCP, built to return verdicts, receipts, usage logs, and audit-ready JSO
Maven Central MCP — Java/JVM artifact registry
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/VM233/VMUnityMCP'
If you have feedback or need assistance with the MCP directory API, please join our Discord server